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, SyntaxErrorEvent};
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 fn syntax_error_event<'a>(
5247 &'a self,
5248 offending: Option<TokenId>,
5249 line: usize,
5250 column: usize,
5251 message: &'a str,
5252 error: Option<&'a AntlrError>,
5253 ) -> SyntaxErrorEvent<'a> {
5254 let offending = offending.and_then(|token| self.token_store().view(token));
5255 SyntaxErrorEvent {
5256 offending,
5257 line,
5258 column,
5259 span: offending.and_then(|token| token.byte_span()),
5260 message,
5261 error,
5262 }
5263 }
5264
5265 pub fn report_unrecovered_parser_error(&self, error: &AntlrError) {
5270 let AntlrError::ParserError {
5271 line,
5272 column,
5273 message,
5274 offending,
5275 } = error
5276 else {
5277 return;
5278 };
5279 self.notify_error_listeners(self.syntax_error_event(
5280 *offending,
5281 *line,
5282 *column,
5283 message,
5284 Some(error),
5285 ));
5286 }
5287
5288 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
5289 self.notify_error_listeners(self.syntax_error_event(
5290 diagnostic.offending,
5291 diagnostic.line,
5292 diagnostic.column,
5293 &diagnostic.message,
5294 None,
5295 ));
5296 }
5297
5298 fn dispatch_parser_diagnostics<'a>(
5299 &self,
5300 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
5301 ) {
5302 for diagnostic in diagnostics {
5303 self.dispatch_parser_diagnostic(diagnostic);
5304 }
5305 }
5306
5307 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
5308 if self.input.token_source().report_error(source_error) {
5309 return;
5310 }
5311 self.notify_error_listeners(source_error.into());
5314 }
5315
5316 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
5317 for error in errors {
5318 self.dispatch_token_source_error(error);
5319 }
5320 }
5321
5322 fn dispatch_generated_diagnostics(
5325 &self,
5326 parser_diagnostics: &[ParserDiagnostic],
5327 token_errors: &[TokenSourceError],
5328 ) {
5329 let mut token_iter = token_errors.iter().peekable();
5335 for diagnostic in parser_diagnostics {
5336 while let Some(error) = token_iter.peek() {
5337 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
5338 self.dispatch_token_source_error(error);
5339 token_iter.next();
5340 } else {
5341 break;
5342 }
5343 }
5344 self.dispatch_parser_diagnostic(diagnostic);
5345 }
5346 for error in token_iter {
5347 self.dispatch_token_source_error(error);
5348 }
5349 }
5350
5351 pub fn record_generated_ambiguity_diagnostic(
5354 &mut self,
5355 atn: &Atn,
5356 state_number: usize,
5357 start_index: usize,
5358 stop_index: usize,
5359 alts: &[usize],
5360 ) {
5361 if !self.report_diagnostic_errors || alts.len() < 2 {
5362 return;
5363 }
5364 let Some(decision) = atn
5365 .decision_to_state()
5366 .iter()
5367 .position(|candidate| candidate == state_number)
5368 else {
5369 return;
5370 };
5371 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5372 return;
5373 };
5374 let rule_name = self
5375 .rule_names()
5376 .get(rule_index)
5377 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5378 let input = display_input_text(&self.input.text(start_index, stop_index));
5379 let alts = alts
5380 .iter()
5381 .map(usize::to_string)
5382 .collect::<Vec<_>>()
5383 .join(", ");
5384 let key = (decision, start_index, format!("{alts}:{input}"));
5385 if !self.reported_prediction_diagnostics.insert(key) {
5386 return;
5387 }
5388 let start_diagnostic = diagnostic_for_token(
5389 self.token_at(start_index),
5390 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5391 );
5392 let stop_diagnostic = diagnostic_for_token(
5393 self.token_at(stop_index),
5394 format!(
5395 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5396 ),
5397 );
5398 self.generated_parser_diagnostics.push(start_diagnostic);
5399 self.generated_parser_diagnostics.push(stop_diagnostic);
5400 }
5401
5402 pub fn record_generated_prediction_diagnostic(
5405 &mut self,
5406 atn: &Atn,
5407 state_number: usize,
5408 prediction: &ParserAtnPrediction,
5409 ) {
5410 let Some(diagnostic) = &prediction.diagnostic else {
5411 return;
5412 };
5413 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5414 return;
5415 }
5416 let Some(decision) = atn
5417 .decision_to_state()
5418 .iter()
5419 .position(|candidate| candidate == state_number)
5420 else {
5421 return;
5422 };
5423 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5424 return;
5425 };
5426 let rule_name = self
5427 .rule_names()
5428 .get(rule_index)
5429 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5430 let attempt_input = display_input_text(
5431 &self
5432 .input
5433 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5434 );
5435 let result_input = display_input_text(
5436 &self
5437 .input
5438 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5439 );
5440 let alts = diagnostic
5441 .conflicting_alts
5442 .iter()
5443 .map(usize::to_string)
5444 .collect::<Vec<_>>()
5445 .join(", ");
5446 let key = (
5447 decision,
5448 diagnostic.start_index,
5449 format!(
5450 "{:?}:{alts}:{attempt_input}:{result_input}",
5451 diagnostic.kind
5452 ),
5453 );
5454 if !self.reported_prediction_diagnostics.insert(key) {
5455 return;
5456 }
5457 let attempt_diagnostic = diagnostic_for_token(
5458 self.token_at(diagnostic.sll_stop_index),
5459 format!(
5460 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5461 ),
5462 );
5463 self.generated_parser_diagnostics.push(attempt_diagnostic);
5464 let message = match diagnostic.kind {
5465 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5466 if !diagnostic.exact {
5471 return;
5472 }
5473 format!(
5474 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5475 )
5476 }
5477 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5478 format!(
5479 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5480 )
5481 }
5482 };
5483 let result_diagnostic =
5484 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5485 self.generated_parser_diagnostics.push(result_diagnostic);
5486 }
5487
5488 pub fn la(&self, offset: isize) -> i32 {
5489 self.input.la_token(offset)
5490 }
5491
5492 pub fn consume(&mut self) {
5493 IntStream::consume(&mut self.input);
5494 }
5495
5496 pub fn set_int_member(&mut self, member: usize, value: i64) {
5498 self.int_members.set_scalar(member, value);
5499 }
5500
5501 pub fn int_member(&self, member: usize) -> Option<i64> {
5503 self.int_members.scalar(member)
5504 }
5505
5506 pub fn push_stack_member(&mut self, member: usize, value: i64) {
5508 self.int_members.push_stack(member, value);
5509 }
5510
5511 pub fn pop_stack_member(&mut self, member: usize) -> Option<i64> {
5514 self.int_members.pop_stack(member)
5515 }
5516
5517 #[must_use]
5520 pub fn stack_member_top(&self, member: usize) -> Option<i64> {
5521 self.int_members.stack_top(member)
5522 }
5523
5524 #[must_use]
5526 pub fn stack_member_len(&self, member: usize) -> usize {
5527 self.int_members.stack_len(member)
5528 }
5529
5530 pub fn set_initial_members(&mut self, initial: impl IntoIterator<Item = (usize, i64)>) {
5537 self.int_members = MemberEnv::with_initial_scalars(initial);
5538 }
5539
5540 #[must_use]
5546 pub fn int_members_checkpoint(&self) -> MemberEnv {
5547 self.int_members.clone()
5548 }
5549
5550 pub fn restore_int_members(&mut self, members: MemberEnv) {
5552 self.int_members = members;
5553 }
5554
5555 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5557 self.int_members.add_scalar(member, delta)
5558 }
5559
5560 fn token_type_for_id(&self, id: TokenId) -> i32 {
5561 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5562 }
5563
5564 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5565 if self.build_parse_trees {
5566 self.tree.terminal(id)
5567 } else {
5568 NodeId::placeholder()
5569 }
5570 }
5571
5572 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5573 if self.build_parse_trees {
5574 self.tree.error(id)
5575 } else {
5576 NodeId::placeholder()
5577 }
5578 }
5579
5580 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5581 context.set_start_id(id);
5582 }
5583
5584 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5585 context.set_stop_id(id);
5586 }
5587
5588 fn insert_synthetic_token(
5589 &mut self,
5590 token_type: i32,
5591 text: String,
5592 line: usize,
5593 column: usize,
5594 ) -> Result<TokenId, AntlrError> {
5595 self.input
5596 .insert(
5597 TokenSpec::explicit(token_type, text)
5598 .with_span(usize::MAX, usize::MAX)
5599 .with_position(line, column),
5600 )
5601 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5602 }
5603
5604 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5611 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5612 line: 0,
5613 column: 0,
5614 message: "missing current token".to_owned(),
5615 offending: None,
5616 })?;
5617 let current_type = self.token_type_for_id(current);
5618 if current_type == token_type {
5619 self.reset_generated_recovery_state();
5620 self.consume();
5621 Ok(self.terminal_tree(current))
5622 } else {
5623 Err(AntlrError::MismatchedInput {
5624 expected: self.vocabulary().display_name(token_type),
5625 found: self.vocabulary().display_name(current_type),
5626 })
5627 }
5628 }
5629
5630 pub fn match_token_recovering(
5634 &mut self,
5635 token_type: i32,
5636 follow_state: usize,
5637 atn: &Atn,
5638 ) -> Result<GeneratedMatch, AntlrError> {
5639 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5640 line: 0,
5641 column: 0,
5642 message: "missing current token".to_owned(),
5643 offending: None,
5644 })?;
5645 let current_type = self.token_type_for_id(current);
5646 if current_type == token_type {
5647 self.generated_sync_expected = None;
5648 self.reset_generated_recovery_state();
5649 let consumed_eof = current_type == TOKEN_EOF;
5650 self.consume();
5651 return Ok(GeneratedMatch {
5652 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5653 consumed_eof,
5654 });
5655 }
5656 let mut expected_symbols = BTreeSet::new();
5657 expected_symbols.insert(token_type);
5658 self.recover_generated_match(
5659 current,
5660 GeneratedExpectedSymbols::Tree(&expected_symbols),
5661 follow_state,
5662 atn,
5663 |symbol| symbol == token_type,
5664 )
5665 }
5666
5667 pub fn match_set_recovering(
5668 &mut self,
5669 intervals: &[(i32, i32)],
5670 follow_state: usize,
5671 atn: &Atn,
5672 ) -> Result<GeneratedMatch, AntlrError> {
5673 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5674 line: 0,
5675 column: 0,
5676 message: "missing current token".to_owned(),
5677 offending: None,
5678 })?;
5679 let current_type = self.token_type_for_id(current);
5680 if interval_set_contains(intervals, current_type) {
5681 self.generated_sync_expected = None;
5682 self.reset_generated_recovery_state();
5683 let consumed_eof = current_type == TOKEN_EOF;
5684 self.consume();
5685 return Ok(GeneratedMatch {
5686 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5687 consumed_eof,
5688 });
5689 }
5690 let expected_symbols = interval_symbols(intervals);
5691 self.recover_generated_match(
5692 current,
5693 GeneratedExpectedSymbols::Tree(&expected_symbols),
5694 follow_state,
5695 atn,
5696 |symbol| interval_set_contains(intervals, symbol),
5697 )
5698 }
5699
5700 pub fn match_token_set_recovering(
5701 &mut self,
5702 set: ParserIntervalSet<'_>,
5703 follow_state: usize,
5704 atn: &Atn,
5705 ) -> Result<GeneratedMatch, AntlrError> {
5706 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5707 line: 0,
5708 column: 0,
5709 message: "missing current token".to_owned(),
5710 offending: None,
5711 })?;
5712 let current_type = self.token_type_for_id(current);
5713 if set.contains(current_type) {
5714 self.generated_sync_expected = None;
5715 self.reset_generated_recovery_state();
5716 let consumed_eof = current_type == TOKEN_EOF;
5717 self.consume();
5718 return Ok(GeneratedMatch {
5719 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5720 consumed_eof,
5721 });
5722 }
5723 self.recover_generated_match(
5724 current,
5725 GeneratedExpectedSymbols::TokenSet(set),
5726 follow_state,
5727 atn,
5728 |symbol| set.contains(symbol),
5729 )
5730 }
5731
5732 pub fn match_not_set_recovering(
5733 &mut self,
5734 intervals: &[(i32, i32)],
5735 min_vocabulary: i32,
5736 max_vocabulary: i32,
5737 follow_state: usize,
5738 atn: &Atn,
5739 ) -> Result<GeneratedMatch, AntlrError> {
5740 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5741 line: 0,
5742 column: 0,
5743 message: "missing current token".to_owned(),
5744 offending: None,
5745 })?;
5746 let current_type = self.token_type_for_id(current);
5747 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5748 && !interval_set_contains(intervals, current_type)
5749 {
5750 self.generated_sync_expected = None;
5751 self.reset_generated_recovery_state();
5752 let consumed_eof = current_type == TOKEN_EOF;
5753 self.consume();
5754 return Ok(GeneratedMatch {
5755 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5756 consumed_eof,
5757 });
5758 }
5759 let expected_symbols =
5760 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5761 self.recover_generated_match(
5762 current,
5763 GeneratedExpectedSymbols::Tree(&expected_symbols),
5764 follow_state,
5765 atn,
5766 |symbol| {
5767 (min_vocabulary..=max_vocabulary).contains(&symbol)
5768 && !interval_set_contains(intervals, symbol)
5769 },
5770 )
5771 }
5772
5773 pub fn match_not_token_set_recovering(
5774 &mut self,
5775 set: ParserIntervalSet<'_>,
5776 min_vocabulary: i32,
5777 max_vocabulary: i32,
5778 follow_state: usize,
5779 atn: &Atn,
5780 ) -> Result<GeneratedMatch, AntlrError> {
5781 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5782 line: 0,
5783 column: 0,
5784 message: "missing current token".to_owned(),
5785 offending: None,
5786 })?;
5787 let current_type = self.token_type_for_id(current);
5788 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
5789 {
5790 self.generated_sync_expected = None;
5791 self.reset_generated_recovery_state();
5792 let consumed_eof = current_type == TOKEN_EOF;
5793 self.consume();
5794 return Ok(GeneratedMatch {
5795 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5796 consumed_eof,
5797 });
5798 }
5799 self.recover_generated_match(
5800 current,
5801 GeneratedExpectedSymbols::TokenSetComplement {
5802 set,
5803 min_vocabulary,
5804 max_vocabulary,
5805 },
5806 follow_state,
5807 atn,
5808 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
5809 )
5810 }
5811
5812 fn recover_generated_match(
5813 &mut self,
5814 current: TokenId,
5815 expected_symbols: GeneratedExpectedSymbols<'_>,
5816 follow_state: usize,
5817 atn: &Atn,
5818 matches: impl Fn(i32) -> bool,
5819 ) -> Result<GeneratedMatch, AntlrError> {
5820 let expected_display = expected_symbols.display(self.vocabulary());
5821 let (current_type, current_line, current_column, current_display) = {
5822 let token = self
5823 .input
5824 .token_view(current)
5825 .expect("current token ID should be valid");
5826 (
5827 token.token_type(),
5828 token.line(),
5829 token.column(),
5830 token_input_display(&token),
5831 )
5832 };
5833 if self.bail_on_error {
5834 return Err(AntlrError::ParserError {
5835 line: current_line,
5836 column: current_column,
5837 message: format!("mismatched input {current_display} expecting {expected_display}"),
5838 offending: Some(current),
5839 });
5840 }
5841 if current_type != TOKEN_EOF
5842 && let Some(next) = self.input.lt_id(2)
5843 && matches(self.token_type_for_id(next))
5844 {
5845 let message =
5846 format!("extraneous input {current_display} expecting {expected_display}");
5847 self.push_generated_parser_diagnostic(ParserDiagnostic {
5848 line: current_line,
5849 column: current_column,
5850 message,
5851 offending: Some(current),
5852 });
5853 self.record_syntax_errors(1);
5854 self.generated_sync_expected = None;
5855 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5858 self.consume();
5859 self.consume();
5860 self.reset_generated_recovery_state();
5861 return Ok(GeneratedMatch {
5862 children: GeneratedMatchChildren::Many(vec![
5863 self.error_tree(current),
5864 self.terminal_tree(next),
5865 ]),
5866 consumed_eof,
5867 });
5868 }
5869 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5870 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5879 && self
5880 .cached_state_expected_symbols(atn, follow_state)
5881 .contains(&TOKEN_EOF);
5882 if follow_symbols.contains(¤t_type)
5883 && (current_type != TOKEN_EOF
5884 || self.rule_context_stack.len() > 1
5885 || expected_symbols.is_empty()
5886 || follow_explicitly_expects_eof)
5887 {
5888 let message = format!("missing {expected_display} at {current_display}");
5889 self.push_generated_parser_diagnostic(ParserDiagnostic {
5890 line: current_line,
5891 column: current_column,
5892 message,
5893 offending: Some(current),
5894 });
5895 self.record_syntax_errors(1);
5896 self.generated_sync_expected = None;
5897 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
5898 let missing_display = expected_symbol_display(token_type, self.vocabulary());
5899 let token = self.insert_synthetic_token(
5900 token_type,
5901 format!("<missing {missing_display}>"),
5902 current_line,
5903 current_column,
5904 )?;
5905 return Ok(GeneratedMatch {
5910 children: GeneratedMatchChildren::One(self.error_tree(token)),
5911 consumed_eof: false,
5912 });
5913 }
5914 let mismatch_expected_display = self
5915 .generated_sync_expected
5916 .take()
5917 .map_or(expected_display, |symbols| {
5918 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
5919 });
5920 Err(AntlrError::ParserError {
5921 line: current_line,
5922 column: current_column,
5923 message: format!(
5924 "mismatched input {current_display} expecting {mismatch_expected_display}"
5925 ),
5926 offending: Some(current),
5927 })
5928 }
5929
5930 fn generated_recovery_follow_symbols(
5931 &mut self,
5932 atn: &Atn,
5933 follow_state: usize,
5934 ) -> BTreeSet<i32> {
5935 let mut follow = self
5936 .cached_state_expected_symbols(atn, follow_state)
5937 .as_ref()
5938 .clone();
5939 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5940 follow.extend(self.context_expected_symbols(atn));
5941 }
5942 follow
5943 }
5944
5945 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5946 self.match_token(TOKEN_EOF)
5947 }
5948
5949 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5950 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5951 }
5952
5953 pub fn match_not_set(
5954 &mut self,
5955 intervals: &[(i32, i32)],
5956 min_vocabulary: i32,
5957 max_vocabulary: i32,
5958 ) -> Result<ParseTree, AntlrError> {
5959 self.match_interval_condition(intervals, |symbol| {
5960 (min_vocabulary..=max_vocabulary).contains(&symbol)
5961 && !interval_set_contains(intervals, symbol)
5962 })
5963 }
5964
5965 fn match_interval_condition(
5966 &mut self,
5967 intervals: &[(i32, i32)],
5968 matches: impl FnOnce(i32) -> bool,
5969 ) -> Result<ParseTree, AntlrError> {
5970 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5971 line: 0,
5972 column: 0,
5973 message: "missing current token".to_owned(),
5974 offending: None,
5975 })?;
5976 let current_type = self.token_type_for_id(current);
5977 if matches(current_type) {
5978 self.reset_generated_recovery_state();
5979 self.consume();
5980 Ok(self.terminal_tree(current))
5981 } else {
5982 Err(AntlrError::MismatchedInput {
5983 expected: self.interval_display(intervals),
5984 found: self.vocabulary().display_name(current_type),
5985 })
5986 }
5987 }
5988
5989 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5990 let values = intervals
5991 .iter()
5992 .map(|(start, stop)| {
5993 if start == stop {
5994 self.vocabulary().display_name(*start)
5995 } else {
5996 format!(
5997 "{}..{}",
5998 self.vocabulary().display_name(*start),
5999 self.vocabulary().display_name(*stop)
6000 )
6001 }
6002 })
6003 .collect::<Vec<_>>()
6004 .join(", ");
6005 format!("{{{values}}}")
6006 }
6007
6008 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
6009 if self.build_parse_trees {
6010 self.tree.finish_rule(context)
6011 } else {
6012 NodeId::placeholder()
6013 }
6014 }
6015
6016 #[must_use]
6025 pub const fn generated_rule_stack_check_due(&self) -> bool {
6026 self.rule_context_stack
6027 .len()
6028 .is_multiple_of(GENERATED_RULE_STACK_CHECK_INTERVAL)
6029 }
6030
6031 #[inline]
6049 pub fn rule_depth_cap_violation(&mut self) -> Option<AntlrError> {
6050 let max = self.max_rule_depth?;
6051 if self.rule_depth_error.is_none()
6054 && self.rule_context_stack.len() + self.recursion_expansions < max
6055 {
6056 return None;
6057 }
6058 Some(self.rule_depth_cap_violation_cold(max))
6059 }
6060
6061 #[cold]
6062 fn rule_depth_cap_violation_cold(&mut self, max: usize) -> AntlrError {
6063 if let Some(error) = &self.rule_depth_error {
6064 return error.clone();
6065 }
6066 let current = self.input.lt(1);
6067 let (line, column) = current
6068 .as_ref()
6069 .map_or((0, 0), |token| (token.line(), token.column()));
6070 let error = AntlrError::ParserError {
6071 line,
6072 column,
6073 message: format!("rule nesting depth limit of {max} exceeded"),
6074 offending: current.as_ref().map(Token::token_id),
6075 };
6076 self.rule_depth_error = Some(error.clone());
6077 error
6078 }
6079
6080 pub const fn take_rule_depth_error(&mut self) -> Option<AntlrError> {
6087 self.rule_depth_error.take()
6088 }
6089
6090 #[must_use]
6097 pub const fn has_rule_depth_cap(&self) -> bool {
6098 self.max_rule_depth.is_some()
6099 }
6100
6101 pub fn add_parse_listener<L>(&mut self, listener: L)
6105 where
6106 L: ParseListener + 'static,
6107 {
6108 self.parse_listeners
6109 .push(ParseListenerSlot(Box::new(listener)));
6110 }
6111
6112 pub fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
6119 self.parse_listener_abort = None;
6120 self.parse_listeners.drain(..).map(|slot| slot.0).collect()
6121 }
6122
6123 #[must_use]
6129 pub const fn has_parse_listeners(&self) -> bool {
6130 !self.parse_listeners.is_empty()
6131 }
6132
6133 #[doc(hidden)]
6138 #[must_use]
6139 pub fn observes_parser_decisions(&self) -> bool {
6140 self.semantic_hooks.observes_parser_decisions()
6141 }
6142
6143 pub fn parse_listener_enter_rule(&mut self, rule_index: usize) -> Option<AntlrError> {
6154 if self.parse_listeners.is_empty() {
6155 return None;
6156 }
6157 self.parse_listener_enter_rule_dispatch(rule_index)
6158 }
6159
6160 fn parse_listener_enter_rule_dispatch(&mut self, rule_index: usize) -> Option<AntlrError> {
6161 if let Some(error) = &self.parse_listener_abort {
6162 return Some(error.clone());
6163 }
6164 let event = EnterRuleEvent {
6165 rule_index,
6166 current: self.input.lt(1),
6167 };
6168 let mut listeners = std::mem::take(&mut self.parse_listeners);
6172 let mut abort = None;
6173 for slot in &mut listeners {
6174 if let Err(error) = slot.0.enter_every_rule(&event) {
6175 abort = Some(error);
6176 break;
6177 }
6178 }
6179 self.parse_listeners = listeners;
6180 if let Some(error) = abort {
6181 self.parse_listener_abort = Some(error.clone());
6182 return Some(error);
6183 }
6184 None
6185 }
6186
6187 pub fn parse_listener_exit_rule(&mut self, rule_index: usize) {
6194 if self.parse_listeners.is_empty() {
6195 return;
6196 }
6197 for slot in self.parse_listeners.iter_mut().rev() {
6200 slot.0.exit_every_rule(rule_index);
6201 }
6202 }
6203
6204 pub const fn take_parse_listener_abort(&mut self) -> Option<AntlrError> {
6211 self.parse_listener_abort.take()
6212 }
6213
6214 pub fn take_parse_abort(&mut self) -> Option<AntlrError> {
6223 if let Some(error) = self.rule_depth_error.take() {
6224 self.parse_listener_abort = None;
6225 return Some(error);
6226 }
6227 self.parse_listener_abort.take()
6228 }
6229
6230 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
6233 self.set_state(state);
6234 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
6235 self.rule_context_stack.push(RuleContextFrame {
6236 rule_index,
6237 invoking_state,
6238 });
6239 self.advance_rule_context_version();
6240 let start_index = self.current_visible_index();
6241 let mut context = ParserRuleContext::new(rule_index, invoking_state);
6242 if let Some(token) = self.token_id_at(start_index) {
6243 self.set_context_start(&mut context, token);
6244 }
6245 context
6246 }
6247
6248 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
6255 let marker = self.pending_invoking_states.len();
6256 self.pending_invoking_states.push(invoking_state);
6257 marker
6258 }
6259
6260 pub fn discard_invoking_state(&mut self, marker: usize) {
6262 self.pending_invoking_states.truncate(marker);
6263 }
6264
6265 pub fn exit_rule(&mut self) {
6267 self.rule_context_stack.pop();
6268 self.advance_rule_context_version();
6269 }
6270
6271 pub fn prediction_context_return_states<'a>(
6274 &'a self,
6275 atn: &'a Atn,
6276 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
6277 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
6278 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
6279 return None;
6280 };
6281 let Some(Transition::Rule { follow_state, .. }) = atn
6282 .state(state_number)
6283 .and_then(|state| state.transitions().first())
6284 .map(ParserTransition::data)
6285 else {
6286 return None;
6287 };
6288 Some(follow_state)
6289 })
6290 }
6291
6292 pub const fn rule_context_version(&self) -> usize {
6297 self.rule_context_version
6298 }
6299
6300 const fn advance_rule_context_version(&mut self) {
6301 self.rule_context_version = self.rule_context_version.wrapping_add(1);
6302 }
6303
6304 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
6309 if self.build_parse_trees {
6310 self.tree.add_child(context, child);
6311 } else {
6312 context.note_matched_child();
6313 }
6314 }
6315
6316 fn release_tree_scratch_if_idle(&mut self) {
6317 if self.rule_context_stack.is_empty() {
6318 self.tree.release_scratch();
6319 }
6320 }
6321
6322 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
6324 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6325 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6326 self.set_context_stop(&mut context, token);
6327 }
6328 let node = self.rule_node(context);
6329 self.exit_rule();
6330 self.release_tree_scratch_if_idle();
6331 node
6332 }
6333
6334 pub fn recover_generated_rule(
6341 &mut self,
6342 context: &mut ParserRuleContext,
6343 atn: &Atn,
6344 error: AntlrError,
6345 ) {
6346 let diagnostic = self.generated_rule_error_diagnostic(error);
6347 self.push_generated_parser_diagnostic(diagnostic);
6348 self.generated_sync_expected = None;
6349 let error_index = self.input.index();
6350 let error_state = self.data.state();
6351 if self.generated_recovery_error_index == Some(error_index)
6356 && self.generated_recovery_error_states.contains(&error_state)
6357 && self.la(1) != TOKEN_EOF
6358 && let Some(token) = self.input.lt_id(1)
6359 {
6360 self.consume();
6361 let child = self.error_tree(token);
6362 self.add_parse_child(context, child);
6363 }
6364 let recovery_index = self.input.index();
6365 if self.generated_recovery_error_index != Some(recovery_index) {
6366 self.generated_recovery_error_index = Some(recovery_index);
6367 self.generated_recovery_error_states.clear();
6368 }
6369 self.generated_recovery_error_states.insert(error_state);
6370 let recovery_symbols = self.context_expected_symbols(atn);
6371 loop {
6372 let symbol = self.la(1);
6373 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
6374 break;
6375 }
6376 let Some(token) = self.input.lt_id(1) else {
6377 break;
6378 };
6379 self.consume();
6380 let child = self.error_tree(token);
6381 self.add_parse_child(context, child);
6382 }
6383 self.record_syntax_errors(1);
6384 }
6385
6386 fn reset_generated_recovery_state(&mut self) {
6387 if self.generated_recovery_error_index.is_some() {
6388 self.generated_recovery_error_index = None;
6389 self.generated_recovery_error_states.clear();
6390 }
6391 }
6392
6393 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
6394 if self
6395 .generated_parser_diagnostics
6396 .iter()
6397 .any(|existing| existing == &diagnostic)
6398 {
6399 return;
6400 }
6401 self.generated_parser_diagnostics.push(diagnostic);
6402 }
6403
6404 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
6405 match error {
6406 AntlrError::ParserError {
6410 line,
6411 column,
6412 message,
6413 offending,
6414 } => ParserDiagnostic {
6415 line,
6416 column,
6417 message,
6418 offending,
6419 },
6420 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
6421 self.input.lt(1),
6422 format!("mismatched input {found} expecting {expected}"),
6423 ),
6424 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
6425 self.input.lt(1),
6426 format!("no viable alternative at input {input}"),
6427 ),
6428 AntlrError::LexerError {
6429 line,
6430 column,
6431 message,
6432 } => ParserDiagnostic {
6433 line,
6434 column,
6435 message,
6436 offending: None,
6437 },
6438 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
6439 }
6440 }
6441
6442 pub fn finish_recursion_rule(
6444 &mut self,
6445 mut context: ParserRuleContext,
6446 consumed_eof: bool,
6447 ) -> ParseTree {
6448 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6449 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6450 self.set_context_stop(&mut context, token);
6451 }
6452 let node = self.rule_node(context);
6453 self.unroll_recursion_context();
6454 self.release_tree_scratch_if_idle();
6455 node
6456 }
6457
6458 pub fn enter_recursion_rule(
6460 &mut self,
6461 state: isize,
6462 rule_index: usize,
6463 precedence: i32,
6464 ) -> ParserRuleContext {
6465 self.precedence_stack.push(precedence);
6466 self.recursion_expansion_marks
6467 .push(self.recursion_expansions);
6468 self.enter_rule(state, rule_index)
6469 }
6470
6471 pub fn push_new_recursion_context(
6473 &mut self,
6474 state: isize,
6475 rule_index: usize,
6476 ) -> ParserRuleContext {
6477 self.set_state(state);
6478 self.recursion_expansions += 1;
6481 ParserRuleContext::new(rule_index, state)
6482 }
6483
6484 pub fn push_new_recursion_context_with_previous(
6487 &mut self,
6488 state: isize,
6489 rule_index: usize,
6490 current: &mut ParserRuleContext,
6491 ) {
6492 self.set_state(state);
6493 self.recursion_expansions += 1;
6499 if let Some(stop) = self
6500 .rule_stop_token_index(self.input.index(), false)
6501 .and_then(|index| self.token_id_at(index))
6502 {
6503 self.set_context_stop(current, stop);
6504 }
6505 let invoking_state = current.invoking_state();
6506 let start = current.start_id();
6507 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
6508 if start.is_some() {
6509 replacement.set_start_from_context(current);
6510 }
6511 let previous = std::mem::replace(current, replacement);
6512 if self.build_parse_trees {
6513 let previous = self.rule_node(previous);
6514 self.tree.add_child(current, previous);
6515 }
6516 }
6517
6518 pub fn unroll_recursion_context(&mut self) {
6520 if self.precedence_stack.len() > 1 {
6521 self.precedence_stack.pop();
6522 }
6523 if let Some(mark) = self.recursion_expansion_marks.pop() {
6529 self.recursion_expansions = mark;
6530 }
6531 self.exit_rule();
6532 }
6533
6534 pub fn left_recursive_loop_enter_prediction(
6548 &mut self,
6549 atn: &Atn,
6550 state_number: usize,
6551 precedence: i32,
6552 ) -> Option<bool> {
6553 let symbol = self.la(1);
6554 if symbol == TOKEN_EOF {
6555 return Some(false);
6556 }
6557 let operator_lookahead =
6558 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
6559 let can_single = operator_lookahead.single_token.contains(symbol);
6560 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
6561 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
6562 if !can_single && !can_multi && !can_predicate {
6563 return Some(false);
6564 }
6565 if can_predicate && !can_single {
6566 return None;
6567 }
6568 if !can_single && can_multi && precedence > 0 {
6572 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
6573 if baseline.single_token.contains(symbol) {
6574 return None;
6575 }
6576 }
6577 let atn_key = SharedAtnCacheKey::for_atn(atn);
6578 let cached_overlap = self
6579 .left_recursive_caller_overlap_cache
6580 .iter()
6581 .flatten()
6582 .find(|entry| {
6583 entry.atn_key == atn_key
6584 && entry.state_number == state_number
6585 && entry.symbol == symbol
6586 && entry.context_version == self.rule_context_version
6587 })
6588 .map(|entry| entry.overlaps);
6589 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
6590 let overlaps = caller_context_can_match_symbol_before_state(
6591 atn,
6592 self.prediction_context_return_states(atn),
6593 state_number,
6594 symbol,
6595 );
6596 if let Some(slot) = self
6597 .left_recursive_caller_overlap_cache
6598 .iter_mut()
6599 .find(|slot| slot.is_none())
6600 {
6601 *slot = Some(LeftRecursiveCallerOverlap {
6602 atn_key,
6603 state_number,
6604 symbol,
6605 context_version: self.rule_context_version,
6606 overlaps,
6607 });
6608 }
6609 overlaps
6610 });
6611 if caller_overlaps {
6612 return None;
6613 }
6614 Some(true)
6615 }
6616
6617 fn cached_left_recursive_operator_lookahead(
6618 atn: &Atn,
6619 state_number: usize,
6620 precedence: i32,
6621 ) -> Rc<LeftRecursiveOperatorLookahead> {
6622 with_shared_atn_caches(atn, |cache| {
6623 let key = (state_number, precedence);
6624 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
6625 return Rc::clone(cached);
6626 }
6627 let lookahead = Rc::new(left_recursive_operator_lookahead(
6628 atn,
6629 state_number,
6630 precedence,
6631 ));
6632 cache
6633 .left_recursive_operator_lookahead
6634 .insert(key, Rc::clone(&lookahead));
6635 lookahead
6636 })
6637 }
6638
6639 pub fn left_recursive_loop_enter_matches(
6642 &mut self,
6643 atn: &Atn,
6644 state_number: usize,
6645 precedence: i32,
6646 ) -> bool {
6647 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
6648 }
6649
6650 pub fn precpred(&self, precedence: i32) -> bool {
6652 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
6653 }
6654
6655 pub fn parser_semantic_predicate_matches(
6658 &mut self,
6659 predicates: &[(usize, usize, ParserPredicate)],
6660 rule_index: usize,
6661 pred_index: usize,
6662 ) -> bool {
6663 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
6664 }
6665
6666 pub fn parser_semantic_predicate_matches_with_local(
6669 &mut self,
6670 predicates: &[(usize, usize, ParserPredicate)],
6671 rule_index: usize,
6672 pred_index: usize,
6673 local_int_arg: i32,
6674 ) -> bool {
6675 self.parser_semantic_predicate_matches_inner(
6676 predicates,
6677 rule_index,
6678 pred_index,
6679 Some((rule_index, i64::from(local_int_arg))),
6680 )
6681 }
6682
6683 fn parser_semantic_predicate_matches_inner(
6684 &mut self,
6685 predicates: &[(usize, usize, ParserPredicate)],
6686 rule_index: usize,
6687 pred_index: usize,
6688 local_int_arg: Option<(usize, i64)>,
6689 ) -> bool {
6690 let index = self.input.index();
6691 let member_values = self.int_members.clone();
6692 self.parser_predicate_matches(PredicateEval {
6693 index,
6694 rule_index,
6695 pred_index,
6696 predicates,
6697 semantics: None,
6698 context: None,
6699 local_int_arg,
6700 member_values: &member_values,
6701 })
6702 }
6703
6704 pub fn parser_semantic_predicate_matches_with_context_and_local(
6707 &mut self,
6708 predicates: &[(usize, usize, ParserPredicate)],
6709 rule_index: usize,
6710 pred_index: usize,
6711 context: &ParserRuleContext,
6712 local_int_arg: i32,
6713 ) -> bool {
6714 let index = self.input.index();
6715 let member_values = self.int_members.clone();
6716 self.parser_predicate_matches(PredicateEval {
6717 index,
6718 rule_index,
6719 pred_index,
6720 predicates,
6721 semantics: None,
6722 context: Some(context),
6723 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6724 member_values: &member_values,
6725 })
6726 }
6727
6728 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6731 &mut self,
6732 semantics: &ParserSemantics,
6733 rule_index: usize,
6734 pred_index: usize,
6735 context: &ParserRuleContext,
6736 local_int_arg: i32,
6737 ) -> bool {
6738 let index = self.input.index();
6739 let member_values = self.int_members.clone();
6740 self.parser_predicate_matches(PredicateEval {
6741 index,
6742 rule_index,
6743 pred_index,
6744 predicates: &[],
6745 semantics: Some(semantics),
6746 context: Some(context),
6747 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6748 member_values: &member_values,
6749 })
6750 }
6751
6752 pub fn parser_semantic_predicate_failure_message(
6755 &self,
6756 rule_index: usize,
6757 pred_index: usize,
6758 predicates: &[(usize, usize, ParserPredicate)],
6759 ) -> Option<&'static str> {
6760 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6761 }
6762
6763 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6765 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6766 line: 0,
6767 column: 0,
6768 message: "missing current token".to_owned(),
6769 offending: None,
6770 })?;
6771 if self.token_type_for_id(current) == TOKEN_EOF {
6772 return Err(AntlrError::MismatchedInput {
6773 expected: "wildcard".to_owned(),
6774 found: self.vocabulary().display_name(TOKEN_EOF),
6775 });
6776 }
6777 self.reset_generated_recovery_state();
6778 self.consume();
6779 Ok(self.terminal_tree(current))
6780 }
6781
6782 #[allow(clippy::unnecessary_wraps)]
6786 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
6787 self.set_state(state);
6788 Ok(())
6789 }
6790
6791 pub fn sync_decision(
6799 &mut self,
6800 atn: &Atn,
6801 state_number: usize,
6802 current_context_empty: bool,
6803 loop_back: bool,
6804 ) -> Result<Vec<ParseTree>, AntlrError> {
6805 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
6806 self.generated_sync_expected = None;
6807 let Some(state) = atn.state(state_number) else {
6808 return Ok(Vec::new());
6809 };
6810 let Some(rule_index) = state.rule_index() else {
6811 return Ok(Vec::new());
6812 };
6813 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
6814 return Ok(Vec::new());
6815 };
6816 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6817 let symbol = self.la(1);
6818 let mut has_expected_symbols = false;
6819 let mut nullable = false;
6820 let mut explicit_eof_expected = false;
6828 for transition in &entry.transitions {
6829 if transition.symbols.contains(symbol) {
6830 return Ok(Vec::new());
6831 }
6832 has_expected_symbols |= !transition.symbols.is_empty();
6833 nullable |= transition.nullable;
6834 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
6835 }
6836 if nullable && self.context_expected_contains(atn, symbol) {
6841 return Ok(Vec::new());
6842 }
6843 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
6844 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
6845 return Ok(Vec::new());
6846 }
6847 let mut expected = TokenBitSet::default();
6848 for transition in &entry.transitions {
6849 expected.extend_from(&transition.symbols);
6850 }
6851 if let Some(context_expected) = context_expected {
6852 expected.extend_from(&context_expected);
6853 }
6854 let can_delete_in_place =
6855 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
6856 let loop_sync = loop_back;
6873 if symbol != TOKEN_EOF && can_delete_in_place {
6874 let mut cursor = self.input.index();
6875 let mut skipped = Vec::new();
6876 loop {
6877 let current = self.token_type_at(cursor);
6878 if current == TOKEN_EOF {
6879 break;
6880 }
6881 skipped.push(cursor);
6882 let next = self.consume_index(cursor, current);
6883 if next == cursor {
6884 break;
6885 }
6886 let next_symbol = self.token_type_at(next);
6887 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
6895 explicit_eof_expected
6896 } else {
6897 expected.contains(next_symbol)
6898 };
6899 if next_is_expected_stop {
6900 let current_token = self.input.lt(1);
6901 let expected_symbols = expected.to_btree_set();
6902 let message = format!(
6903 "extraneous input {} expecting {}",
6904 current_token
6905 .as_ref()
6906 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6907 self.expected_symbols_display(&expected_symbols)
6908 );
6909 self.push_generated_parser_diagnostic(diagnostic_for_token(
6910 current_token,
6911 message,
6912 ));
6913 self.record_syntax_errors(1);
6914 let mut children = Vec::with_capacity(skipped.len());
6915 for index in skipped {
6916 if let Some(token) = self.token_id_at(index) {
6917 self.consume();
6918 children.push(self.error_tree(token));
6919 }
6920 }
6921 if !loop_sync {
6922 self.reset_generated_recovery_state();
6923 }
6924 return Ok(children);
6925 }
6926 if !loop_sync {
6930 break;
6931 }
6932 cursor = next;
6933 }
6934 }
6935 if nullable {
6936 self.generated_sync_expected = Some(expected);
6937 return Ok(Vec::new());
6938 }
6939 let current = self.input.lt(1);
6940 let expected_symbols = expected.to_btree_set();
6941 Err(AntlrError::ParserError {
6942 line: current.as_ref().map(Token::line).unwrap_or_default(),
6943 column: current.as_ref().map(Token::column).unwrap_or_default(),
6944 message: format!(
6945 "mismatched input {} expecting {}",
6946 current
6947 .as_ref()
6948 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6949 self.expected_symbols_display(&expected_symbols)
6950 ),
6951 offending: current.as_ref().map(Token::token_id),
6952 })
6953 }
6954
6955 pub fn ll1_decision_prediction(
6962 &mut self,
6963 atn: &Atn,
6964 state_number: usize,
6965 ) -> Option<ParserAtnPrediction> {
6966 let state = atn.state(state_number)?;
6967 if state.precedence_rule_decision() {
6968 return None;
6969 }
6970 let rule_stop = state
6971 .rule_index()
6972 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
6973 let symbol = self.la(1);
6974 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6975 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
6976 alt: alt + 1,
6977 requires_full_context: false,
6978 has_semantic_context: false,
6979 diagnostic: None,
6980 })
6981 }
6982
6983 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
6984 let mut expected = BTreeSet::new();
6985 for index in (1..self.rule_context_stack.len()).rev() {
6986 let invoking_state = self.rule_context_stack[index].invoking_state;
6987 let Ok(state_number) = usize::try_from(invoking_state) else {
6988 continue;
6989 };
6990 let Some(Transition::Rule { follow_state, .. }) = atn
6991 .state(state_number)
6992 .and_then(|state| state.transitions().first())
6993 .map(ParserTransition::data)
6994 else {
6995 continue;
6996 };
6997 let return_state = follow_state;
6998 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
6999 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
7000 return expected;
7001 }
7002 }
7003 expected.insert(TOKEN_EOF);
7004 expected
7005 }
7006
7007 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
7008 let mut expected = TokenBitSet::default();
7009 for index in (1..self.rule_context_stack.len()).rev() {
7010 let invoking_state = self.rule_context_stack[index].invoking_state;
7011 let Ok(state_number) = usize::try_from(invoking_state) else {
7012 continue;
7013 };
7014 let Some(Transition::Rule { follow_state, .. }) = atn
7015 .state(state_number)
7016 .and_then(|state| state.transitions().first())
7017 .map(ParserTransition::data)
7018 else {
7019 continue;
7020 };
7021 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
7022 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7023 return expected;
7024 }
7025 }
7026 expected.insert(TOKEN_EOF);
7027 expected
7028 }
7029
7030 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
7041 for index in (1..self.rule_context_stack.len()).rev() {
7042 let invoking_state = self.rule_context_stack[index].invoking_state;
7043 let Ok(state_number) = usize::try_from(invoking_state) else {
7044 continue;
7045 };
7046 let Some(Transition::Rule { follow_state, .. }) = atn
7047 .state(state_number)
7048 .and_then(|state| state.transitions().first())
7049 .map(ParserTransition::data)
7050 else {
7051 continue;
7052 };
7053 if self
7054 .cached_state_expected_token_set(atn, follow_state)
7055 .contains(symbol)
7056 {
7057 return true;
7058 }
7059 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7060 return false;
7061 }
7062 }
7063 symbol == TOKEN_EOF
7064 }
7065
7066 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
7068 let error_index = self.input.index();
7069 self.no_viable_alternative_error_at(start_index, error_index)
7070 }
7071
7072 pub fn no_viable_alternative_error_at(
7077 &self,
7078 start_index: usize,
7079 error_index: usize,
7080 ) -> AntlrError {
7081 let diagnostic = self.no_viable_alternative(start_index, error_index);
7082 AntlrError::ParserError {
7083 line: diagnostic.line,
7084 column: diagnostic.column,
7085 message: diagnostic.message,
7086 offending: diagnostic.offending,
7087 }
7088 }
7089
7090 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
7092 let current = self.input.lt(1);
7093 AntlrError::ParserError {
7094 line: current.as_ref().map(Token::line).unwrap_or_default(),
7095 column: current.as_ref().map(Token::column).unwrap_or_default(),
7096 message: format!("rule failed predicate: {}", message.into()),
7097 offending: current.as_ref().map(Token::token_id),
7098 }
7099 }
7100
7101 pub fn failed_predicate_option_error(
7104 &self,
7105 rule_index: usize,
7106 message: impl Into<String>,
7107 ) -> AntlrError {
7108 let current = self.input.lt(1);
7109 let rule_name = self
7110 .rule_names()
7111 .get(rule_index)
7112 .map_or_else(|| rule_index.to_string(), Clone::clone);
7113 AntlrError::ParserError {
7114 line: current.as_ref().map(Token::line).unwrap_or_default(),
7115 column: current.as_ref().map(Token::column).unwrap_or_default(),
7116 message: format!("rule {rule_name} {}", message.into()),
7117 offending: current.as_ref().map(Token::token_id),
7118 }
7119 }
7120
7121 pub fn parser_action_at_current(
7123 &mut self,
7124 source_state: usize,
7125 rule_index: usize,
7126 start_index: usize,
7127 consumed_eof: bool,
7128 ) -> ParserAction {
7129 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7130 ParserAction::new(source_state, rule_index, start_index, stop_index)
7131 }
7132
7133 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
7138 let rule_index = action.rule_index();
7139 let rule_name = self.rule_names().get(rule_index).cloned();
7140 let context = None;
7141 let input = &mut self.input;
7142 let semantic_hooks = &mut self.semantic_hooks;
7143 let member_values = &self.int_members;
7144 let mut ctx = ParserSemCtx {
7145 input,
7146 tree_storage: &self.tree,
7147 rule_index,
7148 coordinate_index: usize::MAX,
7149 rule_name,
7150 context,
7151 tree: Some(tree),
7152 local_int_arg: None,
7153 member_values,
7154 action: Some(action),
7155 };
7156 let handled = semantic_hooks.action(&mut ctx, action);
7157 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
7163 let coordinate = (rule_index, action.source_state());
7164 if !self.unhandled_action_hits.contains(&coordinate) {
7165 self.unhandled_action_hits.push(coordinate);
7166 }
7167 }
7168 handled
7169 }
7170
7171 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
7176 &mut self,
7177 atn: &'atn Atn,
7178 simulator: &mut ParserAtnSimulator<'atn>,
7179 rule_index: usize,
7180 ) -> Result<ParseTree, AntlrError> {
7181 let start_index = self.current_visible_index();
7182 self.clear_prediction_diagnostics();
7183 self.reset_per_parse_caches();
7184 self.reset_recognition_arena();
7185 let tree_checkpoint = self.tree.checkpoint();
7186 let mut decision_by_state = vec![None; atn.states().len()];
7187 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
7188 if let Some(slot) = decision_by_state.get_mut(state_number) {
7189 *slot = Some(decision);
7190 }
7191 }
7192
7193 let result = DirectAdaptiveParser {
7194 parser: self,
7195 atn,
7196 simulator,
7197 decision_by_state,
7198 steps: 0,
7199 }
7200 .parse_rule(rule_index, -1, 0);
7201
7202 match result {
7203 Ok(tree) => {
7204 self.report_token_source_errors();
7205 self.release_tree_scratch_if_idle();
7206 Ok(tree)
7207 }
7208 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
7209 let _ = reason;
7210 self.tree.rollback(tree_checkpoint);
7211 self.input.seek(start_index);
7212 self.parse_atn_rule(atn, rule_index)
7213 }
7214 }
7215 }
7216
7217 pub fn parse_atn_rule(
7227 &mut self,
7228 atn: &Atn,
7229 rule_index: usize,
7230 ) -> Result<ParseTree, AntlrError> {
7231 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
7232 }
7233
7234 pub fn parse_atn_rule_with_precedence(
7237 &mut self,
7238 atn: &Atn,
7239 rule_index: usize,
7240 precedence: i32,
7241 ) -> Result<ParseTree, AntlrError> {
7242 self.parse_atn_rule_with_precedence_inner(
7243 atn,
7244 rule_index,
7245 precedence,
7246 None,
7247 AltNumberTracking::default(),
7248 )
7249 }
7250
7251 fn parse_atn_rule_with_precedence_inner(
7252 &mut self,
7253 atn: &Atn,
7254 rule_index: usize,
7255 precedence: i32,
7256 predicate_context: Option<FastPredicateContext<'_>>,
7257 alt_tracking: AltNumberTracking,
7258 ) -> Result<ParseTree, AntlrError> {
7259 let report_unrecovered_error = self.is_top_level_entry();
7260 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7261 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7262 })?;
7263 let stop_state = atn
7264 .rule_to_stop_state()
7265 .get(rule_index)
7266 .filter(|state| *state != usize::MAX)
7267 .ok_or_else(|| {
7268 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7269 })?;
7270
7271 let start_index = self.current_visible_index();
7272 self.clear_prediction_diagnostics();
7273 self.reset_per_parse_caches();
7274 self.reset_recognition_arena();
7275 let caller_follow_state = self.pending_invoking_follow_state(atn);
7276 self.fast_recovery_enabled = false;
7277 self.fast_token_nodes_enabled = false;
7278 self.fast_track_alt_numbers = alt_tracking.any();
7279 let top_request = FastRecognizeTopRequest {
7280 start_state,
7281 stop_state,
7282 start_index,
7283 precedence,
7284 caller_follow_state,
7285 };
7286 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
7287 self.fast_token_nodes_enabled = self.build_parse_trees;
7288 let needs_tree_retry = matches!(
7289 &first_pass,
7290 Ok((outcome, _, _))
7291 if self.build_parse_trees
7292 && self
7293 .recognition_arena
7294 .sequence_has_left_recursive_boundary(outcome.nodes)
7295 );
7296 let needs_retry = match &first_pass {
7297 Err(_) => true,
7310 Ok((outcome, _, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
7311 };
7312 let (outcome, _expected, alt_number) = if needs_retry {
7313 self.fast_first_set_prefilter = false;
7314 self.fast_recovery_enabled = false;
7315 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7316 let clean_selected = if needs_tree_retry {
7317 match clean_retry {
7318 ok @ Ok(_) => ok,
7319 Err(_) => first_pass,
7320 }
7321 } else {
7322 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
7323 };
7324 let selected = if clean_selected.is_err()
7325 || matches!(&clean_selected, Ok((outcome, _, _)) if !outcome.diagnostics.is_empty())
7326 {
7327 self.fast_recovery_enabled = true;
7328 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7329 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
7330 } else {
7331 clean_selected
7332 };
7333 self.fast_first_set_prefilter = true;
7334 self.fast_recovery_enabled = true;
7335 selected.map_err(|expected| {
7336 if predicate_context.is_some()
7337 && let Some(error) = self.unknown_semantic_error()
7338 {
7339 self.report_token_source_errors();
7340 return error;
7341 }
7342 let error = self.recognition_error(rule_index, start_index, &expected);
7343 self.record_syntax_errors(1);
7344 self.report_token_source_errors();
7345 if report_unrecovered_error {
7346 self.report_unrecovered_parser_error(&error);
7347 }
7348 error
7349 })?
7350 } else {
7351 first_pass.expect("first_pass is Ok in the no-retry branch")
7352 };
7353 if predicate_context.is_some()
7354 && let Some(error) = self.unknown_semantic_error()
7355 {
7356 self.report_token_source_errors();
7357 return Err(error);
7358 }
7359 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7360 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7361 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7362 self.report_token_source_errors();
7363 let mut context = ParserRuleContext::with_child_capacity(
7364 rule_index,
7365 self.state(),
7366 if self.build_parse_trees {
7367 self.recognition_arena.sequence_len(outcome.nodes)
7368 } else {
7369 0
7370 },
7371 );
7372 if alt_tracking.public {
7373 context.set_alt_number(alt_number.max(1));
7374 }
7375 if alt_tracking.context {
7376 context.set_context_alt_number(alt_number);
7377 }
7378 if let Some(token) = self.token_id_at(start_index) {
7379 self.set_context_start(&mut context, token);
7380 }
7381 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
7382 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
7383 self.set_context_stop(&mut context, token);
7384 }
7385 let live_root = if self.build_parse_trees {
7386 self.recognition_arena
7387 .fold_left_recursive_boundaries(outcome.nodes)
7388 } else {
7389 outcome.nodes
7390 };
7391 if self.build_parse_trees {
7392 if self
7393 .recognition_arena
7394 .sequence_has_explicit_token(live_root)
7395 {
7396 let mut cursor = live_root;
7397 while let Some(link) = self.recognition_arena.link(cursor) {
7398 let child = self.arena_recognized_node_tree(
7399 link.head,
7400 alt_tracking.public,
7401 alt_tracking.context,
7402 )?;
7403 self.tree.add_child(&mut context, child);
7404 cursor = link.tail;
7405 }
7406 } else {
7407 self.add_arena_implicit_token_children(
7408 &mut context,
7409 start_index,
7410 stop_index,
7411 live_root,
7412 alt_tracking,
7413 )?;
7414 }
7415 }
7416 self.finish_recognition_arena(live_root, outcome.diagnostics);
7417 self.input.seek(outcome.index);
7418
7419 let tree = self.rule_node(context);
7420 self.release_tree_scratch_if_idle();
7421 Ok(tree)
7422 }
7423
7424 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
7425 let invoking_state = self.pending_invoking_states.last().copied()?;
7426 let state_number = usize::try_from(invoking_state).ok()?;
7427 match atn.state(state_number)?.transitions().first()?.data() {
7428 Transition::Rule { follow_state, .. } => Some(follow_state),
7429 _ => None,
7430 }
7431 }
7432
7433 #[cfg(test)]
7434 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
7435 caller_follow_token_info_for_stream(&mut self.input, index)
7436 }
7437
7438 fn fast_recognize_top(
7443 &mut self,
7444 atn: &Atn,
7445 request: FastRecognizeTopRequest,
7446 predicate_context: Option<FastPredicateContext<'_>>,
7447 ) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
7448 let FastRecognizeTopRequest {
7449 start_state,
7450 stop_state,
7451 start_index,
7452 precedence,
7453 caller_follow_state,
7454 } = request;
7455 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
7464 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
7465 recognize_scratch.prepare(memo_capacity);
7466 let mut expected = ExpectedTokens::default();
7467 let empty_recovery = self.empty_recovery_symbols();
7468 let outcomes = self.recognize_state_fast(
7469 atn,
7470 FastRecognizeRequest {
7471 state_number: start_state,
7472 stop_state,
7473 index: start_index,
7474 rule_start_index: start_index,
7475 decision_start_index: None,
7476 precedence,
7477 depth: 0,
7478 recovery_symbols: empty_recovery,
7479 recovery_state: None,
7480 },
7481 FastRecognizeScratch {
7482 predicate_context,
7483 visiting: &mut recognize_scratch.visiting,
7484 memo: &mut recognize_scratch.memo,
7485 expected: &mut expected,
7486 native_depth: 0,
7487 },
7488 );
7489 recognize_scratch.release_oversized_memo();
7490 self.fast_recognize_scratch = recognize_scratch;
7491 #[cfg(feature = "perf-counters")]
7492 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
7493 perf_counters::dump();
7494 perf_counters::reset();
7495 }
7496 let caller_follow =
7497 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
7498 let selected = {
7499 let arena = &self.recognition_arena;
7500 let input = &mut self.input;
7501 select_best_fast_outcome(
7502 outcomes.into_iter(),
7503 self.prediction_mode,
7504 caller_follow.as_deref(),
7505 |index| caller_follow_token_info_for_stream(input, index),
7506 arena,
7507 )
7508 };
7509 match selected {
7510 Some(mut outcome) => {
7511 let alt_number = if self.build_parse_trees || self.fast_track_alt_numbers {
7512 self.materialize_fast_outcome_nodes(&mut outcome)
7513 } else {
7514 0
7515 };
7516 Ok((outcome, expected, alt_number))
7517 }
7518 None => Err(expected),
7519 }
7520 }
7521
7522 fn arena_recognized_node_tree(
7524 &mut self,
7525 node_id: RecognizedNodeId,
7526 track_alt_numbers: bool,
7527 track_context_alt_numbers: bool,
7528 ) -> Result<ParseTree, AntlrError> {
7529 let node = self.recognition_arena.node(node_id);
7530 match node {
7531 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
7532 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
7533 ArenaRecognizedNode::MissingToken { extra } => {
7534 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
7535 RecognitionExtra::MissingToken {
7536 token_type,
7537 at_index,
7538 text,
7539 } => (*token_type, *at_index as usize, text.clone()),
7540 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
7541 unreachable!("missing-token node must reference missing-token extra")
7542 }
7543 };
7544 let (line, column) = self
7545 .token_at(at_index)
7546 .map_or((0, 0), |token| (token.line(), token.column()));
7547 let token = self.insert_synthetic_token(token_type, text, line, column)?;
7548 Ok(self.error_tree(token))
7549 }
7550 ArenaRecognizedNode::Rule {
7551 rule_index,
7552 invoking_state,
7553 alt_number,
7554 start_index,
7555 stop_index,
7556 return_values,
7557 children,
7558 } => {
7559 let mut context = ParserRuleContext::with_child_capacity(
7560 rule_index as usize,
7561 invoking_state as isize,
7562 self.recognition_arena.sequence_len(children),
7563 );
7564 if track_alt_numbers {
7565 context.set_alt_number((alt_number as usize).max(1));
7566 }
7567 if track_context_alt_numbers {
7568 context.set_context_alt_number(alt_number as usize);
7569 }
7570 if let Some(extra) = return_values {
7571 let RecognitionExtra::ReturnValues(values) =
7572 self.recognition_arena.extra(extra)
7573 else {
7574 unreachable!("rule node must reference return-values extra");
7575 };
7576 for (name, value) in values {
7577 context.set_int_return(name.clone(), *value);
7578 }
7579 }
7580 if let Some(token) = self.token_id_at(start_index as usize) {
7581 self.set_context_start(&mut context, token);
7582 }
7583 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7584 self.set_context_stop(&mut context, token);
7585 }
7586 let mut cursor = self
7587 .recognition_arena
7588 .fold_left_recursive_boundaries(children);
7589 while let Some(link) = self.recognition_arena.link(cursor) {
7590 let child = self.arena_recognized_node_tree(
7591 link.head,
7592 track_alt_numbers,
7593 track_context_alt_numbers,
7594 )?;
7595 self.tree.add_child(&mut context, child);
7596 cursor = link.tail;
7597 }
7598 Ok(self.rule_node(context))
7599 }
7600 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
7601 Err(AntlrError::Unsupported(format!(
7602 "unfolded left-recursive boundary for rule {rule_index}"
7603 )))
7604 }
7605 }
7606 }
7607
7608 fn arena_recognized_node_tree_with_implicit_tokens(
7609 &mut self,
7610 node_id: RecognizedNodeId,
7611 alt_tracking: AltNumberTracking,
7612 ) -> Result<ParseTree, AntlrError> {
7613 let node = self.recognition_arena.node(node_id);
7614 match node {
7615 ArenaRecognizedNode::Rule {
7616 rule_index,
7617 invoking_state,
7618 alt_number,
7619 start_index,
7620 stop_index,
7621 children,
7622 ..
7623 } => {
7624 let mut context = ParserRuleContext::with_child_capacity(
7625 rule_index as usize,
7626 invoking_state as isize,
7627 self.recognition_arena.sequence_len(children),
7628 );
7629 if alt_tracking.public {
7630 context.set_alt_number((alt_number as usize).max(1));
7631 }
7632 if alt_tracking.context {
7633 context.set_context_alt_number(alt_number as usize);
7634 }
7635 if let Some(token) = self.token_id_at(start_index as usize) {
7636 self.set_context_start(&mut context, token);
7637 }
7638 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7639 self.set_context_stop(&mut context, token);
7640 }
7641 let children = self
7642 .recognition_arena
7643 .fold_left_recursive_boundaries(children);
7644 self.add_arena_implicit_token_children(
7645 &mut context,
7646 start_index as usize,
7647 stop_index.map(|index| index as usize),
7648 children,
7649 alt_tracking,
7650 )?;
7651 Ok(self.rule_node(context))
7652 }
7653 _ => {
7654 self.arena_recognized_node_tree(node_id, alt_tracking.public, alt_tracking.context)
7655 }
7656 }
7657 }
7658
7659 fn add_arena_implicit_token_children(
7660 &mut self,
7661 context: &mut ParserRuleContext,
7662 start_index: usize,
7663 stop_index: Option<usize>,
7664 mut children: NodeSeqId,
7665 alt_tracking: AltNumberTracking,
7666 ) -> Result<(), AntlrError> {
7667 let mut cursor = Some(start_index);
7668 while let Some(link) = self.recognition_arena.link(children) {
7669 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
7670 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
7671 let child =
7672 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7673 self.tree.add_child(context, child);
7674 if let Some(child_stop) = child_stop {
7675 let next = self.next_visible_after_token(child_stop);
7676 cursor = match (cursor, next) {
7677 (None, _) | (_, None) => None,
7678 (Some(current), Some(next)) => Some(current.max(next)),
7679 };
7680 }
7681 } else {
7682 let child =
7683 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7684 self.tree.add_child(context, child);
7685 }
7686 children = link.tail;
7687 }
7688 if let Some(stop) = stop_index {
7689 self.add_visible_terminals_through(context, cursor, stop)?;
7690 }
7691 Ok(())
7692 }
7693
7694 fn add_visible_terminals_before(
7695 &mut self,
7696 context: &mut ParserRuleContext,
7697 cursor: &mut Option<usize>,
7698 before: usize,
7699 ) -> Result<(), AntlrError> {
7700 let Some(stop) = before.checked_sub(1) else {
7701 return Ok(());
7702 };
7703 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
7704 *cursor = next;
7705 Ok(())
7706 }
7707
7708 fn add_visible_terminals_through(
7709 &mut self,
7710 context: &mut ParserRuleContext,
7711 mut cursor: Option<usize>,
7712 stop: usize,
7713 ) -> Result<Option<usize>, AntlrError> {
7714 while let Some(index) = cursor {
7715 if index > stop {
7716 return Ok(Some(index));
7717 }
7718 let token = self
7719 .input
7720 .get_id(index)
7721 .ok_or_else(|| AntlrError::ParserError {
7722 line: 0,
7723 column: 0,
7724 message: format!("missing token at index {index}"),
7725 offending: None,
7726 })?;
7727 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
7728 let child = self.terminal_tree(token);
7729 self.tree.add_child(context, child);
7730 if is_eof {
7731 return Ok(None);
7732 }
7733 cursor = self.next_visible_after_token(index);
7734 }
7735 Ok(None)
7736 }
7737
7738 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
7739 let next = self.input.next_visible_after(index);
7740 (next != index).then_some(next)
7741 }
7742
7743 pub fn parse_atn_rule_with_actions(
7750 &mut self,
7751 atn: &Atn,
7752 rule_index: usize,
7753 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7754 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
7755 }
7756
7757 pub fn parse_atn_rule_with_action_inits(
7765 &mut self,
7766 atn: &Atn,
7767 rule_index: usize,
7768 init_action_rules: &[usize],
7769 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7770 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
7771 }
7772
7773 pub fn parse_atn_rule_with_action_options(
7779 &mut self,
7780 atn: &Atn,
7781 rule_index: usize,
7782 init_action_rules: &[usize],
7783 track_alt_numbers: bool,
7784 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7785 self.parse_atn_rule_with_runtime_options(
7786 atn,
7787 rule_index,
7788 ParserRuntimeOptions {
7789 init_action_rules,
7790 track_alt_numbers,
7791 ..ParserRuntimeOptions::default()
7792 },
7793 )
7794 }
7795
7796 pub fn parse_atn_rule_with_runtime_options(
7803 &mut self,
7804 atn: &Atn,
7805 rule_index: usize,
7806 options: ParserRuntimeOptions<'_>,
7807 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7808 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
7809 }
7810
7811 pub fn parse_atn_rule_with_runtime_options_and_precedence(
7814 &mut self,
7815 atn: &Atn,
7816 rule_index: usize,
7817 precedence: i32,
7818 options: ParserRuntimeOptions<'_>,
7819 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7820 let report_unrecovered_error = self.is_top_level_entry();
7821 let ParserRuntimeOptions {
7822 init_action_rules,
7823 track_alt_numbers,
7824 track_context_alt_numbers,
7825 predicates,
7826 semantics,
7827 rule_args,
7828 member_actions,
7829 return_actions,
7830 unknown_predicate_policy,
7831 } = options;
7832 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
7833 if init_action_rules.is_empty()
7834 && !capture_alt_numbers
7835 && predicates.is_empty()
7836 && semantics.is_none()
7837 && rule_args.is_empty()
7838 && member_actions.is_empty()
7839 && return_actions.is_empty()
7840 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
7841 && !atn_has_observable_action_transitions(atn)
7842 && !self.semantic_hooks.observes_parser_decisions()
7843 && (!self.semantic_hooks.observes_parser_predicates()
7844 || !atn_has_predicate_transitions(atn))
7845 {
7846 return self
7847 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
7848 .map(|tree| (tree, Vec::new()));
7849 }
7850 if !self.semantic_hooks.observes_parser_decisions()
7851 && can_use_fast_predicate_recognizer(atn, &options)
7852 {
7853 self.unknown_predicate_policy = unknown_predicate_policy;
7854 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7855 let member_values = self.int_members.clone();
7856 let result = self
7857 .parse_atn_rule_with_precedence_inner(
7858 atn,
7859 rule_index,
7860 precedence,
7861 Some(FastPredicateContext {
7862 predicates,
7863 semantics,
7864 member_values: &member_values,
7865 }),
7866 AltNumberTracking {
7867 public: track_alt_numbers,
7868 context: track_context_alt_numbers,
7869 },
7870 )
7871 .map(|tree| (tree, Vec::new()));
7872 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
7873 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7874 }
7875 return result;
7876 }
7877 self.unknown_predicate_policy = unknown_predicate_policy;
7878 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7885 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7886 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7887 })?;
7888 let stop_state = atn
7889 .rule_to_stop_state()
7890 .get(rule_index)
7891 .filter(|state| *state != usize::MAX)
7892 .ok_or_else(|| {
7893 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7894 })?;
7895
7896 let start_index = self.current_visible_index();
7897 self.clear_prediction_diagnostics();
7898 self.reset_per_parse_caches();
7899 self.reset_recognition_arena();
7900 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
7901 let invoking_state = self.pending_invoking_states.pop();
7902 let local_int_arg = invoking_state
7903 .and_then(|state| usize::try_from(state).ok())
7904 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
7905 let mut visiting = BTreeSet::new();
7906 let mut memo = BTreeMap::new();
7907 let mut expected = ExpectedTokens::default();
7908 let member_values = self.int_members.clone();
7909 let return_values = BTreeMap::new();
7910 let outcomes = self.recognize_state(
7911 atn,
7912 RecognizeRequest {
7913 state_number: start_state,
7914 stop_state,
7915 index: start_index,
7916 rule_start_index: start_index,
7917 decision_start_index: None,
7918 init_action_rules: &init_action_rules,
7919 predicates,
7920 semantics,
7921 rule_args,
7922 member_actions,
7923 return_actions,
7924 local_int_arg,
7925 member_values,
7926 return_values,
7927 rule_alt_number: 0,
7928 track_alt_numbers: capture_alt_numbers,
7929 consumed_eof: false,
7930 committed_decision: false,
7931 precedence,
7932 depth: 0,
7933 recovery_symbols: BTreeSet::new(),
7934 recovery_state: None,
7935 },
7936 &mut visiting,
7937 &mut memo,
7938 &mut expected,
7939 );
7940 if let Some(error) = self.unknown_semantic_error() {
7941 self.report_token_source_errors();
7942 return Err(error);
7949 }
7950 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7953 let Some(outcome) = select_best_outcome(
7954 outcomes.into_iter(),
7955 self.prediction_mode,
7956 &self.recognition_arena,
7957 ) else {
7958 let error = self.recognition_error(rule_index, start_index, &expected);
7959 self.record_syntax_errors(1);
7960 self.report_token_source_errors();
7961 if report_unrecovered_error {
7962 self.report_unrecovered_parser_error(&error);
7963 }
7964 return Err(error);
7965 };
7966
7967 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7968 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7969 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7970 self.report_token_source_errors();
7971 let mut actions = outcome.actions;
7972 if init_action_rules.contains(&rule_index) {
7973 actions.insert(
7974 0,
7975 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
7976 );
7977 }
7978 let mut context =
7979 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
7980 if track_alt_numbers {
7981 context.set_alt_number(outcome.alt_number.max(1));
7982 }
7983 if track_context_alt_numbers {
7984 context.set_context_alt_number(outcome.alt_number);
7985 }
7986 for (name, value) in outcome.return_values {
7987 context.set_int_return(name, value);
7988 }
7989 if let Some(token) = self.token_id_at(start_index) {
7990 self.set_context_start(&mut context, token);
7991 }
7992 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
7993 self.set_context_stop(&mut context, token);
7994 }
7995 let live_root = if self.build_parse_trees {
7996 self.recognition_arena
7997 .fold_left_recursive_boundaries(outcome.nodes)
7998 } else {
7999 outcome.nodes
8000 };
8001 if self.build_parse_trees {
8002 let mut nodes = live_root;
8003 while let Some(link) = self.recognition_arena.link(nodes) {
8004 let child = self.arena_recognized_node_tree(
8005 link.head,
8006 track_alt_numbers,
8007 track_context_alt_numbers,
8008 )?;
8009 self.tree.add_child(&mut context, child);
8010 nodes = link.tail;
8011 }
8012 }
8013 self.finish_recognition_arena(live_root, outcome.diagnostics);
8014 self.input.seek(outcome.index);
8015
8016 let tree = self.rule_node(context);
8017 self.release_tree_scratch_if_idle();
8018 Ok((tree, actions))
8019 }
8020
8021 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
8028 let mut context = ParserRuleContext::new(rule_index, self.state());
8029 while self.la(1) != TOKEN_EOF {
8030 let token_type = self.la(1);
8031 let child = self.match_token(token_type)?;
8032 if self.build_parse_trees {
8033 self.tree.add_child(&mut context, child);
8034 }
8035 }
8036 if self.build_parse_trees {
8037 let child = self.match_eof()?;
8038 self.tree.add_child(&mut context, child);
8039 }
8040 let tree = self.rule_node(context);
8041 self.release_tree_scratch_if_idle();
8042 Ok(tree)
8043 }
8044
8045 fn recognition_error(
8048 &mut self,
8049 rule_index: usize,
8050 start_index: usize,
8051 expected: &ExpectedTokens,
8052 ) -> AntlrError {
8053 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
8054 self.input.seek(index);
8055 let current = self.input.lt(1);
8056 let line = current.as_ref().map(Token::line).unwrap_or_default();
8057 let column = current.as_ref().map(Token::column).unwrap_or_default();
8058 AntlrError::ParserError {
8059 line,
8060 column,
8061 message,
8062 offending: current.as_ref().map(Token::token_id),
8063 }
8064 }
8065
8066 fn expected_error_message(
8068 &mut self,
8069 rule_index: usize,
8070 start_index: usize,
8071 expected: &ExpectedTokens,
8072 ) -> (usize, String) {
8073 let index = expected
8074 .index
8075 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
8076 .unwrap_or_else(|| self.input.index());
8077 self.input.seek(index);
8078 let current = self.input.lt(1);
8079 let message = if expected
8080 .no_viable
8081 .as_ref()
8082 .is_some_and(|no_viable| no_viable.error_index == index)
8083 {
8084 let start = expected
8085 .no_viable
8086 .as_ref()
8087 .map_or(start_index, |no_viable| no_viable.start_index);
8088 let text = display_input_text(&self.input.text(start, index));
8089 format!("no viable alternative at input '{text}'")
8090 } else if expected.symbols.is_empty() {
8091 if expected.index.is_some() {
8092 let found = current
8093 .as_ref()
8094 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
8095 if current
8096 .as_ref()
8097 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8098 {
8099 format!(
8100 "missing {} at {found}",
8101 self.expected_symbols_display(&expected.symbols)
8102 )
8103 } else {
8104 format!("mismatched input {found}")
8105 }
8106 } else {
8107 format!("no viable alternative while parsing rule {rule_index}")
8108 }
8109 } else {
8110 format!(
8111 "mismatched input {} expecting {}",
8112 current
8113 .as_ref()
8114 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8115 self.expected_symbols_display(&expected.symbols)
8116 )
8117 };
8118 (index, message)
8119 }
8120
8121 fn child_rule_failure_recovery(
8124 &mut self,
8125 rule_index: usize,
8126 start_index: usize,
8127 sync_symbols: &BTreeSet<i32>,
8128 member_values: MemberEnv,
8129 expected: &ExpectedTokens,
8130 ) -> Option<RecognizeOutcome> {
8131 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8132 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8133 let mut next_index = error_index;
8134 loop {
8135 let symbol = self.token_type_at(next_index);
8136 if sync_symbols.contains(&symbol) {
8137 if next_index == error_index {
8138 return None;
8139 }
8140 break;
8141 }
8142 if symbol == TOKEN_EOF {
8143 break;
8144 }
8145 let after = self.consume_index(next_index, symbol);
8146 if after == next_index {
8147 break;
8148 }
8149 next_index = after;
8150 }
8151 let mut nodes = NodeSeqId::EMPTY;
8152 let error = self.arena_token_node(error_index, true);
8153 self.arena_prepend(&mut nodes, error);
8154 let diagnostics = self
8155 .recognition_arena
8156 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8157 Some(RecognizeOutcome {
8158 index: next_index,
8159 consumed_eof: false,
8160 alt_number: 0,
8161 member_values,
8162 return_values: BTreeMap::new(),
8163 diagnostics,
8164 decisions: Vec::new(),
8165 actions: Vec::new(),
8166 nodes,
8167 })
8168 }
8169
8170 fn child_rule_failure_recovery_outcomes(
8173 &mut self,
8174 request: ChildRuleFailureRecovery<'_>,
8175 ) -> Vec<RecognizeOutcome> {
8176 let sync_symbols =
8177 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
8178 self.child_rule_failure_recovery(
8179 request.rule_index,
8180 request.start_index,
8181 &sync_symbols,
8182 request.member_values,
8183 request.expected,
8184 )
8185 .into_iter()
8186 .collect()
8187 }
8188
8189 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
8191 expected_symbols_display(symbols, self.vocabulary())
8192 }
8193
8194 fn single_token_deletion(
8197 &mut self,
8198 transition: ParserTransition<'_>,
8199 index: usize,
8200 max_token_type: i32,
8201 expected_symbols: &BTreeSet<i32>,
8202 ) -> Option<(ParserDiagnostic, usize, i32)> {
8203 let current_symbol = self.token_type_at(index);
8204 if current_symbol == TOKEN_EOF {
8205 return None;
8206 }
8207 let next_index = self.consume_index(index, current_symbol);
8208 if next_index == index {
8209 return None;
8210 }
8211 let next_symbol = self.token_type_at(next_index);
8212 if !transition.matches(next_symbol, 1, max_token_type) {
8213 return None;
8214 }
8215 let transition_expected = transition_expected_symbols(transition, max_token_type);
8216 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8217 &transition_expected
8218 } else {
8219 expected_symbols
8220 });
8221 let current = self.token_at(index);
8222 let message = format!(
8223 "extraneous input {} expecting {expected_display}",
8224 current
8225 .as_ref()
8226 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8227 );
8228 Some((
8229 diagnostic_for_token(current, message),
8230 next_index,
8231 next_symbol,
8232 ))
8233 }
8234
8235 fn current_token_deletion(
8238 &mut self,
8239 index: usize,
8240 expected_symbols: &BTreeSet<i32>,
8241 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
8242 if expected_symbols.is_empty() {
8243 return None;
8244 }
8245 let current_symbol = self.token_type_at(index);
8246 if current_symbol == TOKEN_EOF {
8247 return None;
8248 }
8249 let current = self.token_at(index);
8250 let message = format!(
8251 "extraneous input {} expecting {}",
8252 current
8253 .as_ref()
8254 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8255 self.expected_symbols_display(expected_symbols)
8256 );
8257 let diagnostic = diagnostic_for_token(current, message);
8258 let mut skipped = Vec::new();
8259 let mut cursor = index;
8260 loop {
8261 let symbol = self.token_type_at(cursor);
8262 if symbol == TOKEN_EOF {
8263 return None;
8264 }
8265 skipped.push(cursor);
8266 let next_index = self.consume_index(cursor, symbol);
8267 if next_index == cursor {
8268 return None;
8269 }
8270 let next_symbol = self.token_type_at(next_index);
8271 if expected_symbols.contains(&next_symbol) {
8272 return Some((diagnostic, next_index, skipped));
8273 }
8274 cursor = next_index;
8275 }
8276 }
8277
8278 fn single_token_insertion(
8282 &mut self,
8283 transition: ParserTransition<'_>,
8284 index: usize,
8285 max_token_type: i32,
8286 expected_symbols: &BTreeSet<i32>,
8287 follow_symbols: &BTreeSet<i32>,
8288 ) -> Option<(ParserDiagnostic, i32, String)> {
8289 let current_symbol = self.token_type_at(index);
8290 if !follow_symbols.contains(¤t_symbol) {
8291 return None;
8292 }
8293 let transition_expected = transition_expected_symbols(transition, max_token_type);
8294 let token_type = transition_expected.iter().next().copied()?;
8295 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8296 &transition_expected
8297 } else {
8298 expected_symbols
8299 });
8300 let mut token_symbols = BTreeSet::new();
8301 token_symbols.insert(token_type);
8302 let missing_token_display = self.expected_symbols_display(&token_symbols);
8303 let current = self.token_at(index);
8304 let message = format!(
8305 "missing {expected_display} at {}",
8306 current
8307 .as_ref()
8308 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8309 );
8310 let text = format!("<missing {missing_token_display}>");
8311 Some((
8312 diagnostic_for_token(current.as_ref(), message),
8313 token_type,
8314 text,
8315 ))
8316 }
8317
8318 fn fast_single_token_deletion_recovery(
8322 &mut self,
8323 recovery: FastRecoveryRequest<'_, '_>,
8324 predicate_context: Option<FastPredicateContext<'_>>,
8325 ) -> Vec<FastRecognizeOutcome> {
8326 let FastRecoveryRequest {
8327 atn,
8328 transition,
8329 expected_symbols,
8330 target,
8331 request,
8332 visiting,
8333 memo,
8334 expected,
8335 } = recovery;
8336 let FastRecognizeRequest {
8337 stop_state,
8338 index,
8339 rule_start_index,
8340 decision_start_index,
8341 precedence,
8342 depth,
8343 ..
8344 } = request;
8345 let Some((diagnostic, next_index, next_symbol)) =
8346 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8347 else {
8348 return Vec::new();
8349 };
8350 let after_next = self.consume_index(next_index, next_symbol);
8351 let empty_recovery = self.empty_recovery_symbols();
8352 self.recognize_state_fast(
8353 atn,
8354 FastRecognizeRequest {
8355 state_number: target,
8356 stop_state,
8357 index: after_next,
8358 rule_start_index,
8359 decision_start_index,
8360 precedence,
8361 depth: depth + 1,
8362 recovery_symbols: empty_recovery,
8363 recovery_state: None,
8364 },
8365 FastRecognizeScratch {
8366 predicate_context,
8367 visiting,
8368 memo,
8369 expected,
8370 native_depth: 0,
8371 },
8372 )
8373 .into_iter()
8374 .map(|mut outcome| {
8375 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
8376 outcome.diagnostics = self
8377 .recognition_arena
8378 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8379 if self.fast_token_nodes_enabled {
8380 let token = self.arena_token_node(next_index, false);
8381 self.defer_fast_outcome_node(&mut outcome, token);
8382 let error = self.arena_token_node(index, true);
8383 self.defer_fast_outcome_node(&mut outcome, error);
8384 }
8385 outcome
8386 })
8387 .collect()
8388 }
8389
8390 fn fast_single_token_insertion_recovery(
8394 &mut self,
8395 recovery: FastRecoveryRequest<'_, '_>,
8396 predicate_context: Option<FastPredicateContext<'_>>,
8397 ) -> Vec<FastRecognizeOutcome> {
8398 let FastRecoveryRequest {
8399 atn,
8400 transition,
8401 expected_symbols,
8402 target,
8403 request,
8404 visiting,
8405 memo,
8406 expected,
8407 } = recovery;
8408 let FastRecognizeRequest {
8409 stop_state,
8410 index,
8411 rule_start_index,
8412 decision_start_index,
8413 precedence,
8414 depth,
8415 ..
8416 } = request;
8417 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
8418 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
8419 transition,
8420 index,
8421 atn.max_token_type(),
8422 &expected_symbols,
8423 &follow_symbols,
8424 ) else {
8425 return Vec::new();
8426 };
8427 let empty_recovery = self.empty_recovery_symbols();
8428 self.recognize_state_fast(
8429 atn,
8430 FastRecognizeRequest {
8431 state_number: target,
8432 stop_state,
8433 index,
8434 rule_start_index,
8435 decision_start_index,
8436 precedence,
8437 depth: depth + 1,
8438 recovery_symbols: empty_recovery,
8439 recovery_state: None,
8440 },
8441 FastRecognizeScratch {
8442 predicate_context,
8443 visiting,
8444 memo,
8445 expected,
8446 native_depth: 0,
8447 },
8448 )
8449 .into_iter()
8450 .map(|mut outcome| {
8451 outcome.diagnostics = self
8452 .recognition_arena
8453 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8454 let missing = self.arena_missing_token_node(token_type, index, text.clone());
8455 self.defer_fast_outcome_node(&mut outcome, missing);
8456 outcome
8457 })
8458 .collect()
8459 }
8460
8461 fn fast_current_token_deletion_recovery(
8464 &mut self,
8465 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
8466 predicate_context: Option<FastPredicateContext<'_>>,
8467 ) -> Vec<FastRecognizeOutcome> {
8468 let FastCurrentTokenDeletionRequest {
8469 atn,
8470 expected_symbols,
8471 mut request,
8472 visiting,
8473 memo,
8474 expected,
8475 } = recovery;
8476 if request.index == request.rule_start_index {
8477 return Vec::new();
8478 }
8479 let Some((diagnostic, next_index, skipped)) =
8480 self.current_token_deletion(request.index, &expected_symbols)
8481 else {
8482 return Vec::new();
8483 };
8484 request.state_number = request.recovery_state.unwrap_or(request.state_number);
8485 request.index = next_index;
8486 request.depth += 1;
8487 request.recovery_state = None;
8488 self.recognize_state_fast(
8489 atn,
8490 request,
8491 FastRecognizeScratch {
8492 predicate_context,
8493 visiting,
8494 memo,
8495 expected,
8496 native_depth: 0,
8497 },
8498 )
8499 .into_iter()
8500 .map(|mut outcome| {
8501 outcome.diagnostics = self
8502 .recognition_arena
8503 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8504 for index in skipped.iter().rev() {
8505 let error = self.arena_token_node(*index, true);
8506 self.defer_fast_outcome_node(&mut outcome, error);
8507 }
8508 outcome
8509 })
8510 .collect()
8511 }
8512
8513 fn fast_child_rule_failure_recovery(
8516 &mut self,
8517 rule_index: usize,
8518 start_index: usize,
8519 sync_symbols: &BTreeSet<i32>,
8520 expected: &ExpectedTokens,
8521 ) -> Option<FastRecognizeOutcome> {
8522 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8523 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8524 let mut next_index = error_index;
8525 loop {
8526 let symbol = self.token_type_at(next_index);
8527 if sync_symbols.contains(&symbol) {
8528 if next_index == error_index {
8529 return None;
8530 }
8531 break;
8532 }
8533 if symbol == TOKEN_EOF {
8534 break;
8535 }
8536 let after = self.consume_index(next_index, symbol);
8537 if after == next_index {
8538 break;
8539 }
8540 next_index = after;
8541 }
8542 let diagnostics = self
8543 .recognition_arena
8544 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8545 let mut nodes = NodeSeqId::EMPTY;
8546 if self.fast_token_nodes_enabled {
8547 let error = self.arena_token_node(error_index, true);
8548 self.arena_prepend(&mut nodes, error);
8549 }
8550 Some(FastRecognizeOutcome {
8551 index: next_index,
8552 consumed_eof: false,
8553 diagnostics,
8554 deferred_nodes: FastDeferredNodeId::EMPTY,
8555 nodes,
8556 })
8557 }
8558
8559 fn fast_child_rule_failure_recovery_outcomes(
8562 &mut self,
8563 request: FastChildRuleFailureRecoveryRequest<'_>,
8564 ) -> Vec<FastRecognizeOutcome> {
8565 let FastChildRuleFailureRecoveryRequest {
8566 atn,
8567 rule_index,
8568 start_index,
8569 follow_state,
8570 stop_state,
8571 expected,
8572 } = request;
8573 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
8574 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
8575 .into_iter()
8576 .collect()
8577 }
8578
8579 fn defer_fast_outcome_node(
8580 &mut self,
8581 outcome: &mut FastRecognizeOutcome,
8582 node: RecognizedNodeId,
8583 ) {
8584 if outcome.deferred_nodes.is_empty() {
8585 self.arena_prepend(&mut outcome.nodes, node);
8586 return;
8587 }
8588 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
8589 let fragment = self.recognition_arena.deferred_fragment(fragment);
8590 outcome.deferred_nodes = self
8591 .recognition_arena
8592 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
8593 }
8594
8595 fn defer_fast_outcome_alternative(
8596 &mut self,
8597 outcome: &mut FastRecognizeOutcome,
8598 alt_number: usize,
8599 ) {
8600 let alternative = self.recognition_arena.deferred_alternative(alt_number);
8601 outcome.deferred_nodes = self
8602 .recognition_arena
8603 .concat_deferred_nodes(alternative, outcome.deferred_nodes);
8604 }
8605
8606 fn defer_fast_outcome_boundary(
8607 &mut self,
8608 outcome: &mut FastRecognizeOutcome,
8609 rule_index: usize,
8610 ) {
8611 let boundary = self
8612 .recognition_arena
8613 .deferred_left_recursive_boundary(rule_index);
8614 outcome.deferred_nodes = self
8615 .recognition_arena
8616 .concat_deferred_nodes(boundary, outcome.deferred_nodes);
8617 }
8618
8619 fn materialize_fast_deferred_nodes(
8620 &mut self,
8621 root: FastDeferredNodeId,
8622 initial_suffix: NodeSeqId,
8623 ) -> (NodeSeqId, usize) {
8624 if root.is_empty() {
8625 return (initial_suffix, 0);
8626 }
8627
8628 enum Frame {
8629 Visit(FastDeferredNodeId),
8630 ContinuePrefix(FastDeferredNodeId),
8631 FinishRule {
8632 rule: FastDeferredRule,
8633 parent_suffix: NodeSeqId,
8634 parent_alt_number: u32,
8635 parent_pending_boundary: Option<RecognizedNodeId>,
8636 },
8637 }
8638
8639 let mut result = initial_suffix;
8640 let mut alt_number = 0;
8644 let mut pending_boundary = None;
8645 let mut pending = Vec::with_capacity(16);
8646 pending.push(Frame::Visit(root));
8647 let mut fragment_nodes = Vec::new();
8648 while let Some(frame) = pending.pop() {
8649 match frame {
8650 Frame::Visit(deferred) => {
8651 if deferred.is_empty() {
8652 continue;
8653 }
8654
8655 match self.recognition_arena.deferred_node(deferred) {
8656 FastDeferredNode::Fragment(sequence) => {
8657 fragment_nodes.clear();
8658 fragment_nodes.extend(self.recognition_arena.iter(sequence));
8659 while let Some(node) = fragment_nodes.pop() {
8660 self.arena_prepend(&mut result, node);
8661 }
8662 }
8663 FastDeferredNode::Rule(rule) => {
8664 let rule = self.recognition_arena.deferred_rule(rule);
8665 let parent_suffix = result;
8666 let parent_alt_number = alt_number;
8667 let parent_pending_boundary = pending_boundary;
8668 result = rule.children;
8669 alt_number = 0;
8670 pending_boundary = None;
8671 pending.push(Frame::FinishRule {
8672 rule,
8673 parent_suffix,
8674 parent_alt_number,
8675 parent_pending_boundary,
8676 });
8677 pending.push(Frame::Visit(rule.deferred_children));
8678 }
8679 FastDeferredNode::Alternative(selected) => {
8680 if let Some(boundary) = pending_boundary {
8681 self.recognition_arena
8682 .set_boundary_alt_number(boundary, selected);
8683 } else {
8684 alt_number = selected;
8685 }
8686 }
8687 FastDeferredNode::LeftRecursiveBoundary { rule_index } => {
8688 let boundary = self.arena_boundary_node(rule_index as usize, 0);
8689 self.arena_prepend(&mut result, boundary);
8690 pending_boundary = Some(boundary);
8691 }
8692 FastDeferredNode::Concat {
8693 prefix,
8694 suffix: deferred_suffix,
8695 } => {
8696 pending.push(Frame::ContinuePrefix(prefix));
8697 pending.push(Frame::Visit(deferred_suffix));
8698 }
8699 }
8700 }
8701 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
8702 Frame::FinishRule {
8703 rule,
8704 parent_suffix,
8705 parent_alt_number,
8706 parent_pending_boundary,
8707 } => {
8708 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
8709 rule_index: rule.rule_index,
8710 invoking_state: rule.invoking_state,
8711 alt_number,
8712 start_index: rule.start_index,
8713 stop_index: rule.stop_index,
8714 return_values: None,
8715 children: result,
8716 });
8717 result = parent_suffix;
8718 self.arena_prepend(&mut result, node);
8719 alt_number = parent_alt_number;
8720 pending_boundary = parent_pending_boundary;
8721 }
8722 }
8723 }
8724 (result, alt_number as usize)
8725 }
8726
8727 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) -> usize {
8728 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
8729 let (nodes, alt_number) =
8730 self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
8731 outcome.nodes = nodes;
8732 alt_number
8733 }
8734
8735 fn recognize_repetition_fast(
8738 &mut self,
8739 atn: &Atn,
8740 request: &FastRecognizeRequest,
8741 shape: FastRepetitionShape,
8742 scratch: FastRecognizeScratch<'_, '_>,
8743 ) -> Vec<FastRecognizeOutcome> {
8744 let FastRecognizeScratch {
8745 predicate_context,
8746 visiting,
8747 memo,
8748 expected,
8749 native_depth,
8750 } = scratch;
8751 let lookahead = if self.fast_first_set_prefilter {
8752 atn.state(request.state_number).and_then(|state| {
8753 state
8754 .rule_index()
8755 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8756 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
8757 })
8758 } else {
8759 None
8760 };
8761 let (enter_alt_number, exit_alt_number) = if self.fast_track_alt_numbers {
8762 let state = atn
8763 .state(request.state_number)
8764 .expect("repetition request state must exist");
8765 (
8766 next_alt_number(state, 2, shape.enter_transition_index, 0, true),
8767 next_alt_number(state, 2, shape.exit_transition_index, 0, true),
8768 )
8769 } else {
8770 (0, 0)
8771 };
8772 let mut work = Vec::with_capacity(2);
8773 push_fast_repetition_work(
8774 &mut work,
8775 shape,
8776 FastRepetitionPath {
8777 index: request.index,
8778 deferred_nodes: FastDeferredNodeId::EMPTY,
8779 diagnostics: DiagnosticSeqId::EMPTY,
8780 consumed_eof: false,
8781 },
8782 lookahead.as_deref(),
8783 self.token_type_at(request.index),
8784 );
8785 let mut coordinates = FastRepetitionCoordinates::new(request.index);
8786 let mut outcomes = Vec::new();
8787 while let Some(item) = work.pop() {
8788 match item {
8789 FastRepetitionWork::Enter(path) => {
8790 if !coordinates.insert_entered(path) {
8791 continue;
8792 }
8793 let path_nodes = if enter_alt_number == 0 {
8794 path.deferred_nodes
8795 } else {
8796 let alternative = self
8797 .recognition_arena
8798 .deferred_alternative(enter_alt_number);
8799 self.recognition_arena
8800 .concat_deferred_nodes(path.deferred_nodes, alternative)
8801 };
8802 let body_outcomes = self.recognize_state_fast(
8803 atn,
8804 FastRecognizeRequest {
8805 state_number: shape.enter_target,
8806 stop_state: shape.body_stop_state,
8807 index: path.index,
8808 rule_start_index: request.rule_start_index,
8809 decision_start_index: request.decision_start_index,
8810 precedence: request.precedence,
8811 depth: request.depth.saturating_add(1),
8812 recovery_symbols: Rc::clone(&request.recovery_symbols),
8813 recovery_state: request.recovery_state,
8814 },
8815 FastRecognizeScratch {
8816 predicate_context,
8817 visiting: &mut *visiting,
8818 memo: &mut *memo,
8819 expected: &mut *expected,
8820 native_depth: native_depth + 1,
8821 },
8822 );
8823 for body in body_outcomes.into_iter().rev() {
8824 if body.index <= path.index {
8828 continue;
8829 }
8830 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
8831 let body_nodes = self
8832 .recognition_arena
8833 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
8834 let deferred_nodes = self
8835 .recognition_arena
8836 .concat_deferred_nodes(path_nodes, body_nodes);
8837 let next_path = FastRepetitionPath {
8838 index: body.index,
8839 deferred_nodes,
8840 diagnostics: self
8841 .recognition_arena
8842 .concat_diagnostics(path.diagnostics, body.diagnostics),
8843 consumed_eof: path.consumed_eof || body.consumed_eof,
8844 };
8845 let symbol = self.token_type_at(next_path.index);
8846 push_fast_repetition_work(
8847 &mut work,
8848 shape,
8849 next_path,
8850 lookahead.as_deref(),
8851 symbol,
8852 );
8853 }
8854 }
8855 FastRepetitionWork::Exit(path) => {
8856 if !coordinates.insert_exited(path) {
8857 continue;
8858 }
8859 let path_nodes = if exit_alt_number == 0 {
8860 path.deferred_nodes
8861 } else {
8862 let alternative =
8863 self.recognition_arena.deferred_alternative(exit_alt_number);
8864 self.recognition_arena
8865 .concat_deferred_nodes(path.deferred_nodes, alternative)
8866 };
8867 let suffixes = self.recognize_state_fast(
8868 atn,
8869 FastRecognizeRequest {
8870 state_number: shape.exit_target,
8871 stop_state: request.stop_state,
8872 index: path.index,
8873 rule_start_index: request.rule_start_index,
8874 decision_start_index: request.decision_start_index,
8875 precedence: request.precedence,
8876 depth: request.depth.saturating_add(1),
8877 recovery_symbols: Rc::clone(&request.recovery_symbols),
8878 recovery_state: request.recovery_state,
8879 },
8880 FastRecognizeScratch {
8881 predicate_context,
8882 visiting: &mut *visiting,
8883 memo: &mut *memo,
8884 expected: &mut *expected,
8885 native_depth: native_depth + 1,
8886 },
8887 );
8888 for mut outcome in suffixes {
8889 outcome.deferred_nodes = self
8890 .recognition_arena
8891 .concat_deferred_nodes(path_nodes, outcome.deferred_nodes);
8892 outcome.diagnostics = self
8893 .recognition_arena
8894 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
8895 outcome.consumed_eof |= path.consumed_eof;
8896 outcomes.push(outcome);
8897 }
8898 }
8899 }
8900 }
8901 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8902 outcomes
8903 }
8904
8905 fn recognize_state_fast(
8908 &mut self,
8909 atn: &Atn,
8910 request: FastRecognizeRequest,
8911 scratch: FastRecognizeScratch<'_, '_>,
8912 ) -> Vec<FastRecognizeOutcome> {
8913 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
8914 return self.recognize_state_fast_inner(atn, request, scratch);
8915 }
8916 self.recognize_state_fast_checked(atn, request, scratch)
8917 }
8918
8919 #[inline(never)]
8920 fn recognize_state_fast_checked(
8921 &mut self,
8922 atn: &Atn,
8923 request: FastRecognizeRequest,
8924 mut scratch: FastRecognizeScratch<'_, '_>,
8925 ) -> Vec<FastRecognizeOutcome> {
8926 scratch.native_depth = 1;
8927 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
8928 self.recognize_state_fast_inner(atn, request, scratch)
8929 })
8930 }
8931
8932 #[allow(clippy::too_many_lines)]
8933 fn recognize_state_fast_inner(
8934 &mut self,
8935 atn: &Atn,
8936 request: FastRecognizeRequest,
8937 scratch: FastRecognizeScratch<'_, '_>,
8938 ) -> Vec<FastRecognizeOutcome> {
8939 #[cfg(feature = "perf-counters")]
8940 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
8941 let FastRecognizeScratch {
8942 predicate_context,
8943 visiting,
8944 memo,
8945 expected,
8946 native_depth,
8947 } = scratch;
8948 let FastRecognizeRequest {
8949 mut state_number,
8950 stop_state,
8951 mut index,
8952 rule_start_index,
8953 decision_start_index,
8954 precedence,
8955 mut depth,
8956 recovery_symbols,
8957 recovery_state,
8958 } = request;
8959 let max_token_type = atn.max_token_type();
8960 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
8979 let mut inline_consumed_eof = false;
8980 loop {
8981 if depth > RECOGNITION_DEPTH_LIMIT {
8982 return Vec::new();
8983 }
8984 if state_number == stop_state {
8985 let mut nodes = NodeSeqId::EMPTY;
8986 if self.fast_token_nodes_enabled {
8987 for token_index in inline_consumed_tokens.iter().rev() {
8988 let token = self.arena_token_node(*token_index, false);
8989 self.arena_prepend(&mut nodes, token);
8990 }
8991 }
8992 return vec![FastRecognizeOutcome {
8993 index,
8994 consumed_eof: inline_consumed_eof,
8995 diagnostics: DiagnosticSeqId::EMPTY,
8996 deferred_nodes: FastDeferredNodeId::EMPTY,
8997 nodes,
8998 }];
8999 }
9000 let Some(state) = atn.state(state_number) else {
9001 return Vec::new();
9002 };
9003 let transitions = state.transitions();
9004 if transitions.len() == 1 && !state.precedence_rule_decision() {
9005 let transition = transitions
9006 .first()
9007 .expect("single transition checked above");
9008 let transition_kind = transition.kind();
9009 let target = transition.target();
9010 match transition_kind {
9011 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
9012 if left_recursive_boundary(atn, state, target).is_none() =>
9013 {
9014 #[cfg(feature = "perf-counters")]
9015 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9016 state_number = target;
9017 depth += 1;
9018 continue;
9019 }
9020 ParserTransitionKind::Predicate
9021 if left_recursive_boundary(atn, state, target).is_none() =>
9022 {
9023 #[cfg(feature = "perf-counters")]
9024 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9025 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
9026 {
9027 record_predicate_no_viable(expected, decision_start_index, index);
9028 return Vec::new();
9029 }
9030 state_number = target;
9031 depth += 1;
9032 continue;
9033 }
9034 ParserTransitionKind::Precedence
9035 if packed_i32(transition.arg0()) >= precedence
9036 && left_recursive_boundary(atn, state, target).is_none() =>
9037 {
9038 #[cfg(feature = "perf-counters")]
9039 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9040 state_number = target;
9041 depth += 1;
9042 continue;
9043 }
9044 ParserTransitionKind::Atom
9054 | ParserTransitionKind::Range
9055 | ParserTransitionKind::Set
9056 | ParserTransitionKind::NotSet
9057 | ParserTransitionKind::Wildcard
9058 if !self.fast_recovery_enabled =>
9059 {
9060 let symbol = self.token_type_at(index);
9061 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9062 #[cfg(feature = "perf-counters")]
9063 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9064 if self.fast_token_nodes_enabled {
9065 inline_consumed_tokens.push(index);
9066 }
9067 inline_consumed_eof |= symbol == TOKEN_EOF;
9068 index = self.consume_index(index, symbol);
9069 state_number = target;
9070 depth += 1;
9071 continue;
9072 }
9073 }
9076 _ => {}
9077 }
9078 }
9079 break;
9080 }
9081 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
9085 let Some(state) = atn.state(state_number) else {
9086 return Vec::new();
9087 };
9088 let transitions = state.transitions();
9089 let transition_count = transitions.len();
9090 if !self.fast_recovery_enabled
9091 && let Some(shape) = fast_repetition_shape(atn, state)
9092 {
9093 let mut outcomes = self.recognize_repetition_fast(
9094 atn,
9095 &FastRecognizeRequest {
9096 state_number,
9097 stop_state,
9098 index,
9099 rule_start_index,
9100 decision_start_index,
9101 precedence,
9102 depth,
9103 recovery_symbols: Rc::clone(&recovery_symbols),
9104 recovery_state,
9105 },
9106 shape,
9107 FastRecognizeScratch {
9108 predicate_context,
9109 visiting: &mut *visiting,
9110 memo: &mut *memo,
9111 expected: &mut *expected,
9112 native_depth: native_depth + 1,
9113 },
9114 );
9115 if inline_pending {
9116 for outcome in &mut outcomes {
9117 outcome.consumed_eof |= inline_consumed_eof;
9118 if self.fast_token_nodes_enabled {
9119 for token_index in inline_consumed_tokens.iter().rev() {
9120 let token = self.arena_token_node(*token_index, false);
9121 self.defer_fast_outcome_node(outcome, token);
9122 }
9123 }
9124 }
9125 }
9126 return outcomes;
9127 }
9128 let key = if self.fast_recovery_enabled {
9138 FastRecognizeKey {
9139 state_number,
9140 stop_state,
9141 index,
9142 rule_start_index,
9143 decision_start_index,
9144 precedence,
9145 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
9146 recovery_state,
9147 }
9148 } else {
9149 FastRecognizeKey {
9150 state_number,
9151 stop_state,
9152 index,
9153 rule_start_index: 0,
9154 decision_start_index: None,
9155 precedence,
9156 recovery_symbols_id: 0,
9157 recovery_state: None,
9158 }
9159 };
9160 let memo_lookup_enabled = self.fast_recovery_enabled
9165 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
9166 if memo_lookup_enabled {
9167 if let Some(outcomes) = memo.get(&key) {
9168 #[cfg(feature = "perf-counters")]
9169 {
9170 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
9171 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
9172 }
9173 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
9177 let inline_eof = inline_consumed_eof;
9178 let inline_tokens = &inline_consumed_tokens;
9179 return outcomes
9180 .iter()
9181 .copied()
9182 .map(|mut outcome| {
9183 if inline_eof {
9184 outcome.consumed_eof = true;
9185 }
9186 if self.fast_token_nodes_enabled {
9187 for token_index in inline_tokens.iter().rev() {
9188 let token = self.arena_token_node(*token_index, false);
9189 self.defer_fast_outcome_node(&mut outcome, token);
9190 }
9191 }
9192 outcome
9193 })
9194 .collect();
9195 }
9196 return outcomes.to_vec();
9197 }
9198 #[cfg(feature = "perf-counters")]
9199 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
9200 }
9201
9202 let needs_cycle_guard = if self.fast_recovery_enabled {
9207 transitions.iter().any(ParserTransition::is_epsilon)
9208 } else {
9209 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
9210 };
9211 #[cfg(feature = "perf-counters")]
9212 if needs_cycle_guard {
9213 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
9214 } else {
9215 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
9216 match state
9217 .transitions()
9218 .first()
9219 .expect("single-transition path requires one transition")
9220 .data()
9221 {
9222 Transition::Rule { .. } => {
9223 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
9224 }
9225 Transition::Atom { .. }
9226 | Transition::Range { .. }
9227 | Transition::Set { .. }
9228 | Transition::NotSet { .. }
9229 | Transition::Wildcard { .. } => {
9230 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
9231 }
9232 _ => {
9233 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
9234 }
9235 }
9236 }
9237 let has_inserted_cycle_guard = if needs_cycle_guard {
9238 if !visiting.insert(key.clone()) {
9239 #[cfg(feature = "perf-counters")]
9240 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
9241 return Vec::new();
9242 }
9243 true
9244 } else {
9245 false
9246 };
9247 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9248 Some(index)
9249 } else {
9250 decision_start_index
9251 };
9252 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
9253 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
9254 } else {
9255 (Rc::clone(&recovery_symbols), recovery_state)
9256 };
9257
9258 let lookahead_filter = if transition_count > 1
9277 && self.fast_first_set_prefilter
9278 && !state.precedence_rule_decision()
9279 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
9280 {
9281 state
9282 .rule_index()
9283 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9284 .map(|rule_stop| {
9285 let symbol = self.token_type_at(index);
9286 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
9287 (symbol, entry)
9288 })
9289 } else {
9290 None
9291 };
9292 let ll1_only_alt: Option<usize> = if transition_count > 1
9301 && let Some((symbol, entry)) = lookahead_filter.as_ref()
9302 {
9303 let key = (state.state_number(), *symbol);
9304 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
9305 cached
9306 } else {
9307 let result = ll1_unique_alt(entry, *symbol);
9308 self.ll1_decision_cache.insert(key, result);
9309 result
9310 }
9311 } else {
9312 None
9313 };
9314 let lookahead_filter = lookahead_filter.as_ref();
9315 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
9321 for (transition_index, transition) in transitions.iter().enumerate() {
9322 if let Some(alt) = ll1_only_alt {
9323 if alt != transition_index {
9325 continue;
9326 }
9327 }
9328 let transition_kind = transition.kind();
9329 if ll1_only_alt.is_none()
9330 && should_skip_via_lookahead(
9331 transition_kind,
9332 transition_index,
9333 lookahead_filter,
9334 index,
9335 self.fast_recovery_enabled,
9336 expected,
9337 )
9338 {
9339 continue;
9340 }
9341 let target = transition.target();
9342 let outcomes_before_transition = outcomes.len();
9343 let left_recursive_boundary = match transition_kind {
9344 ParserTransitionKind::Epsilon
9345 | ParserTransitionKind::Action
9346 | ParserTransitionKind::Predicate
9347 | ParserTransitionKind::Precedence => left_recursive_boundary(atn, state, target),
9348 ParserTransitionKind::Atom
9349 | ParserTransitionKind::Range
9350 | ParserTransitionKind::Set
9351 | ParserTransitionKind::NotSet
9352 | ParserTransitionKind::Wildcard
9353 | ParserTransitionKind::Rule => None,
9354 };
9355 match transition_kind {
9356 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
9357 #[cfg(feature = "perf-counters")]
9358 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9359 outcomes.extend(self.recognize_state_fast(
9360 atn,
9361 FastRecognizeRequest {
9362 state_number: target,
9363 stop_state,
9364 index,
9365 rule_start_index,
9366 decision_start_index: next_decision_start_index,
9367 precedence,
9368 depth: depth + 1,
9369 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9370 recovery_state: epsilon_recovery_state,
9371 },
9372 FastRecognizeScratch {
9373 predicate_context,
9374 visiting,
9375 memo,
9376 expected,
9377 native_depth: native_depth + 1,
9378 },
9379 ));
9380 }
9381 ParserTransitionKind::Predicate => {
9382 #[cfg(feature = "perf-counters")]
9383 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9384 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
9385 outcomes.extend(self.recognize_state_fast(
9386 atn,
9387 FastRecognizeRequest {
9388 state_number: target,
9389 stop_state,
9390 index,
9391 rule_start_index,
9392 decision_start_index: next_decision_start_index,
9393 precedence,
9394 depth: depth + 1,
9395 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9396 recovery_state: epsilon_recovery_state,
9397 },
9398 FastRecognizeScratch {
9399 predicate_context,
9400 visiting,
9401 memo,
9402 expected,
9403 native_depth: native_depth + 1,
9404 },
9405 ));
9406 } else {
9407 record_predicate_no_viable(expected, next_decision_start_index, index);
9408 }
9409 }
9410 ParserTransitionKind::Precedence => {
9411 let transition_precedence = packed_i32(transition.arg0());
9412 if transition_precedence >= precedence {
9413 outcomes.extend(self.recognize_state_fast(
9414 atn,
9415 FastRecognizeRequest {
9416 state_number: target,
9417 stop_state,
9418 index,
9419 rule_start_index,
9420 decision_start_index: next_decision_start_index,
9421 precedence,
9422 depth: depth + 1,
9423 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9424 recovery_state: epsilon_recovery_state,
9425 },
9426 FastRecognizeScratch {
9427 predicate_context,
9428 visiting,
9429 memo,
9430 expected,
9431 native_depth: native_depth + 1,
9432 },
9433 ));
9434 }
9435 }
9436 ParserTransitionKind::Rule => {
9437 let rule_index = transition.arg0() as usize;
9438 let follow_state = transition.arg1() as usize;
9439 let rule_precedence = packed_i32(transition.arg2());
9440 #[cfg(feature = "perf-counters")]
9441 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
9442 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
9443 continue;
9444 };
9445 let symbol = self.token_type_at(index);
9457 if self.fast_first_set_prefilter {
9458 let first = self.cached_rule_first_set(atn, target, child_stop);
9471 if should_skip_rule_via_first_set(
9472 &first,
9473 symbol,
9474 self.fast_recovery_enabled,
9475 index,
9476 expected,
9477 ) {
9478 continue;
9479 }
9480 }
9481 let expected_before_child =
9482 self.fast_recovery_enabled.then(|| expected.clone());
9483 let mut children = self.recognize_state_fast(
9484 atn,
9485 FastRecognizeRequest {
9486 state_number: target,
9487 stop_state: child_stop,
9488 index,
9489 rule_start_index: index,
9490 decision_start_index: None,
9491 precedence: rule_precedence,
9492 depth: depth + 1,
9493 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9494 recovery_state: epsilon_recovery_state,
9495 },
9496 FastRecognizeScratch {
9497 predicate_context,
9498 visiting,
9499 memo,
9500 expected,
9501 native_depth: native_depth + 1,
9502 },
9503 );
9504 if children.is_empty() && self.fast_recovery_enabled {
9505 children = self.fast_child_rule_failure_recovery_outcomes(
9506 FastChildRuleFailureRecoveryRequest {
9507 atn,
9508 rule_index,
9509 start_index: index,
9510 follow_state,
9511 stop_state,
9512 expected,
9513 },
9514 );
9515 }
9516 if let Some(expected_before_child) = expected_before_child {
9517 if children
9518 .iter()
9519 .any(|child| child.diagnostics.is_empty() && child.index > index)
9520 {
9521 *expected = expected_before_child;
9522 }
9523 }
9524 for child in children {
9525 let child_index = child.index;
9526 let child_consumed_eof = child.consumed_eof;
9527 let child_diagnostics = child.diagnostics;
9528 let empty_recovery = self.empty_recovery_symbols();
9529 let follow_outcomes = self.recognize_state_fast(
9530 atn,
9531 FastRecognizeRequest {
9532 state_number: follow_state,
9533 stop_state,
9534 index: child_index,
9535 rule_start_index,
9536 decision_start_index: next_decision_start_index,
9537 precedence,
9538 depth: depth + 1,
9539 recovery_symbols: empty_recovery,
9540 recovery_state: None,
9541 },
9542 FastRecognizeScratch {
9543 predicate_context,
9544 visiting,
9545 memo,
9546 expected,
9547 native_depth: native_depth + 1,
9548 },
9549 );
9550 if follow_outcomes.is_empty() {
9551 continue;
9552 }
9553 let child_stop_index =
9554 self.rule_stop_token_index(child_index, child_consumed_eof);
9555 let child_node = self.build_parse_trees.then(|| {
9556 self.recognition_arena.deferred_rule_node(FastDeferredRule {
9557 rule_index: u32::try_from(rule_index)
9558 .expect("rule index fits in u32"),
9559 invoking_state: i32::try_from(invoking_state_number(state_number))
9560 .expect("invoking state fits in i32"),
9561 start_index: u32::try_from(index)
9562 .expect("rule start index fits in u32"),
9563 stop_index: child_stop_index.map(|stop_index| {
9564 u32::try_from(stop_index).expect("rule stop index fits in u32")
9565 }),
9566 deferred_children: child.deferred_nodes,
9567 children: child.nodes,
9568 })
9569 });
9570 let child_diags_empty = child_diagnostics.is_empty();
9571 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
9572 outcome.consumed_eof |= child_consumed_eof;
9573 if !child_diags_empty {
9576 outcome.diagnostics = self
9577 .recognition_arena
9578 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
9579 }
9580 if let Some(child_node) = child_node {
9581 outcome.deferred_nodes = self
9582 .recognition_arena
9583 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
9584 }
9585 outcome
9586 }));
9587 }
9588 }
9589 ParserTransitionKind::Atom
9590 | ParserTransitionKind::Range
9591 | ParserTransitionKind::Set
9592 | ParserTransitionKind::NotSet
9593 | ParserTransitionKind::Wildcard => {
9594 #[cfg(feature = "perf-counters")]
9595 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9596 let symbol = self.token_type_at(index);
9597 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9598 let next_index = self.consume_index(index, symbol);
9599 let empty_recovery = self.empty_recovery_symbols();
9600 outcomes.extend(
9601 self.recognize_state_fast(
9602 atn,
9603 FastRecognizeRequest {
9604 state_number: target,
9605 stop_state,
9606 index: next_index,
9607 rule_start_index,
9608 decision_start_index: next_decision_start_index,
9609 precedence,
9610 depth: depth + 1,
9611 recovery_symbols: empty_recovery,
9612 recovery_state: None,
9613 },
9614 FastRecognizeScratch {
9615 predicate_context,
9616 visiting,
9617 memo,
9618 expected,
9619 native_depth: native_depth + 1,
9620 },
9621 )
9622 .into_iter()
9623 .map(|mut outcome| {
9624 outcome.consumed_eof |= symbol == TOKEN_EOF;
9625 if self.fast_token_nodes_enabled {
9626 let token = self.arena_token_node(index, false);
9627 self.defer_fast_outcome_node(&mut outcome, token);
9628 }
9629 outcome
9630 }),
9631 );
9632 } else {
9633 if !self.fast_recovery_enabled {
9634 continue;
9642 }
9643 let expected_symbols = fast_recovery_expected_symbols(
9644 self,
9645 atn,
9646 state.state_number(),
9647 &recovery_symbols,
9648 );
9649 if expected_symbols.contains(&symbol) {
9650 continue;
9651 }
9652 {
9653 expected.record_transition(index, transition, max_token_type);
9654 record_no_viable_if_ambiguous(
9655 expected,
9656 next_decision_start_index,
9657 index,
9658 );
9659 outcomes.extend(self.fast_single_token_deletion_recovery(
9660 FastRecoveryRequest {
9661 atn,
9662 transition,
9663 expected_symbols: Rc::clone(&expected_symbols),
9664 target,
9665 request: FastRecognizeRequest {
9666 state_number,
9667 stop_state,
9668 index,
9669 rule_start_index,
9670 decision_start_index,
9671 precedence,
9672 depth,
9673 recovery_symbols: Rc::clone(&recovery_symbols),
9674 recovery_state,
9675 },
9676 visiting,
9677 memo,
9678 expected,
9679 },
9680 predicate_context,
9681 ));
9682 if !state_is_left_recursive_rule(atn, state) {
9683 outcomes.extend(self.fast_single_token_insertion_recovery(
9684 FastRecoveryRequest {
9685 atn,
9686 transition,
9687 expected_symbols: Rc::clone(&expected_symbols),
9688 target,
9689 request: FastRecognizeRequest {
9690 state_number,
9691 stop_state,
9692 index,
9693 rule_start_index,
9694 decision_start_index,
9695 precedence,
9696 depth,
9697 recovery_symbols: Rc::clone(&recovery_symbols),
9698 recovery_state,
9699 },
9700 visiting,
9701 memo,
9702 expected,
9703 },
9704 predicate_context,
9705 ));
9706 }
9707 outcomes.extend(self.fast_current_token_deletion_recovery(
9708 FastCurrentTokenDeletionRequest {
9709 atn,
9710 expected_symbols,
9711 request: FastRecognizeRequest {
9712 state_number,
9713 stop_state,
9714 index,
9715 rule_start_index,
9716 decision_start_index,
9717 precedence,
9718 depth,
9719 recovery_symbols: Rc::clone(&recovery_symbols),
9720 recovery_state,
9721 },
9722 visiting,
9723 memo,
9724 expected,
9725 },
9726 predicate_context,
9727 ));
9728 }
9729 }
9730 }
9731 }
9732 let alt_number = next_alt_number(
9733 state,
9734 transition_count,
9735 transition_index,
9736 0,
9737 self.fast_track_alt_numbers,
9738 );
9739 if alt_number != 0 || left_recursive_boundary.is_some() {
9740 for outcome in &mut outcomes[outcomes_before_transition..] {
9741 if alt_number != 0 {
9742 self.defer_fast_outcome_alternative(outcome, alt_number);
9743 }
9744 if let Some(rule_index) = left_recursive_boundary {
9745 self.defer_fast_outcome_boundary(outcome, rule_index);
9746 }
9747 }
9748 }
9749 }
9750
9751 if has_inserted_cycle_guard {
9752 visiting.remove(&key);
9753 }
9754 if matches!(
9755 self.prediction_mode,
9756 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9757 ) && self.fast_recovery_enabled
9758 {
9759 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
9763 }
9764 if self.fast_recovery_enabled {
9765 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
9766 } else {
9767 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9768 }
9769 let should_memoize = self.fast_recovery_enabled
9779 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
9780 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
9784 if inline_consumed_eof {
9785 outcome.consumed_eof = true;
9786 }
9787 if !inline_consumed_tokens.is_empty() {
9788 for token_index in inline_consumed_tokens.iter().rev() {
9789 let token = self.arena_token_node(*token_index, false);
9790 self.defer_fast_outcome_node(&mut outcome, token);
9791 }
9792 }
9793 outcome
9794 };
9795 if should_memoize {
9796 #[cfg(feature = "perf-counters")]
9797 {
9798 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
9799 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
9800 match outcomes.len() {
9801 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9802 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9803 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9804 }
9805 }
9806 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
9811 memo.insert(key, Rc::clone(&stored));
9812 if inline_pending {
9813 return stored
9814 .iter()
9815 .copied()
9816 .map(&mut apply_inline_pending)
9817 .collect();
9818 }
9819 return stored.to_vec();
9820 }
9821 #[cfg(feature = "perf-counters")]
9822 match outcomes.len() {
9823 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9824 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9825 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9826 }
9827 if inline_pending {
9828 return outcomes.into_iter().map(apply_inline_pending).collect();
9829 }
9830 outcomes
9831 }
9832
9833 fn single_token_deletion_recovery(
9836 &mut self,
9837 recovery: RecoveryRequest<'_, '_>,
9838 ) -> Vec<RecognizeOutcome> {
9839 let RecoveryRequest {
9840 atn,
9841 transition,
9842 expected_symbols,
9843 target,
9844 request,
9845 visiting,
9846 memo,
9847 expected,
9848 } = recovery;
9849 let RecognizeRequest {
9850 stop_state,
9851 index,
9852 rule_start_index,
9853 decision_start_index,
9854 init_action_rules,
9855 predicates,
9856 semantics,
9857 rule_args,
9858 member_actions,
9859 return_actions,
9860 local_int_arg,
9861 member_values,
9862 return_values,
9863 rule_alt_number,
9864 track_alt_numbers,
9865 consumed_eof,
9866 precedence,
9867 depth,
9868 ..
9869 } = request;
9870 let Some((diagnostic, next_index, next_symbol)) =
9871 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
9872 else {
9873 return Vec::new();
9874 };
9875 let after_next = self.consume_index(next_index, next_symbol);
9876 self.recognize_state(
9877 atn,
9878 RecognizeRequest {
9879 state_number: target,
9880 stop_state,
9881 index: after_next,
9882 rule_start_index,
9883 decision_start_index,
9884 init_action_rules,
9885 predicates,
9886 semantics,
9887 rule_args,
9888 member_actions,
9889 return_actions,
9890 local_int_arg,
9891 member_values,
9892 return_values,
9893 rule_alt_number,
9894 track_alt_numbers,
9895 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
9896 committed_decision: false,
9897 precedence,
9898 depth: depth + 1,
9899 recovery_symbols: BTreeSet::new(),
9900 recovery_state: None,
9901 },
9902 visiting,
9903 memo,
9904 expected,
9905 )
9906 .into_iter()
9907 .map(|mut outcome| {
9908 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
9909 outcome.diagnostics = self
9910 .recognition_arena
9911 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9912 let token = self.arena_token_node(next_index, false);
9913 self.arena_prepend(&mut outcome.nodes, token);
9914 let error = self.arena_token_node(index, true);
9915 self.arena_prepend(&mut outcome.nodes, error);
9916 outcome
9917 })
9918 .collect()
9919 }
9920
9921 fn current_token_deletion_recovery(
9924 &mut self,
9925 recovery: CurrentTokenDeletionRequest<'_, '_>,
9926 ) -> Vec<RecognizeOutcome> {
9927 let CurrentTokenDeletionRequest {
9928 atn,
9929 expected_symbols,
9930 mut request,
9931 visiting,
9932 memo,
9933 expected,
9934 } = recovery;
9935 let error_index = request.index;
9936 if error_index == request.rule_start_index {
9937 return Vec::new();
9938 }
9939 let Some((diagnostic, next_index, skipped)) =
9940 self.current_token_deletion(error_index, &expected_symbols)
9941 else {
9942 return Vec::new();
9943 };
9944 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9945 request.index = next_index;
9946 request.committed_decision = false;
9947 request.depth += 1;
9948 request.recovery_state = None;
9949 self.recognize_state(atn, request, visiting, memo, expected)
9950 .into_iter()
9951 .map(|mut outcome| {
9952 outcome.diagnostics = self
9953 .recognition_arena
9954 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9955 for index in skipped.iter().rev() {
9956 let error = self.arena_token_node(*index, true);
9957 self.arena_prepend(&mut outcome.nodes, error);
9958 }
9959 outcome
9960 })
9961 .collect()
9962 }
9963
9964 fn consuming_failure_fallback(
9967 &mut self,
9968 fallback: ConsumingFailureFallback<'_>,
9969 visiting: &mut BTreeSet<RecognizeKey>,
9970 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9971 expected: &mut ExpectedTokens,
9972 ) -> Vec<RecognizeOutcome> {
9973 if fallback.expected_symbols.is_empty() {
9974 return Vec::new();
9975 }
9976 if fallback.symbol == TOKEN_EOF {
9977 return self.eof_consuming_failure_fallback(fallback, expected);
9978 }
9979 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
9980 }
9981
9982 fn non_eof_consuming_failure_fallback(
9985 &mut self,
9986 fallback: ConsumingFailureFallback<'_>,
9987 visiting: &mut BTreeSet<RecognizeKey>,
9988 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9989 expected: &mut ExpectedTokens,
9990 ) -> Vec<RecognizeOutcome> {
9991 let ConsumingFailureFallback {
9992 atn,
9993 target,
9994 request,
9995 symbol,
9996 expected_symbols,
9997 decision_start_index,
9998 decision,
9999 } = fallback;
10000 let error_index = request.index;
10001 let diagnostic =
10002 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
10003 let next_index = self.consume_index(error_index, symbol);
10004 self.recognize_state(
10005 atn,
10006 RecognizeRequest {
10007 state_number: target,
10008 stop_state: request.stop_state,
10009 index: next_index,
10010 rule_start_index: request.rule_start_index,
10011 decision_start_index,
10012 init_action_rules: request.init_action_rules,
10013 predicates: request.predicates,
10014 semantics: request.semantics,
10015 rule_args: request.rule_args,
10016 member_actions: request.member_actions,
10017 return_actions: request.return_actions,
10018 local_int_arg: request.local_int_arg,
10019 member_values: request.member_values,
10020 return_values: request.return_values,
10021 rule_alt_number: request.rule_alt_number,
10022 track_alt_numbers: request.track_alt_numbers,
10023 consumed_eof: request.consumed_eof,
10024 committed_decision: false,
10025 precedence: request.precedence,
10026 depth: request.depth + 1,
10027 recovery_symbols: BTreeSet::new(),
10028 recovery_state: None,
10029 },
10030 visiting,
10031 memo,
10032 expected,
10033 )
10034 .into_iter()
10035 .map(|mut outcome| {
10036 prepend_decision(&mut outcome, decision);
10037 outcome.diagnostics = self
10038 .recognition_arena
10039 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10040 let error = self.arena_token_node(error_index, true);
10041 self.arena_prepend(&mut outcome.nodes, error);
10042 outcome
10043 })
10044 .collect()
10045 }
10046
10047 fn eof_consuming_failure_fallback(
10050 &mut self,
10051 fallback: ConsumingFailureFallback<'_>,
10052 expected: &ExpectedTokens,
10053 ) -> Vec<RecognizeOutcome> {
10054 let request = fallback.request;
10055 if request.index == request.rule_start_index {
10056 return Vec::new();
10057 }
10058 let diagnostic =
10059 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
10060 let diagnostics = self
10061 .recognition_arena
10062 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10063 vec![RecognizeOutcome {
10064 index: request.index,
10065 consumed_eof: request.consumed_eof,
10066 alt_number: request.rule_alt_number,
10067 member_values: request.member_values,
10068 return_values: request.return_values,
10069 diagnostics,
10070 decisions: Vec::new(),
10071 actions: Vec::new(),
10072 nodes: NodeSeqId::EMPTY,
10073 }]
10074 }
10075
10076 fn single_token_insertion_recovery(
10079 &mut self,
10080 recovery: RecoveryRequest<'_, '_>,
10081 ) -> Vec<RecognizeOutcome> {
10082 let RecoveryRequest {
10083 atn,
10084 transition,
10085 expected_symbols,
10086 target,
10087 request,
10088 visiting,
10089 memo,
10090 expected,
10091 } = recovery;
10092 let RecognizeRequest {
10093 stop_state,
10094 index,
10095 rule_start_index,
10096 decision_start_index,
10097 init_action_rules,
10098 predicates,
10099 semantics,
10100 rule_args,
10101 member_actions,
10102 return_actions,
10103 local_int_arg,
10104 member_values,
10105 return_values,
10106 rule_alt_number,
10107 track_alt_numbers,
10108 consumed_eof,
10109 precedence,
10110 depth,
10111 ..
10112 } = request;
10113 let follow_symbols = state_expected_symbols(atn, transition.target());
10114 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
10115 transition,
10116 index,
10117 atn.max_token_type(),
10118 &expected_symbols,
10119 &follow_symbols,
10120 ) else {
10121 return Vec::new();
10122 };
10123 self.recognize_state(
10124 atn,
10125 RecognizeRequest {
10126 state_number: target,
10127 stop_state,
10128 index,
10129 rule_start_index,
10130 decision_start_index,
10131 init_action_rules,
10132 predicates,
10133 semantics,
10134 rule_args,
10135 member_actions,
10136 return_actions,
10137 local_int_arg,
10138 member_values,
10139 return_values,
10140 rule_alt_number,
10141 track_alt_numbers,
10142 consumed_eof,
10143 committed_decision: false,
10144 precedence,
10145 depth: depth + 1,
10146 recovery_symbols: BTreeSet::new(),
10147 recovery_state: None,
10148 },
10149 visiting,
10150 memo,
10151 expected,
10152 )
10153 .into_iter()
10154 .map(|mut outcome| {
10155 outcome.diagnostics = self
10156 .recognition_arena
10157 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10158 let missing = self.arena_missing_token_node(token_type, index, text.clone());
10159 self.arena_prepend(&mut outcome.nodes, missing);
10160 outcome
10161 })
10162 .collect()
10163 }
10164
10165 #[allow(clippy::too_many_lines)]
10168 fn recognize_state(
10169 &mut self,
10170 atn: &Atn,
10171 request: RecognizeRequest<'_>,
10172 visiting: &mut BTreeSet<RecognizeKey>,
10173 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10174 expected: &mut ExpectedTokens,
10175 ) -> Vec<RecognizeOutcome> {
10176 let request_template = request.clone();
10177 let RecognizeRequest {
10178 state_number,
10179 stop_state,
10180 index,
10181 rule_start_index,
10182 decision_start_index,
10183 init_action_rules,
10184 predicates,
10185 semantics,
10186 rule_args,
10187 member_actions,
10188 return_actions,
10189 local_int_arg,
10190 member_values,
10191 return_values,
10192 rule_alt_number,
10193 track_alt_numbers,
10194 consumed_eof,
10195 committed_decision,
10196 precedence,
10197 depth,
10198 recovery_symbols,
10199 recovery_state,
10200 } = request;
10201 if depth > RECOGNITION_DEPTH_LIMIT {
10202 return Vec::new();
10203 }
10204 if state_number == stop_state {
10205 return stop_outcome(
10206 index,
10207 consumed_eof,
10208 rule_alt_number,
10209 member_values,
10210 return_values,
10211 );
10212 }
10213 let key = RecognizeKey {
10214 state_number,
10215 stop_state,
10216 index,
10217 rule_start_index,
10218 decision_start_index,
10219 local_int_arg,
10220 member_values: member_values.clone(),
10221 return_values: return_values.clone(),
10222 rule_alt_number,
10223 track_alt_numbers,
10224 consumed_eof,
10225 committed_decision,
10226 precedence,
10227 recovery_symbols: recovery_symbols.clone(),
10228 recovery_state,
10229 };
10230 if let Some(outcomes) = memo.get(&key) {
10231 return outcomes.clone();
10232 }
10233
10234 let visit_key = key.clone();
10235 if !visiting.insert(visit_key.clone()) {
10236 return Vec::new();
10237 }
10238
10239 let Some(state) = atn.state(state_number) else {
10240 visiting.remove(&visit_key);
10241 return Vec::new();
10242 };
10243 let decision_override_generation = self.decision_override_generation;
10244 let transitions = state.transitions();
10245 let transition_count = transitions.len();
10246 let overridden_transition = if transition_count > 1
10247 && self.semantic_hooks.observes_parser_decisions()
10248 {
10249 atn.decision_to_state()
10250 .iter()
10251 .position(|candidate| candidate == state_number)
10252 .and_then(|decision| {
10253 self.semantic_hooks
10254 .parser_decision_override(decision, index, transition_count)
10255 })
10256 .and_then(|alternative| alternative.checked_sub(1))
10257 .filter(|alternative| *alternative < transition_count)
10258 } else {
10259 None
10260 };
10261 if overridden_transition.is_some() {
10262 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
10263 }
10264 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
10265 Some(index)
10266 } else {
10267 decision_start_index
10268 };
10269 let (epsilon_recovery_symbols, epsilon_recovery_state) =
10270 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
10271 let mut outcomes = Vec::new();
10272 for (transition_index, transition) in transitions.iter().enumerate() {
10273 if overridden_transition.is_some_and(|forced| forced != transition_index) {
10274 continue;
10275 }
10276 let transition_committed =
10277 committed_decision || overridden_transition == Some(transition_index);
10278 let mut transition_request = request_template.clone();
10279 transition_request.committed_decision = transition_committed;
10280 let decision =
10281 transition_decision(atn, state, transition_count, transition_index, predicates);
10282 let next_alt_number = next_alt_number(
10283 state,
10284 transition_count,
10285 transition_index,
10286 rule_alt_number,
10287 track_alt_numbers,
10288 );
10289 let transition_data = transition.data();
10290 match &transition_data {
10291 Transition::Epsilon { target } | Transition::Action { target, .. } => {
10292 let action_rule_index = match &transition_data {
10293 Transition::Action { rule_index, .. } => Some(*rule_index),
10294 _ => None,
10295 };
10296 outcomes.extend(self.recognize_epsilon_or_action_step(
10297 atn,
10298 &transition_request,
10299 EpsilonActionStep {
10300 source_state: state_number,
10301 target: *target,
10302 action_rule_index,
10303 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
10304 decision,
10305 decision_start_index: next_decision_start_index,
10306 alt_number: next_alt_number,
10307 recovery_symbols: epsilon_recovery_symbols.clone(),
10308 recovery_state: epsilon_recovery_state,
10309 },
10310 RecognizeScratch {
10311 visiting,
10312 memo,
10313 expected,
10314 },
10315 ));
10316 }
10317 Transition::Predicate {
10318 target,
10319 rule_index,
10320 pred_index,
10321 ..
10322 } => {
10323 let predicate = PredicateEval {
10324 index,
10325 rule_index: *rule_index,
10326 pred_index: *pred_index,
10327 predicates,
10328 semantics,
10329 context: None,
10330 local_int_arg,
10331 member_values: &member_values,
10332 };
10333 if self.parser_predicate_matches(predicate) {
10334 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
10335 outcomes.extend(
10336 self.recognize_state(
10337 atn,
10338 RecognizeRequest {
10339 state_number: *target,
10340 stop_state,
10341 index,
10342 rule_start_index,
10343 decision_start_index: next_decision_start_index,
10344 init_action_rules,
10345 predicates,
10346 semantics,
10347 rule_args,
10348 member_actions,
10349 return_actions,
10350 local_int_arg,
10351 member_values: member_values.clone(),
10352 return_values: return_values.clone(),
10353 rule_alt_number: next_alt_number,
10354 track_alt_numbers,
10355 consumed_eof,
10356 committed_decision: transition_committed,
10357 precedence,
10358 depth: depth + 1,
10359 recovery_symbols: epsilon_recovery_symbols.clone(),
10360 recovery_state: epsilon_recovery_state,
10361 },
10362 visiting,
10363 memo,
10364 expected,
10365 )
10366 .into_iter()
10367 .map(|mut outcome| {
10368 prepend_decision(&mut outcome, decision);
10369 if let Some(rule_index) = left_recursive_boundary {
10370 let boundary =
10371 self.arena_boundary_node(rule_index, next_alt_number);
10372 self.arena_prepend(&mut outcome.nodes, boundary);
10373 }
10374 outcome
10375 }),
10376 );
10377 } else if let Some(message) = semantics
10378 .and_then(|semantics| {
10379 self.parser_semantic_ir_predicate_failure_message(
10380 *rule_index,
10381 *pred_index,
10382 semantics,
10383 )
10384 })
10385 .or_else(|| {
10386 self.parser_predicate_failure_message(
10387 *rule_index,
10388 *pred_index,
10389 predicates,
10390 )
10391 })
10392 {
10393 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
10394 rule_index: *rule_index,
10395 index,
10396 message,
10397 member_values: member_values.clone(),
10398 return_values: return_values.clone(),
10399 rule_alt_number,
10400 }));
10401 } else {
10402 record_predicate_no_viable(expected, next_decision_start_index, index);
10403 }
10404 }
10405 Transition::Precedence {
10406 target,
10407 precedence: transition_precedence,
10408 } => {
10409 if *transition_precedence >= precedence {
10410 outcomes.extend(
10411 self.recognize_state(
10412 atn,
10413 RecognizeRequest {
10414 state_number: *target,
10415 stop_state,
10416 index,
10417 rule_start_index,
10418 decision_start_index: next_decision_start_index,
10419 init_action_rules,
10420 predicates,
10421 semantics,
10422 rule_args,
10423 member_actions,
10424 return_actions,
10425 local_int_arg,
10426 member_values: member_values.clone(),
10427 return_values: return_values.clone(),
10428 rule_alt_number: next_alt_number,
10429 track_alt_numbers,
10430 consumed_eof,
10431 committed_decision: transition_committed,
10432 precedence,
10433 depth: depth + 1,
10434 recovery_symbols: epsilon_recovery_symbols.clone(),
10435 recovery_state: epsilon_recovery_state,
10436 },
10437 visiting,
10438 memo,
10439 expected,
10440 )
10441 .into_iter()
10442 .map(|mut outcome| {
10443 prepend_decision(&mut outcome, decision);
10444 outcome
10445 }),
10446 );
10447 }
10448 }
10449 Transition::Rule {
10450 target,
10451 rule_index,
10452 follow_state,
10453 precedence: rule_precedence,
10454 ..
10455 } => {
10456 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
10457 continue;
10458 };
10459 let child_local_int_arg =
10460 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
10461 let expected_before_child = expected.clone();
10462 let children = self.recognize_state(
10463 atn,
10464 RecognizeRequest {
10465 state_number: *target,
10466 stop_state: child_stop,
10467 index,
10468 rule_start_index: index,
10469 decision_start_index: None,
10470 init_action_rules,
10471 predicates,
10472 semantics,
10473 rule_args,
10474 member_actions,
10475 return_actions,
10476 local_int_arg: child_local_int_arg,
10477 member_values: member_values.clone(),
10478 return_values: BTreeMap::new(),
10479 rule_alt_number: 0,
10480 track_alt_numbers,
10481 consumed_eof: false,
10482 committed_decision: transition_committed,
10483 precedence: *rule_precedence,
10484 depth: depth + 1,
10485 recovery_symbols: epsilon_recovery_symbols.clone(),
10486 recovery_state: epsilon_recovery_state,
10487 },
10488 visiting,
10489 memo,
10490 expected,
10491 );
10492 let children = if children.is_empty() {
10493 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
10494 atn,
10495 rule_index: *rule_index,
10496 start_index: index,
10497 follow_state: *follow_state,
10498 stop_state,
10499 member_values: member_values.clone(),
10500 expected,
10501 })
10502 } else {
10503 children
10504 };
10505 let preserve_child_expected =
10506 self.child_expected_reaches_clean_eof(&children, expected);
10507 restore_expected(
10508 &children,
10509 index,
10510 expected,
10511 expected_before_child,
10512 preserve_child_expected,
10513 );
10514 for child in children {
10515 let child_stop_index =
10516 self.rule_stop_token_index(child.index, child.consumed_eof);
10517 let child_nodes = self
10518 .recognition_arena
10519 .fold_left_recursive_boundaries(child.nodes);
10520 let child_node = self.arena_rule_node(ArenaRuleSpec {
10521 rule_index: *rule_index,
10522 invoking_state: invoking_state_number(state_number),
10523 alt_number: child.alt_number,
10524 start_index: index,
10525 stop_index: child_stop_index,
10526 return_values: child.return_values.clone(),
10527 children: child_nodes,
10528 });
10529 outcomes.extend(
10530 self.recognize_state(
10531 atn,
10532 RecognizeRequest {
10533 state_number: *follow_state,
10534 stop_state,
10535 index: child.index,
10536 rule_start_index,
10537 decision_start_index: next_decision_start_index,
10538 init_action_rules,
10539 predicates,
10540 semantics,
10541 rule_args,
10542 member_actions,
10543 return_actions,
10544 local_int_arg,
10545 member_values: child.member_values.clone(),
10546 return_values: return_values.clone(),
10547 rule_alt_number,
10548 track_alt_numbers,
10549 consumed_eof: consumed_eof || child.consumed_eof,
10550 committed_decision: transition_committed
10551 && child.index == index,
10552 precedence,
10553 depth: depth + 1,
10554 recovery_symbols: BTreeSet::new(),
10555 recovery_state: None,
10556 },
10557 visiting,
10558 memo,
10559 expected,
10560 )
10561 .into_iter()
10562 .map(|mut outcome| {
10563 outcome.consumed_eof |= child.consumed_eof;
10564 outcome.diagnostics = self
10565 .recognition_arena
10566 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
10567 let mut decisions = child.decisions.clone();
10568 decisions.append(&mut outcome.decisions);
10569 outcome.decisions = decisions;
10570 prepend_decision(&mut outcome, decision);
10571 let mut actions = child.actions.clone();
10572 if init_action_rules.contains(rule_index) {
10573 actions.insert(
10574 0,
10575 ParserAction::new_rule_init(
10576 *rule_index,
10577 index,
10578 Some(*follow_state),
10579 ),
10580 );
10581 }
10582 actions.append(&mut outcome.actions);
10583 outcome.actions = actions;
10584 self.arena_prepend(&mut outcome.nodes, child_node);
10585 outcome
10586 }),
10587 );
10588 }
10589 }
10590 Transition::Atom { target, .. }
10591 | Transition::Range { target, .. }
10592 | Transition::Set { target, .. }
10593 | Transition::NotSet { target, .. }
10594 | Transition::Wildcard { target, .. } => {
10595 let symbol = self.token_type_at(index);
10596 if transition_data.matches(symbol, 1, atn.max_token_type()) {
10597 let next_index = self.consume_index(index, symbol);
10598 outcomes.extend(
10599 self.recognize_state(
10600 atn,
10601 RecognizeRequest {
10602 state_number: *target,
10603 stop_state,
10604 index: next_index,
10605 rule_start_index,
10606 decision_start_index: next_decision_start_index,
10607 init_action_rules,
10608 predicates,
10609 semantics,
10610 rule_args,
10611 member_actions,
10612 return_actions,
10613 local_int_arg,
10614 member_values: member_values.clone(),
10615 return_values: return_values.clone(),
10616 rule_alt_number: next_alt_number,
10617 track_alt_numbers,
10618 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
10619 committed_decision: false,
10620 precedence,
10621 depth: depth + 1,
10622 recovery_symbols: BTreeSet::new(),
10623 recovery_state: None,
10624 },
10625 visiting,
10626 memo,
10627 expected,
10628 )
10629 .into_iter()
10630 .map(|mut outcome| {
10631 prepend_decision(&mut outcome, decision);
10632 outcome.consumed_eof |= symbol == TOKEN_EOF;
10633 let token = self.arena_token_node(index, false);
10634 self.arena_prepend(&mut outcome.nodes, token);
10635 outcome
10636 }),
10637 );
10638 } else {
10639 let expected_symbols =
10640 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
10641 if expected_symbols.contains(&symbol) && !transition_committed {
10642 continue;
10643 }
10644 expected.record_transition(index, transition, atn.max_token_type());
10645 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
10646 let before_recovery = outcomes.len();
10647 let recovery_request = transition_request.clone();
10648 if transition_committed {
10649 outcomes.extend(self.consuming_failure_fallback(
10650 ConsumingFailureFallback {
10651 atn,
10652 target: *target,
10653 request: recovery_request,
10654 symbol,
10655 expected_symbols,
10656 decision_start_index: next_decision_start_index,
10657 decision,
10658 },
10659 visiting,
10660 memo,
10661 expected,
10662 ));
10663 break;
10664 }
10665 outcomes.extend(
10666 self.single_token_deletion_recovery(RecoveryRequest {
10667 atn,
10668 transition,
10669 expected_symbols: expected_symbols.clone(),
10670 target: *target,
10671 request: recovery_request.clone(),
10672 visiting,
10673 memo,
10674 expected,
10675 })
10676 .into_iter()
10677 .map(|mut outcome| {
10678 prepend_decision(&mut outcome, decision);
10679 outcome
10680 }),
10681 );
10682 if !state_is_left_recursive_rule(atn, state) {
10683 outcomes.extend(
10684 self.single_token_insertion_recovery(RecoveryRequest {
10685 atn,
10686 transition,
10687 expected_symbols: expected_symbols.clone(),
10688 target: *target,
10689 request: recovery_request.clone(),
10690 visiting,
10691 memo,
10692 expected,
10693 })
10694 .into_iter()
10695 .map(|mut outcome| {
10696 prepend_decision(&mut outcome, decision);
10697 outcome
10698 }),
10699 );
10700 }
10701 outcomes.extend(self.current_token_deletion_recovery(
10702 CurrentTokenDeletionRequest {
10703 atn,
10704 expected_symbols: expected_symbols.clone(),
10705 request: recovery_request.clone(),
10706 visiting,
10707 memo,
10708 expected,
10709 },
10710 ));
10711 if outcomes.len() == before_recovery {
10712 outcomes.extend(self.consuming_failure_fallback(
10713 ConsumingFailureFallback {
10714 atn,
10715 target: *target,
10716 request: recovery_request,
10717 symbol,
10718 expected_symbols,
10719 decision_start_index: next_decision_start_index,
10720 decision,
10721 },
10722 visiting,
10723 memo,
10724 expected,
10725 ));
10726 }
10727 }
10728 }
10729 }
10730 if self.decision_override_generation != decision_override_generation {
10731 break;
10732 }
10733 }
10734
10735 visiting.remove(&visit_key);
10736 self.record_prediction_diagnostics(atn, state, index, &outcomes);
10737 if matches!(
10738 self.prediction_mode,
10739 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
10740 ) {
10741 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
10742 }
10743 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
10744 memo.insert(key, outcomes.clone());
10745 outcomes
10746 }
10747
10748 fn recognize_epsilon_or_action_step(
10751 &mut self,
10752 atn: &Atn,
10753 request: &RecognizeRequest<'_>,
10754 step: EpsilonActionStep,
10755 scratch: RecognizeScratch<'_>,
10756 ) -> Vec<RecognizeOutcome> {
10757 let RecognizeScratch {
10758 visiting,
10759 memo,
10760 expected,
10761 } = scratch;
10762 let action = step.action_rule_index.map(|rule_index| {
10763 ParserAction::new(
10764 step.source_state,
10765 rule_index,
10766 request.rule_start_index,
10767 self.rule_stop_token_index(request.index, request.consumed_eof),
10768 )
10769 });
10770 let next_member_values = if action.is_some() {
10771 member_values_after_action(
10772 step.source_state,
10773 request.member_actions,
10774 request.semantics,
10775 &request.member_values,
10776 )
10777 } else {
10778 request.member_values.clone()
10779 };
10780 let next_return_values = action.map_or_else(
10781 || request.return_values.clone(),
10782 |action| {
10783 return_values_after_action(
10784 step.source_state,
10785 action.rule_index(),
10786 request.return_actions,
10787 request.semantics,
10788 &request.return_values,
10789 )
10790 },
10791 );
10792
10793 self.recognize_state(
10794 atn,
10795 RecognizeRequest {
10796 state_number: step.target,
10797 stop_state: request.stop_state,
10798 index: request.index,
10799 rule_start_index: request.rule_start_index,
10800 decision_start_index: step.decision_start_index,
10801 init_action_rules: request.init_action_rules,
10802 predicates: request.predicates,
10803 semantics: request.semantics,
10804 rule_args: request.rule_args,
10805 member_actions: request.member_actions,
10806 return_actions: request.return_actions,
10807 local_int_arg: request.local_int_arg,
10808 member_values: next_member_values,
10809 return_values: next_return_values,
10810 rule_alt_number: if step.left_recursive_boundary.is_some() {
10811 0
10812 } else {
10813 step.alt_number
10814 },
10815 track_alt_numbers: request.track_alt_numbers,
10816 consumed_eof: request.consumed_eof,
10817 committed_decision: request.committed_decision,
10818 precedence: request.precedence,
10819 depth: request.depth + 1,
10820 recovery_symbols: step.recovery_symbols,
10821 recovery_state: step.recovery_state,
10822 },
10823 visiting,
10824 memo,
10825 expected,
10826 )
10827 .into_iter()
10828 .map(|mut outcome| {
10829 prepend_decision(&mut outcome, step.decision);
10830 if let Some(rule_index) = step.left_recursive_boundary {
10831 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
10832 self.arena_prepend(&mut outcome.nodes, boundary);
10833 }
10834 if let Some(action) = action {
10835 outcome.actions.insert(0, action);
10836 }
10837 outcome
10838 })
10839 .collect()
10840 }
10841
10842 fn token_type_at(&mut self, index: usize) -> i32 {
10847 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
10848 self.input.fill();
10849 }
10850 self.input.token_type_at_index(index)
10851 }
10852
10853 fn cached_state_expected_symbols(
10865 &mut self,
10866 atn: &Atn,
10867 state_number: usize,
10868 ) -> Rc<BTreeSet<i32>> {
10869 if let Some(cached) = self.state_expected_cache.get(&state_number) {
10870 return Rc::clone(cached);
10871 }
10872 let symbols = state_expected_symbols(atn, state_number);
10873 let entry = self.intern_recovery_symbols(symbols);
10874 self.state_expected_cache
10875 .insert(state_number, Rc::clone(&entry));
10876 entry
10877 }
10878
10879 fn cached_state_expected_token_set(
10880 &mut self,
10881 atn: &Atn,
10882 state_number: usize,
10883 ) -> Rc<TokenBitSet> {
10884 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
10885 return Rc::clone(cached);
10886 }
10887 let symbols = with_shared_atn_caches(atn, |cache| {
10891 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
10892 return Rc::clone(cached);
10893 }
10894 let symbols = Rc::new(state_expected_token_set(atn, state_number));
10895 cache
10896 .state_expected_tokens
10897 .insert(state_number, Rc::clone(&symbols));
10898 symbols
10899 });
10900 self.state_expected_token_cache
10901 .insert(state_number, Rc::clone(&symbols));
10902 symbols
10903 }
10904
10905 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
10906 if self.rule_stop_reach_cache.len() <= state_number {
10907 self.rule_stop_reach_cache
10908 .resize_with(atn.states().len().max(state_number + 1), || None);
10909 }
10910 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
10911 return reaches;
10912 }
10913 let reaches = with_shared_atn_caches(atn, |cache| {
10914 *cache
10915 .rule_stop_reach
10916 .entry(state_number)
10917 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
10918 });
10919 self.rule_stop_reach_cache[state_number] = Some(reaches);
10920 reaches
10921 }
10922
10923 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
10926 Rc::clone(&self.empty_recovery_symbols)
10927 }
10928
10929 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
10938 if set.is_empty() {
10939 return Rc::clone(&self.empty_recovery_symbols);
10940 }
10941 let candidate = Rc::new(set);
10942 match self.recovery_symbols_intern.get(&candidate) {
10943 Some(existing) => Rc::clone(existing),
10944 None => {
10945 self.recovery_symbols_intern
10946 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
10947 candidate
10948 }
10949 }
10950 }
10951
10952 fn cached_decision_lookahead(
10957 &mut self,
10958 atn: &Atn,
10959 state: AtnState<'_>,
10960 rule_stop_state: usize,
10961 ) -> Rc<DecisionLookahead> {
10962 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
10969 return Rc::clone(cached);
10970 }
10971 let entry = with_shared_atn_caches(atn, |cache| {
10972 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
10973 return Rc::clone(cached);
10974 }
10975 let mut entry = DecisionLookahead {
10976 transitions: Vec::with_capacity(state.transitions().len()),
10977 };
10978 for transition in &state.transitions() {
10979 entry.transitions.push(transition_first_set(
10980 atn,
10981 transition,
10982 rule_stop_state,
10983 &mut cache.first_set,
10984 ));
10985 }
10986 let entry = Rc::new(entry);
10987 cache
10988 .decision_lookahead
10989 .insert(state.state_number(), Rc::clone(&entry));
10990 entry
10991 });
10992 self.decision_lookahead_cache
10993 .insert(state.state_number(), Rc::clone(&entry));
10994 entry
10995 }
10996
10997 fn cached_rule_first_set(
10998 &mut self,
10999 atn: &Atn,
11000 target: usize,
11001 child_stop: usize,
11002 ) -> Rc<FirstSet> {
11003 if self.rule_first_set_cache.len() <= target {
11004 self.rule_first_set_cache
11005 .resize_with(atn.states().len().max(target + 1), || None);
11006 }
11007 if let Some(cached) = self
11008 .rule_first_set_cache
11009 .get(target)
11010 .and_then(Option::as_ref)
11011 {
11012 return Rc::clone(cached);
11013 }
11014 let first = with_shared_first_set_cache(atn, |cache| {
11015 rule_first_set(atn, target, child_stop, cache)
11016 });
11017 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
11018 first
11019 }
11020
11021 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
11022 let atn_key = SharedAtnCacheKey::for_atn(atn);
11023 if self.empty_cycle_cache_atn != Some(atn_key) {
11024 self.empty_cycle_cache.clear();
11025 self.empty_cycle_cache_atn = Some(atn_key);
11026 }
11027 if self.empty_cycle_cache.len() <= state_number {
11028 self.empty_cycle_cache
11029 .resize_with(atn.state_count().max(state_number + 1), || None);
11030 }
11031 if let Some(cached) = self.empty_cycle_cache[state_number] {
11032 return cached;
11033 }
11034 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
11035 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
11036 self.empty_cycle_cache[state_number] = Some(result);
11037 result
11038 }
11039
11040 fn empty_path_reaches_state(
11041 &mut self,
11042 atn: &Atn,
11043 state_number: usize,
11044 target_state: usize,
11045 visited: &mut FxHashSet<usize>,
11046 ) -> bool {
11047 enum Work {
11048 Visit(usize),
11049 RuleFollow {
11050 target: usize,
11051 rule_index: usize,
11052 follow_state: usize,
11053 },
11054 }
11055
11056 let mut work = vec![Work::Visit(state_number)];
11057 while let Some(item) = work.pop() {
11058 match item {
11059 Work::Visit(state_number) => {
11060 if !visited.insert(state_number) {
11061 continue;
11062 }
11063 let Some(state) = atn.state(state_number) else {
11064 continue;
11065 };
11066 let transitions = state.transitions();
11067 for transition_index in (0..transitions.len()).rev() {
11068 let transition = transitions
11069 .get(transition_index)
11070 .expect("in-bounds parser transition");
11071 let kind = transition.kind();
11072 let target = transition.target();
11073 match kind {
11074 ParserTransitionKind::Atom
11075 | ParserTransitionKind::Range
11076 | ParserTransitionKind::Set
11077 | ParserTransitionKind::NotSet
11078 | ParserTransitionKind::Wildcard => {}
11079 ParserTransitionKind::Rule => {
11080 if target == target_state {
11081 return true;
11082 }
11083 work.push(Work::RuleFollow {
11084 target,
11085 rule_index: transition.arg0() as usize,
11086 follow_state: transition.arg1() as usize,
11087 });
11088 work.push(Work::Visit(target));
11089 }
11090 ParserTransitionKind::Epsilon
11091 | ParserTransitionKind::Predicate
11092 | ParserTransitionKind::Action
11093 | ParserTransitionKind::Precedence => {
11094 if target == target_state {
11095 return true;
11096 }
11097 work.push(Work::Visit(target));
11098 }
11099 }
11100 }
11101 }
11102 Work::RuleFollow {
11103 target,
11104 rule_index,
11105 follow_state,
11106 } => {
11107 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
11108 continue;
11109 };
11110 if self.cached_rule_first_set(atn, target, child_stop).nullable {
11111 if follow_state == target_state {
11112 return true;
11113 }
11114 work.push(Work::Visit(follow_state));
11115 }
11116 }
11117 }
11118 }
11119 false
11120 }
11121
11122 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
11125 match self.clean_memo_mode {
11126 CleanMemoMode::Promote => true,
11127 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
11128 CleanMemoMode::Sparse => {
11129 self.clean_memo_sparse_samples += 1;
11130 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
11131 return false;
11132 }
11133 self.clean_memo_sparse_samples = 0;
11134 self.clean_memo_mode = CleanMemoMode::Probe;
11135 self.clean_memo_probe_samples = 0;
11136 self.clean_memo_probe_repeats = 0;
11137 self.clean_memo_probe_seen.clear();
11138 self.observe_clean_memo_probe(key)
11139 }
11140 }
11141 }
11142
11143 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
11144 self.clean_memo_probe_samples += 1;
11145 if !self.clean_memo_probe_seen.insert(key.clone()) {
11146 self.clean_memo_probe_repeats += 1;
11147 }
11148 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
11149 self.clean_memo_mode = CleanMemoMode::Promote;
11150 self.clean_memo_probe_seen.clear();
11151 return true;
11152 }
11153 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
11154 self.clean_memo_mode = CleanMemoMode::Sparse;
11155 self.clean_memo_sparse_samples = 0;
11156 self.clean_memo_probe_seen.clear();
11157 return false;
11158 }
11159 true
11160 }
11161
11162 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
11164 self.input.get(index)
11165 }
11166
11167 fn token_id_at(&self, index: usize) -> Option<TokenId> {
11169 self.input.get_id(index)
11170 }
11171
11172 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
11173 let token = self
11174 .token_id_at(index)
11175 .expect("recognized token index must exist in the token store");
11176 let node = if error {
11177 ArenaRecognizedNode::ErrorToken { token }
11178 } else {
11179 ArenaRecognizedNode::Token { token }
11180 };
11181 self.recognition_arena.push_node(node)
11182 }
11183
11184 fn arena_missing_token_node(
11185 &mut self,
11186 token_type: i32,
11187 at_index: usize,
11188 text: String,
11189 ) -> RecognizedNodeId {
11190 let extra = self
11191 .recognition_arena
11192 .push_extra(RecognitionExtra::MissingToken {
11193 token_type,
11194 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
11195 text,
11196 });
11197 self.recognition_arena
11198 .push_node(ArenaRecognizedNode::MissingToken { extra })
11199 }
11200
11201 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
11202 let ArenaRuleSpec {
11203 rule_index,
11204 invoking_state,
11205 alt_number,
11206 start_index,
11207 stop_index,
11208 return_values,
11209 children,
11210 } = spec;
11211 let return_values = (!return_values.is_empty()).then(|| {
11212 self.recognition_arena
11213 .push_extra(RecognitionExtra::ReturnValues(return_values))
11214 });
11215 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
11216 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11217 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
11218 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11219 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
11220 stop_index: stop_index
11221 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
11222 return_values,
11223 children,
11224 })
11225 }
11226
11227 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
11228 self.recognition_arena
11229 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
11230 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11231 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11232 })
11233 }
11234
11235 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
11236 *sequence = self.recognition_arena.prepend(*sequence, node);
11237 }
11238
11239 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
11240 self.last_recognition_arena_root = root;
11241 self.last_recognition_arena_diagnostics = diagnostics;
11242 #[cfg(feature = "perf-counters")]
11243 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
11244 let stats = self.recognition_arena_stats();
11245 #[allow(clippy::print_stderr)]
11246 {
11247 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
11248 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
11249 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
11250 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
11251 eprintln!("perf recognition_links_total={}", stats.total_links);
11252 eprintln!("perf recognition_links_live={}", stats.live_links);
11253 eprintln!("perf recognition_links_dead={}", stats.dead_links);
11254 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
11255 eprintln!("perf recognition_extras_total={}", stats.total_extras);
11256 eprintln!("perf recognition_extras_live={}", stats.live_extras);
11257 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
11258 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
11259 }
11260 }
11261 }
11262
11263 fn reset_recognition_arena(&mut self) {
11264 self.recognition_arena.reset();
11265 self.last_recognition_arena_root = NodeSeqId::EMPTY;
11266 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
11267 }
11268
11269 fn current_visible_index(&mut self) -> usize {
11272 let index = self.input.index();
11273 self.input.seek(index);
11274 self.input.index()
11275 }
11276
11277 fn child_expected_reaches_clean_eof(
11280 &mut self,
11281 children: &[RecognizeOutcome],
11282 expected: &ExpectedTokens,
11283 ) -> bool {
11284 let Some(index) = expected.index else {
11285 return false;
11286 };
11287 self.token_type_at(index) == TOKEN_EOF
11288 && children
11289 .iter()
11290 .any(|child| child.diagnostics.is_empty() && child.index == index)
11291 }
11292
11293 fn previous_token_index(&self, index: usize) -> Option<usize> {
11300 self.input.previous_visible_token_index(index)
11301 }
11302
11303 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
11308 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
11309 Some(index)
11310 } else {
11311 self.previous_token_index(index)
11312 }
11313 }
11314
11315 #[must_use]
11332 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
11333 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
11334 self.rule_stop_token_index(current_index, consumed_eof)
11335 }
11336
11337 #[must_use]
11346 pub fn after_action_stop_index_for_tree(
11347 &mut self,
11348 tree: ParseTree,
11349 current_index: usize,
11350 ) -> Option<usize> {
11351 if let Some(stop) = self
11352 .node(tree)
11353 .as_rule()
11354 .and_then(crate::tree::RuleNodeView::stop_id)
11355 {
11356 return Some(stop.index());
11357 }
11358 self.after_action_stop_index(current_index)
11359 }
11360
11361 #[must_use]
11371 pub fn after_action_start_index_for_tree(
11372 &self,
11373 tree: ParseTree,
11374 fallback_index: usize,
11375 ) -> usize {
11376 if let Some(start) = self
11377 .node(tree)
11378 .as_rule()
11379 .and_then(crate::tree::RuleNodeView::start_id)
11380 {
11381 return start.index();
11382 }
11383 fallback_index
11384 }
11385
11386 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
11391 self.rule_stop_token_index(index, consumed_eof)
11392 .and_then(|token_index| self.token_id_at(token_index))
11393 }
11394
11395 fn predicate_failure_recovery(
11402 &mut self,
11403 request: PredicateFailureRecovery<'_>,
11404 ) -> RecognizeOutcome {
11405 let PredicateFailureRecovery {
11406 rule_index,
11407 index,
11408 message,
11409 member_values,
11410 return_values,
11411 rule_alt_number,
11412 } = request;
11413 let rule_name = self
11414 .rule_names()
11415 .get(rule_index)
11416 .map_or_else(|| rule_index.to_string(), Clone::clone);
11417 let diagnostic = diagnostic_for_token(
11418 self.token_at(index).as_ref(),
11419 format!("rule {rule_name} {message}"),
11420 );
11421 let mut reversed_nodes = NodeSeqId::EMPTY;
11422 let mut next_index = index;
11423 loop {
11424 let symbol = self.token_type_at(next_index);
11425 if symbol == TOKEN_EOF {
11426 break;
11427 }
11428 let error = self.arena_token_node(next_index, true);
11429 self.arena_prepend(&mut reversed_nodes, error);
11430 let after = self.consume_index(next_index, symbol);
11431 if after == next_index {
11432 break;
11433 }
11434 next_index = after;
11435 }
11436 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
11437 let diagnostics = self
11438 .recognition_arena
11439 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
11440 RecognizeOutcome {
11441 index: next_index,
11442 consumed_eof: false,
11443 alt_number: rule_alt_number,
11444 member_values,
11445 return_values,
11446 diagnostics,
11447 decisions: Vec::new(),
11448 actions: Vec::new(),
11449 nodes,
11450 }
11451 }
11452
11453 fn parser_semantic_hook_result(
11456 &mut self,
11457 request: ParserSemanticHookRequest<'_>,
11458 ) -> Option<bool> {
11459 let ParserSemanticHookRequest {
11460 index,
11461 rule_index,
11462 pred_index,
11463 context,
11464 local_int_arg,
11465 member_values,
11466 } = request;
11467 let rule_name = self.rule_names().get(rule_index).cloned();
11468 self.input.seek(index);
11469 let input = &mut self.input;
11470 let semantic_hooks = &mut self.semantic_hooks;
11471 let mut ctx = ParserSemCtx {
11472 input,
11473 tree_storage: &self.tree,
11474 rule_index,
11475 coordinate_index: pred_index,
11476 rule_name,
11477 context,
11478 tree: None,
11479 local_int_arg,
11480 member_values,
11481 action: None,
11482 };
11483 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
11484 }
11485
11486 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
11491 if prior.is_empty() {
11492 return;
11493 }
11494 let mut merged = prior;
11495 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
11496 if !merged.contains(&coordinate) {
11497 merged.push(coordinate);
11498 }
11499 }
11500 self.unknown_predicate_hits = merged;
11501 }
11502
11503 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
11512 apply_unknown_predicate_policy(
11513 self.unknown_predicate_policy,
11514 rule_index,
11515 pred_index,
11516 &mut self.unknown_predicate_hits,
11517 )
11518 }
11519
11520 fn unknown_semantic_error(&self) -> Option<AntlrError> {
11523 use std::fmt::Write as _;
11524 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
11525 return None;
11526 }
11527 let mut message = String::new();
11528 for (rule_index, pred_index) in &self.unknown_predicate_hits {
11529 if !message.is_empty() {
11530 message.push_str("; ");
11531 }
11532 let _ = match self.rule_names().get(*rule_index) {
11533 Some(rule_name) => write!(
11534 message,
11535 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
11536 ),
11537 None => write!(
11538 message,
11539 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
11540 ),
11541 };
11542 }
11543 for (rule_index, source_state) in &self.unhandled_action_hits {
11544 if !message.is_empty() {
11545 message.push_str("; ");
11546 }
11547 let _ = match self.rule_names().get(*rule_index) {
11548 Some(rule_name) => write!(
11549 message,
11550 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
11551 ),
11552 None => write!(
11553 message,
11554 "unhandled semantic action: rule_index={rule_index} state={source_state}"
11555 ),
11556 };
11557 }
11558 Some(AntlrError::Unsupported(message))
11559 }
11560
11561 fn parser_semir_predicate_matches(
11569 &mut self,
11570 semantics: &ParserSemantics,
11571 predicate: &ParserSemanticPredicate,
11572 request: ParserSemanticHookRequest<'_>,
11573 ) -> bool {
11574 self.input.seek(request.index);
11575 let rule_name = self
11576 .data
11577 .rule_names()
11578 .get(request.rule_index)
11579 .map(String::as_str);
11580 let unknown_predicate_policy = self.unknown_predicate_policy;
11581 let mut ctx = ParserSemIrCtx {
11582 input: &mut self.input,
11583 tree_storage: &self.tree,
11584 semantic_hooks: &mut self.semantic_hooks,
11585 rule_index: request.rule_index,
11586 coordinate_index: request.pred_index,
11587 rule_name,
11588 context: request.context,
11589 local_int_arg: request.local_int_arg,
11590 member_values: request.member_values,
11591 invoked_predicates: &mut self.invoked_predicates,
11592 unknown_predicate_policy,
11593 unknown_predicate_hits: &mut self.unknown_predicate_hits,
11594 };
11595 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
11596 }
11597
11598 fn fast_parser_predicate_matches(
11599 &mut self,
11600 context: Option<FastPredicateContext<'_>>,
11601 transition: ParserTransition<'_>,
11602 index: usize,
11603 ) -> bool {
11604 let Some(context) = context else {
11605 return true;
11606 };
11607 let rule_index = transition.arg0() as usize;
11608 let pred_index = transition.arg1() as usize;
11609 let key = (index, rule_index, pred_index);
11610 if let Some(result) = self.fast_predicate_cache.get(&key) {
11611 return *result;
11612 }
11613 let result = self.parser_predicate_matches(PredicateEval {
11614 index,
11615 rule_index,
11616 pred_index,
11617 predicates: context.predicates,
11618 semantics: context.semantics,
11619 context: None,
11620 local_int_arg: None,
11621 member_values: context.member_values,
11622 });
11623 self.fast_predicate_cache.insert(key, result);
11624 result
11625 }
11626
11627 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
11628 let PredicateEval {
11629 index,
11630 rule_index,
11631 pred_index,
11632 predicates,
11633 semantics,
11634 context,
11635 local_int_arg,
11636 member_values,
11637 } = eval;
11638 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
11639 semantics
11640 .predicates
11641 .iter()
11642 .find(|predicate| {
11643 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11644 })
11645 .map(|predicate| (semantics, predicate))
11646 }) {
11647 return self.parser_semir_predicate_matches(
11648 semantics,
11649 predicate,
11650 ParserSemanticHookRequest {
11651 index,
11652 rule_index,
11653 pred_index,
11654 context,
11655 local_int_arg,
11656 member_values,
11657 },
11658 );
11659 }
11660 let Some((_, _, predicate)) = predicates
11661 .iter()
11662 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
11663 else {
11664 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
11665 index,
11666 rule_index,
11667 pred_index,
11668 context,
11669 local_int_arg,
11670 member_values,
11671 }) {
11672 return result;
11673 }
11674 return self.unknown_predicate_result(rule_index, pred_index);
11675 };
11676 self.input.seek(index);
11677 match predicate {
11678 ParserPredicate::True => true,
11679 ParserPredicate::False => false,
11680 ParserPredicate::FalseWithMessage { .. } => false,
11681 ParserPredicate::Invoke { value } => {
11682 let key = (rule_index, pred_index);
11683 if !self.invoked_predicates.contains(&key) {
11684 self.invoked_predicates.push(key);
11685 use std::io::Write as _;
11686 let mut stdout = std::io::stdout().lock();
11687 let _ = writeln!(stdout, "eval={value}");
11688 }
11689 *value
11690 }
11691 ParserPredicate::LookaheadTextEquals { offset, text } => self
11692 .input
11693 .lt(*offset)
11694 .is_some_and(|token| Token::text(&token) == Some(*text)),
11695 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
11696 self.la(*offset) != *token_type
11697 }
11698 ParserPredicate::TokenPairAdjacent => {
11699 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
11700 return false;
11701 };
11702 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
11703 return false;
11704 };
11705 first + 1 == second
11706 }
11707 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
11708 .and_then(|context| {
11709 context
11710 .child_rules(&self.tree, self.input.token_store(), *rule_index)
11711 .next()
11712 .map(crate::tree::RuleNodeView::text)
11713 })
11714 .is_none_or(|actual| actual != *text),
11715 ParserPredicate::LocalIntEquals { value } => {
11716 local_int_arg.is_none_or(|(_, actual)| actual == *value)
11717 }
11718 ParserPredicate::LocalIntLessOrEqual { value } => {
11719 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
11720 }
11721 ParserPredicate::MemberModuloEquals {
11722 member,
11723 modulus,
11724 value,
11725 equals,
11726 } => {
11727 if *modulus == 0 {
11728 return false;
11729 }
11730 let actual = member_values.scalar(*member).unwrap_or_default() % *modulus;
11731 (actual == *value) == *equals
11732 }
11733 ParserPredicate::MemberEquals {
11734 member,
11735 value,
11736 equals,
11737 } => {
11738 let actual = member_values.scalar(*member).unwrap_or_default();
11739 (actual == *value) == *equals
11740 }
11741 }
11742 }
11743
11744 fn parser_predicate_failure_message(
11746 &self,
11747 rule_index: usize,
11748 pred_index: usize,
11749 predicates: &[(usize, usize, ParserPredicate)],
11750 ) -> Option<&'static str> {
11751 predicates
11752 .iter()
11753 .find_map(|(rule, pred, predicate)| match predicate {
11754 ParserPredicate::FalseWithMessage { message }
11755 if *rule == rule_index && *pred == pred_index =>
11756 {
11757 Some(*message)
11758 }
11759 _ => None,
11760 })
11761 }
11762
11763 pub fn parser_semantic_ir_predicate_failure_message(
11766 &self,
11767 rule_index: usize,
11768 pred_index: usize,
11769 semantics: &ParserSemantics,
11770 ) -> Option<&'static str> {
11771 semantics
11772 .predicates
11773 .iter()
11774 .find(|predicate| {
11775 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11776 })
11777 .and_then(|predicate| predicate.failure_message)
11778 }
11779
11780 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
11789 if symbol == TOKEN_EOF {
11790 return index;
11791 }
11792 self.input.next_visible_after(index)
11793 }
11794
11795 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
11798 let text = display_input_text(&self.input.text(start_index, error_index));
11799 diagnostic_for_token(
11800 self.token_at(error_index).as_ref(),
11801 format!("no viable alternative at input '{text}'"),
11802 )
11803 }
11804
11805 fn recovery_failure_diagnostic(
11808 &self,
11809 index: usize,
11810 decision_start_index: Option<usize>,
11811 expected_symbols: &BTreeSet<i32>,
11812 ) -> ParserDiagnostic {
11813 if expected_symbols.len() > 1 {
11814 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11815 return self.no_viable_alternative(decision_start, index);
11816 }
11817 }
11818 diagnostic_for_token(
11819 self.token_at(index).as_ref(),
11820 format!(
11821 "mismatched input {} expecting {}",
11822 self.token_at(index)
11823 .as_ref()
11824 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11825 self.expected_symbols_display(expected_symbols)
11826 ),
11827 )
11828 }
11829
11830 fn eof_rule_recovery_diagnostic(
11833 &self,
11834 index: usize,
11835 expected_symbols: &BTreeSet<i32>,
11836 expected: &ExpectedTokens,
11837 ) -> ParserDiagnostic {
11838 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
11839 &expected.symbols
11840 } else {
11841 expected_symbols
11842 };
11843 diagnostic_for_token(
11844 self.token_at(index).as_ref(),
11845 format!(
11846 "mismatched input {} expecting {}",
11847 self.token_at(index)
11848 .as_ref()
11849 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11850 self.expected_symbols_display(symbols)
11851 ),
11852 )
11853 }
11854
11855 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
11861 let Some(stop) = stop else {
11862 return String::new();
11863 };
11864 let stop = if self
11865 .token_at(stop)
11866 .is_some_and(|token| token.token_type() == TOKEN_EOF)
11867 {
11868 let Some(previous) = self.previous_token_index(stop) else {
11869 return String::new();
11870 };
11871 previous
11872 } else {
11873 stop
11874 };
11875 self.input.text(start, stop)
11876 }
11877
11878 fn clear_prediction_diagnostics(&mut self) {
11881 self.prediction_diagnostics.clear();
11882 self.reported_prediction_diagnostics.clear();
11883 }
11884
11885 fn reset_per_parse_caches(&mut self) {
11909 self.rule_first_set_cache.clear();
11910 self.decision_lookahead_cache.clear();
11911 self.ll1_decision_cache.clear();
11912 self.fast_predicate_cache.clear();
11913 self.rule_stop_reach_cache.clear();
11914 self.clean_memo_mode = CleanMemoMode::Probe;
11915 self.clean_memo_probe_seen.clear();
11916 self.clean_memo_probe_samples = 0;
11917 self.clean_memo_probe_repeats = 0;
11918 self.clean_memo_sparse_samples = 0;
11919 self.recovery_symbols_intern.clear();
11920 self.state_expected_cache.clear();
11921 self.state_expected_token_cache.clear();
11922 }
11923
11924 fn record_prediction_diagnostics(
11927 &mut self,
11928 atn: &Atn,
11929 state: AtnState<'_>,
11930 start_index: usize,
11931 outcomes: &[RecognizeOutcome],
11932 ) {
11933 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
11934 return;
11935 }
11936 let Some(decision) = atn
11937 .decision_to_state()
11938 .iter()
11939 .position(|state_number| state_number == state.state_number())
11940 else {
11941 return;
11942 };
11943 let Some(rule_index) = state.rule_index() else {
11944 return;
11945 };
11946 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
11947 for outcome in outcomes
11948 .iter()
11949 .filter(|outcome| outcome.diagnostics.is_empty())
11950 {
11951 let Some(alt) = outcome.decisions.first() else {
11952 continue;
11953 };
11954 alts_by_end
11955 .entry(outcome.index)
11956 .or_default()
11957 .insert(alt + 1);
11958 }
11959 let Some((&end_index, ambig_alts)) = alts_by_end
11960 .iter()
11961 .filter(|(_, alts)| alts.len() > 1)
11962 .max_by_key(|(end, _)| *end)
11963 else {
11964 return;
11965 };
11966 let rule_name = self
11967 .rule_names()
11968 .get(rule_index)
11969 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
11970 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
11971 let input = display_input_text(&self.input.text(start_index, stop_index));
11972 let alts = ambig_alts
11973 .iter()
11974 .map(usize::to_string)
11975 .collect::<Vec<_>>()
11976 .join(", ");
11977 let key = (decision, start_index, format!("{alts}:{input}"));
11978 if !self.reported_prediction_diagnostics.insert(key) {
11979 return;
11980 }
11981 let start_diagnostic = diagnostic_for_token(
11982 self.token_at(start_index),
11983 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
11984 );
11985 let stop_diagnostic = diagnostic_for_token(
11986 self.token_at(stop_index),
11987 format!(
11988 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
11989 ),
11990 );
11991 self.prediction_diagnostics.push(start_diagnostic);
11992 self.prediction_diagnostics.push(stop_diagnostic);
11993 }
11994
11995 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
11997 expected_symbols_display(
11998 &state_expected_symbols(atn, state_number),
11999 self.vocabulary(),
12000 )
12001 }
12002
12003 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
12008 let state = usize::try_from(self.data().state()).unwrap_or(0);
12009 ExpectedTokenSet {
12010 symbols: state_expected_symbols(atn, state),
12011 }
12012 }
12013
12014 pub const fn set_bail_on_error(&mut self, bail: bool) {
12017 self.bail_on_error = bail;
12018 }
12019
12020 #[must_use]
12022 pub const fn bail_on_error(&self) -> bool {
12023 self.bail_on_error
12024 }
12025
12026 pub fn rule_invocation_stack(&self) -> Vec<String> {
12029 self.rule_context_stack
12030 .iter()
12031 .rev()
12032 .map(|frame| {
12033 self.data()
12034 .rule_names()
12035 .get(frame.rule_index)
12036 .cloned()
12037 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
12038 })
12039 .collect()
12040 }
12041
12042 pub fn active_invocation_states(&self) -> Vec<isize> {
12046 self.rule_context_stack
12047 .iter()
12048 .skip(1)
12049 .rev()
12050 .map(|frame| frame.invoking_state)
12051 .collect()
12052 }
12053
12054 pub fn token_display_at(&self, index: usize) -> Option<String> {
12056 self.token_at(index).map(|token| format!("{token}"))
12057 }
12058}
12059
12060impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
12061where
12062 S: TokenSource,
12063 H: SemanticHooks,
12064{
12065 fn parse_rule(
12066 &mut self,
12067 rule_index: usize,
12068 invoking_state: isize,
12069 precedence: i32,
12070 ) -> DirectAdaptiveParseResult<ParseTree> {
12071 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
12072 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
12073 )?;
12074 let stop_state = self
12075 .atn
12076 .rule_to_stop_state()
12077 .get(rule_index)
12078 .filter(|state| *state != usize::MAX)
12079 .ok_or(DirectAdaptiveParseControl::Fallback(
12080 DirectAdaptiveFallback::MissingAtn,
12081 ))?;
12082 let start_index = self.parser.current_visible_index();
12083 let mut context = ParserRuleContext::new(rule_index, invoking_state);
12084 if let Some(token) = self.parser.token_id_at(start_index) {
12085 self.parser.set_context_start(&mut context, token);
12086 }
12087 let mut state_number = start_state;
12088 let mut consumed_eof = false;
12089 while state_number != stop_state {
12090 self.step()?;
12091 let (transition, boundary) = self.next_transition(state_number, precedence)?;
12092 if boundary.is_some() {
12093 return Err(DirectAdaptiveParseControl::Fallback(
12094 DirectAdaptiveFallback::LeftRecursiveBoundary,
12095 ));
12096 }
12097 match transition.data() {
12098 Transition::Epsilon { target } => {
12099 state_number = target;
12100 }
12101 Transition::Precedence {
12102 target,
12103 precedence: transition_precedence,
12104 } => {
12105 if transition_precedence < precedence {
12106 return Err(DirectAdaptiveParseControl::Fallback(
12107 DirectAdaptiveFallback::Precedence,
12108 ));
12109 }
12110 state_number = target;
12111 }
12112 Transition::Rule {
12113 rule_index,
12114 follow_state,
12115 precedence: rule_precedence,
12116 ..
12117 } => {
12118 let child = self.parse_rule(
12119 rule_index,
12120 invoking_state_number(state_number),
12121 rule_precedence,
12122 )?;
12123 if self.parser.build_parse_trees {
12124 self.parser.tree.add_child(&mut context, child);
12125 }
12126 state_number = follow_state;
12127 }
12128 Transition::Atom { .. }
12129 | Transition::Range { .. }
12130 | Transition::Set { .. }
12131 | Transition::NotSet { .. }
12132 | Transition::Wildcard { .. } => {
12133 let (matched_eof, child) = self.consume_transition(transition)?;
12134 consumed_eof |= matched_eof;
12135 if let Some(child) = child {
12136 self.parser.tree.add_child(&mut context, child);
12137 }
12138 state_number = transition.target();
12139 }
12140 Transition::Predicate { .. } => {
12141 return Err(DirectAdaptiveParseControl::Fallback(
12142 DirectAdaptiveFallback::Predicate,
12143 ));
12144 }
12145 Transition::Action { .. } => {
12146 return Err(DirectAdaptiveParseControl::Fallback(
12147 DirectAdaptiveFallback::Action,
12148 ));
12149 }
12150 }
12151 }
12152
12153 let stop_index = self
12154 .parser
12155 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
12156 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
12157 self.parser.set_context_stop(&mut context, token);
12158 }
12159 Ok(self.parser.rule_node(context))
12160 }
12161
12162 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
12163 self.steps += 1;
12164 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
12165 return Err(DirectAdaptiveParseControl::Fallback(
12166 DirectAdaptiveFallback::StepLimit,
12167 ));
12168 }
12169 Ok(())
12170 }
12171
12172 fn next_transition(
12173 &mut self,
12174 state_number: usize,
12175 precedence: i32,
12176 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
12177 let state = self
12178 .atn
12179 .state(state_number)
12180 .ok_or(DirectAdaptiveParseControl::Fallback(
12181 DirectAdaptiveFallback::MissingAtn,
12182 ))?;
12183 if state.is_rule_stop() {
12184 return Err(DirectAdaptiveParseControl::Fallback(
12185 DirectAdaptiveFallback::RuleStop,
12186 ));
12187 }
12188 let transition_index =
12189 self.transition_index(state_number, state.transitions().len(), precedence)?;
12190 let transition = state.transitions().get(transition_index).ok_or(
12191 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
12192 )?;
12193 let boundary = match &transition.data() {
12194 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
12195 left_recursive_boundary(self.atn, state, *target)
12196 }
12197 _ => None,
12198 };
12199 Ok((transition, boundary))
12200 }
12201
12202 fn transition_index(
12203 &mut self,
12204 state_number: usize,
12205 transition_count: usize,
12206 precedence: i32,
12207 ) -> DirectAdaptiveParseResult<usize> {
12208 match transition_count {
12209 0 => Err(DirectAdaptiveParseControl::Fallback(
12210 DirectAdaptiveFallback::NoTransition,
12211 )),
12212 1 => Ok(0),
12213 _ => {
12214 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
12215 return Ok(alt);
12216 }
12217 let decision = self
12218 .decision_by_state
12219 .get(state_number)
12220 .and_then(|decision| *decision)
12221 .ok_or(DirectAdaptiveParseControl::Fallback(
12222 DirectAdaptiveFallback::UnknownDecision,
12223 ))?;
12224 let prediction = self
12225 .simulator
12226 .adaptive_predict_stream_info_with_precedence(
12227 decision,
12228 direct_precedence(precedence),
12229 &mut self.parser.input,
12230 )
12231 .map_err(|_| {
12232 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
12233 })?;
12234 if prediction.has_semantic_context {
12235 return Err(DirectAdaptiveParseControl::Fallback(
12236 DirectAdaptiveFallback::SemanticContext,
12237 ));
12238 }
12239 prediction
12240 .alt
12241 .checked_sub(1)
12242 .filter(|index| *index < transition_count)
12243 .ok_or(DirectAdaptiveParseControl::Fallback(
12244 DirectAdaptiveFallback::InvalidAlt,
12245 ))
12246 }
12247 }
12248 }
12249
12250 fn ll1_transition_index(
12251 &mut self,
12252 state_number: usize,
12253 transition_count: usize,
12254 ) -> DirectAdaptiveParseResult<Option<usize>> {
12255 let state = self
12256 .atn
12257 .state(state_number)
12258 .ok_or(DirectAdaptiveParseControl::Fallback(
12259 DirectAdaptiveFallback::MissingAtn,
12260 ))?;
12261 if state.precedence_rule_decision() {
12262 return Ok(None);
12263 }
12264 let Some(rule_stop) = state
12265 .rule_index()
12266 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
12267 else {
12268 return Ok(None);
12269 };
12270 let symbol = self.parser.input.la_token(1);
12271 let entry = self
12272 .parser
12273 .cached_decision_lookahead(self.atn, state, rule_stop);
12274 Ok(
12275 ll1_greedy_alt(&entry, symbol, state.non_greedy())
12276 .filter(|alt| *alt < transition_count),
12277 )
12278 }
12279
12280 fn consume_transition(
12281 &mut self,
12282 transition: ParserTransition<'_>,
12283 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
12284 let symbol = self.parser.input.la_token(1);
12285 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
12286 return Err(DirectAdaptiveParseControl::Fallback(
12287 DirectAdaptiveFallback::TokenMismatch,
12288 ));
12289 }
12290 let token = self
12291 .parser
12292 .input
12293 .lt_id(1)
12294 .ok_or(DirectAdaptiveParseControl::Fallback(
12295 DirectAdaptiveFallback::TokenMismatch,
12296 ))?;
12297 let matched_eof = symbol == TOKEN_EOF;
12298 if !matched_eof {
12299 self.parser.consume();
12300 }
12301 let child = self
12302 .parser
12303 .build_parse_trees
12304 .then(|| self.parser.terminal_tree(token));
12305 Ok((matched_eof, child))
12306 }
12307}
12308
12309fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
12312 if !state.precedence_rule_decision() {
12313 return None;
12314 }
12315 let target_state = atn.state(target)?;
12316 if target_state.kind() == AtnStateKind::LoopEnd {
12317 return None;
12318 }
12319 state.rule_index()
12320}
12321
12322fn next_alt_number(
12329 state: AtnState<'_>,
12330 transition_count: usize,
12331 transition_index: usize,
12332 current_alt_number: usize,
12333 track_alt_numbers: bool,
12334) -> usize {
12335 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
12336 return current_alt_number;
12337 }
12338 if matches!(
12339 state.kind(),
12340 AtnStateKind::Basic
12341 | AtnStateKind::BlockStart
12342 | AtnStateKind::PlusBlockStart
12343 | AtnStateKind::StarBlockStart
12344 | AtnStateKind::StarLoopEntry
12345 ) && !state.precedence_rule_decision()
12346 {
12347 return transition_index + 1;
12348 }
12349 current_alt_number
12350}
12351
12352fn invoking_state_number(state_number: usize) -> isize {
12355 isize::try_from(state_number).unwrap_or(isize::MAX)
12356}
12357
12358const fn packed_i32(value: u32) -> i32 {
12359 i32::from_le_bytes(value.to_le_bytes())
12360}
12361
12362fn direct_precedence(precedence: i32) -> usize {
12363 usize::try_from(precedence.max(0)).unwrap_or_default()
12364}
12365
12366fn token_input_display(token: &impl Token) -> String {
12367 format!("'{}'", token.text().unwrap_or("<EOF>"))
12368}
12369
12370fn display_input_text(text: &str) -> String {
12371 let mut out = String::new();
12372 for ch in text.chars() {
12373 match ch {
12374 '\n' => out.push_str("\\n"),
12375 '\r' => out.push_str("\\r"),
12376 '\t' => out.push_str("\\t"),
12377 other => out.push(other),
12378 }
12379 }
12380 out
12381}
12382
12383fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
12384 let (line, column, offending) = token.map_or((0, 0, None), |token| {
12385 (token.line(), token.column(), Some(token.token_id()))
12386 });
12387 ParserDiagnostic {
12388 line,
12389 column,
12390 message,
12391 offending,
12392 }
12393}
12394
12395fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
12396 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
12397}
12398
12399fn expected_symbols_display_iter(
12400 symbols: impl IntoIterator<Item = i32>,
12401 vocabulary: &Vocabulary,
12402) -> String {
12403 let items = symbols
12404 .into_iter()
12405 .map(|symbol| expected_symbol_display(symbol, vocabulary))
12406 .collect::<Vec<_>>();
12407 if let [single] = items.as_slice() {
12408 return single.clone();
12409 }
12410 format!("{{{}}}", items.join(", "))
12411}
12412
12413fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
12414 if symbol == TOKEN_EOF {
12415 return "<EOF>".to_owned();
12416 }
12417 vocabulary.display_name(symbol)
12418}
12419
12420fn caller_follow_token_info_for_stream<S: TokenSource>(
12421 input: &mut CommonTokenStream<S>,
12422 index: usize,
12423) -> (i32, bool, bool) {
12424 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
12427 input.fill();
12428 }
12429 let token_type = input.token_type_at_index(index);
12430 let visible_channel = input.channel();
12431 let token = input.get(index);
12432 let is_boundary = token
12433 .as_ref()
12434 .and_then(Token::text)
12435 .is_some_and(is_caller_follow_boundary_text);
12436 let is_boundary_gap = token.as_ref().is_some_and(|token| {
12437 token.channel() != visible_channel
12438 || is_caller_follow_boundary_gap_text(token.text_or_empty())
12439 });
12440 (token_type, is_boundary, is_boundary_gap)
12441}
12442
12443fn is_caller_follow_boundary_text(text: &str) -> bool {
12444 text.chars().any(|ch| ch == ';' || ch == '\n')
12445 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
12446}
12447
12448fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
12449 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
12450}
12451
12452fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
12456 let Some(rule_index) = state.rule_index() else {
12457 return false;
12458 };
12459 atn.rule_to_start_state()
12460 .get(rule_index)
12461 .and_then(|state_number| atn.state(state_number))
12462 .is_some_and(AtnState::left_recursive_rule)
12463}
12464
12465fn select_better_top_outcome(
12472 first: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
12473 second: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
12474 arena: &RecognitionArena,
12475) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
12476 match (first, second) {
12477 (Ok(first), Ok(second)) => {
12478 if arena.diagnostics(first.0.diagnostics).next().is_none() {
12479 Ok(first)
12480 } else {
12481 Ok(second)
12482 }
12483 }
12484 (Ok(first), Err(_)) => Ok(first),
12485 (Err(_), Ok(second)) => Ok(second),
12486 (Err(_), Err(second_expected)) => Err(second_expected),
12487 }
12488}
12489
12490fn select_best_fast_outcome(
12496 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
12497 prediction_mode: PredictionMode,
12498 caller_follow: Option<&TokenBitSet>,
12499 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
12500 arena: &RecognitionArena,
12501) -> Option<FastRecognizeOutcome> {
12502 let mut best = None;
12503 let mut best_caller_follow = None;
12504 for outcome in outcomes {
12505 if matches!(
12506 prediction_mode,
12507 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
12508 ) && outcome.diagnostics.is_empty()
12509 && let Some(follow) = caller_follow
12510 {
12511 let (token_type, is_boundary, _) = token_info_at(outcome.index);
12512 if is_boundary && follow.contains(token_type) {
12513 let replace =
12514 best_caller_follow
12515 .as_ref()
12516 .is_none_or(|existing: &FastRecognizeOutcome| {
12517 (outcome.index, outcome.consumed_eof)
12518 < (existing.index, existing.consumed_eof)
12519 });
12520 if replace {
12521 best_caller_follow = Some(outcome);
12522 }
12523 }
12524 }
12525 let Some(existing) = best else {
12526 best = Some(outcome);
12527 continue;
12528 };
12529 let outcome_position = (outcome.index, outcome.consumed_eof);
12530 let best_position = (existing.index, existing.consumed_eof);
12531 let better = match prediction_mode {
12532 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
12533 outcome_position,
12534 outcome.diagnostics,
12535 best_position,
12536 existing.diagnostics,
12537 arena,
12538 ),
12539 PredictionMode::Sll => outcome.index > existing.index,
12540 };
12541 best = Some(if better { outcome } else { existing });
12542 }
12543 let should_use_caller_follow =
12544 best_caller_follow
12545 .as_ref()
12546 .zip(best.as_ref())
12547 .is_some_and(|(candidate, selected)| {
12548 if !selected.diagnostics.is_empty() {
12549 return true;
12550 }
12551 candidate.index < selected.index
12552 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
12553 });
12554 if should_use_caller_follow {
12555 best_caller_follow
12556 } else {
12557 best
12558 }
12559}
12560
12561fn select_best_outcome(
12562 outcomes: impl Iterator<Item = RecognizeOutcome>,
12563 prediction_mode: PredictionMode,
12564 arena: &RecognitionArena,
12565) -> Option<RecognizeOutcome> {
12566 let outcomes = outcomes.collect::<Vec<_>>();
12567 let prefer_first_tie = outcomes
12568 .iter()
12569 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
12570 outcomes.into_iter().reduce(|best, outcome| {
12571 let outcome_position = (outcome.index, outcome.consumed_eof);
12572 let best_position = (best.index, best.consumed_eof);
12573 let better = match prediction_mode {
12574 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
12575 outcome_is_better(
12576 outcome_position,
12577 outcome.diagnostics,
12578 best_position,
12579 best.diagnostics,
12580 arena,
12581 ) || (outcome_position == best_position
12582 && arena.diagnostics_len(outcome.diagnostics)
12583 == arena.diagnostics_len(best.diagnostics)
12584 && arena.diagnostics_recovery_rank(outcome.diagnostics)
12585 == arena.diagnostics_recovery_rank(best.diagnostics)
12586 && (outcome.decisions < best.decisions
12587 || (!prefer_first_tie
12588 && outcome.decisions == best.decisions
12589 && outcome.actions > best.actions)))
12590 }
12591 PredictionMode::Sll => {
12592 outcome_position > best_position
12593 || (outcome_position == best_position
12594 && !prefer_first_tie
12595 && (outcome.decisions < best.decisions
12596 || (outcome.decisions == best.decisions
12597 && outcome_is_better(
12598 outcome_position,
12599 outcome.diagnostics,
12600 best_position,
12601 best.diagnostics,
12602 arena,
12603 ))))
12604 }
12605 };
12606 if better {
12607 return outcome;
12608 }
12609 best
12610 })
12611}
12612
12613fn transition_decision(
12620 atn: &Atn,
12621 state: AtnState<'_>,
12622 transition_count: usize,
12623 transition_index: usize,
12624 predicates: &[(usize, usize, ParserPredicate)],
12625) -> Option<usize> {
12626 if transition_count <= 1 || decision_reaches_unsupported_predicate(atn, state, predicates) {
12627 return None;
12628 }
12629 Some(transition_index)
12630}
12631
12632fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
12638 transition_count > 1
12639 && !matches!(
12640 state.kind(),
12641 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
12642 )
12643}
12644
12645fn record_no_viable_if_ambiguous(
12648 expected: &mut ExpectedTokens,
12649 decision_start_index: Option<usize>,
12650 index: usize,
12651) {
12652 if expected.index == Some(index) && expected.symbols.len() > 1 {
12653 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
12654 expected.record_no_viable(decision_start, index);
12655 }
12656 }
12657}
12658
12659const fn record_predicate_no_viable(
12662 expected: &mut ExpectedTokens,
12663 decision_start_index: Option<usize>,
12664 index: usize,
12665) {
12666 if let Some(decision_start) = decision_start_index {
12667 expected.record_no_viable(decision_start, index);
12668 }
12669}
12670
12671const fn no_viable_decision_start(
12673 decision_start_index: Option<usize>,
12674 index: usize,
12675) -> Option<usize> {
12676 match decision_start_index {
12677 Some(start) if index > start => Some(start),
12678 _ => None,
12679 }
12680}
12681
12682fn restore_expected(
12686 children: &[RecognizeOutcome],
12687 child_start_index: usize,
12688 expected: &mut ExpectedTokens,
12689 snapshot: ExpectedTokens,
12690 preserve_child_expected: bool,
12691) {
12692 if preserve_child_expected {
12693 return;
12694 }
12695 if children
12696 .iter()
12697 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
12698 {
12699 *expected = snapshot;
12700 }
12701}
12702
12703fn decision_reaches_unsupported_predicate(
12706 atn: &Atn,
12707 state: AtnState<'_>,
12708 predicates: &[(usize, usize, ParserPredicate)],
12709) -> bool {
12710 state.transitions().iter().any(|transition| {
12711 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
12712 })
12713}
12714
12715fn transition_reaches_unsupported_predicate(
12717 atn: &Atn,
12718 transition: ParserTransition<'_>,
12719 predicates: &[(usize, usize, ParserPredicate)],
12720 visited: &mut BTreeSet<usize>,
12721) -> bool {
12722 match &transition.data() {
12723 Transition::Predicate {
12724 rule_index,
12725 pred_index,
12726 ..
12727 } => !predicates
12728 .iter()
12729 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
12730 Transition::Epsilon { target }
12731 | Transition::Action { target, .. }
12732 | Transition::Rule { target, .. } => {
12733 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
12734 }
12735 Transition::Precedence { .. }
12736 | Transition::Atom { .. }
12737 | Transition::Range { .. }
12738 | Transition::Set { .. }
12739 | Transition::NotSet { .. }
12740 | Transition::Wildcard { .. } => false,
12741 }
12742}
12743
12744fn state_reaches_unsupported_predicate(
12746 atn: &Atn,
12747 state_number: usize,
12748 predicates: &[(usize, usize, ParserPredicate)],
12749 visited: &mut BTreeSet<usize>,
12750) -> bool {
12751 if !visited.insert(state_number) {
12752 return false;
12753 }
12754 let Some(state) = atn.state(state_number) else {
12755 return false;
12756 };
12757 state.transitions().iter().any(|transition| {
12758 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
12759 })
12760}
12761
12762fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
12764 if let Some(decision) = decision {
12765 outcome.decisions.insert(0, decision);
12766 }
12767}
12768
12769fn outcome_is_better(
12770 outcome_position: (usize, bool),
12771 outcome_diagnostics: DiagnosticSeqId,
12772 best_position: (usize, bool),
12773 best_diagnostics: DiagnosticSeqId,
12774 arena: &RecognitionArena,
12775) -> bool {
12776 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
12777 let best_len = arena.diagnostics_len(best_diagnostics);
12778 outcome_position > best_position
12779 || (outcome_position == best_position
12780 && (outcome_len < best_len
12781 || (outcome_len == best_len
12782 && arena.diagnostics_recovery_rank(outcome_diagnostics)
12783 < arena.diagnostics_recovery_rank(best_diagnostics))))
12784}
12785
12786fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
12787 if outcomes
12788 .iter()
12789 .any(|outcome| outcome.diagnostics.is_empty())
12790 {
12791 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12792 }
12793}
12794
12795fn discard_recovered_outcomes_if_clean_path_exists(
12796 outcomes: &mut Vec<RecognizeOutcome>,
12797 arena: &RecognitionArena,
12798) {
12799 if outcomes
12800 .iter()
12801 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
12802 {
12803 return;
12804 }
12805 if outcomes
12806 .iter()
12807 .any(|outcome| outcome.diagnostics.is_empty())
12808 {
12809 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12810 }
12811}
12812
12813fn outcome_has_rule_failure_diagnostic(
12816 outcome: &RecognizeOutcome,
12817 arena: &RecognitionArena,
12818) -> bool {
12819 arena
12820 .diagnostics(outcome.diagnostics)
12821 .any(|diagnostic| diagnostic.message.starts_with("rule "))
12822}
12823
12824fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
12838 if outcomes.len() < 2 {
12839 return;
12840 }
12841 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
12842 outcomes.retain(|outcome| {
12843 seen.insert((
12844 outcome.index,
12845 outcome.consumed_eof,
12846 arena.diagnostics_len(outcome.diagnostics),
12847 arena.diagnostics_recovery_rank(outcome.diagnostics),
12848 ))
12849 });
12850}
12851
12852const FAST_OUTCOME_INLINE_KEYS: usize = 8;
12853const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
12854const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
12855const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
12856
12857#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12858enum FastOutcomeDedupStrategy {
12859 Inline,
12860 Dense,
12861 Sparse,
12862}
12863
12864impl FastOutcomeDedupScratch {
12865 fn prepare_dense(&mut self, word_count: usize) {
12866 while let Some(word_index) = self.touched_dense_words.pop() {
12867 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
12868 }
12869 if self.dense_words.len() < word_count {
12870 self.dense_words.resize(word_count, 0);
12871 }
12872 }
12873}
12874
12875fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
12876 let first_index = outcomes.first()?.index;
12877 let (min_index, max_index) = outcomes[1..].iter().fold(
12878 (first_index, first_index),
12879 |(min_index, max_index), outcome| {
12880 (min_index.min(outcome.index), max_index.max(outcome.index))
12881 },
12882 );
12883 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
12884 let bit_count = index_span.checked_mul(2)?;
12885 let word_count =
12886 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
12887 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
12888 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
12889 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
12890 .then_some((min_index, word_count))
12891}
12892
12893#[cfg(feature = "perf-counters")]
12894fn record_clean_fast_outcome_dedup(
12895 strategy: FastOutcomeDedupStrategy,
12896 input_len: usize,
12897 output_len: usize,
12898 dense_words: usize,
12899) {
12900 let counter = match strategy {
12901 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
12902 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
12903 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
12904 };
12905 perf_counters::inc(
12906 &perf_counters::OUTCOME_DEDUPE_INPUTS,
12907 u64::try_from(input_len).unwrap_or(u64::MAX),
12908 );
12909 perf_counters::inc(
12910 &perf_counters::OUTCOME_DEDUPE_REMOVED,
12911 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
12912 );
12913 perf_counters::inc(counter, 1);
12914 perf_counters::inc(
12915 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
12916 u64::try_from(dense_words).unwrap_or(u64::MAX),
12917 );
12918}
12919
12920fn dedupe_clean_fast_outcomes(
12924 outcomes: &mut Vec<FastRecognizeOutcome>,
12925 scratch: &mut FastOutcomeDedupScratch,
12926) -> FastOutcomeDedupStrategy {
12927 #[cfg(feature = "perf-counters")]
12928 let input_len = outcomes.len();
12929 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
12930 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
12931 let mut inline_len = 0_usize;
12932 outcomes.retain(|outcome| {
12933 let key = (outcome.index, outcome.consumed_eof);
12934 if inline_keys[..inline_len].contains(&key) {
12935 return false;
12936 }
12937 inline_keys[inline_len] = key;
12938 inline_len += 1;
12939 true
12940 });
12941 #[cfg(feature = "perf-counters")]
12942 record_clean_fast_outcome_dedup(
12943 FastOutcomeDedupStrategy::Inline,
12944 input_len,
12945 outcomes.len(),
12946 0,
12947 );
12948 return FastOutcomeDedupStrategy::Inline;
12949 }
12950
12951 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
12952 scratch.prepare_dense(word_count);
12953 outcomes.retain(|outcome| {
12954 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
12955 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
12956 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
12957 let word = &mut scratch.dense_words[word_index];
12958 if *word & bit != 0 {
12959 return false;
12960 }
12961 if *word == 0 {
12962 scratch
12963 .touched_dense_words
12964 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
12965 }
12966 *word |= bit;
12967 true
12968 });
12969 #[cfg(feature = "perf-counters")]
12970 record_clean_fast_outcome_dedup(
12971 FastOutcomeDedupStrategy::Dense,
12972 input_len,
12973 outcomes.len(),
12974 word_count,
12975 );
12976 return FastOutcomeDedupStrategy::Dense;
12977 }
12978
12979 scratch.sparse_keys.clear();
12980 scratch.sparse_keys.reserve(outcomes.len());
12981 outcomes.retain(|outcome| {
12982 scratch
12983 .sparse_keys
12984 .insert((outcome.index, outcome.consumed_eof))
12985 });
12986 #[cfg(feature = "perf-counters")]
12987 record_clean_fast_outcome_dedup(
12988 FastOutcomeDedupStrategy::Sparse,
12989 input_len,
12990 outcomes.len(),
12991 0,
12992 );
12993 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
12994 scratch.sparse_keys = FxHashSet::default();
12995 }
12996 FastOutcomeDedupStrategy::Sparse
12997}
12998
12999fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
13002 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
13003 outcomes
13004 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
13005}
13006
13007fn compare_recognize_outcomes(
13008 left: &RecognizeOutcome,
13009 right: &RecognizeOutcome,
13010 arena: &RecognitionArena,
13011) -> Ordering {
13012 left.index
13013 .cmp(&right.index)
13014 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
13015 .then_with(|| left.alt_number.cmp(&right.alt_number))
13016 .then_with(|| left.member_values.cmp(&right.member_values))
13017 .then_with(|| left.return_values.cmp(&right.return_values))
13018 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
13019 .then_with(|| left.decisions.cmp(&right.decisions))
13020 .then_with(|| left.actions.cmp(&right.actions))
13021 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
13022}
13023
13024impl<S, H> Recognizer for BaseParser<S, H>
13025where
13026 S: TokenSource,
13027 H: SemanticHooks,
13028{
13029 fn data(&self) -> &RecognizerData {
13030 &self.data
13031 }
13032
13033 fn data_mut(&mut self) -> &mut RecognizerData {
13034 &mut self.data
13035 }
13036}
13037
13038impl<S, H> Parser for BaseParser<S, H>
13039where
13040 S: TokenSource,
13041 H: SemanticHooks,
13042{
13043 fn build_parse_trees(&self) -> bool {
13044 self.build_parse_trees
13045 }
13046
13047 fn set_build_parse_trees(&mut self, build: bool) {
13048 self.build_parse_trees = build;
13049 }
13050
13051 fn number_of_syntax_errors(&self) -> usize {
13052 Self::number_of_syntax_errors(self)
13053 }
13054
13055 fn report_diagnostic_errors(&self) -> bool {
13056 self.report_diagnostic_errors
13057 }
13058
13059 fn set_report_diagnostic_errors(&mut self, report: bool) {
13060 self.report_diagnostic_errors = report;
13061 }
13062
13063 fn prediction_mode(&self) -> PredictionMode {
13064 self.prediction_mode
13065 }
13066
13067 fn set_prediction_mode(&mut self, mode: PredictionMode) {
13068 self.prediction_mode = mode;
13069 }
13070
13071 fn max_rule_depth(&self) -> Option<usize> {
13072 self.max_rule_depth
13073 }
13074
13075 fn set_max_rule_depth(&mut self, depth: Option<usize>) {
13076 self.max_rule_depth = depth;
13077 }
13078
13079 fn add_parse_listener(&mut self, listener: Box<dyn ParseListener>) {
13080 self.parse_listeners.push(ParseListenerSlot(listener));
13081 }
13082
13083 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
13084 Self::remove_parse_listeners(self)
13085 }
13086}
13087
13088#[cfg(test)]
13089#[allow(clippy::disallowed_methods)] mod tests {
13091 use super::*;
13092 use crate::atn::parser::{
13093 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
13094 };
13095 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
13096 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
13097 use crate::token_stream::CommonTokenStream;
13098 use crate::tree::{NodeKind, ParseTreeStats};
13099 use crate::vocabulary::Vocabulary;
13100 use std::cell::RefCell;
13101 use std::mem::size_of;
13102 use std::rc::Rc;
13103 use std::sync::{Arc, Mutex};
13104
13105 #[test]
13106 fn fx_hasher_write_matches_typed_methods_for_full_words() {
13107 let value: u64 = 0x0102_0304_0506_0708;
13114 let mut typed = FxHasher::default();
13115 typed.write_u64(value);
13116 let mut bytewise = FxHasher::default();
13117 bytewise.write(&value.to_le_bytes());
13118 assert_eq!(typed.finish(), bytewise.finish());
13119 }
13120
13121 #[derive(Clone, Debug)]
13122 struct TestToken {
13123 spec: TokenSpec,
13124 id: TokenId,
13125 source_name: String,
13126 }
13127
13128 impl TestToken {
13129 fn new(token_type: i32) -> Self {
13130 Self {
13131 spec: TokenSpec::explicit(token_type, ""),
13132 id: TokenId::try_from(0).expect("zero token ID"),
13133 source_name: String::new(),
13134 }
13135 }
13136
13137 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
13138 Self {
13139 spec: TokenSpec::eof(index, index, line, column),
13140 id: TokenId::try_from(0).expect("zero token ID"),
13141 source_name: source_name.to_owned(),
13142 }
13143 }
13144
13145 fn with_text(mut self, text: impl Into<String>) -> Self {
13146 self.spec.text = Some(text.into());
13147 self
13148 }
13149
13150 const fn with_channel(mut self, channel: i32) -> Self {
13151 self.spec.channel = channel;
13152 self
13153 }
13154
13155 fn with_span(mut self, start: usize, stop: usize) -> Self {
13156 self.spec = self.spec.with_span(start, stop);
13157 self
13158 }
13159
13160 fn with_byte_span(mut self, start: usize, stop: usize) -> Self {
13161 self.spec = self.spec.with_byte_span(start, stop);
13162 self
13163 }
13164
13165 const fn with_position(mut self, line: usize, column: usize) -> Self {
13166 self.spec.line = line;
13167 self.spec.column = column;
13168 self
13169 }
13170
13171 fn set_token_index(&mut self, index: isize) {
13172 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
13173 }
13174 }
13175
13176 impl Token for TestToken {
13177 fn token_id(&self) -> TokenId {
13178 self.id
13179 }
13180
13181 fn token_type(&self) -> i32 {
13182 self.spec.token_type
13183 }
13184
13185 fn channel(&self) -> i32 {
13186 self.spec.channel
13187 }
13188
13189 fn start(&self) -> usize {
13190 self.spec.start
13191 }
13192
13193 fn stop(&self) -> usize {
13194 self.spec.stop
13195 }
13196
13197 fn line(&self) -> usize {
13198 self.spec.line
13199 }
13200
13201 fn column(&self) -> usize {
13202 self.spec.column
13203 }
13204
13205 fn text(&self) -> Option<&str> {
13206 self.spec.text.as_deref()
13207 }
13208
13209 fn source_name(&self) -> &str {
13210 &self.source_name
13211 }
13212
13213 fn start_byte(&self) -> Option<usize> {
13214 (self.spec.start_byte != usize::MAX).then_some(self.spec.start_byte)
13215 }
13216
13217 fn stop_byte(&self) -> Option<usize> {
13218 (self.spec.stop_byte != usize::MAX).then_some(self.spec.stop_byte)
13219 }
13220 }
13221
13222 #[derive(Debug)]
13223 struct Source {
13224 tokens: Vec<TestToken>,
13225 index: usize,
13226 }
13227
13228 impl TokenSource for Source {
13229 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
13230 let token = self
13231 .tokens
13232 .get(self.index)
13233 .cloned()
13234 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
13235 self.index += 1;
13236 sink.push(token.spec)
13237 }
13238
13239 fn line(&self) -> usize {
13240 1
13241 }
13242
13243 fn column(&self) -> usize {
13244 self.index
13245 }
13246
13247 fn source_name(&self) -> &'static str {
13248 "parser-test"
13249 }
13250 }
13251
13252 #[derive(Clone, Debug, Eq, PartialEq)]
13253 struct RecordedDiagnostic {
13254 grammar_file_name: String,
13255 offending_text: Option<String>,
13256 line: usize,
13257 column: usize,
13258 span: Option<std::ops::Range<usize>>,
13259 message: String,
13260 error: Option<AntlrError>,
13261 }
13262
13263 #[derive(Clone, Debug)]
13264 struct RecordingErrorListener {
13265 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
13266 }
13267
13268 impl<R> crate::ErrorListener<R> for RecordingErrorListener
13269 where
13270 R: Recognizer + ?Sized,
13271 {
13272 fn syntax_error(&mut self, recognizer: &R, event: &SyntaxErrorEvent<'_>) {
13273 self.diagnostics
13274 .lock()
13275 .expect("recorded diagnostics lock")
13276 .push(RecordedDiagnostic {
13277 grammar_file_name: recognizer.grammar_file_name().to_owned(),
13278 offending_text: event
13279 .offending
13280 .and_then(|token| token.text().map(str::to_owned)),
13281 line: event.line,
13282 column: event.column,
13283 span: event.span.clone(),
13284 message: event.message.to_owned(),
13285 error: event.error.cloned(),
13286 });
13287 }
13288 }
13289
13290 #[derive(Debug)]
13291 struct ReportingSource {
13292 source: Source,
13293 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
13294 }
13295
13296 impl TokenSource for ReportingSource {
13297 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
13298 self.source.next_token(sink)
13299 }
13300
13301 fn line(&self) -> usize {
13302 self.source.line()
13303 }
13304
13305 fn column(&self) -> usize {
13306 self.source.column()
13307 }
13308
13309 fn source_name(&self) -> &str {
13310 self.source.source_name()
13311 }
13312
13313 fn report_error(&self, error: &TokenSourceError) -> bool {
13314 self.diagnostics.borrow_mut().push(error.clone());
13315 true
13316 }
13317 }
13318
13319 fn mini_parser_data() -> RecognizerData {
13320 RecognizerData::new(
13321 "Mini.g4",
13322 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
13323 )
13324 .with_rule_names(["s"])
13325 }
13326
13327 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
13328 let data = mini_parser_data();
13329 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
13330 }
13331
13332 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
13333 where
13334 H: SemanticHooks,
13335 {
13336 BaseParser::with_semantic_hooks(
13337 CommonTokenStream::new(Source { tokens, index: 0 }),
13338 mini_parser_data(),
13339 hooks,
13340 )
13341 }
13342
13343 #[test]
13344 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
13345 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
13346 parser.remove_error_listeners();
13347 let diagnostics = Arc::new(Mutex::new(Vec::new()));
13348 parser.add_error_listener(RecordingErrorListener {
13349 diagnostics: Arc::clone(&diagnostics),
13350 });
13351 let parser_diagnostics = [ParserDiagnostic {
13352 line: 1,
13353 column: 2,
13354 message: "missing 'x' at 'y'".to_owned(),
13355 offending: None,
13356 }];
13357 let token_errors = [
13358 TokenSourceError::new(1, 1, "token recognition error at: '@'").with_span(1..2),
13359 TokenSourceError::new(1, 3, "token recognition error at: '#'").with_span(3..4),
13360 ];
13361
13362 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
13363
13364 insta::assert_debug_snapshot!(
13367 "parser_dispatches_recovery_diagnostics_through_registered_listeners",
13368 *diagnostics.lock().expect("recorded diagnostics lock")
13369 );
13370
13371 parser.remove_error_listeners();
13372 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
13373 assert_eq!(
13374 diagnostics.lock().expect("recorded diagnostics lock").len(),
13375 3
13376 );
13377 }
13378
13379 #[test]
13380 fn recovery_diagnostics_expose_the_offending_token_to_listeners() {
13381 let mut parser = mini_parser(vec![
13382 TestToken::new(7)
13383 .with_text("oops")
13384 .with_span(0, 3)
13385 .with_byte_span(0, 4)
13386 .with_position(1, 2),
13387 TestToken::eof("parser-test", 4, 1, 6),
13388 ]);
13389 parser.remove_error_listeners();
13390 let diagnostics = Arc::new(Mutex::new(Vec::new()));
13391 parser.add_error_listener(RecordingErrorListener {
13392 diagnostics: Arc::clone(&diagnostics),
13393 });
13394 let offending = parser.input.lt_id(1);
13395 assert!(offending.is_some(), "current token should be buffered");
13396 let parser_diagnostics = [ParserDiagnostic {
13397 line: 1,
13398 column: 2,
13399 message: "extraneous input 'oops'".to_owned(),
13400 offending,
13401 }];
13402
13403 parser.dispatch_generated_diagnostics(&parser_diagnostics, &[]);
13404
13405 let recorded = diagnostics
13409 .lock()
13410 .expect("recorded diagnostics lock")
13411 .clone();
13412 insta::assert_debug_snapshot!(
13413 "recovery_diagnostics_expose_the_offending_token_to_listeners",
13414 recorded
13415 );
13416 }
13417
13418 #[test]
13419 fn recovery_diagnostics_preserve_unknown_custom_token_span() {
13420 let mut parser = mini_parser(vec![
13421 TestToken::new(7)
13422 .with_text("oops")
13423 .with_span(0, 3)
13424 .with_position(1, 2),
13425 TestToken::eof("parser-test", 4, 1, 6),
13426 ]);
13427 parser.remove_error_listeners();
13428 let diagnostics = Arc::new(Mutex::new(Vec::new()));
13429 parser.add_error_listener(RecordingErrorListener {
13430 diagnostics: Arc::clone(&diagnostics),
13431 });
13432 let offending = parser.input.lt_id(1);
13433 assert!(offending.is_some(), "current token should be buffered");
13434
13435 parser.dispatch_parser_diagnostic(&ParserDiagnostic {
13436 line: 1,
13437 column: 2,
13438 message: "extraneous input 'oops'".to_owned(),
13439 offending,
13440 });
13441
13442 let span = {
13443 let diagnostics = diagnostics.lock().expect("recorded diagnostics lock");
13444 assert_eq!(diagnostics.len(), 1);
13445 diagnostics[0].span.clone()
13446 };
13447 assert_eq!(span, None);
13448 }
13449
13450 #[test]
13451 fn parser_leaves_token_errors_to_source_owned_listeners() {
13452 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
13453 let source = ReportingSource {
13454 source: Source {
13455 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
13456 index: 0,
13457 },
13458 diagnostics: Rc::clone(&source_diagnostics),
13459 };
13460 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
13461 parser.remove_error_listeners();
13462 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
13463 parser.add_error_listener(RecordingErrorListener {
13464 diagnostics: Arc::clone(&parser_diagnostics),
13465 });
13466 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
13467
13468 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
13469
13470 assert_eq!(*source_diagnostics.borrow(), [source_error]);
13471 assert!(
13472 parser_diagnostics
13473 .lock()
13474 .expect("recorded diagnostics lock")
13475 .is_empty()
13476 );
13477 }
13478
13479 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
13480 builder.finish().expect("valid packed parser ATN")
13481 }
13482
13483 fn nested_rule_chain_atn(depth: usize) -> Atn {
13484 nested_rule_graph_atn(depth, false, false)
13485 }
13486
13487 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
13488 assert!(depth > 0);
13489 let mut atn = ParserAtnBuilder::new(2);
13490 let mut starts = Vec::with_capacity(depth);
13491 let mut stops = Vec::with_capacity(depth);
13492 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
13493 for rule_index in 0..depth {
13494 starts.push(
13495 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
13496 .expect("rule start")
13497 .index(),
13498 );
13499 }
13500 for rule_index in 0..depth {
13501 stops.push(
13502 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
13503 .expect("rule stop")
13504 .index(),
13505 );
13506 }
13507 if consuming_follows {
13508 for rule_index in 0..depth - 1 {
13509 follows.push(
13510 atn.add_state(AtnStateKind::Basic, Some(rule_index))
13511 .expect("rule follow")
13512 .index(),
13513 );
13514 }
13515 }
13516 atn.set_rule_to_start_state(starts.clone())
13517 .expect("rule start states");
13518 atn.set_rule_to_stop_state(stops.clone())
13519 .expect("rule stop states");
13520 for rule_index in 0..depth - 1 {
13521 let follow_state = if consuming_follows {
13522 follows[rule_index]
13523 } else {
13524 stops[rule_index]
13525 };
13526 atn.add_transition(
13527 starts[rule_index],
13528 ParserTransitionSpec::Rule {
13529 target: starts[rule_index + 1],
13530 rule_index: rule_index + 1,
13531 follow_state,
13532 precedence: 0,
13533 },
13534 )
13535 .expect("nested rule transition");
13536 if branching {
13537 atn.add_transition(
13538 starts[rule_index],
13539 ParserTransitionSpec::Atom {
13540 target: stops[rule_index],
13541 label: 2,
13542 },
13543 )
13544 .expect("dead branch transition");
13545 }
13546 if consuming_follows {
13547 atn.add_transition(
13548 follow_state,
13549 ParserTransitionSpec::Atom {
13550 target: stops[rule_index],
13551 label: 1,
13552 },
13553 )
13554 .expect("consuming follow transition");
13555 }
13556 }
13557 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
13558 atn.add_transition(
13559 starts[depth - 1],
13560 ParserTransitionSpec::Set {
13561 target: stops[depth - 1],
13562 set: token_set,
13563 },
13564 )
13565 .expect("terminal set transition");
13566 if branching {
13567 atn.add_transition(
13568 starts[depth - 1],
13569 ParserTransitionSpec::Atom {
13570 target: stops[depth - 1],
13571 label: 2,
13572 },
13573 )
13574 .expect("dead leaf branch transition");
13575 }
13576 finish_atn(atn)
13577 }
13578
13579 fn ordinary_star_loop_atn() -> Atn {
13580 let mut atn = ParserAtnBuilder::new(2);
13581 for (state_number, kind, rule_index) in [
13582 (0, AtnStateKind::RuleStart, 0),
13583 (1, AtnStateKind::StarLoopEntry, 0),
13584 (2, AtnStateKind::Basic, 0),
13585 (3, AtnStateKind::StarLoopBack, 0),
13586 (4, AtnStateKind::LoopEnd, 0),
13587 (5, AtnStateKind::Basic, 0),
13588 (6, AtnStateKind::RuleStop, 0),
13589 (7, AtnStateKind::RuleStart, 1),
13590 (8, AtnStateKind::Basic, 1),
13591 (9, AtnStateKind::RuleStop, 1),
13592 ] {
13593 assert_eq!(
13594 atn.add_state(kind, Some(rule_index))
13595 .expect("state")
13596 .index(),
13597 state_number
13598 );
13599 }
13600 atn.set_rule_to_start_state(vec![0, 7])
13601 .expect("rule start states");
13602 atn.set_rule_to_stop_state(vec![6, 9])
13603 .expect("rule stop states");
13604 atn.add_decision_state(1).expect("decision state");
13605 atn.set_loop_back_state(4, 3).expect("loop back state");
13606 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13607 .expect("transition");
13608 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13609 .expect("transition");
13610 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
13611 .expect("transition");
13612 atn.add_transition(
13613 2,
13614 ParserTransitionSpec::Rule {
13615 target: 7,
13616 rule_index: 1,
13617 follow_state: 3,
13618 precedence: 0,
13619 },
13620 )
13621 .expect("transition");
13622 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
13623 .expect("transition");
13624 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13625 .expect("transition");
13626 atn.add_transition(
13627 5,
13628 ParserTransitionSpec::Atom {
13629 target: 6,
13630 label: TOKEN_EOF,
13631 },
13632 )
13633 .expect("transition");
13634 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
13635 .expect("transition");
13636 atn.add_transition(
13637 8,
13638 ParserTransitionSpec::Atom {
13639 target: 9,
13640 label: 1,
13641 },
13642 )
13643 .expect("transition");
13644 finish_atn(atn)
13645 }
13646
13647 fn ambiguous_ordinary_star_loop_atn() -> Atn {
13649 let mut atn = ParserAtnBuilder::new(1);
13650 for (state_number, kind) in [
13651 (0, AtnStateKind::RuleStart),
13652 (1, AtnStateKind::StarLoopEntry),
13653 (2, AtnStateKind::StarBlockStart),
13654 (3, AtnStateKind::Basic),
13655 (4, AtnStateKind::BlockEnd),
13656 (5, AtnStateKind::StarLoopBack),
13657 (6, AtnStateKind::LoopEnd),
13658 (7, AtnStateKind::Basic),
13659 (8, AtnStateKind::RuleStop),
13660 ] {
13661 assert_eq!(
13662 atn.add_state(kind, Some(0)).expect("state").index(),
13663 state_number
13664 );
13665 }
13666 atn.set_rule_to_start_state(vec![0])
13667 .expect("rule start states");
13668 atn.set_rule_to_stop_state(vec![8])
13669 .expect("rule stop states");
13670 atn.set_end_state(2, 4).expect("block end state");
13671 atn.set_loop_back_state(6, 5).expect("loop back state");
13672 atn.add_decision_state(1).expect("decision state");
13673 atn.add_decision_state(2).expect("decision state");
13674 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13675 .expect("transition");
13676 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13677 .expect("transition");
13678 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
13679 .expect("transition");
13680 atn.add_transition(
13681 2,
13682 ParserTransitionSpec::Atom {
13683 target: 4,
13684 label: 1,
13685 },
13686 )
13687 .expect("transition");
13688 atn.add_transition(
13689 2,
13690 ParserTransitionSpec::Atom {
13691 target: 3,
13692 label: 1,
13693 },
13694 )
13695 .expect("transition");
13696 atn.add_transition(
13697 3,
13698 ParserTransitionSpec::Atom {
13699 target: 4,
13700 label: 1,
13701 },
13702 )
13703 .expect("transition");
13704 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13705 .expect("transition");
13706 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
13707 .expect("transition");
13708 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13709 .expect("transition");
13710 atn.add_transition(
13711 7,
13712 ParserTransitionSpec::Atom {
13713 target: 8,
13714 label: TOKEN_EOF,
13715 },
13716 )
13717 .expect("transition");
13718 finish_atn(atn)
13719 }
13720
13721 fn ordinary_plus_loop_atn() -> Atn {
13722 let mut atn = ParserAtnBuilder::new(2);
13723 for (state_number, kind, rule_index) in [
13724 (0, AtnStateKind::RuleStart, 0),
13725 (1, AtnStateKind::Basic, 0),
13726 (2, AtnStateKind::PlusLoopBack, 0),
13727 (3, AtnStateKind::LoopEnd, 0),
13728 (4, AtnStateKind::Basic, 0),
13729 (5, AtnStateKind::RuleStop, 0),
13730 (6, AtnStateKind::RuleStart, 1),
13731 (7, AtnStateKind::Basic, 1),
13732 (8, AtnStateKind::RuleStop, 1),
13733 ] {
13734 assert_eq!(
13735 atn.add_state(kind, Some(rule_index))
13736 .expect("state")
13737 .index(),
13738 state_number
13739 );
13740 }
13741 atn.set_rule_to_start_state(vec![0, 6])
13742 .expect("rule start states");
13743 atn.set_rule_to_stop_state(vec![5, 8])
13744 .expect("rule stop states");
13745 atn.add_decision_state(2).expect("decision state");
13746 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13747 .expect("transition");
13748 atn.add_transition(
13749 1,
13750 ParserTransitionSpec::Rule {
13751 target: 6,
13752 rule_index: 1,
13753 follow_state: 2,
13754 precedence: 0,
13755 },
13756 )
13757 .expect("transition");
13758 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
13759 .expect("transition");
13760 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13761 .expect("transition");
13762 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13763 .expect("transition");
13764 atn.add_transition(
13765 4,
13766 ParserTransitionSpec::Atom {
13767 target: 5,
13768 label: TOKEN_EOF,
13769 },
13770 )
13771 .expect("transition");
13772 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13773 .expect("transition");
13774 atn.add_transition(
13775 7,
13776 ParserTransitionSpec::Atom {
13777 target: 8,
13778 label: 1,
13779 },
13780 )
13781 .expect("transition");
13782 finish_atn(atn)
13783 }
13784
13785 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
13786 let mut tokens = (0..count)
13787 .map(|_| TestToken::new(1).with_text("x"))
13788 .collect::<Vec<_>>();
13789 tokens.push(TestToken::eof("parser-test", count, 1, count));
13790 tokens
13791 }
13792
13793 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
13794 let mut atn = ParserAtnBuilder::new(2);
13795 assert_eq!(
13796 atn.add_state(AtnStateKind::RuleStart, Some(0))
13797 .expect("state")
13798 .index(),
13799 0
13800 );
13801 assert_eq!(
13802 atn.add_state(AtnStateKind::Basic, Some(0))
13803 .expect("state")
13804 .index(),
13805 1
13806 );
13807 assert_eq!(
13808 atn.add_state(AtnStateKind::Basic, Some(0))
13809 .expect("state")
13810 .index(),
13811 2
13812 );
13813 assert_eq!(
13814 atn.add_state(AtnStateKind::RuleStart, Some(1))
13815 .expect("state")
13816 .index(),
13817 3
13818 );
13819 atn.set_left_recursive_rule(3)
13820 .expect("left-recursive rule start");
13821 assert_eq!(
13822 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
13823 .expect("state")
13824 .index(),
13825 4
13826 );
13827 atn.set_precedence_rule_decision(4)
13828 .expect("precedence decision");
13829 assert_eq!(
13830 atn.add_state(AtnStateKind::Basic, Some(1))
13831 .expect("state")
13832 .index(),
13833 5
13834 );
13835 assert_eq!(
13836 atn.add_state(AtnStateKind::Basic, Some(1))
13837 .expect("state")
13838 .index(),
13839 6
13840 );
13841 assert_eq!(
13842 atn.add_state(AtnStateKind::LoopEnd, Some(1))
13843 .expect("state")
13844 .index(),
13845 7
13846 );
13847 assert_eq!(
13848 atn.add_state(AtnStateKind::RuleStop, Some(1))
13849 .expect("state")
13850 .index(),
13851 8
13852 );
13853 assert_eq!(
13854 atn.add_state(AtnStateKind::RuleStop, Some(0))
13855 .expect("state")
13856 .index(),
13857 9
13858 );
13859 atn.set_rule_to_start_state(vec![0, 3])
13860 .expect("rule start states");
13861 atn.set_rule_to_stop_state(vec![9, 8])
13862 .expect("rule stop states");
13863 atn.add_transition(
13864 1,
13865 ParserTransitionSpec::Rule {
13866 target: 3,
13867 rule_index: 1,
13868 follow_state: 2,
13869 precedence: 0,
13870 },
13871 )
13872 .expect("transition");
13873 atn.add_transition(
13874 2,
13875 ParserTransitionSpec::Atom {
13876 target: 9,
13877 label: caller_symbol,
13878 },
13879 )
13880 .expect("transition");
13881 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13882 .expect("transition");
13883 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
13884 .expect("transition");
13885 atn.add_transition(
13886 5,
13887 ParserTransitionSpec::Precedence {
13888 target: 6,
13889 precedence: 1,
13890 },
13891 )
13892 .expect("transition");
13893 atn.add_transition(
13894 6,
13895 ParserTransitionSpec::Atom {
13896 target: 4,
13897 label: 1,
13898 },
13899 )
13900 .expect("transition");
13901 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
13902 .expect("transition");
13903 finish_atn(atn)
13904 }
13905
13906 fn labeled_left_recursive_operator_atn() -> Atn {
13907 let mut atn = ParserAtnBuilder::new(4);
13908 for (state, kind) in [
13909 (0, AtnStateKind::RuleStart),
13910 (1, AtnStateKind::BlockStart),
13911 (2, AtnStateKind::StarLoopEntry),
13912 (3, AtnStateKind::StarBlockStart),
13913 (4, AtnStateKind::Basic),
13914 (5, AtnStateKind::Basic),
13915 (6, AtnStateKind::Basic),
13916 (7, AtnStateKind::StarLoopBack),
13917 (8, AtnStateKind::LoopEnd),
13918 (9, AtnStateKind::RuleStop),
13919 ] {
13920 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13921 }
13922 atn.set_left_recursive_rule(0)
13923 .expect("left-recursive rule start");
13924 atn.set_precedence_rule_decision(2)
13925 .expect("precedence decision");
13926 atn.set_loop_back_state(8, 7).expect("loop-back state");
13927 atn.set_rule_to_start_state(vec![0])
13928 .expect("rule start states");
13929 atn.set_rule_to_stop_state(vec![9])
13930 .expect("rule stop states");
13931 for state in [1, 2, 3] {
13932 atn.add_decision_state(state).expect("decision state");
13933 }
13934 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
13935 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
13936 .expect("epsilon transition");
13937 }
13938 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3), (6, 7, 1)] {
13939 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
13940 .expect("token transition");
13941 }
13942 for (target, precedence) in [(4, 2), (5, 1)] {
13943 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
13944 .expect("operator precedence");
13945 }
13946 finish_atn(atn)
13947 }
13948
13949 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
13950 let mut parser = mini_parser(vec![
13951 TestToken::new(symbol).with_text("lookahead"),
13952 TestToken::eof("parser-test", 1, 1, 1),
13953 ]);
13954 parser.rule_context_stack = vec![
13955 RuleContextFrame {
13956 rule_index: 0,
13957 invoking_state: -1,
13958 },
13959 RuleContextFrame {
13960 rule_index: 1,
13961 invoking_state: 1,
13962 },
13963 ];
13964 parser
13965 }
13966
13967 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
13968 let mut atn = ParserAtnBuilder::new(1);
13972 for (state, kind, rule) in [
13973 (0, AtnStateKind::RuleStart, 0),
13974 (1, AtnStateKind::StarLoopEntry, 0),
13975 (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),
13982 (9, AtnStateKind::RuleStop, 0),
13983 ] {
13984 assert_eq!(
13985 atn.add_state(kind, Some(rule)).expect("state").index(),
13986 state
13987 );
13988 if state == 0 {
13989 atn.set_left_recursive_rule(state)
13990 .expect("left-recursive rule start");
13991 } else if state == 1 {
13992 atn.set_precedence_rule_decision(state)
13993 .expect("precedence decision");
13994 }
13995 }
13996 atn.set_rule_to_start_state(vec![0])
13997 .expect("rule start states");
13998 atn.set_rule_to_stop_state(vec![9])
13999 .expect("rule stop states");
14000 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14001 .expect("ops");
14002 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
14003 .expect("exit");
14004 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
14005 .expect("to shift");
14006 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
14007 .expect("to rel");
14008 atn.add_transition(
14009 3,
14010 ParserTransitionSpec::Precedence {
14011 target: 4,
14012 precedence: 2,
14013 },
14014 )
14015 .expect("shift prec");
14016 atn.add_transition(
14017 4,
14018 ParserTransitionSpec::Atom {
14019 target: 5,
14020 label: 1,
14021 },
14022 )
14023 .expect("shift first >");
14024 atn.add_transition(
14025 5,
14026 ParserTransitionSpec::Atom {
14027 target: 1,
14028 label: 1,
14029 },
14030 )
14031 .expect("shift second >");
14032 atn.add_transition(
14033 6,
14034 ParserTransitionSpec::Precedence {
14035 target: 7,
14036 precedence: 1,
14037 },
14038 )
14039 .expect("rel prec");
14040 atn.add_transition(
14041 7,
14042 ParserTransitionSpec::Atom {
14043 target: 1,
14044 label: 1,
14045 },
14046 )
14047 .expect("rel >");
14048 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14049 .expect("loop end");
14050 finish_atn(atn)
14051 }
14052
14053 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
14054 let mut atn = ParserAtnBuilder::new(2);
14055 for (state, kind, rule) in [
14056 (0, AtnStateKind::RuleStart, 0),
14057 (1, AtnStateKind::StarLoopEntry, 0),
14058 (2, AtnStateKind::Basic, 0),
14059 (3, AtnStateKind::Basic, 0),
14060 (4, AtnStateKind::Basic, 0),
14061 (5, AtnStateKind::Basic, 0),
14062 (6, AtnStateKind::Basic, 0),
14063 (7, AtnStateKind::Basic, 0),
14064 (8, AtnStateKind::LoopEnd, 0),
14065 (9, AtnStateKind::RuleStop, 0),
14066 (10, AtnStateKind::RuleStart, 1),
14067 (11, AtnStateKind::Basic, 1),
14068 (12, AtnStateKind::RuleStop, 1),
14069 ] {
14070 assert_eq!(
14071 atn.add_state(kind, Some(rule)).expect("state").index(),
14072 state
14073 );
14074 if state == 0 {
14075 atn.set_left_recursive_rule(state)
14076 .expect("left-recursive rule start");
14077 } else if state == 1 {
14078 atn.set_precedence_rule_decision(state)
14079 .expect("precedence decision");
14080 }
14081 }
14082 atn.set_rule_to_start_state(vec![0, 10])
14083 .expect("rule start states");
14084 atn.set_rule_to_stop_state(vec![9, 12])
14085 .expect("rule stop states");
14086 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14087 .expect("ops");
14088 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
14089 .expect("exit");
14090 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
14091 .expect("to shift");
14092 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
14093 .expect("to relational");
14094 atn.add_transition(
14095 3,
14096 ParserTransitionSpec::Precedence {
14097 target: 4,
14098 precedence: 2,
14099 },
14100 )
14101 .expect("shift precedence");
14102 atn.add_transition(
14103 4,
14104 ParserTransitionSpec::Rule {
14105 target: 10,
14106 rule_index: 1,
14107 follow_state: 5,
14108 precedence: 0,
14109 },
14110 )
14111 .expect("first shift token helper");
14112 atn.add_transition(
14113 5,
14114 ParserTransitionSpec::Atom {
14115 target: 1,
14116 label: 1,
14117 },
14118 )
14119 .expect("second shift token");
14120 atn.add_transition(
14121 6,
14122 ParserTransitionSpec::Precedence {
14123 target: 7,
14124 precedence: 1,
14125 },
14126 )
14127 .expect("relational precedence");
14128 atn.add_transition(
14129 7,
14130 ParserTransitionSpec::Atom {
14131 target: 1,
14132 label: 1,
14133 },
14134 )
14135 .expect("relational token");
14136 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14137 .expect("loop end");
14138 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
14139 .expect("helper entry");
14140 atn.add_transition(
14141 11,
14142 ParserTransitionSpec::Atom {
14143 target: 12,
14144 label: 1,
14145 },
14146 )
14147 .expect("first shift token");
14148 finish_atn(atn)
14149 }
14150
14151 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
14152 let mut atn = ParserAtnBuilder::new(1);
14153 for (state, kind) in [
14154 (0, AtnStateKind::RuleStart),
14155 (1, AtnStateKind::StarLoopEntry),
14156 (2, AtnStateKind::Basic),
14157 (3, AtnStateKind::Basic),
14158 (4, AtnStateKind::Basic),
14159 (5, AtnStateKind::Basic),
14160 (6, AtnStateKind::Basic),
14161 (7, AtnStateKind::Basic),
14162 (8, AtnStateKind::Basic),
14163 (9, AtnStateKind::LoopEnd),
14164 (10, AtnStateKind::RuleStop),
14165 ] {
14166 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
14167 if state == 0 {
14168 atn.set_left_recursive_rule(state)
14169 .expect("left-recursive rule start");
14170 } else if state == 1 {
14171 atn.set_precedence_rule_decision(state)
14172 .expect("precedence decision");
14173 }
14174 }
14175 atn.set_rule_to_start_state(vec![0])
14176 .expect("rule start states");
14177 atn.set_rule_to_stop_state(vec![10])
14178 .expect("rule stop states");
14179 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14180 .expect("ops");
14181 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
14182 .expect("exit");
14183 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
14184 .expect("to multi-token operator");
14185 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
14186 .expect("to predicate operator");
14187 atn.add_transition(
14188 3,
14189 ParserTransitionSpec::Precedence {
14190 target: 4,
14191 precedence: 2,
14192 },
14193 )
14194 .expect("multi-token precedence");
14195 atn.add_transition(
14196 4,
14197 ParserTransitionSpec::Atom {
14198 target: 5,
14199 label: 1,
14200 },
14201 )
14202 .expect("multi-token first");
14203 atn.add_transition(
14204 5,
14205 ParserTransitionSpec::Atom {
14206 target: 1,
14207 label: 1,
14208 },
14209 )
14210 .expect("multi-token second");
14211 atn.add_transition(
14212 6,
14213 ParserTransitionSpec::Precedence {
14214 target: 7,
14215 precedence: 2,
14216 },
14217 )
14218 .expect("predicate precedence");
14219 atn.add_transition(
14220 7,
14221 ParserTransitionSpec::Predicate {
14222 target: 8,
14223 rule_index: 0,
14224 pred_index: 0,
14225 context_dependent: false,
14226 },
14227 )
14228 .expect("operator predicate");
14229 atn.add_transition(
14230 8,
14231 ParserTransitionSpec::Atom {
14232 target: 1,
14233 label: 1,
14234 },
14235 )
14236 .expect("predicate single token");
14237 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
14238 .expect("loop end");
14239 finish_atn(atn)
14240 }
14241
14242 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
14243 let mut atn = ParserAtnBuilder::new(2);
14244 for (state, kind, rule) in [
14245 (0, AtnStateKind::RuleStart, 0),
14246 (1, AtnStateKind::StarLoopEntry, 0),
14247 (2, AtnStateKind::Basic, 0),
14248 (3, AtnStateKind::Basic, 0),
14249 (4, AtnStateKind::Basic, 0),
14250 (5, AtnStateKind::LoopEnd, 0),
14251 (6, AtnStateKind::RuleStop, 0),
14252 (7, AtnStateKind::RuleStart, 1),
14253 (8, AtnStateKind::RuleStop, 1),
14254 (9, AtnStateKind::Basic, 1),
14255 ] {
14256 assert_eq!(
14257 atn.add_state(kind, Some(rule)).expect("state").index(),
14258 state
14259 );
14260 if state == 0 {
14261 atn.set_left_recursive_rule(state)
14262 .expect("left-recursive rule start");
14263 } else if state == 1 {
14264 atn.set_precedence_rule_decision(state)
14265 .expect("precedence decision");
14266 }
14267 }
14268 atn.set_rule_to_start_state(vec![0, 7])
14269 .expect("rule start states");
14270 atn.set_rule_to_stop_state(vec![6, 8])
14271 .expect("rule stop states");
14272 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14273 .expect("transition");
14274 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
14275 .expect("transition");
14276 atn.add_transition(
14277 2,
14278 ParserTransitionSpec::Precedence {
14279 target: 3,
14280 precedence: 3,
14281 },
14282 )
14283 .expect("transition");
14284 atn.add_transition(
14285 3,
14286 ParserTransitionSpec::Rule {
14287 target: 7,
14288 rule_index: 1,
14289 follow_state: 4,
14290 precedence: 0,
14291 },
14292 )
14293 .expect("transition");
14294 atn.add_transition(
14295 4,
14296 ParserTransitionSpec::Atom {
14297 target: 1,
14298 label: 1,
14299 },
14300 )
14301 .expect("transition");
14302 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
14303 .expect("transition");
14304 atn.add_transition(
14305 7,
14306 ParserTransitionSpec::Precedence {
14307 target: 9,
14308 precedence: 1,
14309 },
14310 )
14311 .expect("transition");
14312 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
14313 .expect("transition");
14314 finish_atn(atn)
14315 }
14316
14317 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
14318 let mut atn = ParserAtnBuilder::new(2);
14319 for (state, kind) in [
14320 (0, AtnStateKind::RuleStart),
14321 (1, AtnStateKind::StarLoopEntry),
14322 (2, AtnStateKind::Basic),
14323 (3, AtnStateKind::Basic),
14324 (4, AtnStateKind::Basic),
14325 (5, AtnStateKind::LoopEnd),
14326 (6, AtnStateKind::RuleStop),
14327 ] {
14328 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
14329 if state == 0 {
14330 atn.set_left_recursive_rule(state)
14331 .expect("left-recursive rule start");
14332 } else if state == 1 {
14333 atn.set_precedence_rule_decision(state)
14334 .expect("precedence decision");
14335 }
14336 }
14337 atn.set_rule_to_start_state(vec![0])
14338 .expect("rule start states");
14339 atn.set_rule_to_stop_state(vec![6])
14340 .expect("rule stop states");
14341 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14342 .expect("transition");
14343 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
14344 .expect("transition");
14345 atn.add_transition(
14346 2,
14347 ParserTransitionSpec::Precedence {
14348 target: 3,
14349 precedence: 1,
14350 },
14351 )
14352 .expect("transition");
14353 atn.add_transition(
14354 3,
14355 ParserTransitionSpec::Predicate {
14356 target: 4,
14357 rule_index: 0,
14358 pred_index: 0,
14359 context_dependent: false,
14360 },
14361 )
14362 .expect("transition");
14363 atn.add_transition(
14364 4,
14365 ParserTransitionSpec::Atom {
14366 target: 1,
14367 label: 1,
14368 },
14369 )
14370 .expect("transition");
14371 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
14372 .expect("transition");
14373 finish_atn(atn)
14374 }
14375
14376 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
14377 let mut atn = ParserAtnBuilder::new(2);
14378 for (state, kind, rule) in [
14379 (0, AtnStateKind::RuleStart, 0),
14380 (1, AtnStateKind::Basic, 0),
14381 (2, AtnStateKind::Basic, 0),
14382 (3, AtnStateKind::Basic, 0),
14383 (4, AtnStateKind::RuleStop, 0),
14384 (5, AtnStateKind::RuleStart, 1),
14385 (6, AtnStateKind::StarLoopEntry, 1),
14386 (7, AtnStateKind::Basic, 1),
14387 (8, AtnStateKind::Basic, 1),
14388 (9, AtnStateKind::LoopEnd, 1),
14389 (10, AtnStateKind::RuleStop, 1),
14390 (11, AtnStateKind::RuleStart, 2),
14391 (12, AtnStateKind::RuleStop, 2),
14392 ] {
14393 assert_eq!(
14394 atn.add_state(kind, Some(rule)).expect("state").index(),
14395 state
14396 );
14397 if state == 5 {
14398 atn.set_left_recursive_rule(state)
14399 .expect("left-recursive rule start");
14400 } else if state == 6 {
14401 atn.set_precedence_rule_decision(state)
14402 .expect("precedence decision");
14403 }
14404 }
14405 atn.set_rule_to_start_state(vec![0, 5, 11])
14406 .expect("rule start states");
14407 atn.set_rule_to_stop_state(vec![4, 10, 12])
14408 .expect("rule stop states");
14409 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14410 .expect("transition");
14411 atn.add_transition(
14412 1,
14413 ParserTransitionSpec::Rule {
14414 target: 5,
14415 rule_index: 1,
14416 follow_state: 2,
14417 precedence: 0,
14418 },
14419 )
14420 .expect("transition");
14421 atn.add_transition(
14422 2,
14423 ParserTransitionSpec::Rule {
14424 target: 11,
14425 rule_index: 2,
14426 follow_state: 3,
14427 precedence: 0,
14428 },
14429 )
14430 .expect("transition");
14431 atn.add_transition(
14432 3,
14433 ParserTransitionSpec::Atom {
14434 target: 4,
14435 label: caller_symbol,
14436 },
14437 )
14438 .expect("transition");
14439 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
14440 .expect("transition");
14441 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
14442 .expect("transition");
14443 atn.add_transition(
14444 7,
14445 ParserTransitionSpec::Precedence {
14446 target: 8,
14447 precedence: 1,
14448 },
14449 )
14450 .expect("transition");
14451 atn.add_transition(
14452 8,
14453 ParserTransitionSpec::Atom {
14454 target: 6,
14455 label: 1,
14456 },
14457 )
14458 .expect("transition");
14459 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
14460 .expect("transition");
14461 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
14462 .expect("transition");
14463 finish_atn(atn)
14464 }
14465
14466 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
14467 let mut atn = ParserAtnBuilder::new(2);
14468 for (state, kind, rule) in [
14469 (0, AtnStateKind::RuleStart, 0),
14470 (1, AtnStateKind::Basic, 0),
14471 (2, AtnStateKind::Basic, 0),
14472 (3, AtnStateKind::RuleStop, 0),
14473 (4, AtnStateKind::RuleStart, 1),
14474 (5, AtnStateKind::Basic, 1),
14475 (6, AtnStateKind::Basic, 1),
14476 (7, AtnStateKind::RuleStop, 1),
14477 (8, AtnStateKind::RuleStart, 2),
14478 (9, AtnStateKind::StarLoopEntry, 2),
14479 (10, AtnStateKind::Basic, 2),
14480 (11, AtnStateKind::Basic, 2),
14481 (12, AtnStateKind::LoopEnd, 2),
14482 (13, AtnStateKind::RuleStop, 2),
14483 ] {
14484 assert_eq!(
14485 atn.add_state(kind, Some(rule)).expect("state").index(),
14486 state
14487 );
14488 if state == 8 {
14489 atn.set_left_recursive_rule(state)
14490 .expect("left-recursive rule start");
14491 } else if state == 9 {
14492 atn.set_precedence_rule_decision(state)
14493 .expect("precedence decision");
14494 }
14495 }
14496 atn.set_rule_to_start_state(vec![0, 4, 8])
14497 .expect("rule start states");
14498 atn.set_rule_to_stop_state(vec![3, 7, 13])
14499 .expect("rule stop states");
14500 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14501 .expect("transition");
14502 atn.add_transition(
14503 1,
14504 ParserTransitionSpec::Rule {
14505 target: 4,
14506 rule_index: 1,
14507 follow_state: 2,
14508 precedence: 0,
14509 },
14510 )
14511 .expect("transition");
14512 atn.add_transition(
14513 2,
14514 ParserTransitionSpec::Atom {
14515 target: 3,
14516 label: caller_symbol,
14517 },
14518 )
14519 .expect("transition");
14520 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14521 .expect("transition");
14522 atn.add_transition(
14523 5,
14524 ParserTransitionSpec::Rule {
14525 target: 8,
14526 rule_index: 2,
14527 follow_state: 6,
14528 precedence: 0,
14529 },
14530 )
14531 .expect("transition");
14532 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
14533 .expect("transition");
14534 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
14535 .expect("transition");
14536 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
14537 .expect("transition");
14538 atn.add_transition(
14539 10,
14540 ParserTransitionSpec::Precedence {
14541 target: 11,
14542 precedence: 1,
14543 },
14544 )
14545 .expect("transition");
14546 atn.add_transition(
14547 11,
14548 ParserTransitionSpec::Atom {
14549 target: 9,
14550 label: 1,
14551 },
14552 )
14553 .expect("transition");
14554 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
14555 .expect("transition");
14556 finish_atn(atn)
14557 }
14558
14559 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
14560 let mut atn = ParserAtnBuilder::new(2);
14561 for (state, kind, rule) in [
14562 (0, AtnStateKind::RuleStart, 0),
14563 (1, AtnStateKind::Basic, 0),
14564 (2, AtnStateKind::Basic, 0),
14565 (3, AtnStateKind::RuleStop, 0),
14566 (4, AtnStateKind::RuleStart, 1),
14567 (5, AtnStateKind::StarLoopEntry, 1),
14568 (6, AtnStateKind::Basic, 1),
14569 (7, AtnStateKind::Basic, 1),
14570 (8, AtnStateKind::Basic, 1),
14571 (9, AtnStateKind::Basic, 1),
14572 (10, AtnStateKind::LoopEnd, 1),
14573 (11, AtnStateKind::RuleStop, 1),
14574 ] {
14575 assert_eq!(
14576 atn.add_state(kind, Some(rule)).expect("state").index(),
14577 state
14578 );
14579 if state == 4 {
14580 atn.set_left_recursive_rule(state)
14581 .expect("left-recursive rule start");
14582 } else if state == 5 {
14583 atn.set_precedence_rule_decision(state)
14584 .expect("precedence decision");
14585 }
14586 }
14587 atn.set_rule_to_start_state(vec![0, 4])
14588 .expect("rule start states");
14589 atn.set_rule_to_stop_state(vec![3, 11])
14590 .expect("rule stop states");
14591 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14592 .expect("transition");
14593 atn.add_transition(
14594 1,
14595 ParserTransitionSpec::Rule {
14596 target: 4,
14597 rule_index: 1,
14598 follow_state: 2,
14599 precedence: 0,
14600 },
14601 )
14602 .expect("transition");
14603 atn.add_transition(
14604 2,
14605 ParserTransitionSpec::Atom {
14606 target: 3,
14607 label: caller_symbol,
14608 },
14609 )
14610 .expect("transition");
14611 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
14612 .expect("transition");
14613 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
14614 .expect("transition");
14615 atn.add_transition(
14616 6,
14617 ParserTransitionSpec::Precedence {
14618 target: 7,
14619 precedence: 1,
14620 },
14621 )
14622 .expect("transition");
14623 atn.add_transition(
14624 7,
14625 ParserTransitionSpec::Atom {
14626 target: 8,
14627 label: 1,
14628 },
14629 )
14630 .expect("transition");
14631 atn.add_transition(
14632 8,
14633 ParserTransitionSpec::Rule {
14634 target: 4,
14635 rule_index: 1,
14636 follow_state: 9,
14637 precedence: 2,
14638 },
14639 )
14640 .expect("transition");
14641 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
14642 .expect("transition");
14643 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
14644 .expect("transition");
14645 finish_atn(atn)
14646 }
14647
14648 #[test]
14649 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
14650 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
14651 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
14652
14653 let mut overlapping = parser_inside_left_recursive_callee(1);
14654 assert_eq!(
14655 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
14656 None
14657 );
14658
14659 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
14660 assert_eq!(
14661 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
14662 Some(true)
14663 );
14664
14665 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
14666 assert_eq!(
14667 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
14668 Some(false)
14669 );
14670
14671 assert_eq!(
14672 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
14673 Some(true),
14674 "overlap results must not leak across ATNs"
14675 );
14676 }
14677
14678 #[test]
14679 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
14680 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
14681 let mut parser = mini_parser(vec![
14682 TestToken::new(1).with_text("operator"),
14683 TestToken::eof("parser-test", 1, 1, 1),
14684 ]);
14685 parser.rule_context_stack = vec![RuleContextFrame {
14686 rule_index: 0,
14687 invoking_state: -1,
14688 }];
14689
14690 assert_eq!(
14691 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14692 Some(true)
14693 );
14694 assert_eq!(
14695 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14696 Some(true),
14697 "cached operator lookahead must preserve the nullable prefix return path"
14698 );
14699 assert_eq!(
14700 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14701 Some(true),
14702 "the nullable child must use its rule-call precedence, not the caller precedence"
14703 );
14704 }
14705
14706 #[test]
14707 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
14708 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
14713 let mut parser = mini_parser(vec![
14714 TestToken::new(1).with_text(">"),
14715 TestToken::new(2).with_text("id"),
14716 TestToken::eof("parser-test", 1, 1, 1),
14717 ]);
14718 parser.rule_context_stack = vec![RuleContextFrame {
14719 rule_index: 0,
14720 invoking_state: -1,
14721 }];
14722
14723 assert_eq!(
14724 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14725 Some(true),
14726 "at low precedence relational `>` is a single-token operator"
14727 );
14728 assert_eq!(
14729 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
14730 Some(true),
14731 "relational remains single-token at its own precedence"
14732 );
14733 assert_eq!(
14734 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14735 None,
14736 "at shift precedence, bare `>` must not force enter"
14737 );
14738 }
14739
14740 #[test]
14741 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
14742 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
14743 let mut parser = mini_parser(vec![
14744 TestToken::new(1).with_text(">"),
14745 TestToken::new(2).with_text("id"),
14746 TestToken::eof("parser-test", 1, 1, 1),
14747 ]);
14748 parser.rule_context_stack = vec![RuleContextFrame {
14749 rule_index: 0,
14750 invoking_state: -1,
14751 }];
14752
14753 assert_eq!(
14754 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14755 Some(true),
14756 "the direct relational alternative remains a one-token operator"
14757 );
14758 assert_eq!(
14759 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14760 None,
14761 "a token matched in the helper rule must return to the second shift token"
14762 );
14763 }
14764
14765 #[test]
14766 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
14767 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
14768 let mut parser = mini_parser(vec![
14769 TestToken::new(1).with_text(">"),
14770 TestToken::new(2).with_text("id"),
14771 TestToken::eof("parser-test", 1, 1, 1),
14772 ]);
14773 parser.rule_context_stack = vec![RuleContextFrame {
14774 rule_index: 0,
14775 invoking_state: -1,
14776 }];
14777
14778 assert_eq!(
14779 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14780 None,
14781 "a predicate-gated single-token path must not be hidden by a multi-token path"
14782 );
14783 }
14784
14785 #[test]
14786 fn left_recursive_loop_defers_predicate_guarded_operator() {
14787 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
14788 let mut parser = mini_parser_with_hooks(
14789 vec![
14790 TestToken::new(1).with_text("operator"),
14791 TestToken::eof("parser-test", 1, 1, 1),
14792 ],
14793 RejectingPredicateHooks::default(),
14794 );
14795 parser.rule_context_stack = vec![RuleContextFrame {
14796 rule_index: 0,
14797 invoking_state: -1,
14798 }];
14799
14800 assert_eq!(
14801 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14802 None,
14803 "a false predicate must be evaluated before entering the operator alternative"
14804 );
14805 assert_eq!(
14806 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14807 None,
14808 "cached predicate-dependent lookahead must keep deferring"
14809 );
14810 }
14811
14812 #[test]
14813 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
14814 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
14815 let mut parser = parser_inside_left_recursive_callee(1);
14816
14817 assert_eq!(
14818 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
14819 None
14820 );
14821 assert_eq!(
14822 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
14823 None,
14824 "the cached overlap must preserve the nullable child return path"
14825 );
14826 }
14827
14828 #[test]
14829 fn left_recursive_loop_defers_through_nullable_parent_return() {
14830 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
14831 let mut parser = mini_parser(vec![
14832 TestToken::new(1).with_text("lookahead"),
14833 TestToken::eof("parser-test", 1, 1, 1),
14834 ]);
14835 parser.rule_context_stack = vec![
14836 RuleContextFrame {
14837 rule_index: 0,
14838 invoking_state: -1,
14839 },
14840 RuleContextFrame {
14841 rule_index: 1,
14842 invoking_state: 1,
14843 },
14844 RuleContextFrame {
14845 rule_index: 2,
14846 invoking_state: 5,
14847 },
14848 ];
14849
14850 assert_eq!(
14851 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
14852 None,
14853 "a nullable caller must unwind to its parent's consuming follow path"
14854 );
14855 assert_eq!(
14856 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
14857 None,
14858 "the caller-overlap cache must not retain a false negative"
14859 );
14860 }
14861
14862 #[test]
14863 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
14864 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
14865 let mut parser = mini_parser(vec![
14866 TestToken::new(1).with_text("lookahead"),
14867 TestToken::eof("parser-test", 1, 1, 1),
14868 ]);
14869 parser.rule_context_stack = vec![
14870 RuleContextFrame {
14871 rule_index: 0,
14872 invoking_state: -1,
14873 },
14874 RuleContextFrame {
14875 rule_index: 1,
14876 invoking_state: 1,
14877 },
14878 RuleContextFrame {
14879 rule_index: 1,
14880 invoking_state: 8,
14881 },
14882 ];
14883
14884 assert_eq!(
14885 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14886 None,
14887 "a recursive operand return must preserve its parent caller context"
14888 );
14889 assert_eq!(
14890 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14891 None,
14892 "the caller-overlap cache must preserve the loop-boundary return"
14893 );
14894 }
14895
14896 fn token_then_eof_atn() -> Atn {
14897 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14898 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, ]))
14914 .deserialize_parser()
14915 .expect("artificial parser ATN should deserialize")
14916 }
14917
14918 fn epsilon_cycle_atn() -> Atn {
14919 let mut atn = ParserAtnBuilder::new(1);
14920 for (state_number, kind) in [
14921 (0, AtnStateKind::RuleStart),
14922 (1, AtnStateKind::Basic),
14923 (2, AtnStateKind::RuleStop),
14924 ] {
14925 assert_eq!(
14926 atn.add_state(kind, Some(0)).expect("state").index(),
14927 state_number
14928 );
14929 }
14930 atn.set_rule_to_start_state(vec![0])
14931 .expect("rule start states");
14932 atn.set_rule_to_stop_state(vec![2])
14933 .expect("rule stop states");
14934 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14935 .expect("transition");
14936 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
14937 .expect("self-cycle transition");
14938 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14939 .expect("exit transition");
14940 finish_atn(atn)
14941 }
14942
14943 fn eof_then_action_atn() -> Atn {
14944 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14945 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, ]))
14961 .deserialize_parser()
14962 .expect("artificial parser ATN should deserialize")
14963 }
14964
14965 fn noop_action_then_token_then_eof_atn() -> Atn {
14966 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14967 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, ]))
14985 .deserialize_parser()
14986 .expect("artificial no-op action ATN should deserialize")
14987 }
14988
14989 fn two_alt_decision_atn() -> Atn {
14990 let mut atn = ParserAtnBuilder::new(2);
14991 assert_eq!(
14992 atn.add_state(AtnStateKind::RuleStart, Some(0))
14993 .expect("state")
14994 .index(),
14995 0
14996 );
14997 assert_eq!(
14998 atn.add_state(AtnStateKind::BlockStart, Some(0))
14999 .expect("state")
15000 .index(),
15001 1
15002 );
15003 assert_eq!(
15004 atn.add_state(AtnStateKind::Basic, Some(0))
15005 .expect("state")
15006 .index(),
15007 2
15008 );
15009 assert_eq!(
15010 atn.add_state(AtnStateKind::Basic, Some(0))
15011 .expect("state")
15012 .index(),
15013 3
15014 );
15015 assert_eq!(
15016 atn.add_state(AtnStateKind::BlockEnd, Some(0))
15017 .expect("state")
15018 .index(),
15019 4
15020 );
15021 assert_eq!(
15022 atn.add_state(AtnStateKind::RuleStop, Some(0))
15023 .expect("state")
15024 .index(),
15025 5
15026 );
15027 atn.set_rule_to_start_state(vec![0])
15028 .expect("rule start states");
15029 atn.set_rule_to_stop_state(vec![5])
15030 .expect("rule stop states");
15031 atn.add_decision_state(1).expect("decision state");
15032 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15033 .expect("transition");
15034 atn.add_transition(
15035 1,
15036 ParserTransitionSpec::Atom {
15037 target: 2,
15038 label: 1,
15039 },
15040 )
15041 .expect("transition");
15042 atn.add_transition(
15043 1,
15044 ParserTransitionSpec::Atom {
15045 target: 3,
15046 label: 2,
15047 },
15048 )
15049 .expect("transition");
15050 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
15051 .expect("transition");
15052 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15053 .expect("transition");
15054 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15055 .expect("transition");
15056 finish_atn(atn)
15057 }
15058
15059 fn optional_then_b_eof_atn() -> Atn {
15062 let mut atn = ParserAtnBuilder::new(3);
15063 assert_eq!(
15064 atn.add_state(AtnStateKind::RuleStart, Some(0))
15065 .expect("state")
15066 .index(),
15067 0
15068 );
15069 assert_eq!(
15070 atn.add_state(AtnStateKind::BlockStart, Some(0))
15071 .expect("state")
15072 .index(),
15073 1
15074 );
15075 assert_eq!(
15076 atn.add_state(AtnStateKind::Basic, Some(0))
15077 .expect("state")
15078 .index(),
15079 2
15080 );
15081 assert_eq!(
15082 atn.add_state(AtnStateKind::Basic, Some(0))
15083 .expect("state")
15084 .index(),
15085 3
15086 );
15087 assert_eq!(
15088 atn.add_state(AtnStateKind::Basic, Some(0))
15089 .expect("state")
15090 .index(),
15091 4
15092 );
15093 assert_eq!(
15094 atn.add_state(AtnStateKind::RuleStop, Some(0))
15095 .expect("state")
15096 .index(),
15097 5
15098 );
15099 atn.set_rule_to_start_state(vec![0])
15100 .expect("rule start states");
15101 atn.set_rule_to_stop_state(vec![5])
15102 .expect("rule stop states");
15103 atn.add_decision_state(1).expect("decision state");
15104 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15105 .expect("transition");
15106 atn.add_transition(
15108 1,
15109 ParserTransitionSpec::Atom {
15110 target: 3,
15111 label: 1,
15112 },
15113 )
15114 .expect("transition");
15115 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
15116 .expect("transition");
15117 atn.add_transition(
15119 3,
15120 ParserTransitionSpec::Atom {
15121 target: 4,
15122 label: 2,
15123 },
15124 )
15125 .expect("transition");
15126 atn.add_transition(
15127 4,
15128 ParserTransitionSpec::Atom {
15129 target: 5,
15130 label: TOKEN_EOF,
15131 },
15132 )
15133 .expect("transition");
15134 finish_atn(atn)
15135 }
15136
15137 #[test]
15138 fn sync_decision_deletes_only_a_single_token() {
15139 let atn = optional_then_b_eof_atn();
15147
15148 let mut single = mini_parser(vec![
15149 TestToken::new(3).with_text("c"),
15150 TestToken::new(2).with_text("b"),
15151 TestToken::eof("parser-test", 1, 2, 2),
15152 ]);
15153 single.rule_context_stack = vec![RuleContextFrame {
15154 rule_index: 0,
15155 invoking_state: 0,
15156 }];
15157 let children = single
15158 .sync_decision(&atn, 1, true, false)
15159 .expect("single extraneous token recovers");
15160 assert_eq!(children.len(), 1);
15161 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
15162 assert_eq!(single.number_of_syntax_errors(), 1);
15163 assert_eq!(single.la(1), 2);
15165
15166 let mut double = mini_parser(vec![
15167 TestToken::new(3).with_text("c"),
15168 TestToken::new(3).with_text("c"),
15169 TestToken::new(2).with_text("b"),
15170 TestToken::eof("parser-test", 1, 3, 3),
15171 ]);
15172 double.rule_context_stack = vec![RuleContextFrame {
15173 rule_index: 0,
15174 invoking_state: 0,
15175 }];
15176 let result = double.sync_decision(&atn, 1, true, false);
15177 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
15182 match error {
15183 AntlrError::ParserError { message, .. } => {
15184 assert!(message.starts_with("mismatched input"), "got: {message}");
15185 }
15186 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
15187 }
15188 assert_eq!(double.la(1), 3);
15189 }
15190
15191 fn star_loop_then_eof_atn() -> Atn {
15195 AtnDeserializer::new(&SerializedAtn::from_i32(&[
15196 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,
15197 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,
15198 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,
15199 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
15200 ]))
15201 .deserialize_parser()
15202 .expect("star-loop-then-EOF ATN should deserialize")
15203 }
15204
15205 fn plus_loop_with_recovering_body_atn() -> Atn {
15211 let mut atn = ParserAtnBuilder::new(2);
15212 assert_eq!(
15213 atn.add_state(AtnStateKind::RuleStart, Some(0))
15214 .expect("state")
15215 .index(),
15216 0
15217 );
15218 assert_eq!(
15219 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
15220 .expect("state")
15221 .index(),
15222 1
15223 );
15224 assert_eq!(
15225 atn.add_state(AtnStateKind::Basic, Some(0))
15226 .expect("state")
15227 .index(),
15228 2
15229 );
15230 assert_eq!(
15231 atn.add_state(AtnStateKind::BlockEnd, Some(0))
15232 .expect("state")
15233 .index(),
15234 3
15235 );
15236 assert_eq!(
15237 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
15238 .expect("state")
15239 .index(),
15240 4
15241 );
15242 assert_eq!(
15243 atn.add_state(AtnStateKind::LoopEnd, Some(0))
15244 .expect("state")
15245 .index(),
15246 5
15247 );
15248 assert_eq!(
15249 atn.add_state(AtnStateKind::RuleStop, Some(0))
15250 .expect("state")
15251 .index(),
15252 6
15253 );
15254 assert_eq!(
15255 atn.add_state(AtnStateKind::RuleStart, Some(1))
15256 .expect("state")
15257 .index(),
15258 7
15259 );
15260 assert_eq!(
15261 atn.add_state(AtnStateKind::Basic, Some(1))
15262 .expect("state")
15263 .index(),
15264 8
15265 );
15266 assert_eq!(
15267 atn.add_state(AtnStateKind::RuleStop, Some(1))
15268 .expect("state")
15269 .index(),
15270 9
15271 );
15272 atn.set_rule_to_start_state(vec![0, 7])
15273 .expect("rule start states");
15274 atn.set_rule_to_stop_state(vec![6, 9])
15275 .expect("rule stop states");
15276 atn.set_end_state(1, 3).expect("block end state");
15277 atn.set_loop_back_state(5, 4).expect("loop back state");
15278 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15279 .expect("transition");
15280 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15281 .expect("transition");
15282 atn.add_transition(
15283 2,
15284 ParserTransitionSpec::Rule {
15285 target: 7,
15286 rule_index: 1,
15287 follow_state: 3,
15288 precedence: 0,
15289 },
15290 )
15291 .expect("transition");
15292 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15293 .expect("transition");
15294 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
15295 .expect("transition");
15296 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15297 .expect("transition");
15298 atn.add_transition(
15299 5,
15300 ParserTransitionSpec::Atom {
15301 target: 6,
15302 label: 2,
15303 },
15304 )
15305 .expect("transition");
15306 atn.add_transition(
15307 7,
15308 ParserTransitionSpec::Atom {
15309 target: 8,
15310 label: 1,
15311 },
15312 )
15313 .expect("transition");
15314 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15315 .expect("transition");
15316 finish_atn(atn)
15317 }
15318
15319 #[test]
15320 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
15321 let atn = plus_loop_with_recovering_body_atn();
15322 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15323
15324 let error = parser
15325 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15326 .expect_err("EOF recovery should report a bounded mismatch");
15327
15328 let AntlrError::ParserError { message, .. } = error else {
15329 panic!("expected ParserError, got {error:?}");
15330 };
15331 insta::assert_snapshot!(message, @"mismatched input '<EOF>' expecting {'x', 2}");
15332 assert_eq!(parser.number_of_syntax_errors(), 1);
15333 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
15334 }
15335
15336 #[test]
15337 fn sync_decision_deletes_token_before_eof_at_loop_back() {
15338 let atn = star_loop_then_eof_atn();
15344 let mut parser = mini_parser(vec![
15345 TestToken::new(2).with_text("c"),
15346 TestToken::eof("parser-test", 1, 1, 1),
15347 ]);
15348 parser.rule_context_stack = vec![RuleContextFrame {
15349 rule_index: 0,
15350 invoking_state: 0,
15351 }];
15352 let children = parser
15353 .sync_decision(&atn, 5, true, false)
15354 .expect("single token before EOF recovers");
15355 assert_eq!(children.len(), 1);
15356 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
15357 assert_eq!(parser.number_of_syntax_errors(), 1);
15358 assert_eq!(
15359 parser.la(1),
15360 TOKEN_EOF,
15361 "EOF is left for the rule's EOF match"
15362 );
15363 }
15364
15365 #[test]
15366 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
15367 let atn = star_loop_then_eof_atn();
15372 let mut parser = mini_parser(vec![
15373 TestToken::new(2).with_text("c"),
15374 TestToken::new(2).with_text("c"),
15375 TestToken::eof("parser-test", 1, 2, 2),
15376 ]);
15377 parser.rule_context_stack = vec![RuleContextFrame {
15378 rule_index: 0,
15379 invoking_state: 0,
15380 }];
15381 let error = parser
15382 .sync_decision(&atn, 5, true, false)
15383 .expect_err("two tokens at the loop entry must not be deleted");
15384 match error {
15385 AntlrError::ParserError { message, .. } => {
15386 assert!(message.starts_with("mismatched input"), "got: {message}");
15387 }
15388 other => panic!("expected mismatched-input ParserError, got {other:?}"),
15389 }
15390 assert_eq!(
15391 parser.la(1),
15392 2,
15393 "nothing consumed; cursor still on first `c`"
15394 );
15395 }
15396
15397 #[test]
15398 fn sync_decision_consumes_until_eof_at_loop_back() {
15399 let atn = star_loop_then_eof_atn();
15405 let mut parser = mini_parser(vec![
15406 TestToken::new(2).with_text("c"),
15407 TestToken::new(2).with_text("c"),
15408 TestToken::eof("parser-test", 1, 2, 2),
15409 ]);
15410 parser.rule_context_stack = vec![RuleContextFrame {
15411 rule_index: 0,
15412 invoking_state: 0,
15413 }];
15414 let children = parser
15415 .sync_decision(&atn, 5, false, true)
15416 .expect("loop-back multi-token deletion recovers onto EOF");
15417 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
15418 assert!(
15419 children
15420 .iter()
15421 .all(|child| parser.node(*child).kind() == NodeKind::Error)
15422 );
15423 assert_eq!(parser.number_of_syntax_errors(), 1);
15424 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
15425 }
15426
15427 fn predicate_after_token_atn() -> Atn {
15428 let mut atn = ParserAtnBuilder::new(2);
15429 assert_eq!(
15430 atn.add_state(AtnStateKind::RuleStart, Some(0))
15431 .expect("state")
15432 .index(),
15433 0
15434 );
15435 assert_eq!(
15436 atn.add_state(AtnStateKind::Basic, Some(0))
15437 .expect("state")
15438 .index(),
15439 1
15440 );
15441 assert_eq!(
15442 atn.add_state(AtnStateKind::Basic, Some(0))
15443 .expect("state")
15444 .index(),
15445 2
15446 );
15447 assert_eq!(
15448 atn.add_state(AtnStateKind::Basic, Some(0))
15449 .expect("state")
15450 .index(),
15451 3
15452 );
15453 assert_eq!(
15454 atn.add_state(AtnStateKind::RuleStop, Some(0))
15455 .expect("state")
15456 .index(),
15457 4
15458 );
15459 atn.set_rule_to_start_state(vec![0])
15460 .expect("rule start states");
15461 atn.set_rule_to_stop_state(vec![4])
15462 .expect("rule stop states");
15463 atn.add_transition(
15464 0,
15465 ParserTransitionSpec::Atom {
15466 target: 1,
15467 label: 1,
15468 },
15469 )
15470 .expect("transition");
15471 atn.add_transition(
15472 1,
15473 ParserTransitionSpec::Predicate {
15474 target: 2,
15475 rule_index: 0,
15476 pred_index: 0,
15477 context_dependent: false,
15478 },
15479 )
15480 .expect("transition");
15481 atn.add_transition(
15482 2,
15483 ParserTransitionSpec::Atom {
15484 target: 3,
15485 label: 2,
15486 },
15487 )
15488 .expect("transition");
15489 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15490 .expect("transition");
15491 finish_atn(atn)
15492 }
15493
15494 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
15495 let mut atn = ParserAtnBuilder::new(1);
15496 for (state_number, kind) in [
15497 (0, AtnStateKind::RuleStart),
15498 (1, AtnStateKind::BlockStart),
15499 (2, AtnStateKind::Basic),
15500 (3, AtnStateKind::Basic),
15501 (4, AtnStateKind::Basic),
15502 (5, AtnStateKind::Basic),
15503 (6, AtnStateKind::BlockEnd),
15504 (7, AtnStateKind::RuleStop),
15505 ] {
15506 assert_eq!(
15507 atn.add_state(kind, Some(0)).expect("state").index(),
15508 state_number
15509 );
15510 }
15511 atn.set_rule_to_start_state(vec![0])
15512 .expect("rule start states");
15513 atn.set_rule_to_stop_state(vec![7])
15514 .expect("rule stop states");
15515 atn.add_decision_state(1).expect("decision state");
15516 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15517 .expect("transition");
15518 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15519 .expect("transition");
15520 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
15521 .expect("transition");
15522 atn.add_transition(
15523 2,
15524 ParserTransitionSpec::Predicate {
15525 target: 4,
15526 rule_index: 0,
15527 pred_index: pred_indexes[0],
15528 context_dependent: false,
15529 },
15530 )
15531 .expect("transition");
15532 atn.add_transition(
15533 3,
15534 ParserTransitionSpec::Predicate {
15535 target: 5,
15536 rule_index: 0,
15537 pred_index: pred_indexes[1],
15538 context_dependent: false,
15539 },
15540 )
15541 .expect("transition");
15542 atn.add_transition(
15543 4,
15544 ParserTransitionSpec::Atom {
15545 target: 6,
15546 label: 1,
15547 },
15548 )
15549 .expect("transition");
15550 atn.add_transition(
15551 5,
15552 ParserTransitionSpec::Atom {
15553 target: 6,
15554 label: 1,
15555 },
15556 )
15557 .expect("transition");
15558 atn.add_transition(
15559 6,
15560 ParserTransitionSpec::Atom {
15561 target: 7,
15562 label: TOKEN_EOF,
15563 },
15564 )
15565 .expect("transition");
15566 finish_atn(atn)
15567 }
15568
15569 fn nested_nullable_context_atn() -> Atn {
15570 let mut atn = ParserAtnBuilder::new(1);
15571 for state_number in 0..=20 {
15572 let kind = match state_number {
15573 0 | 10 | 16 => AtnStateKind::RuleStart,
15574 9 | 15 | 20 => AtnStateKind::RuleStop,
15575 _ => AtnStateKind::Basic,
15576 };
15577 let rule_index = match state_number {
15578 0..=9 => 0,
15579 10..=15 => 1,
15580 _ => 2,
15581 };
15582 assert_eq!(
15583 atn.add_state(kind, Some(rule_index))
15584 .expect("state")
15585 .index(),
15586 state_number
15587 );
15588 }
15589 atn.set_rule_to_start_state(vec![0, 10, 16])
15590 .expect("rule start states");
15591 atn.set_rule_to_stop_state(vec![9, 15, 20])
15592 .expect("rule stop states");
15593 atn.add_transition(
15594 1,
15595 ParserTransitionSpec::Rule {
15596 target: 10,
15597 rule_index: 1,
15598 follow_state: 8,
15599 precedence: 0,
15600 },
15601 )
15602 .expect("transition");
15603 atn.add_transition(
15604 8,
15605 ParserTransitionSpec::Atom {
15606 target: 9,
15607 label: 1,
15608 },
15609 )
15610 .expect("transition");
15611 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15612 .expect("transition");
15613 atn.add_transition(
15614 2,
15615 ParserTransitionSpec::Rule {
15616 target: 16,
15617 rule_index: 2,
15618 follow_state: 14,
15619 precedence: 0,
15620 },
15621 )
15622 .expect("transition");
15623 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
15624 .expect("transition");
15625 finish_atn(atn)
15626 }
15627
15628 fn generated_match_recovery_atn() -> Atn {
15629 let mut atn = ParserAtnBuilder::new(2);
15630 assert_eq!(
15631 atn.add_state(AtnStateKind::RuleStart, Some(0))
15632 .expect("state")
15633 .index(),
15634 0
15635 );
15636 assert_eq!(
15637 atn.add_state(AtnStateKind::Basic, Some(0))
15638 .expect("state")
15639 .index(),
15640 1
15641 );
15642 assert_eq!(
15643 atn.add_state(AtnStateKind::Basic, Some(0))
15644 .expect("state")
15645 .index(),
15646 2
15647 );
15648 assert_eq!(
15649 atn.add_state(AtnStateKind::RuleStop, Some(0))
15650 .expect("state")
15651 .index(),
15652 3
15653 );
15654 assert_eq!(
15655 atn.add_state(AtnStateKind::RuleStart, Some(1))
15656 .expect("state")
15657 .index(),
15658 4
15659 );
15660 assert_eq!(
15661 atn.add_state(AtnStateKind::RuleStop, Some(1))
15662 .expect("state")
15663 .index(),
15664 5
15665 );
15666 atn.set_rule_to_start_state(vec![0, 4])
15667 .expect("rule start states");
15668 atn.set_rule_to_stop_state(vec![3, 5])
15669 .expect("rule stop states");
15670 atn.add_transition(
15671 1,
15672 ParserTransitionSpec::Rule {
15673 target: 4,
15674 rule_index: 1,
15675 follow_state: 2,
15676 precedence: 0,
15677 },
15678 )
15679 .expect("transition");
15680 atn.add_transition(
15681 2,
15682 ParserTransitionSpec::Atom {
15683 target: 3,
15684 label: TOKEN_EOF,
15685 },
15686 )
15687 .expect("transition");
15688 finish_atn(atn)
15689 }
15690
15691 fn complement_set_atn() -> Atn {
15692 let mut atn = ParserAtnBuilder::new(1);
15693 assert_eq!(
15694 atn.add_state(AtnStateKind::RuleStart, Some(0))
15695 .expect("state")
15696 .index(),
15697 0
15698 );
15699 assert_eq!(
15700 atn.add_state(AtnStateKind::RuleStop, Some(0))
15701 .expect("state")
15702 .index(),
15703 1
15704 );
15705 atn.set_rule_to_start_state(vec![0])
15706 .expect("rule start states");
15707 atn.set_rule_to_stop_state(vec![1])
15708 .expect("rule stop states");
15709 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
15710 atn.add_transition(
15711 0,
15712 ParserTransitionSpec::NotSet {
15713 target: 1,
15714 set: excluded,
15715 },
15716 )
15717 .expect("transition");
15718 finish_atn(atn)
15719 }
15720
15721 fn wildcard_then_eof_atn() -> Atn {
15724 let mut atn = ParserAtnBuilder::new(1);
15725 assert_eq!(
15726 atn.add_state(AtnStateKind::RuleStart, Some(0))
15727 .expect("state")
15728 .index(),
15729 0
15730 );
15731 assert_eq!(
15732 atn.add_state(AtnStateKind::RuleStop, Some(0))
15733 .expect("state")
15734 .index(),
15735 1
15736 );
15737 assert_eq!(
15738 atn.add_state(AtnStateKind::Basic, Some(0))
15739 .expect("state")
15740 .index(),
15741 2
15742 );
15743 atn.set_rule_to_start_state(vec![0])
15744 .expect("rule start states");
15745 atn.set_rule_to_stop_state(vec![1])
15746 .expect("rule stop states");
15747 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
15748 .expect("transition");
15749 atn.add_transition(
15750 2,
15751 ParserTransitionSpec::Atom {
15752 target: 1,
15753 label: TOKEN_EOF,
15754 },
15755 )
15756 .expect("transition");
15757 finish_atn(atn)
15758 }
15759
15760 #[test]
15761 fn parser_matches_token_and_reports_mismatch() {
15762 let source = Source {
15763 tokens: vec![
15764 TestToken::new(1).with_text("x"),
15765 TestToken::eof("parser-test", 1, 1, 1),
15766 ],
15767 index: 0,
15768 };
15769 let data = RecognizerData::new(
15770 "Mini.g4",
15771 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15772 );
15773 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
15774 let matched = parser.match_token(1).expect("token 1 should match");
15775 assert_eq!(parser.node(matched).text(), "x");
15776 assert!(parser.match_token(1).is_err());
15777 }
15778
15779 #[test]
15780 fn parser_matches_token_sets() {
15781 let mut parser = mini_parser(vec![
15782 TestToken::new(1).with_text("x"),
15783 TestToken::eof("parser-test", 1, 1, 1),
15784 ]);
15785
15786 let matched = parser
15787 .match_set(&[(1, 1), (3, 4)])
15788 .expect("token set should match");
15789 assert_eq!(parser.node(matched).text(), "x");
15790 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
15791 }
15792
15793 #[test]
15794 fn generated_rule_api_tracks_state_and_precedence() {
15795 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15796
15797 let context = parser.enter_rule(7, 2);
15798 assert_eq!(context.rule_index(), 2);
15799 assert_eq!(parser.state(), 7);
15800 assert_eq!(
15801 parser.rule_context_stack,
15802 vec![RuleContextFrame {
15803 rule_index: 2,
15804 invoking_state: 7
15805 }]
15806 );
15807
15808 let recursive = parser.enter_recursion_rule(11, 3, 4);
15809 assert_eq!(recursive.rule_index(), 3);
15810 assert!(parser.precpred(4));
15811 assert!(parser.precpred(5));
15812 assert!(!parser.precpred(3));
15813
15814 let next = parser.push_new_recursion_context(13, 3);
15815 assert_eq!(next.invoking_state(), 13);
15816 parser.unroll_recursion_context();
15817 assert_eq!(parser.precedence_stack, vec![0]);
15818 assert_eq!(
15819 parser.rule_context_stack,
15820 vec![RuleContextFrame {
15821 rule_index: 2,
15822 invoking_state: 7
15823 }]
15824 );
15825
15826 parser.exit_rule();
15827 assert!(parser.rule_context_stack.is_empty());
15828 }
15829
15830 #[test]
15831 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
15832 let mut parser = mini_parser(vec![
15833 TestToken::new(1).with_text("x"),
15834 TestToken::eof("parser-test", 1, 1, 1),
15835 ]);
15836 let matched = parser.match_token(1).expect("token should match");
15837 assert_eq!(parser.node(matched).text(), "x");
15838 parser.record_generated_syntax_error();
15839 parser.set_int_member(7, 11);
15840 parser.set_build_parse_trees(false);
15841 parser.set_report_diagnostic_errors(true);
15842 parser.set_prediction_mode(PredictionMode::Sll);
15843 parser.set_bail_on_error(true);
15844 let _context = parser.enter_recursion_rule(9, 0, 4);
15845 parser.pending_invoking_states.push(5);
15846 parser.unknown_predicate_hits.push((0, 1));
15847 parser.unhandled_action_hits.push((0, 2));
15848
15849 parser.reset();
15850
15851 assert_eq!(parser.input.index(), 0);
15852 assert_eq!(parser.la(1), 1);
15853 assert_eq!(parser.state(), -1);
15854 assert_eq!(parser.number_of_syntax_errors(), 0);
15855 assert_eq!(parser.parse_tree_storage().node_count(), 0);
15856 assert!(parser.rule_context_stack.is_empty());
15857 assert!(parser.pending_invoking_states.is_empty());
15858 assert_eq!(parser.precedence_stack, [0]);
15859 assert!(parser.unknown_predicate_hits.is_empty());
15860 assert!(parser.unhandled_action_hits.is_empty());
15861 assert_eq!(parser.int_member(7), Some(11));
15862 assert!(!parser.build_parse_trees());
15863 assert!(parser.report_diagnostic_errors());
15864 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
15865 assert!(parser.bail_on_error());
15866 }
15867
15868 #[test]
15869 fn set_token_stream_replaces_input_and_resets_parser() {
15870 let mut parser = mini_parser(vec![
15871 TestToken::new(1).with_text("old"),
15872 TestToken::eof("parser-test", 1, 1, 1),
15873 ]);
15874 parser.consume();
15875 parser.record_generated_syntax_error();
15876 let replacement = CommonTokenStream::new(Source {
15877 tokens: vec![
15878 TestToken::new(2).with_text("new"),
15879 TestToken::eof("parser-test", 1, 1, 1),
15880 ],
15881 index: 0,
15882 });
15883
15884 parser.set_token_stream(replacement);
15885
15886 assert_eq!(parser.input.index(), 0);
15887 assert_eq!(parser.la(1), 2);
15888 assert_eq!(parser.input.text_all(), "new");
15889 assert_eq!(parser.number_of_syntax_errors(), 0);
15890 }
15891
15892 #[test]
15893 fn active_invocation_states_exclude_the_root_frame() {
15894 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15895
15896 let _root = parser.enter_rule(0, 0);
15897 assert!(parser.active_invocation_states().is_empty());
15898
15899 let marker = parser.push_invoking_state(6);
15900 let _child = parser.enter_rule(2, 1);
15901 parser.discard_invoking_state(marker);
15902 assert_eq!(parser.active_invocation_states(), [6]);
15903
15904 let marker = parser.push_invoking_state(13);
15905 let _grandchild = parser.enter_rule(4, 2);
15906 parser.discard_invoking_state(marker);
15907 assert_eq!(parser.active_invocation_states(), [13, 6]);
15908
15909 parser.exit_rule();
15910 parser.exit_rule();
15911 parser.exit_rule();
15912 }
15913
15914 #[test]
15915 fn parser_predicates_support_token_adjacency() {
15916 let mut parser = mini_parser(vec![
15917 TestToken::new(1).with_text("=").with_span(0, 0),
15918 TestToken::new(1).with_text(">").with_span(1, 1),
15919 TestToken::eof("parser-test", 2, 1, 2),
15920 ]);
15921 parser.consume();
15922 parser.consume();
15923
15924 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
15925
15926 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15927
15928 let mut parser = mini_parser(vec![
15929 TestToken::new(1).with_text("=").with_span(0, 0),
15930 TestToken::new(1)
15931 .with_text(" ")
15932 .with_channel(HIDDEN_CHANNEL)
15933 .with_span(1, 1),
15934 TestToken::new(1).with_text(">").with_span(2, 2),
15935 TestToken::eof("parser-test", 3, 1, 3),
15936 ]);
15937 parser.consume();
15938 parser.consume();
15939
15940 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15941 }
15942
15943 #[test]
15944 fn parser_predicates_support_context_child_text_checks() {
15945 let mut parser = mini_parser(vec![
15946 TestToken::new(1).with_text("var"),
15947 TestToken::eof("parser-test", 1, 1, 1),
15948 ]);
15949 let mut context = ParserRuleContext::new(1, 0);
15950 let mut child_context = ParserRuleContext::new(2, 0);
15951 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
15952 parser.tree.add_child(&mut child_context, terminal);
15953 let child = parser.rule_node(child_context);
15954 parser.tree.add_child(&mut context, child);
15955 let predicates = [(
15956 1,
15957 0,
15958 ParserPredicate::ContextChildRuleTextNotEquals {
15959 rule_index: 2,
15960 text: "var",
15961 },
15962 )];
15963
15964 assert!(
15965 !parser.parser_semantic_predicate_matches_with_context_and_local(
15966 &predicates,
15967 1,
15968 0,
15969 &context,
15970 0,
15971 )
15972 );
15973 }
15974
15975 #[test]
15976 fn context_expected_symbols_walks_nullable_parent_contexts() {
15977 let atn = nested_nullable_context_atn();
15978 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15979 parser.rule_context_stack = vec![
15980 RuleContextFrame {
15981 rule_index: 0,
15982 invoking_state: 0,
15983 },
15984 RuleContextFrame {
15985 rule_index: 1,
15986 invoking_state: 1,
15987 },
15988 RuleContextFrame {
15989 rule_index: 2,
15990 invoking_state: 2,
15991 },
15992 ];
15993
15994 let expected = parser.context_expected_symbols(&atn);
15995
15996 assert!(expected.contains(&1));
15997 assert!(expected.contains(&TOKEN_EOF));
15998 }
15999
16000 #[test]
16001 fn prediction_context_return_states_track_rule_stack_changes() {
16002 let atn = nested_nullable_context_atn();
16003 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16004 parser.rule_context_stack = vec![
16005 RuleContextFrame {
16006 rule_index: 0,
16007 invoking_state: 0,
16008 },
16009 RuleContextFrame {
16010 rule_index: 1,
16011 invoking_state: 1,
16012 },
16013 RuleContextFrame {
16014 rule_index: 2,
16015 invoking_state: 2,
16016 },
16017 ];
16018
16019 let initial_version = parser.rule_context_version();
16020 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
16021 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
16022 assert_eq!(first, second);
16023 assert_eq!(parser.rule_context_version(), initial_version);
16024
16025 parser.exit_rule();
16026 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
16027 assert_ne!(first, after_pop);
16028 assert_ne!(parser.rule_context_version(), initial_version);
16029 }
16030
16031 #[test]
16032 fn generated_match_token_recovers_missing_token_from_context_follow() {
16033 let atn = generated_match_recovery_atn();
16034 let data = RecognizerData::new(
16035 "Mini.g4",
16036 Vocabulary::new(
16037 [None, Some("'X'"), Some("'Y'")],
16038 [None, Some("X"), Some("Y")],
16039 [None::<&str>, None, None],
16040 ),
16041 );
16042 let mut parser = BaseParser::new(
16043 CommonTokenStream::new(Source {
16044 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
16045 index: 0,
16046 }),
16047 data,
16048 );
16049 parser.rule_context_stack = vec![
16050 RuleContextFrame {
16051 rule_index: 0,
16052 invoking_state: 0,
16053 },
16054 RuleContextFrame {
16055 rule_index: 1,
16056 invoking_state: 1,
16057 },
16058 ];
16059 assert_eq!(parser.number_of_syntax_errors(), 0);
16060
16061 let node = parser
16062 .match_token_recovering(2, 5, &atn)
16063 .expect("generated match should insert missing token");
16064
16065 assert_eq!(node.children().len(), 1);
16066 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
16067 assert_eq!(
16068 node.clone()
16069 .into_child_iter()
16070 .map(|child| parser.node(child).text())
16071 .collect::<Vec<_>>(),
16072 ["<missing 'Y'>"]
16073 );
16074 assert!(!node.consumed_eof());
16077 assert_eq!(parser.la(1), TOKEN_EOF);
16078 assert_eq!(parser.number_of_syntax_errors(), 1);
16079 assert_eq!(
16080 parser.generated_parser_diagnostics,
16081 [ParserDiagnostic {
16082 line: 1,
16083 column: 3,
16084 message: "missing 'Y' at '<EOF>'".to_owned(),
16085 offending: parser.input.lt_id(1),
16086 }]
16087 );
16088 }
16089
16090 #[test]
16091 fn generated_match_token_counts_single_token_deletion_recovery() {
16092 let atn = generated_match_recovery_atn();
16093 let data = RecognizerData::new(
16094 "Mini.g4",
16095 Vocabulary::new(
16096 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
16097 [None, Some("X"), Some("Y"), Some("Z")],
16098 [None::<&str>, None, None, None],
16099 ),
16100 );
16101 let mut parser = BaseParser::new(
16102 CommonTokenStream::new(Source {
16103 tokens: vec![
16104 TestToken::new(3).with_text("z"),
16105 TestToken::new(2).with_text("y"),
16106 TestToken::eof("parser-test", 3, 1, 3),
16107 ],
16108 index: 0,
16109 }),
16110 data,
16111 );
16112
16113 let node = parser
16114 .match_token_recovering(2, 5, &atn)
16115 .expect("generated match should delete the extraneous token");
16116
16117 assert_eq!(node.children().len(), 2);
16118 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
16119 assert_eq!(parser.node(node.children()[0]).text(), "z");
16120 assert_eq!(parser.node(node.children()[1]).text(), "y");
16121 assert_eq!(
16122 node.into_child_iter()
16123 .map(|child| parser.node(child).text())
16124 .collect::<Vec<_>>(),
16125 ["z", "y"]
16126 );
16127 assert_eq!(parser.number_of_syntax_errors(), 1);
16128 }
16129
16130 #[test]
16131 fn generated_match_token_iterates_single_success_without_a_children_vec() {
16132 let atn = generated_match_recovery_atn();
16133 let data = RecognizerData::new(
16134 "Mini.g4",
16135 Vocabulary::new(
16136 [None, Some("'X'"), Some("'Y'")],
16137 [None, Some("X"), Some("Y")],
16138 [None::<&str>, None, None],
16139 ),
16140 );
16141 let mut parser = BaseParser::new(
16142 CommonTokenStream::new(Source {
16143 tokens: vec![
16144 TestToken::new(2).with_text("y"),
16145 TestToken::eof("parser-test", 1, 1, 1),
16146 ],
16147 index: 0,
16148 }),
16149 data,
16150 );
16151
16152 let node = parser
16153 .match_token_recovering(2, 5, &atn)
16154 .expect("generated match should consume the expected token");
16155
16156 assert_eq!(
16157 node.into_child_iter()
16158 .map(|child| parser.node(child).text())
16159 .collect::<Vec<_>>(),
16160 ["y"]
16161 );
16162 assert_eq!(parser.number_of_syntax_errors(), 0);
16163 }
16164
16165 #[test]
16166 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
16167 let atn = generated_match_recovery_atn();
16168 let data = RecognizerData::new(
16169 "Mini.g4",
16170 Vocabulary::new(
16171 [None, Some("'X'"), Some("'Y'")],
16172 [None, Some("X"), Some("Y")],
16173 [None::<&str>, None, None],
16174 ),
16175 );
16176 let mut parser = BaseParser::new(
16177 CommonTokenStream::new(Source {
16178 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
16179 index: 0,
16180 }),
16181 data,
16182 );
16183 parser.rule_context_stack = vec![
16184 RuleContextFrame {
16185 rule_index: 0,
16186 invoking_state: 0,
16187 },
16188 RuleContextFrame {
16189 rule_index: 1,
16190 invoking_state: 1,
16191 },
16192 ];
16193 let marker = parser.generated_diagnostics_checkpoint();
16194
16195 let _ = parser
16196 .match_token_recovering(2, 5, &atn)
16197 .expect("generated match should insert missing token");
16198 assert_eq!(parser.number_of_syntax_errors(), 1);
16199
16200 parser.restore_generated_diagnostics(marker);
16201
16202 assert_eq!(parser.number_of_syntax_errors(), 0);
16203 assert!(parser.generated_parser_diagnostics.is_empty());
16204 }
16205
16206 #[test]
16207 fn generated_prediction_diagnostics_use_adaptive_context() {
16208 let atn = two_alt_decision_atn();
16209 let data = RecognizerData::new(
16210 "Mini.g4",
16211 Vocabulary::new(
16212 [None, Some("'x'"), Some("'y'")],
16213 [None, Some("X"), Some("Y")],
16214 [None::<&str>, None, None],
16215 ),
16216 )
16217 .with_rule_names(["s"]);
16218 let mut parser = BaseParser::new(
16219 CommonTokenStream::new(Source {
16220 tokens: vec![
16221 TestToken::new(1)
16222 .with_text("x")
16223 .with_position(1, 0)
16224 .with_span(0, 0),
16225 TestToken::new(2)
16226 .with_text("y")
16227 .with_position(1, 2)
16228 .with_span(1, 1),
16229 TestToken::eof("parser-test", 2, 1, 3),
16230 ],
16231 index: 0,
16232 }),
16233 data,
16234 );
16235 parser.set_report_diagnostic_errors(true);
16236
16237 parser.record_generated_prediction_diagnostic(
16238 &atn,
16239 1,
16240 &ParserAtnPrediction {
16241 alt: 1,
16242 requires_full_context: true,
16243 has_semantic_context: false,
16244 diagnostic: Some(ParserAtnPredictionDiagnostic {
16245 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
16246 start_index: 0,
16247 sll_stop_index: 1,
16248 ll_stop_index: 0,
16249 conflicting_alts: vec![1, 2],
16250 exact: false,
16251 }),
16252 },
16253 );
16254 parser.record_generated_prediction_diagnostic(
16259 &atn,
16260 1,
16261 &ParserAtnPrediction {
16262 alt: 1,
16263 requires_full_context: true,
16264 has_semantic_context: false,
16265 diagnostic: Some(ParserAtnPredictionDiagnostic {
16266 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
16267 start_index: 0,
16268 sll_stop_index: 1,
16269 ll_stop_index: 1,
16270 conflicting_alts: vec![1, 2],
16271 exact: false,
16272 }),
16273 },
16274 );
16275
16276 insta::assert_debug_snapshot!(
16279 "generated_prediction_diagnostics_use_adaptive_context",
16280 parser.generated_parser_diagnostics
16281 );
16282 }
16283
16284 #[test]
16285 fn generated_match_not_set_recovers_empty_complement_at_eof() {
16286 let atn = complement_set_atn();
16287 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16288 parser.rule_context_stack = vec![RuleContextFrame {
16289 rule_index: 0,
16290 invoking_state: 0,
16291 }];
16292
16293 let node = parser
16294 .match_not_token_set_recovering(
16295 atn.token_set(0).expect("excluded token set"),
16296 1,
16297 1,
16298 1,
16299 &atn,
16300 )
16301 .expect("empty complement should recover at EOF");
16302
16303 assert_eq!(node.children().len(), 1);
16304 assert!(!node.consumed_eof());
16307 assert_eq!(parser.la(1), TOKEN_EOF);
16308 assert_eq!(
16309 parser.generated_parser_diagnostics,
16310 [ParserDiagnostic {
16311 line: 1,
16312 column: 1,
16313 message: "missing {} at '<EOF>'".to_owned(),
16314 offending: parser.input.lt_id(1),
16315 }]
16316 );
16317 }
16318
16319 #[test]
16320 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
16321 let atn = wildcard_then_eof_atn();
16327 let data = RecognizerData::new(
16328 "Mini.g4",
16329 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
16330 );
16331 let mut parser = BaseParser::new(
16332 CommonTokenStream::new(Source {
16333 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
16334 index: 0,
16335 }),
16336 data,
16337 );
16338 parser.rule_context_stack = vec![RuleContextFrame {
16339 rule_index: 0,
16340 invoking_state: 0,
16341 }];
16342
16343 let node = parser
16344 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
16345 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
16346
16347 assert_eq!(node.children().len(), 1);
16349 assert!(!node.consumed_eof());
16350 assert!(
16351 parser
16352 .node(node.children()[0])
16353 .text()
16354 .starts_with("<missing")
16355 );
16356 assert_eq!(parser.la(1), TOKEN_EOF);
16357 assert_eq!(
16358 parser.generated_parser_diagnostics,
16359 [ParserDiagnostic {
16360 line: 1,
16361 column: 1,
16362 message: "missing 'x' at '<EOF>'".to_owned(),
16363 offending: parser.input.lt_id(1),
16364 }]
16365 );
16366 }
16367
16368 #[test]
16369 fn generated_rule_recovery_consumes_to_parent_follow() {
16370 let atn = generated_match_recovery_atn();
16371 let data = RecognizerData::new(
16372 "Mini.g4",
16373 Vocabulary::new(
16374 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
16375 [None, Some("X"), Some("Y"), Some("Z")],
16376 [None::<&str>, None, None, None],
16377 ),
16378 );
16379 let mut parser = BaseParser::new(
16380 CommonTokenStream::new(Source {
16381 tokens: vec![
16382 TestToken::new(3).with_text("z"),
16383 TestToken::eof("parser-test", 1, 1, 1),
16384 ],
16385 index: 0,
16386 }),
16387 data,
16388 );
16389 let _parent = parser.enter_rule(0, 0);
16390 let marker = parser.push_invoking_state(1);
16391 let mut child = parser.enter_rule(4, 1);
16392 parser.discard_invoking_state(marker);
16393
16394 let offending = parser.input.lt_id(1);
16397 assert!(offending.is_some(), "the 'z' token should be buffered");
16398 parser.recover_generated_rule(
16399 &mut child,
16400 &atn,
16401 AntlrError::ParserError {
16402 line: 1,
16403 column: 0,
16404 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
16405 offending,
16406 },
16407 );
16408 let tree = parser.finish_rule(child, false);
16409
16410 assert_eq!(parser.la(1), TOKEN_EOF);
16411 assert_eq!(
16412 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
16413 "(a z)"
16414 );
16415 assert_eq!(parser.number_of_syntax_errors(), 1);
16416 assert_eq!(
16417 parser.generated_parser_diagnostics,
16418 [ParserDiagnostic {
16419 line: 1,
16420 column: 0,
16421 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
16422 offending,
16423 }]
16424 );
16425 parser.exit_rule();
16426 }
16427
16428 #[test]
16429 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
16430 let atn = nested_nullable_context_atn();
16431 let mut parser = mini_parser(vec![
16432 TestToken::new(1).with_text("x"),
16433 TestToken::eof("parser-test", 1, 1, 1),
16434 ]);
16435 parser.rule_context_stack = vec![
16436 RuleContextFrame {
16437 rule_index: 0,
16438 invoking_state: 0,
16439 },
16440 RuleContextFrame {
16441 rule_index: 1,
16442 invoking_state: 1,
16443 },
16444 RuleContextFrame {
16445 rule_index: 2,
16446 invoking_state: 2,
16447 },
16448 ];
16449 parser.set_state(20);
16450 let mut context = ParserRuleContext::new(2, 2);
16451
16452 parser.recover_generated_rule(
16453 &mut context,
16454 &atn,
16455 AntlrError::NoViableAlternative {
16456 input: "'x'".to_owned(),
16457 },
16458 );
16459 assert_eq!(parser.input.index(), 0);
16460
16461 parser.set_state(21);
16462 parser.recover_generated_rule(
16463 &mut context,
16464 &atn,
16465 AntlrError::NoViableAlternative {
16466 input: "'x'".to_owned(),
16467 },
16468 );
16469 assert_eq!(parser.input.index(), 0);
16470 assert_eq!(
16471 parser.generated_recovery_error_states,
16472 BTreeSet::from([20, 21])
16473 );
16474
16475 parser.set_state(20);
16476 parser.recover_generated_rule(
16477 &mut context,
16478 &atn,
16479 AntlrError::NoViableAlternative {
16480 input: "'x'".to_owned(),
16481 },
16482 );
16483
16484 assert_eq!(parser.input.index(), 1);
16485 assert_eq!(parser.la(1), TOKEN_EOF);
16486 assert!(context.has_matched_child());
16487 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
16488
16489 parser.match_eof().expect("EOF should match");
16490 assert_eq!(parser.generated_recovery_error_index, None);
16491 assert!(parser.generated_recovery_error_states.is_empty());
16492 }
16493
16494 #[test]
16495 fn greedy_ll1_alt_handles_nullable_loop_exit() {
16496 let mut body_symbols = TokenBitSet::default();
16497 body_symbols.insert(1);
16498 let entry = DecisionLookahead {
16499 transitions: vec![
16500 TransitionLookSet {
16501 symbols: body_symbols,
16502 nullable: false,
16503 },
16504 TransitionLookSet {
16505 symbols: TokenBitSet::default(),
16506 nullable: true,
16507 },
16508 ],
16509 };
16510
16511 assert_eq!(ll1_unique_alt(&entry, 2), None);
16512 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
16513 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
16514 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
16515 }
16516
16517 #[test]
16518 fn ordinary_repetition_builds_tree_in_input_order() {
16519 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16520 let mut parser = mini_parser(repeated_x_tokens(3));
16521 let tree = parser
16522 .parse_atn_rule(&atn, 0)
16523 .expect("ordinary repetition should parse");
16524
16525 let root = parser
16526 .node(tree)
16527 .as_rule()
16528 .expect("entry result should be a rule");
16529 let body_rules = root.child_rules(1).collect::<Vec<_>>();
16530 assert_eq!(root.text(), "xxx<EOF>");
16531 assert_eq!(body_rules.len(), 3);
16532 assert_eq!(
16533 body_rules
16534 .iter()
16535 .map(|rule| rule.start_id().expect("body start").index())
16536 .collect::<Vec<_>>(),
16537 [0, 1, 2]
16538 );
16539 assert_eq!(
16540 body_rules
16541 .iter()
16542 .map(|rule| rule.stop_id().expect("body stop").index())
16543 .collect::<Vec<_>>(),
16544 [0, 1, 2]
16545 );
16546 assert_eq!(parser.number_of_syntax_errors(), 0);
16547 }
16548 }
16549
16550 #[test]
16551 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
16552 const DEPTH: usize = 20_000;
16553
16554 std::thread::Builder::new()
16555 .name("deferred-rule-materialization".to_owned())
16556 .stack_size(256 * 1024)
16557 .spawn(|| {
16558 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16559 let mut root = FastDeferredNodeId::EMPTY;
16560 for depth in 0..DEPTH {
16561 root = parser
16562 .recognition_arena
16563 .deferred_rule_node(FastDeferredRule {
16564 rule_index: u32::try_from(depth).expect("depth fits in u32"),
16565 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
16566 start_index: 0,
16567 stop_index: None,
16568 deferred_children: root,
16569 children: NodeSeqId::EMPTY,
16570 });
16571 }
16572
16573 let (mut children, alt_number) =
16574 parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
16575 assert_eq!(alt_number, 0);
16576 for expected_rule in (0..DEPTH).rev() {
16577 let mut nodes = parser.recognition_arena.iter(children);
16578 let node = nodes.next().expect("nested rule node");
16579 assert!(nodes.next().is_none(), "each rule has one child");
16580 let ArenaRecognizedNode::Rule {
16581 rule_index,
16582 children: nested,
16583 ..
16584 } = parser.recognition_arena.node(node)
16585 else {
16586 panic!("expected nested rule");
16587 };
16588 assert_eq!(rule_index as usize, expected_rule);
16589 children = nested;
16590 }
16591 assert!(children.is_empty());
16592 })
16593 .expect("small-stack thread should start")
16594 .join()
16595 .expect("deferred rules should materialize without recursion");
16596 }
16597
16598 #[test]
16599 fn deferred_alternatives_preserve_left_recursive_contexts() {
16600 let mut parser = mini_parser(vec![
16601 TestToken::new(1).with_text("1"),
16602 TestToken::new(2).with_text("+"),
16603 TestToken::new(1).with_text("2"),
16604 TestToken::eof("parser-test", 3, 1, 3),
16605 ]);
16606 let base = parser.arena_token_node(0, false);
16607 let operator = parser.arena_token_node(1, false);
16608 let right = parser.arena_token_node(2, false);
16609
16610 let base = parser.recognition_arena.prepend(NodeSeqId::EMPTY, base);
16611 let base = parser.recognition_arena.deferred_fragment(base);
16612 let operator = parser.recognition_arena.prepend(NodeSeqId::EMPTY, operator);
16613 let operator = parser.recognition_arena.deferred_fragment(operator);
16614 let right = parser.recognition_arena.prepend(NodeSeqId::EMPTY, right);
16615 let right = parser.recognition_arena.deferred_fragment(right);
16616 let base_alt = parser.recognition_arena.deferred_alternative(1);
16617 let boundary = parser.recognition_arena.deferred_left_recursive_boundary(0);
16618 let operator_alt = parser.recognition_arena.deferred_alternative(6);
16619
16620 let mut deferred = FastDeferredNodeId::EMPTY;
16621 for fragment in [base_alt, base, boundary, operator_alt, operator, right] {
16622 deferred = parser
16623 .recognition_arena
16624 .concat_deferred_nodes(deferred, fragment);
16625 }
16626 let (nodes, root_alt_number) =
16627 parser.materialize_fast_deferred_nodes(deferred, NodeSeqId::EMPTY);
16628 let nodes = parser
16629 .recognition_arena
16630 .fold_left_recursive_boundaries(nodes);
16631
16632 let mut root = ParserRuleContext::new(0, -1);
16633 root.set_context_alt_number(root_alt_number);
16634 let mut cursor = nodes;
16635 while let Some(link) = parser.recognition_arena.link(cursor) {
16636 let child = parser
16637 .arena_recognized_node_tree(link.head, false, true)
16638 .expect("materialized child should become a public tree");
16639 parser.tree.add_child(&mut root, child);
16640 cursor = link.tail;
16641 }
16642 let tree = parser.rule_node(root);
16643 let contexts = parser
16644 .node(tree)
16645 .descendants()
16646 .filter_map(Node::as_rule)
16647 .map(|rule| {
16648 (
16649 rule.rule_index(),
16650 rule.alt_number(),
16651 rule.context_alt_number(),
16652 rule.text(),
16653 )
16654 })
16655 .collect::<Vec<_>>();
16656
16657 insta::assert_debug_snapshot!(
16658 "deferred_alternatives_preserve_left_recursive_contexts",
16659 contexts
16660 );
16661 }
16662
16663 #[test]
16664 fn fast_recognizer_preserves_labeled_left_recursive_operator_context() {
16665 let atn = labeled_left_recursive_operator_atn();
16666 let mut parser = mini_parser(vec![
16667 TestToken::new(1).with_text("a"),
16668 TestToken::new(3).with_text("+"),
16669 TestToken::new(1).with_text("b"),
16670 TestToken::eof("parser-test", 3, 1, 3),
16671 ]);
16672
16673 let (tree, _) = parser
16674 .parse_atn_rule_with_runtime_options(
16675 &atn,
16676 0,
16677 ParserRuntimeOptions {
16678 track_context_alt_numbers: true,
16679 ..ParserRuntimeOptions::default()
16680 },
16681 )
16682 .expect("labeled left-recursive addition should parse");
16683 let contexts = parser
16684 .node(tree)
16685 .descendants()
16686 .filter_map(Node::as_rule)
16687 .map(|rule| {
16688 let operator = rule
16689 .children()
16690 .next()
16691 .and_then(Node::as_rule)
16692 .is_some_and(|child| child.rule_index() == rule.rule_index());
16693 (operator, rule.context_alt_number(), rule.text())
16694 })
16695 .collect::<Vec<_>>();
16696
16697 insta::assert_debug_snapshot!(
16698 "fast_recognizer_preserves_labeled_left_recursive_operator_context",
16699 contexts
16700 );
16701 assert!(!parser.recognition_arena.deferred_nodes.is_empty());
16702 assert_eq!(parser.number_of_syntax_errors(), 0);
16703 }
16704
16705 #[test]
16706 fn deeply_nested_rule_calls_grow_the_stack() {
16707 const DEPTH: usize = 4_096;
16708 const STACK_SIZE: usize = 256 * 1024;
16709 let atn = nested_rule_chain_atn(DEPTH);
16710 std::thread::Builder::new()
16711 .name("nested-adaptive-set-rules".to_owned())
16712 .stack_size(STACK_SIZE)
16713 .spawn(move || {
16714 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
16715 parser.set_build_parse_trees(false);
16716 parser.fast_first_set_prefilter = false;
16719 parser
16720 .parse_atn_rule(&atn, 0)
16721 .expect("nested rule chain should grow the native stack");
16722 assert_eq!(parser.input.index(), 1);
16723 })
16724 .expect("small-stack thread should start")
16725 .join()
16726 .expect("nested rule chain should not overflow its stack");
16727 }
16728
16729 #[test]
16730 fn deeply_nested_branching_rules_grow_the_stack() {
16731 const DEPTH: usize = 4_096;
16732 const STACK_SIZE: usize = 256 * 1024;
16733 let atn = nested_rule_graph_atn(DEPTH, true, false);
16734 std::thread::Builder::new()
16735 .name("nested-branching-rules".to_owned())
16736 .stack_size(STACK_SIZE)
16737 .spawn(move || {
16738 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
16739 parser.set_build_parse_trees(false);
16740 parser
16741 .parse_atn_rule(&atn, 0)
16742 .expect("branching rule chain should grow the native stack");
16743 assert_eq!(parser.input.index(), 1);
16744 })
16745 .expect("small-stack thread should start")
16746 .join()
16747 .expect("branching rule chain should not overflow its stack");
16748 }
16749
16750 #[test]
16751 fn deeply_nested_rule_follows_grow_the_stack() {
16752 const DEPTH: usize = 4_096;
16753 const STACK_SIZE: usize = 256 * 1024;
16754 let atn = nested_rule_graph_atn(DEPTH, false, true);
16755 std::thread::Builder::new()
16756 .name("nested-rule-follows".to_owned())
16757 .stack_size(STACK_SIZE)
16758 .spawn(move || {
16759 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
16760 parser.set_build_parse_trees(false);
16761 parser.fast_first_set_prefilter = false;
16762 parser
16763 .parse_atn_rule(&atn, 0)
16764 .expect("rule follow chain should grow the native stack");
16765 assert_eq!(parser.input.index(), DEPTH);
16766 })
16767 .expect("small-stack thread should start")
16768 .join()
16769 .expect("nested rule follow chain should not overflow its stack");
16770 }
16771
16772 #[test]
16773 fn deeply_nested_recovery_grows_the_stack() {
16774 const DEPTH: usize = 4_096;
16775 const STACK_SIZE: usize = 256 * 1024;
16776 let atn = nested_rule_chain_atn(DEPTH);
16777 std::thread::Builder::new()
16778 .name("nested-rule-recovery".to_owned())
16779 .stack_size(STACK_SIZE)
16780 .spawn(move || {
16781 let mut parser = mini_parser(vec![
16782 TestToken::new(2).with_text("z"),
16783 TestToken::new(1).with_text("x"),
16784 TestToken::eof("parser-test", 2, 1, 2),
16785 ]);
16786 parser.set_build_parse_trees(false);
16787 parser.fast_first_set_prefilter = false;
16788 parser
16789 .parse_atn_rule(&atn, 0)
16790 .expect("nested recovery should grow the native stack");
16791 assert_eq!(parser.input.index(), 2);
16792 assert_eq!(parser.number_of_syntax_errors(), 1);
16793 })
16794 .expect("small-stack thread should start")
16795 .join()
16796 .expect("nested rule recovery should not overflow its stack");
16797 }
16798
16799 #[test]
16800 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
16801 const REPETITIONS: usize = 64;
16802
16803 let atn = ambiguous_ordinary_star_loop_atn();
16804 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16805 let tree = parser
16806 .parse_atn_rule(&atn, 0)
16807 .expect("ambiguous ordinary 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(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
16814 assert_eq!(parser.input.index(), REPETITIONS);
16815 assert!(
16816 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
16817 "equivalent segmentations should keep deferred storage linear"
16818 );
16819 assert_eq!(parser.number_of_syntax_errors(), 0);
16820 }
16821
16822 #[test]
16823 fn long_ordinary_repetition_does_not_consume_native_stack() {
16824 const REPETITIONS: usize = 20_000;
16825
16826 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16827 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16828 parser.set_build_parse_trees(false);
16829 parser
16830 .parse_atn_rule(&atn, 0)
16831 .expect("long ordinary repetition should parse");
16832
16833 assert_eq!(parser.input.index(), REPETITIONS);
16834 assert_eq!(parser.number_of_syntax_errors(), 0);
16835 }
16836 }
16837
16838 #[test]
16839 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
16840 const REPETITIONS: usize = 2_000;
16841 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
16842
16843 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16844 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16845 let tree = parser
16846 .parse_atn_rule(&atn, 0)
16847 .expect("long rule repetition should parse");
16848
16849 let root = parser
16850 .node(tree)
16851 .as_rule()
16852 .expect("entry result should be a rule");
16853 assert_eq!(root.text(), expected_text);
16854 assert_eq!(root.child_rules(1).count(), REPETITIONS);
16855 let first_body = root.child_rules(1).next().expect("first body rule");
16856 let last_body = root.child_rules(1).next_back().expect("last body rule");
16857 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
16858 assert_eq!(
16859 last_body.stop_id().expect("last body stop").index(),
16860 REPETITIONS - 1
16861 );
16862
16863 let stats = parser.recognition_arena_stats();
16864 assert_eq!(
16865 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16866 (REPETITIONS, REPETITIONS, 0)
16867 );
16868 assert_eq!(
16869 (stats.total_links, stats.live_links, stats.dead_links),
16870 (REPETITIONS, REPETITIONS, 0)
16871 );
16872 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
16873 assert_eq!(
16874 parser.recognition_arena.deferred_nodes.len(),
16875 REPETITIONS * 2 - 1
16876 );
16877 assert_eq!(parser.number_of_syntax_errors(), 0);
16878 }
16879 }
16880
16881 #[test]
16882 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
16883 let key = |state_number| FastRecognizeKey {
16884 state_number,
16885 stop_state: 10,
16886 index: state_number,
16887 rule_start_index: 0,
16888 decision_start_index: None,
16889 precedence: 0,
16890 recovery_symbols_id: 0,
16891 recovery_state: None,
16892 };
16893
16894 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16895 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
16896 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
16897 }
16898 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
16899 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
16900
16901 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16902 let repeated = key(1);
16903 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
16904 assert!(promote.clean_memo_enabled_for_key(&repeated));
16905 }
16906 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
16907
16908 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
16909 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
16910 }
16911 assert!(sparse.clean_memo_enabled_for_key(&repeated));
16912 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
16913 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
16914 assert!(sparse.clean_memo_enabled_for_key(&repeated));
16915 }
16916 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
16917 }
16918
16919 #[test]
16920 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
16921 assert_eq!(
16922 fast_recognize_memo_capacity(0),
16923 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
16924 );
16925 assert_eq!(
16926 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
16927 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
16928 );
16929 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
16930 assert_eq!(
16931 fast_recognize_memo_capacity(usize::MAX),
16932 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
16933 );
16934 }
16935
16936 #[test]
16937 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
16938 let mut scratch = FastRecognizeTopScratch::default();
16939 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
16940 let retained_capacity = scratch.memo.capacity();
16941 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
16942 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16943
16944 let larger_capacity = retained_capacity + 1;
16945 scratch.prepare(larger_capacity);
16946 let grown_capacity = scratch.memo.capacity();
16947 assert!(grown_capacity >= larger_capacity);
16948 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16949
16950 scratch.memo.insert(
16951 FastRecognizeKey {
16952 state_number: 0,
16953 stop_state: 0,
16954 index: 0,
16955 rule_start_index: 0,
16956 decision_start_index: None,
16957 precedence: 0,
16958 recovery_symbols_id: 0,
16959 recovery_state: None,
16960 },
16961 Rc::from([FastRecognizeOutcome {
16962 index: 0,
16963 consumed_eof: false,
16964 diagnostics: DiagnosticSeqId::EMPTY,
16965 deferred_nodes: FastDeferredNodeId::EMPTY,
16966 nodes: NodeSeqId::EMPTY,
16967 }]),
16968 );
16969 scratch.release_oversized_memo();
16970 assert!(scratch.memo.is_empty());
16971 assert_eq!(scratch.memo.capacity(), grown_capacity);
16972
16973 scratch
16974 .memo
16975 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
16976 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16977
16978 scratch.release_oversized_memo();
16979 assert!(scratch.memo.is_empty());
16980 assert_eq!(scratch.memo.capacity(), 0);
16981 }
16982
16983 #[test]
16984 fn clean_empty_multi_alt_outcomes_are_memoized() {
16985 let mut atn = ParserAtnBuilder::new(2);
16986 assert_eq!(
16987 atn.add_state(AtnStateKind::RuleStart, Some(0))
16988 .expect("state")
16989 .index(),
16990 0
16991 );
16992 assert_eq!(
16993 atn.add_state(AtnStateKind::BlockStart, Some(0))
16994 .expect("state")
16995 .index(),
16996 1
16997 );
16998 assert_eq!(
16999 atn.add_state(AtnStateKind::RuleStop, Some(0))
17000 .expect("state")
17001 .index(),
17002 2
17003 );
17004 atn.set_rule_to_start_state(vec![0])
17005 .expect("rule start states");
17006 atn.set_rule_to_stop_state(vec![2])
17007 .expect("rule stop states");
17008 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17009 .expect("transition");
17010 atn.add_transition(
17011 1,
17012 ParserTransitionSpec::Atom {
17013 target: 2,
17014 label: 1,
17015 },
17016 )
17017 .expect("transition");
17018 atn.add_transition(
17019 1,
17020 ParserTransitionSpec::Atom {
17021 target: 2,
17022 label: 2,
17023 },
17024 )
17025 .expect("transition");
17026 let atn = finish_atn(atn);
17027
17028 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
17029 parser.fast_recovery_enabled = false;
17030 let mut visiting = FxHashSet::default();
17031 let mut memo = FxHashMap::default();
17032 let mut expected = ExpectedTokens::default();
17033 let outcomes = parser.recognize_state_fast(
17034 &atn,
17035 FastRecognizeRequest {
17036 state_number: 1,
17037 stop_state: 2,
17038 index: 0,
17039 rule_start_index: 0,
17040 decision_start_index: None,
17041 precedence: 0,
17042 depth: 0,
17043 recovery_symbols: parser.empty_recovery_symbols(),
17044 recovery_state: None,
17045 },
17046 FastRecognizeScratch {
17047 predicate_context: None,
17048 visiting: &mut visiting,
17049 memo: &mut memo,
17050 expected: &mut expected,
17051 native_depth: 0,
17052 },
17053 );
17054
17055 assert!(outcomes.is_empty());
17056 assert_eq!(memo.len(), 1);
17057 assert!(memo.values().next().expect("memo entry").is_empty());
17058
17059 parser.clean_memo_mode = CleanMemoMode::Sparse;
17060 visiting.clear();
17061 memo.clear();
17062 expected = ExpectedTokens::default();
17063 let sparse_outcomes = parser.recognize_state_fast(
17064 &atn,
17065 FastRecognizeRequest {
17066 state_number: 1,
17067 stop_state: 2,
17068 index: 0,
17069 rule_start_index: 0,
17070 decision_start_index: None,
17071 precedence: 0,
17072 depth: 0,
17073 recovery_symbols: parser.empty_recovery_symbols(),
17074 recovery_state: None,
17075 },
17076 FastRecognizeScratch {
17077 predicate_context: None,
17078 visiting: &mut visiting,
17079 memo: &mut memo,
17080 expected: &mut expected,
17081 native_depth: 0,
17082 },
17083 );
17084
17085 assert!(sparse_outcomes.is_empty());
17086 assert!(memo.is_empty());
17087 }
17088
17089 #[test]
17090 fn wildcard_matches_non_eof_only() {
17091 let mut parser = mini_parser(vec![
17092 TestToken::new(1).with_text("x"),
17093 TestToken::eof("parser-test", 1, 1, 1),
17094 ]);
17095 let matched = parser.match_wildcard().expect("wildcard");
17096 assert_eq!(parser.node(matched).text(), "x");
17097 assert!(parser.match_wildcard().is_err());
17098 }
17099
17100 #[test]
17101 fn add_parse_child_records_match_even_without_tree_building() {
17102 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17107 let token = TestToken::new(1).with_text("x");
17108
17109 parser.set_build_parse_trees(false);
17110 let mut ctx = ParserRuleContext::new(0, 0);
17111 assert!(!ctx.has_matched_child());
17112 let child = parser.terminal_tree(token.id);
17113 parser.add_parse_child(&mut ctx, child);
17114 assert_eq!(ctx.child_count(), 0);
17116 assert_eq!(parser.parse_tree_storage().node_count(), 0);
17117 assert!(ctx.has_matched_child());
17119
17120 parser.set_build_parse_trees(true);
17122 let mut ctx = ParserRuleContext::new(0, 0);
17123 let child = parser.terminal_tree(token.id);
17124 parser.add_parse_child(&mut ctx, child);
17125 assert_eq!(ctx.child_count(), 1);
17126 assert!(ctx.has_matched_child());
17127 }
17128
17129 #[test]
17130 fn disabled_tree_building_does_not_grow_flat_storage() {
17131 let mut parser = mini_parser(vec![
17132 TestToken::new(1).with_text("x"),
17133 TestToken::new(1).with_text("y"),
17134 TestToken::eof("parser-test", 2, 1, 2),
17135 ]);
17136 parser.set_build_parse_trees(false);
17137 let mut context = ParserRuleContext::new(0, -1);
17138
17139 for _ in 0..2 {
17140 let child = parser.match_token(1).expect("token should match");
17141 parser.add_parse_child(&mut context, child);
17142 }
17143 let current = parser.input.lt_id(1).expect("EOF token");
17144 let error = parser.error_tree(current);
17145 parser.add_parse_child(&mut context, error);
17146 let root = parser.rule_node(context);
17147
17148 assert_eq!(
17149 parser.parse_tree_storage().stats(),
17150 ParseTreeStats::default()
17151 );
17152 assert!(
17153 parser
17154 .parse_tree_storage()
17155 .node(parser.token_store(), root)
17156 .is_none(),
17157 "the no-tree sentinel must not resolve to stored data"
17158 );
17159 }
17160
17161 #[test]
17162 fn disabled_tree_building_skips_recognition_rule_node_storage() {
17163 let atn = ordinary_star_loop_atn();
17164 let mut parser = mini_parser(repeated_x_tokens(3));
17165 parser.set_build_parse_trees(false);
17166
17167 parser
17168 .parse_atn_rule(&atn, 0)
17169 .expect("ordinary repetition should parse without a tree");
17170
17171 assert_eq!(parser.input.index(), 3);
17172 assert!(parser.recognition_arena.nodes.is_empty());
17173 assert!(parser.recognition_arena.seq_links.is_empty());
17174 assert!(parser.recognition_arena.deferred_nodes.is_empty());
17175 assert!(parser.recognition_arena.deferred_rules.is_empty());
17176 assert!(!parser.fast_token_nodes_enabled);
17177 assert!(parser.fast_recognize_scratch.memo.is_empty());
17178 }
17179
17180 #[test]
17181 fn parser_interprets_simple_atn_rule() {
17182 let atn = 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 = parser
17189 .parse_atn_rule(&atn, 0)
17190 .expect("artificial parser rule should parse");
17191 assert_eq!(parser.node(tree).text(), "x<EOF>");
17192 assert_eq!(parser.number_of_syntax_errors(), 0);
17193 assert_eq!(
17194 parser
17195 .node(tree)
17196 .first_rule_stop(0)
17197 .expect("rule should stop at EOF")
17198 .token_type(),
17199 TOKEN_EOF
17200 );
17201
17202 let mut parser = mini_parser(vec![
17203 TestToken::new(1).with_text("x"),
17204 TestToken::eof("parser-test", 1, 1, 1),
17205 ]);
17206 let (tree, actions) = parser
17207 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17208 .expect("runtime-option parser rule should parse");
17209 assert!(actions.is_empty());
17210 assert_eq!(
17211 parser
17212 .node(tree)
17213 .first_rule_stop(0)
17214 .expect("rule should stop at EOF")
17215 .token_type(),
17216 TOKEN_EOF
17217 );
17218 }
17219
17220 #[test]
17221 fn runtime_options_default_ignores_noop_action_transitions() {
17222 let atn = noop_action_then_token_then_eof_atn();
17223 let mut parser = mini_parser(vec![
17224 TestToken::new(1).with_text("x"),
17225 TestToken::eof("parser-test", 1, 1, 1),
17226 ]);
17227
17228 let (tree, actions) = parser
17229 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17230 .expect("no-op parser action should not force action replay");
17231
17232 assert_eq!(parser.node(tree).text(), "x<EOF>");
17233 assert!(
17234 actions.is_empty(),
17235 "action_index=None transitions are ANTLR metadata, not replay actions"
17236 );
17237 assert_eq!(parser.number_of_syntax_errors(), 0);
17238 }
17239
17240 #[test]
17241 fn parser_exposes_buffered_token_stream_after_parse() {
17242 let atn = token_then_eof_atn();
17243 let mut parser = mini_parser(vec![
17244 TestToken::new(1).with_text("x"),
17245 TestToken::eof("parser-test", 1, 1, 1),
17246 ]);
17247
17248 let tree = parser
17249 .parse_atn_rule(&atn, 0)
17250 .expect("artificial parser rule should parse");
17251 assert_eq!(parser.node(tree).text(), "x<EOF>");
17252
17253 let stream = parser.token_stream();
17254 let source_index_after_parse = stream.token_source().index;
17255 let buffered = stream.tokens().collect::<Vec<_>>();
17256 assert_eq!(buffered.len(), 2);
17257 assert_eq!(buffered[0].text(), Some("x"));
17258 assert_eq!(buffered[0].token_id().index(), 0);
17259 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
17260 assert_eq!(stream.token_source().index, source_index_after_parse);
17261 drop(buffered);
17262
17263 let stream = parser.into_token_stream();
17264 assert_eq!(stream.token_source().index, source_index_after_parse);
17265 assert_eq!(
17266 stream.tokens().next().expect("first token").text(),
17267 Some("x")
17268 );
17269 assert_eq!(
17270 stream.tokens().nth(1).expect("EOF token").token_type(),
17271 TOKEN_EOF
17272 );
17273 }
17274
17275 #[test]
17276 fn parsed_file_exposes_all_buffered_tokens() {
17277 let atn = token_then_eof_atn();
17278 let mut parser = mini_parser(vec![
17279 TestToken::new(99)
17280 .with_text(" comment")
17281 .with_channel(HIDDEN_CHANNEL),
17282 TestToken::new(1).with_text("x"),
17283 TestToken::eof("parser-test", 9, 1, 9),
17284 ]);
17285
17286 let tree = parser
17287 .parse_atn_rule(&atn, 0)
17288 .expect("artificial parser rule should parse");
17289 let parsed = parser.into_parsed_file(tree);
17290
17291 insta::assert_debug_snapshot!(
17294 "parsed_file_exposes_all_buffered_tokens",
17295 parsed
17296 .tokens()
17297 .iter()
17298 .map(|token| (token.token_type(), token.channel(), token.text()))
17299 .collect::<Vec<_>>()
17300 );
17301 assert_eq!(parsed.tokens().into_iter().count(), 3);
17302 }
17303
17304 #[test]
17305 fn parser_syntax_error_count_tracks_interpreted_recovery() {
17306 let atn = token_then_eof_atn();
17307 let mut parser = mini_parser(vec![
17308 TestToken::new(1).with_text("x"),
17309 TestToken::new(2).with_text("y"),
17310 TestToken::eof("parser-test", 2, 1, 2),
17311 ]);
17312
17313 let tree = parser
17314 .parse_atn_rule(&atn, 0)
17315 .expect("invalid token should recover into an error node");
17316
17317 assert_eq!(parser.number_of_syntax_errors(), 1);
17318 assert_eq!(
17319 parser
17320 .node(tree)
17321 .first_error_token()
17322 .expect("recovery should embed an error token")
17323 .text(),
17324 Some("y")
17325 );
17326 }
17327
17328 #[test]
17329 fn failed_interpreted_parse_notifies_error_listener() {
17330 let atn = token_then_eof_atn();
17331 let mut parser = mini_parser(vec![
17332 TestToken::new(2)
17333 .with_text("y")
17334 .with_span(0, 0)
17335 .with_byte_span(0, 1)
17336 .with_position(3, 5),
17337 TestToken::eof("parser-test", 1, 1, 1),
17338 ]);
17339 parser.remove_error_listeners();
17340 let diagnostics = Arc::new(Mutex::new(Vec::new()));
17341 parser.add_error_listener(RecordingErrorListener {
17342 diagnostics: Arc::clone(&diagnostics),
17343 });
17344
17345 let error = parser
17346 .parse_atn_rule(&atn, 0)
17347 .expect_err("start-rule mismatch should remain a parser error");
17348
17349 assert_eq!(parser.number_of_syntax_errors(), 1);
17350 assert!(matches!(&error, AntlrError::ParserError { .. }));
17351 insta::assert_debug_snapshot!(
17352 "failed_interpreted_parse_notifies_error_listener",
17353 *diagnostics.lock().expect("recorded diagnostics lock")
17354 );
17355 }
17356
17357 #[test]
17358 fn adaptive_direct_rule_uses_simulator_decision() {
17359 let atn = two_alt_decision_atn();
17360 let mut simulator = ParserAtnSimulator::new(&atn);
17361 let mut parser = mini_parser(vec![
17362 TestToken::new(2).with_text("y"),
17363 TestToken::eof("parser-test", 1, 1, 1),
17364 ]);
17365
17366 let tree = parser
17367 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
17368 .expect("direct adaptive rule should parse");
17369
17370 assert_eq!(parser.node(tree).text(), "y");
17371 assert_eq!(parser.input.index(), 1);
17372 }
17373
17374 #[test]
17375 fn adaptive_direct_rule_restores_input_on_fallback() {
17376 let atn = predicate_after_token_atn();
17377 let mut simulator = ParserAtnSimulator::new(&atn);
17378 let mut parser = mini_parser(vec![
17379 TestToken::new(1).with_text("x"),
17380 TestToken::new(2).with_text("y"),
17381 TestToken::eof("parser-test", 2, 1, 2),
17382 ]);
17383
17384 let tree = parser
17385 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
17386 .expect("fallback recognizer should parse");
17387
17388 assert_eq!(parser.node(tree).text(), "xy");
17389 assert_eq!(parser.input.index(), 2);
17390 let stats = parser.parse_tree_storage().stats();
17391 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
17392 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
17393 assert_eq!(stats.scratch_links, 0);
17394 }
17395
17396 #[test]
17397 fn unknown_predicate_policy_defaults_to_assume_true() {
17398 let atn = predicate_after_token_atn();
17399 let mut parser = mini_parser(vec![
17400 TestToken::new(1).with_text("x"),
17401 TestToken::new(2).with_text("y"),
17402 TestToken::eof("parser-test", 2, 1, 2),
17403 ]);
17404
17405 let (tree, _) = parser
17406 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17407 .expect("unknown predicate should pass under the default policy");
17408
17409 assert_eq!(parser.node(tree).text(), "xy");
17410 assert_eq!(parser.number_of_syntax_errors(), 0);
17411 }
17412
17413 #[test]
17414 fn private_context_alt_tracking_keeps_fast_predicate_recognition() {
17415 let atn = predicate_gated_same_lookahead_atn([0, 1]);
17416 let mut parser = mini_parser(vec![
17417 TestToken::new(1).with_text("x"),
17418 TestToken::eof("parser-test", 1, 1, 1),
17419 ]);
17420
17421 let (tree, _) = parser
17422 .parse_atn_rule_with_runtime_options(
17423 &atn,
17424 0,
17425 ParserRuntimeOptions {
17426 predicates: &[
17427 (0, 0, ParserPredicate::False),
17428 (0, 1, ParserPredicate::True),
17429 ],
17430 track_context_alt_numbers: true,
17431 ..ParserRuntimeOptions::default()
17432 },
17433 )
17434 .expect("the second predicate-gated alternative should match");
17435
17436 let root = parser.node(tree).as_rule().expect("entry result is a rule");
17437 insta::assert_debug_snapshot!(
17438 "private_context_alt_tracking_keeps_fast_predicate_recognition",
17439 (root.alt_number(), root.context_alt_number(), root.text())
17440 );
17441 assert_eq!(parser.number_of_syntax_errors(), 0);
17442 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
17443 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
17444 }
17445
17446 #[test]
17447 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
17448 let atn = token_then_eof_atn();
17452 let mut parser = mini_parser(vec![
17453 TestToken::new(1).with_text("x"),
17454 TestToken::eof("parser-test", 1, 1, 1),
17455 ]);
17456
17457 parser.unknown_predicate_hits.push((7, 3));
17459
17460 parser
17462 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17463 .expect("child rule parses");
17464
17465 let error = parser
17467 .take_unknown_semantic_error()
17468 .expect("parent's recorded coordinate must survive the nested interpreted parse");
17469 let AntlrError::Unsupported(message) = error else {
17470 panic!("expected AntlrError::Unsupported, got {error:?}");
17471 };
17472 assert!(message.contains("pred_index=3"), "message: {message}");
17473 }
17474
17475 #[test]
17476 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
17477 let atn = predicate_after_token_atn();
17478 let mut parser = mini_parser(vec![
17479 TestToken::new(1).with_text("x"),
17480 TestToken::new(2).with_text("y"),
17481 TestToken::eof("parser-test", 2, 1, 2),
17482 ]);
17483
17484 let result = parser.parse_atn_rule_with_runtime_options(
17485 &atn,
17486 0,
17487 ParserRuntimeOptions {
17488 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
17489 ..ParserRuntimeOptions::default()
17490 },
17491 );
17492
17493 assert!(
17494 result.is_err(),
17495 "the only path is predicate-guarded, so assume-false must fail the parse"
17496 );
17497 }
17498
17499 #[test]
17500 fn predicate_failure_message_keeps_semantic_recovery_path() {
17501 let atn = predicate_after_token_atn();
17502 let mut parser = mini_parser(vec![
17503 TestToken::new(1).with_text("x"),
17504 TestToken::new(2).with_text("y"),
17505 TestToken::eof("parser-test", 2, 1, 2),
17506 ]);
17507
17508 let (tree, _) = parser
17509 .parse_atn_rule_with_runtime_options(
17510 &atn,
17511 0,
17512 ParserRuntimeOptions {
17513 predicates: &[(
17514 0,
17515 0,
17516 ParserPredicate::FalseWithMessage {
17517 message: "predicate rejected input",
17518 },
17519 )],
17520 ..ParserRuntimeOptions::default()
17521 },
17522 )
17523 .expect("failure-message predicates recover through the semantic interpreter");
17524
17525 assert_eq!(parser.node(tree).text(), "xy");
17526 assert_eq!(parser.number_of_syntax_errors(), 1);
17527 assert!(
17528 parser.fast_predicate_cache.is_empty(),
17529 "failure-message predicates need the semantic interpreter's recovery outcome"
17530 );
17531 }
17532
17533 #[test]
17534 fn unknown_predicate_policy_error_names_the_coordinate() {
17535 let atn = predicate_after_token_atn();
17536 let mut parser = mini_parser(vec![
17537 TestToken::new(1).with_text("x"),
17538 TestToken::new(2).with_text("y"),
17539 TestToken::eof("parser-test", 2, 1, 2),
17540 ]);
17541
17542 let error = parser
17543 .parse_atn_rule_with_runtime_options(
17544 &atn,
17545 0,
17546 ParserRuntimeOptions {
17547 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17548 ..ParserRuntimeOptions::default()
17549 },
17550 )
17551 .expect_err("evaluating an unknown predicate under Error policy must fail");
17552
17553 let AntlrError::Unsupported(message) = error else {
17554 panic!("expected AntlrError::Unsupported, got {error:?}");
17555 };
17556 assert!(
17557 message.contains("unsupported semantic predicate"),
17558 "message should name the failure class: {message}"
17559 );
17560 assert!(
17561 message.contains("pred_index=0"),
17562 "message should carry the coordinate: {message}"
17563 );
17564 }
17565
17566 #[test]
17567 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
17568 let atn = predicate_after_token_atn();
17574 let mut parser = mini_parser(vec![
17575 TestToken::new(1).with_text("x"),
17576 TestToken::new(2).with_text("y"),
17577 TestToken::eof("parser-test", 2, 1, 2),
17578 ]);
17579
17580 parser
17581 .parse_atn_rule_with_runtime_options(
17582 &atn,
17583 0,
17584 ParserRuntimeOptions {
17585 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17586 ..ParserRuntimeOptions::default()
17587 },
17588 )
17589 .expect_err("first parse fails loud under the Error policy");
17590
17591 parser.reset_unknown_semantic_hits();
17596 assert!(
17597 parser.take_unknown_semantic_error().is_none(),
17598 "reset must drop stale unknown-predicate coordinates before a reused parse"
17599 );
17600 }
17601
17602 #[derive(Debug, Default)]
17603 struct RecordingHooks {
17604 predicates: Vec<(usize, usize, usize, Option<String>)>,
17605 actions: Vec<(usize, String, Option<String>)>,
17606 action_trees: Vec<Option<String>>,
17607 }
17608
17609 impl SemanticHooks for RecordingHooks {
17610 fn sempred<S>(
17611 &mut self,
17612 ctx: &mut ParserSemCtx<'_, S>,
17613 rule_index: usize,
17614 pred_index: usize,
17615 ) -> Option<bool>
17616 where
17617 S: TokenSource,
17618 {
17619 self.predicates.push((
17620 ctx.input_index(),
17621 rule_index,
17622 pred_index,
17623 ctx.token_text(1)
17624 .and_then(|token| token.text().map(str::to_owned)),
17625 ));
17626 Some(true)
17627 }
17628
17629 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
17630 where
17631 S: TokenSource,
17632 {
17633 self.actions.push((
17634 action.source_state(),
17635 ctx.action_text(),
17636 ctx.rule_name().map(str::to_owned),
17637 ));
17638 self.action_trees.push(ctx.tree().map(Node::text));
17639 true
17640 }
17641 }
17642
17643 #[derive(Debug, Default)]
17644 struct RejectingPredicateHooks {
17645 predicates: Vec<(usize, usize, usize, Option<String>)>,
17646 }
17647
17648 impl SemanticHooks for RejectingPredicateHooks {
17649 fn sempred<S>(
17650 &mut self,
17651 ctx: &mut ParserSemCtx<'_, S>,
17652 rule_index: usize,
17653 pred_index: usize,
17654 ) -> Option<bool>
17655 where
17656 S: TokenSource,
17657 {
17658 self.predicates.push((
17659 ctx.input_index(),
17660 rule_index,
17661 pred_index,
17662 ctx.token_text(1)
17663 .and_then(|token| token.text().map(str::to_owned)),
17664 ));
17665 Some(false)
17666 }
17667 }
17668
17669 #[test]
17670 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
17671 let atn = predicate_gated_same_lookahead_atn([0, 0]);
17672 let mut parser = mini_parser_with_hooks(
17673 vec![
17674 TestToken::new(1).with_text("x"),
17675 TestToken::eof("parser-test", 1, 1, 1),
17676 ],
17677 RecordingHooks::default(),
17678 );
17679
17680 let (tree, _) = parser
17681 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17682 .expect("both alternatives share one replay-safe predicate result");
17683
17684 assert_eq!(parser.node(tree).text(), "x<EOF>");
17685 assert_eq!(
17686 parser.semantic_hooks.predicates,
17687 vec![(0, 0, 0, Some("x".to_owned()))]
17688 );
17689 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
17690 }
17691
17692 #[test]
17693 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
17694 let atn = predicate_after_token_atn();
17695 let mut parser = mini_parser_with_hooks(
17696 vec![
17697 TestToken::new(1).with_text("x"),
17698 TestToken::new(2).with_text("y"),
17699 TestToken::eof("parser-test", 2, 1, 2),
17700 ],
17701 RecordingHooks::default(),
17702 );
17703
17704 let (tree, _) = parser
17705 .parse_atn_rule_with_runtime_options(
17706 &atn,
17707 0,
17708 ParserRuntimeOptions {
17709 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17710 ..ParserRuntimeOptions::default()
17711 },
17712 )
17713 .expect("hook supplies the missing predicate result");
17714
17715 assert_eq!(parser.node(tree).text(), "xy");
17716 assert_eq!(
17717 parser.semantic_hooks.predicates,
17718 vec![(1, 0, 0, Some("y".to_owned()))]
17719 );
17720 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
17721 }
17722
17723 #[test]
17724 fn runtime_options_default_preserves_semantic_hook_predicates() {
17725 let atn = predicate_after_token_atn();
17726 let mut parser = mini_parser_with_hooks(
17727 vec![
17728 TestToken::new(1).with_text("x"),
17729 TestToken::new(2).with_text("y"),
17730 TestToken::eof("parser-test", 2, 1, 2),
17731 ],
17732 RejectingPredicateHooks::default(),
17733 );
17734
17735 let result =
17736 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
17737
17738 assert!(
17739 result.is_err(),
17740 "default runtime options must not bypass semantic hooks for predicate ATNs"
17741 );
17742 assert_eq!(
17743 parser.semantic_hooks.predicates,
17744 vec![(1, 0, 0, Some("y".to_owned()))]
17745 );
17746 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
17747 }
17748
17749 #[test]
17750 fn semantic_hook_handles_committed_parser_action() {
17751 let atn = token_then_eof_atn();
17752 let mut parser = mini_parser_with_hooks(
17753 vec![
17754 TestToken::new(1).with_text("x"),
17755 TestToken::eof("parser-test", 1, 1, 1),
17756 ],
17757 RecordingHooks::default(),
17758 );
17759 let (tree, _) = parser
17760 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17761 .expect("rule parses before action hook is tested");
17762
17763 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17764 assert_eq!(
17765 parser.semantic_hooks.actions,
17766 vec![(42, "x".to_owned(), Some("s".to_owned()))]
17767 );
17768 assert_eq!(
17769 parser.semantic_hooks.action_trees,
17770 [Some("x<EOF>".to_owned())]
17771 );
17772 }
17773
17774 #[test]
17775 fn unhandled_committed_action_fails_loud_under_error_policy() {
17776 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17780 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
17781 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
17782
17783 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17785
17786 let error = parser
17787 .take_unknown_semantic_error()
17788 .expect("an unhandled committed action under Error policy must fail loud");
17789 let AntlrError::Unsupported(message) = error else {
17790 panic!("expected AntlrError::Unsupported, got {error:?}");
17791 };
17792 assert!(
17793 message.contains("unhandled semantic action") && message.contains("state=42"),
17794 "message should name the dropped action coordinate: {message}"
17795 );
17796
17797 let mut lenient =
17799 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17800 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
17801 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17802 assert!(lenient.take_unknown_semantic_error().is_none());
17803 }
17804
17805 #[test]
17806 fn translated_predicate_is_unaffected_by_error_policy() {
17807 let atn = predicate_after_token_atn();
17808 let mut parser = mini_parser(vec![
17809 TestToken::new(1).with_text("x"),
17810 TestToken::new(2).with_text("y"),
17811 TestToken::eof("parser-test", 2, 1, 2),
17812 ]);
17813
17814 let (tree, _) = parser
17815 .parse_atn_rule_with_runtime_options(
17816 &atn,
17817 0,
17818 ParserRuntimeOptions {
17819 predicates: &[(0, 0, ParserPredicate::True)],
17820 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17821 ..ParserRuntimeOptions::default()
17822 },
17823 )
17824 .expect("a predicate covered by the table is not an unknown coordinate");
17825
17826 assert_eq!(parser.node(tree).text(), "xy");
17827 }
17828
17829 #[test]
17834 fn parser_speculative_replay_threads_stack_member_state() {
17835 let mut ir = SemIr::new();
17836 let one = ir.expr(PExpr::Int(1));
17837 let push = ir.stmt(AStmt::PushMember(0, one));
17838 let pop = ir.stmt(AStmt::PopMember(0));
17839 let semantics = ParserSemantics {
17840 ir,
17841 predicates: Vec::new(),
17842 actions: vec![
17843 ParserSemanticAction {
17844 source_state: 1,
17845 rule_index: usize::MAX,
17846 stmt: push,
17847 speculative: true,
17848 },
17849 ParserSemanticAction {
17850 source_state: 2,
17851 rule_index: usize::MAX,
17852 stmt: pop,
17853 speculative: true,
17854 },
17855 ],
17856 };
17857
17858 let pushed = member_values_after_action(1, &[], Some(&semantics), &MemberEnv::new());
17860 assert_eq!(pushed.stack_top(0), Some(1));
17861 assert_eq!(pushed.stack_len(0), 1);
17862
17863 assert_eq!(MemberEnv::new().stack_len(0), 0);
17866
17867 let popped = member_values_after_action(2, &[], Some(&semantics), &pushed);
17870 assert_eq!(popped.stack_top(0), None);
17871 assert_eq!(popped, MemberEnv::new(), "emptied stack must canonicalize");
17872
17873 let underflowed = member_values_after_action(2, &[], Some(&semantics), &MemberEnv::new());
17875 assert_eq!(underflowed, MemberEnv::new());
17876 }
17877
17878 fn hook_predicate_semantics() -> ParserSemantics {
17883 let mut ir = SemIr::new();
17884 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
17885 ParserSemantics {
17886 ir,
17887 predicates: vec![ParserSemanticPredicate {
17888 rule_index: 0,
17889 pred_index: 0,
17890 expr,
17891 failure_message: None,
17892 }],
17893 actions: Vec::new(),
17894 }
17895 }
17896
17897 #[derive(Debug, Default)]
17898 struct DecliningHooks;
17899
17900 impl SemanticHooks for DecliningHooks {}
17901
17902 #[test]
17903 fn semir_hook_none_falls_through_to_assume_true() {
17904 let atn = predicate_after_token_atn();
17905 let semantics = hook_predicate_semantics();
17906 let mut parser = mini_parser_with_hooks(
17907 vec![
17908 TestToken::new(1).with_text("x"),
17909 TestToken::new(2).with_text("y"),
17910 TestToken::eof("parser-test", 2, 1, 2),
17911 ],
17912 DecliningHooks,
17913 );
17914
17915 let (tree, _) = parser
17916 .parse_atn_rule_with_runtime_options(
17917 &atn,
17918 0,
17919 ParserRuntimeOptions {
17920 semantics: Some(&semantics),
17921 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
17922 ..ParserRuntimeOptions::default()
17923 },
17924 )
17925 .expect("a declined SemIR hook must pass under assume-true");
17926
17927 assert_eq!(parser.node(tree).text(), "xy");
17928 }
17929
17930 #[test]
17931 fn semir_hook_none_falls_through_to_assume_false() {
17932 let atn = predicate_after_token_atn();
17933 let semantics = hook_predicate_semantics();
17934 let mut parser = mini_parser_with_hooks(
17935 vec![
17936 TestToken::new(1).with_text("x"),
17937 TestToken::new(2).with_text("y"),
17938 TestToken::eof("parser-test", 2, 1, 2),
17939 ],
17940 DecliningHooks,
17941 );
17942
17943 let result = parser.parse_atn_rule_with_runtime_options(
17944 &atn,
17945 0,
17946 ParserRuntimeOptions {
17947 semantics: Some(&semantics),
17948 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
17949 ..ParserRuntimeOptions::default()
17950 },
17951 );
17952
17953 assert!(
17954 result.is_err(),
17955 "a declined SemIR hook must fail the only guarded path under assume-false"
17956 );
17957 }
17958
17959 #[test]
17960 fn semir_hook_none_records_coordinate_under_error_policy() {
17961 let atn = predicate_after_token_atn();
17962 let semantics = hook_predicate_semantics();
17963 let mut parser = mini_parser_with_hooks(
17964 vec![
17965 TestToken::new(1).with_text("x"),
17966 TestToken::new(2).with_text("y"),
17967 TestToken::eof("parser-test", 2, 1, 2),
17968 ],
17969 DecliningHooks,
17970 );
17971
17972 let error = parser
17973 .parse_atn_rule_with_runtime_options(
17974 &atn,
17975 0,
17976 ParserRuntimeOptions {
17977 semantics: Some(&semantics),
17978 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17979 ..ParserRuntimeOptions::default()
17980 },
17981 )
17982 .expect_err("a declined SemIR hook under Error policy must fail the parse");
17983
17984 let AntlrError::Unsupported(message) = error else {
17985 panic!("expected AntlrError::Unsupported, got {error:?}");
17986 };
17987 assert!(
17988 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
17989 "message should name the unresolved coordinate: {message}"
17990 );
17991 }
17992
17993 #[test]
17994 fn generated_direct_predicate_honors_installed_policy() {
17995 let semantics = hook_predicate_semantics();
18001 let context = ParserRuleContext::new(0, -1);
18002
18003 let mut assume_true =
18004 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
18005 assert!(
18006 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
18007 &semantics, 0, 0, &context, 0
18008 ),
18009 "default AssumeTrue accepts a declined hook"
18010 );
18011 assert!(assume_true.take_unknown_semantic_error().is_none());
18012
18013 let mut error_policy =
18014 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
18015 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
18016 assert!(
18017 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
18018 &semantics, 0, 0, &context, 0
18019 ),
18020 "Error policy rejects a declined hook on the generated-direct path"
18021 );
18022 let error = error_policy
18023 .take_unknown_semantic_error()
18024 .expect("Error policy records the unresolved coordinate for the generated path");
18025 let AntlrError::Unsupported(message) = error else {
18026 panic!("expected AntlrError::Unsupported, got {error:?}");
18027 };
18028 assert!(message.contains("pred_index=0"), "message: {message}");
18029 }
18030
18031 #[test]
18032 fn parser_rule_start_skips_leading_hidden_tokens() {
18033 let atn = token_then_eof_atn();
18034 let mut parser = mini_parser(vec![
18035 TestToken::new(99)
18036 .with_text(" ")
18037 .with_channel(HIDDEN_CHANNEL),
18038 TestToken::new(1).with_text("x"),
18039 TestToken::eof("parser-test", 2, 1, 2),
18040 ]);
18041
18042 let tree = parser
18043 .parse_atn_rule(&atn, 0)
18044 .expect("artificial parser rule should parse");
18045 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
18046 panic!("rule node should be present");
18047 };
18048 assert_eq!(
18049 rule.start()
18050 .expect("rule should have a start token")
18051 .token_type(),
18052 1
18053 );
18054 }
18055
18056 #[test]
18057 fn parser_action_after_eof_stops_at_eof_token() {
18058 let atn = eof_then_action_atn();
18059 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
18060
18061 let (_, actions) = parser
18062 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
18063 .expect("EOF action rule should parse");
18064
18065 assert_eq!(actions.len(), 1);
18066 assert_eq!(actions[0].stop_index(), Some(0));
18067 assert_eq!(
18068 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
18069 ""
18070 );
18071 }
18072
18073 #[test]
18074 fn after_action_stop_uses_rule_context_stop_not_cursor() {
18075 let mut id = TestToken::new(1).with_text("x");
18080 id.set_token_index(0);
18081 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
18082 eof.set_token_index(1);
18083 let mut parser = mini_parser(vec![id.clone(), eof]);
18084 parser.consume();
18086 assert_eq!(parser.la(1), TOKEN_EOF);
18087
18088 let mut ctx = ParserRuleContext::new(0, 0);
18091 parser.set_context_stop(
18092 &mut ctx,
18093 parser.token_id_at(0).expect("ID token should be buffered"),
18094 );
18095 let tree = parser.rule_node(ctx);
18096
18097 let current_index = parser.input.index();
18098 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
18100 assert_eq!(
18102 parser.after_action_stop_index_for_tree(tree, current_index),
18103 Some(0)
18104 );
18105 }
18106
18107 #[test]
18108 fn after_action_start_uses_rule_context_start_not_cursor() {
18109 let mut parser = mini_parser(vec![
18114 TestToken::new(9)
18115 .with_text(" ")
18116 .with_channel(HIDDEN_CHANNEL),
18117 TestToken::new(9)
18118 .with_text(" ")
18119 .with_channel(HIDDEN_CHANNEL),
18120 TestToken::new(1).with_text("x"),
18121 TestToken::eof("parser-test", 3, 1, 3),
18122 ]);
18123
18124 let mut ctx = ParserRuleContext::new(0, 0);
18125 parser.set_context_start(
18126 &mut ctx,
18127 parser.token_id_at(2).expect("ID token should be buffered"),
18128 );
18129 let tree = parser.rule_node(ctx);
18130
18131 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
18134
18135 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
18137 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
18138 }
18139
18140 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
18141 FastRecognizeOutcome {
18142 index,
18143 consumed_eof,
18144 diagnostics: DiagnosticSeqId::EMPTY,
18145 deferred_nodes: FastDeferredNodeId::EMPTY,
18146 nodes: NodeSeqId(marker),
18147 }
18148 }
18149
18150 #[test]
18151 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
18152 let mut outcomes = vec![
18153 clean_fast_outcome(4, false, 0),
18154 clean_fast_outcome(2, false, 1),
18155 clean_fast_outcome(4, false, 2),
18156 clean_fast_outcome(4, true, 3),
18157 clean_fast_outcome(2, false, 4),
18158 ];
18159 let mut scratch = FastOutcomeDedupScratch::default();
18160
18161 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
18162
18163 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
18164 assert_eq!(
18165 outcomes
18166 .iter()
18167 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
18168 .collect::<Vec<_>>(),
18169 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
18170 );
18171 assert!(scratch.dense_words.is_empty());
18172 assert!(scratch.sparse_keys.is_empty());
18173 }
18174
18175 #[test]
18176 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
18177 let mut scratch = FastOutcomeDedupScratch::default();
18178 let mut outcomes = (100..109)
18179 .flat_map(|index| {
18180 [
18181 clean_fast_outcome(
18182 index,
18183 false,
18184 u32::try_from(index).expect("test index fits in u32"),
18185 ),
18186 clean_fast_outcome(index, false, u32::MAX),
18187 ]
18188 })
18189 .collect();
18190
18191 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
18192
18193 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
18194 assert_eq!(outcomes.len(), 9);
18195 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
18196 let dense_capacity = scratch.dense_words.capacity();
18197
18198 let mut reused = (1_000..1_009)
18199 .map(|index| {
18200 clean_fast_outcome(
18201 index,
18202 false,
18203 u32::try_from(index).expect("test index fits in u32"),
18204 )
18205 })
18206 .collect();
18207 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
18208
18209 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
18210 assert_eq!(reused.len(), 9);
18211 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
18212 }
18213
18214 #[test]
18215 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
18216 let mut scratch = FastOutcomeDedupScratch::default();
18217 let sparse_indexes = [
18218 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
18219 ];
18220 let mut outcomes = sparse_indexes
18221 .into_iter()
18222 .chain([400_000])
18223 .enumerate()
18224 .map(|(marker, index)| {
18225 clean_fast_outcome(
18226 index,
18227 false,
18228 u32::try_from(marker).expect("test marker fits in u32"),
18229 )
18230 })
18231 .collect();
18232
18233 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
18234
18235 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
18236 assert_eq!(outcomes.len(), sparse_indexes.len());
18237 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
18238 let sparse_capacity = scratch.sparse_keys.capacity();
18239
18240 let mut reused = sparse_indexes
18241 .into_iter()
18242 .map(|index| {
18243 clean_fast_outcome(
18244 index,
18245 false,
18246 u32::try_from(index).expect("test index fits in u32"),
18247 )
18248 })
18249 .collect();
18250 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
18251
18252 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
18253 assert_eq!(reused.len(), sparse_indexes.len());
18254 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
18255 }
18256
18257 #[test]
18258 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
18259 let mut scratch = FastOutcomeDedupScratch::default();
18260 scratch
18261 .sparse_keys
18262 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
18263 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
18264 let mut outcomes = (0..9)
18265 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
18266 .collect();
18267
18268 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
18269
18270 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
18271 assert!(scratch.sparse_keys.is_empty());
18272 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
18273 }
18274
18275 #[test]
18276 fn fast_outcome_selection_respects_sll_tie_order() {
18277 let mut arena = RecognitionArena::default();
18278 let first = FastRecognizeOutcome {
18279 index: 1,
18280 consumed_eof: false,
18281 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18282 line: 1,
18283 column: 0,
18284 message: "mismatched input 'x'".to_owned(),
18285 offending: None,
18286 }]),
18287 deferred_nodes: FastDeferredNodeId::EMPTY,
18288 nodes: NodeSeqId::EMPTY,
18289 };
18290 let second = FastRecognizeOutcome {
18291 index: first.index,
18292 consumed_eof: first.consumed_eof,
18293 diagnostics: DiagnosticSeqId::EMPTY,
18294 deferred_nodes: FastDeferredNodeId::EMPTY,
18295 nodes: NodeSeqId::EMPTY,
18296 };
18297
18298 let selected = select_best_fast_outcome(
18299 [first, second].into_iter(),
18300 PredictionMode::Sll,
18301 None,
18302 |_| panic!("caller-follow token probe should not run"),
18303 &arena,
18304 )
18305 .expect("one outcome should be selected");
18306 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
18307 let eof_second = FastRecognizeOutcome {
18308 index: second.index,
18309 consumed_eof: true,
18310 diagnostics: DiagnosticSeqId::EMPTY,
18311 deferred_nodes: FastDeferredNodeId::EMPTY,
18312 nodes: NodeSeqId::EMPTY,
18313 };
18314 let selected = select_best_fast_outcome(
18315 [first, eof_second].into_iter(),
18316 PredictionMode::Sll,
18317 None,
18318 |_| panic!("caller-follow token probe should not run"),
18319 &arena,
18320 )
18321 .expect("one outcome should be selected");
18322 assert!(!selected.consumed_eof);
18323 let selected = select_best_fast_outcome(
18324 [first, second].into_iter(),
18325 PredictionMode::Ll,
18326 None,
18327 |_| panic!("caller-follow token probe should not run"),
18328 &arena,
18329 )
18330 .expect("one outcome should be selected");
18331 assert!(selected.diagnostics.is_empty());
18332 }
18333
18334 #[test]
18335 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
18336 let mut arena = RecognitionArena::default();
18337 let first = FastRecognizeOutcome {
18338 index: 3,
18339 consumed_eof: false,
18340 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18341 line: 1,
18342 column: 0,
18343 message: "mismatched input 'x' expecting 'a'".to_owned(),
18344 offending: None,
18345 }]),
18346 deferred_nodes: FastDeferredNodeId::EMPTY,
18347 nodes: NodeSeqId::EMPTY,
18348 };
18349 let same_rank = FastRecognizeOutcome {
18350 index: first.index,
18351 consumed_eof: first.consumed_eof,
18352 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18353 line: 1,
18354 column: 0,
18355 message: "mismatched input 'x' expecting 'b'".to_owned(),
18356 offending: None,
18357 }]),
18358 deferred_nodes: FastDeferredNodeId::EMPTY,
18359 nodes: NodeSeqId::EMPTY,
18360 };
18361 let better_rank = FastRecognizeOutcome {
18362 index: first.index,
18363 consumed_eof: first.consumed_eof,
18364 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18365 line: 1,
18366 column: 0,
18367 message: "missing 'a' at 'x'".to_owned(),
18368 offending: None,
18369 }]),
18370 deferred_nodes: FastDeferredNodeId::EMPTY,
18371 nodes: NodeSeqId::EMPTY,
18372 };
18373 let mut outcomes = vec![first, same_rank, better_rank];
18374
18375 dedupe_fast_outcomes(&mut outcomes, &arena);
18376
18377 assert_eq!(outcomes.len(), 2);
18378 assert_eq!(
18379 arena
18380 .diagnostics(outcomes[0].diagnostics)
18381 .next()
18382 .expect("first diagnostic")
18383 .message,
18384 "mismatched input 'x' expecting 'a'"
18385 );
18386 assert_eq!(
18387 arena
18388 .diagnostics(outcomes[1].diagnostics)
18389 .next()
18390 .expect("second diagnostic")
18391 .message,
18392 "missing 'a' at 'x'"
18393 );
18394 }
18395
18396 #[test]
18397 fn fast_outcome_selection_prefers_generated_caller_follow() {
18398 let arena = RecognitionArena::default();
18399 let earlier = FastRecognizeOutcome {
18400 index: 7,
18401 consumed_eof: false,
18402 diagnostics: DiagnosticSeqId::EMPTY,
18403 deferred_nodes: FastDeferredNodeId::EMPTY,
18404 nodes: NodeSeqId::EMPTY,
18405 };
18406 let later = FastRecognizeOutcome {
18407 index: 8,
18408 consumed_eof: false,
18409 diagnostics: DiagnosticSeqId::EMPTY,
18410 deferred_nodes: FastDeferredNodeId::EMPTY,
18411 nodes: NodeSeqId::EMPTY,
18412 };
18413 let mut follow = TokenBitSet::default();
18414 follow.insert(5);
18415
18416 let selected = select_best_fast_outcome(
18417 [later, earlier].into_iter(),
18418 PredictionMode::Ll,
18419 Some(&follow),
18420 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
18421 &arena,
18422 )
18423 .expect("one outcome should be selected");
18424 assert_eq!(selected.index, 7);
18425
18426 let selected = select_best_fast_outcome(
18427 [later, earlier].into_iter(),
18428 PredictionMode::Ll,
18429 Some(&follow),
18430 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
18431 &arena,
18432 )
18433 .expect("one outcome should be selected");
18434 assert_eq!(selected.index, 8);
18435
18436 let indented_next_statement = FastRecognizeOutcome {
18437 index: 9,
18438 consumed_eof: false,
18439 diagnostics: DiagnosticSeqId::EMPTY,
18440 deferred_nodes: FastDeferredNodeId::EMPTY,
18441 nodes: NodeSeqId::EMPTY,
18442 };
18443 let selected = select_best_fast_outcome(
18444 [indented_next_statement, earlier].into_iter(),
18445 PredictionMode::Ll,
18446 Some(&follow),
18447 |index| {
18448 let is_boundary = index == 7;
18449 let is_boundary_gap = matches!(index, 7 | 8);
18450 (
18451 if index == 7 { 5 } else { TOKEN_EOF },
18452 is_boundary,
18453 is_boundary_gap,
18454 )
18455 },
18456 &arena,
18457 )
18458 .expect("one outcome should be selected");
18459 assert_eq!(selected.index, 7);
18460
18461 let continuation = FastRecognizeOutcome {
18462 index: 10,
18463 consumed_eof: false,
18464 diagnostics: DiagnosticSeqId::EMPTY,
18465 deferred_nodes: FastDeferredNodeId::EMPTY,
18466 nodes: NodeSeqId::EMPTY,
18467 };
18468 let selected = select_best_fast_outcome(
18469 [continuation, earlier].into_iter(),
18470 PredictionMode::Ll,
18471 Some(&follow),
18472 |index| {
18473 let is_boundary = matches!(index, 7 | 9);
18474 (
18475 if index == 7 { 5 } else { TOKEN_EOF },
18476 is_boundary,
18477 is_boundary,
18478 )
18479 },
18480 &arena,
18481 )
18482 .expect("one outcome should be selected");
18483 assert_eq!(selected.index, 10);
18484
18485 let selected = select_best_fast_outcome(
18486 [earlier, later].into_iter(),
18487 PredictionMode::Sll,
18488 Some(&follow),
18489 |_| panic!("caller-follow token probe should not run in SLL mode"),
18490 &arena,
18491 )
18492 .expect("one outcome should be selected");
18493 assert_eq!(selected.index, 8);
18494 }
18495
18496 #[test]
18497 fn caller_follow_boundary_text_requires_separator_shape() {
18498 assert!(is_caller_follow_boundary_text(";"));
18499 assert!(is_caller_follow_boundary_text("\n"));
18500 assert!(is_caller_follow_boundary_text("\r\n "));
18501 assert!(is_caller_follow_boundary_text(";\n"));
18502 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
18503 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
18504 assert!(!is_caller_follow_boundary_text("identifier"));
18505 assert!(is_caller_follow_boundary_gap_text(" \t "));
18506 assert!(is_caller_follow_boundary_gap_text("\n "));
18507 assert!(is_caller_follow_boundary_gap_text(";\t"));
18508 assert!(!is_caller_follow_boundary_gap_text(
18509 "\"\"\"line1\nline2\"\"\""
18510 ));
18511 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
18512 }
18513
18514 #[test]
18515 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
18516 let mut parser = mini_parser(vec![
18517 TestToken::new(5).with_text("\n"),
18518 TestToken::new(6)
18519 .with_text("// comment\n")
18520 .with_channel(HIDDEN_CHANNEL),
18521 TestToken::new(1).with_text("x"),
18522 TestToken::eof("parser-test", 1, 2, 0),
18523 ]);
18524
18525 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
18526 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
18527 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
18528 }
18529
18530 #[test]
18531 fn caller_follow_token_info_uses_stream_visible_channel() {
18532 let source = Source {
18533 tokens: vec![
18534 TestToken::new(5).with_text("\n").with_channel(2),
18535 TestToken::new(1).with_text("x").with_channel(2),
18536 TestToken::new(6)
18537 .with_text("// comment\n")
18538 .with_channel(HIDDEN_CHANNEL),
18539 TestToken::eof("parser-test", 1, 2, 0),
18540 ],
18541 index: 0,
18542 };
18543 let data = RecognizerData::new(
18544 "Mini.g4",
18545 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18546 );
18547 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
18548
18549 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
18550 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
18551 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
18552 }
18553
18554 #[test]
18555 fn reset_per_parse_caches_clears_state_expected_token_cache() {
18556 let atn = token_then_eof_atn();
18557 let mut parser = mini_parser(Vec::new());
18558
18559 let _ = parser.cached_state_expected_token_set(&atn, 0);
18560 assert!(!parser.state_expected_token_cache.is_empty());
18561
18562 parser.reset_per_parse_caches();
18563 assert!(parser.state_expected_token_cache.is_empty());
18564 }
18565
18566 #[test]
18567 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
18568 let cyclic = epsilon_cycle_atn();
18569 let acyclic = token_then_eof_atn();
18570 let mut parser = mini_parser(Vec::new());
18571
18572 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
18573 assert_eq!(
18574 parser.empty_cycle_cache_atn,
18575 Some(SharedAtnCacheKey::for_atn(&cyclic))
18576 );
18577 assert_eq!(parser.empty_cycle_cache[1], Some(true));
18578
18579 parser.reset_per_parse_caches();
18580 assert_eq!(parser.empty_cycle_cache[1], Some(true));
18581 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
18582
18583 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
18584 assert_eq!(
18585 parser.empty_cycle_cache_atn,
18586 Some(SharedAtnCacheKey::for_atn(&acyclic))
18587 );
18588 assert_eq!(parser.empty_cycle_cache[1], Some(false));
18589 }
18590
18591 #[test]
18592 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
18593 let source = Source {
18594 tokens: vec![
18595 TestToken::new(1).with_text("x"),
18596 TestToken::eof("parser-test", 1, 1, 1),
18597 ],
18598 index: 0,
18599 };
18600 let data = RecognizerData::new(
18601 "Mini.g4",
18602 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18603 );
18604 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
18605 let expected = ExpectedTokens {
18606 index: Some(0),
18607 symbols: BTreeSet::new(),
18608 no_viable: None,
18609 };
18610
18611 let (_, message) = parser.expected_error_message(0, 0, &expected);
18612
18613 assert_eq!(message, "mismatched input 'x'");
18614 }
18615
18616 #[test]
18617 fn eof_rule_stop_index_points_at_eof_token() {
18618 let source = Source {
18619 tokens: vec![
18620 TestToken::new(1).with_text("x"),
18621 TestToken::eof("parser-test", 1, 1, 1),
18622 ],
18623 index: 0,
18624 };
18625 let data = RecognizerData::new(
18626 "Mini.g4",
18627 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18628 );
18629 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
18630
18631 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
18632 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
18633 }
18634
18635 #[test]
18636 fn generated_parser_action_uses_current_rule_stop_boundary() {
18637 let mut parser = mini_parser(vec![
18638 TestToken::new(1).with_text("x"),
18639 TestToken::eof("parser-test", 1, 1, 1),
18640 ]);
18641
18642 parser.match_token(1).expect("token should match");
18643 let action = parser.parser_action_at_current(7, 0, 0, false);
18644 assert_eq!(action.source_state(), 7);
18645 assert_eq!(action.rule_index(), 0);
18646 assert_eq!(action.start_index(), 0);
18647 assert_eq!(action.stop_index(), Some(0));
18648
18649 parser.match_eof().expect("EOF should match");
18650 let action = parser.parser_action_at_current(8, 0, 0, true);
18651 assert_eq!(action.stop_index(), Some(1));
18652 }
18653
18654 #[test]
18655 fn folds_left_recursive_boundary_into_rule_node() {
18656 let mut arena = RecognitionArena::default();
18657 let first = arena.push_node(ArenaRecognizedNode::Token {
18658 token: TokenId::try_from(0).expect("test token ID"),
18659 });
18660 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
18661 rule_index: 1,
18662 alt_number: 3,
18663 });
18664 let second = arena.push_node(ArenaRecognizedNode::Token {
18665 token: TokenId::try_from(1).expect("test token ID"),
18666 });
18667 let mut nodes = NodeSeqId::EMPTY;
18668 for node in [first, boundary, second].into_iter().rev() {
18669 nodes = arena.prepend(nodes, node);
18670 }
18671
18672 let folded = arena.fold_left_recursive_boundaries(nodes);
18673 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
18674
18675 assert_eq!(folded_nodes.len(), 2);
18676 let ArenaRecognizedNode::Rule {
18677 rule_index,
18678 invoking_state,
18679 alt_number,
18680 start_index,
18681 stop_index,
18682 children,
18683 ..
18684 } = arena.node(folded_nodes[0])
18685 else {
18686 panic!("first folded node should be a rule");
18687 };
18688 insta::assert_debug_snapshot!(
18692 "folds_left_recursive_boundary_into_rule_node",
18693 (
18694 rule_index,
18695 invoking_state,
18696 alt_number,
18697 start_index,
18698 stop_index
18699 )
18700 );
18701 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
18702 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
18703
18704 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
18705 assert_eq!(
18706 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18707 (4, 3, 1)
18708 );
18709 assert_eq!(
18710 (stats.total_links, stats.live_links, stats.dead_links),
18711 (9, 3, 6)
18712 );
18713 }
18714
18715 #[test]
18716 fn recognition_arena_reports_live_dead_and_retained_capacity() {
18717 let mut arena = RecognitionArena::default();
18718 let token = arena.push_node(ArenaRecognizedNode::Token {
18719 token: TokenId::try_from(0).expect("test token ID"),
18720 });
18721 let extra = arena.push_extra(RecognitionExtra::MissingToken {
18722 token_type: 2,
18723 at_index: 1,
18724 text: "<missing X>".to_owned(),
18725 });
18726 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
18727 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
18728 token: TokenId::try_from(1).expect("test token ID"),
18729 });
18730 let mut live = NodeSeqId::EMPTY;
18731 live = arena.prepend(live, missing);
18732 live = arena.prepend(live, token);
18733 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
18734 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
18735 line: 1,
18736 column: 0,
18737 message: "missing X".to_owned(),
18738 offending: None,
18739 }]);
18740 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
18741 line: 1,
18742 column: 1,
18743 message: "discarded".to_owned(),
18744 offending: None,
18745 }]);
18746 let deferred_children = arena.deferred_fragment(live);
18747 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
18748 rule_index: 0,
18749 invoking_state: -1,
18750 start_index: 0,
18751 stop_index: Some(1),
18752 deferred_children,
18753 children: NodeSeqId::EMPTY,
18754 });
18755
18756 let stats = arena.stats(live, live_diagnostics);
18757
18758 assert_eq!(
18759 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18760 (3, 2, 1)
18761 );
18762 assert_eq!(
18763 (stats.total_links, stats.live_links, stats.dead_links),
18764 (5, 3, 2)
18765 );
18766 assert_eq!(
18767 (stats.total_extras, stats.live_extras, stats.dead_extras),
18768 (3, 2, 1)
18769 );
18770 assert!(size_of::<SeqLink>() <= 8);
18771 assert!(size_of::<DiagnosticLink>() <= 8);
18772 assert!(size_of::<FastDeferredNode>() <= 12);
18773 assert!(size_of::<FastDeferredRule>() <= 28);
18774 assert!(size_of::<FastRecognizeOutcome>() <= 24);
18775 let capacities = (
18776 stats.node_capacity,
18777 stats.link_capacity,
18778 stats.extra_capacity,
18779 );
18780 let deferred_capacities = (
18781 arena.deferred_nodes.capacity(),
18782 arena.deferred_rules.capacity(),
18783 );
18784
18785 arena.reset();
18786 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
18787 assert_eq!(
18788 (reset.total_nodes, reset.total_links, reset.total_extras),
18789 (0, 0, 0)
18790 );
18791 assert_eq!(
18792 (
18793 reset.node_capacity,
18794 reset.link_capacity,
18795 reset.extra_capacity,
18796 ),
18797 capacities
18798 );
18799 assert!(arena.deferred_nodes.is_empty());
18800 assert!(arena.deferred_rules.is_empty());
18801 assert_eq!(
18802 (
18803 arena.deferred_nodes.capacity(),
18804 arena.deferred_rules.capacity(),
18805 ),
18806 deferred_capacities
18807 );
18808 }
18809
18810 #[test]
18811 fn parser_computes_recognition_arena_stats_on_demand() {
18812 let mut parser = mini_parser(Vec::new());
18813 let live = parser
18814 .recognition_arena
18815 .push_node(ArenaRecognizedNode::Token {
18816 token: TokenId::try_from(0).expect("test token ID"),
18817 });
18818 let discarded = parser
18819 .recognition_arena
18820 .push_node(ArenaRecognizedNode::ErrorToken {
18821 token: TokenId::try_from(1).expect("test token ID"),
18822 });
18823 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
18824 let _discarded_root = parser
18825 .recognition_arena
18826 .prepend(NodeSeqId::EMPTY, discarded);
18827 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
18828
18829 let stats = parser.recognition_arena_stats();
18830
18831 assert_eq!(
18832 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18833 (2, 1, 1)
18834 );
18835 assert_eq!(
18836 (stats.total_links, stats.live_links, stats.dead_links),
18837 (2, 1, 1)
18838 );
18839 }
18840
18841 #[test]
18842 fn recognition_arena_drops_capacity_above_retention_limit() {
18843 let mut storage = Vec::<u8>::with_capacity(4);
18844 storage.extend([1, 2, 3]);
18845
18846 reset_arena_vec(&mut storage, 3);
18847
18848 assert!(storage.is_empty());
18849 assert_eq!(storage.capacity(), 0);
18850 }
18851
18852 #[test]
18853 fn recognition_arena_concatenates_diagnostics_in_source_order() {
18854 let mut arena = RecognitionArena::default();
18855 let prefix = arena.diagnostic_sequence([
18856 ParserDiagnostic {
18857 line: 1,
18858 column: 0,
18859 message: "first".to_owned(),
18860 offending: None,
18861 },
18862 ParserDiagnostic {
18863 line: 1,
18864 column: 1,
18865 message: "second".to_owned(),
18866 offending: None,
18867 },
18868 ]);
18869 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
18870 line: 1,
18871 column: 2,
18872 message: "third".to_owned(),
18873 offending: None,
18874 }]);
18875 let extras_before = arena.extras.len();
18876
18877 let combined = arena.concat_diagnostics(prefix, suffix);
18878 let messages = arena
18879 .diagnostics(combined)
18880 .map(|diagnostic| diagnostic.message.as_str())
18881 .collect::<Vec<_>>();
18882
18883 assert_eq!(messages, ["first", "second", "third"]);
18884 assert_eq!(arena.extras.len(), extras_before);
18885 }
18886
18887 #[test]
18888 fn outcome_ties_keep_later_non_recursive_alternative() {
18889 let arena = RecognitionArena::default();
18890 let first = RecognizeOutcome {
18891 index: 1,
18892 consumed_eof: false,
18893 alt_number: 0,
18894 member_values: MemberEnv::new(),
18895 return_values: BTreeMap::new(),
18896 diagnostics: DiagnosticSeqId::EMPTY,
18897 decisions: Vec::new(),
18898 actions: vec![ParserAction::new(1, 0, 0, None)],
18899 nodes: NodeSeqId::EMPTY,
18900 };
18901 let second = RecognizeOutcome {
18902 actions: vec![ParserAction::new(2, 0, 0, None)],
18903 ..first.clone()
18904 };
18905
18906 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18907 .expect("one outcome should be selected");
18908 assert_eq!(selected.actions[0].source_state(), 2);
18909 }
18910
18911 #[test]
18912 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
18913 let arena = RecognitionArena::default();
18914 let first = RecognizeOutcome {
18915 index: 1,
18916 consumed_eof: false,
18917 alt_number: 0,
18918 member_values: MemberEnv::new(),
18919 return_values: BTreeMap::new(),
18920 diagnostics: DiagnosticSeqId::EMPTY,
18921 decisions: Vec::new(),
18922 actions: vec![ParserAction::new(1, 0, 0, None)],
18923 nodes: NodeSeqId::EMPTY,
18924 };
18925 let second = RecognizeOutcome {
18926 actions: vec![
18927 ParserAction::new(2, 0, 0, None),
18928 ParserAction::new(3, 0, 0, None),
18929 ],
18930 ..first.clone()
18931 };
18932
18933 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
18934 .expect("one outcome should be selected");
18935 assert_eq!(selected.actions.len(), 2);
18936 }
18937
18938 #[test]
18939 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
18940 let arena = RecognitionArena::default();
18941 let first = RecognizeOutcome {
18942 index: 7,
18943 consumed_eof: false,
18944 alt_number: 0,
18945 member_values: MemberEnv::new(),
18946 return_values: BTreeMap::new(),
18947 diagnostics: DiagnosticSeqId::EMPTY,
18948 decisions: vec![1, 0],
18949 actions: vec![
18950 ParserAction::new(23, 2, 2, Some(4)),
18951 ParserAction::new(23, 2, 0, Some(6)),
18952 ],
18953 nodes: NodeSeqId::EMPTY,
18954 };
18955 let second = RecognizeOutcome {
18956 decisions: vec![0, 1],
18957 actions: vec![
18958 ParserAction::new(23, 2, 2, Some(6)),
18959 ParserAction::new(23, 2, 0, Some(6)),
18960 ],
18961 ..first.clone()
18962 };
18963
18964 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18965 .expect("one outcome should be selected");
18966 assert_eq!(selected.actions[0].stop_index(), Some(6));
18967 }
18968
18969 #[test]
18970 fn outcome_ties_keep_first_recursive_tree_shape() {
18971 let mut arena = RecognitionArena::default();
18972 let token = arena.push_node(ArenaRecognizedNode::Token {
18973 token: TokenId::try_from(0).expect("test token ID"),
18974 });
18975 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
18976 let inner = arena.push_node(ArenaRecognizedNode::Rule {
18977 rule_index: 1,
18978 invoking_state: -1,
18979 alt_number: 0,
18980 start_index: 0,
18981 stop_index: Some(0),
18982 return_values: None,
18983 children: token_children,
18984 });
18985 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
18986 let outer = arena.push_node(ArenaRecognizedNode::Rule {
18987 rule_index: 1,
18988 invoking_state: -1,
18989 alt_number: 0,
18990 start_index: 0,
18991 stop_index: Some(0),
18992 return_values: None,
18993 children: inner_children,
18994 });
18995 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
18996 let first = RecognizeOutcome {
18997 index: 1,
18998 consumed_eof: false,
18999 alt_number: 0,
19000 member_values: MemberEnv::new(),
19001 return_values: BTreeMap::new(),
19002 diagnostics: DiagnosticSeqId::EMPTY,
19003 decisions: Vec::new(),
19004 actions: vec![ParserAction::new(1, 0, 0, None)],
19005 nodes: recursive_nodes,
19006 };
19007 let second = RecognizeOutcome {
19008 index: 1,
19009 consumed_eof: false,
19010 alt_number: 0,
19011 member_values: MemberEnv::new(),
19012 return_values: BTreeMap::new(),
19013 diagnostics: DiagnosticSeqId::EMPTY,
19014 decisions: Vec::new(),
19015 actions: vec![ParserAction::new(2, 0, 0, None)],
19016 nodes: recursive_nodes,
19017 };
19018
19019 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
19020 .expect("one outcome should be selected");
19021 assert_eq!(selected.actions[0].source_state(), 1);
19022 }
19023
19024 #[test]
19025 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
19026 let mut arena = RecognitionArena::default();
19027 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
19028 line: 1,
19029 column: 3,
19030 message: "missing 'Y' at '<EOF>'".to_owned(),
19031 offending: None,
19032 }]);
19033 let first_alt = RecognizeOutcome {
19034 index: 2,
19035 consumed_eof: true,
19036 alt_number: 0,
19037 member_values: MemberEnv::new(),
19038 return_values: BTreeMap::new(),
19039 diagnostics: recovered_diagnostics,
19040 decisions: vec![0],
19041 actions: vec![ParserAction::new(1, 0, 0, None)],
19042 nodes: NodeSeqId::EMPTY,
19043 };
19044 let second_alt = RecognizeOutcome {
19045 diagnostics: DiagnosticSeqId::EMPTY,
19046 decisions: vec![1],
19047 actions: vec![ParserAction::new(2, 0, 0, None)],
19048 ..first_alt.clone()
19049 };
19050
19051 let selected = select_best_outcome(
19052 [second_alt, first_alt].into_iter(),
19053 PredictionMode::Sll,
19054 &arena,
19055 )
19056 .expect("one outcome should be selected");
19057 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
19058 assert_eq!(selected.decisions, [0]);
19059 }
19060}