1use std::cell::RefCell;
9use std::cmp::Ordering;
10#[allow(clippy::disallowed_types)]
11use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
12use std::hash::{BuildHasherDefault, Hash, Hasher};
13use std::rc::Rc;
14
15#[derive(Clone, Copy, Default)]
22struct FxHasher {
23 hash: u64,
24}
25
26const FX_ROT: u32 = 5;
27const FX_SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
28
29impl Hasher for FxHasher {
30 #[inline]
38 fn write(&mut self, mut bytes: &[u8]) {
39 while bytes.len() >= 8 {
40 let (head, rest) = bytes.split_at(8);
41 let word = u64::from_le_bytes(head.try_into().expect("8-byte chunk"));
42 self.hash = (self.hash.rotate_left(FX_ROT) ^ word).wrapping_mul(FX_SEED);
43 bytes = rest;
44 }
45 for byte in bytes {
46 self.hash = (self.hash.rotate_left(FX_ROT) ^ u64::from(*byte)).wrapping_mul(FX_SEED);
47 }
48 }
49 #[inline]
50 fn write_u64(&mut self, value: u64) {
51 self.hash = (self.hash.rotate_left(FX_ROT) ^ value).wrapping_mul(FX_SEED);
52 }
53 #[inline]
54 fn write_usize(&mut self, value: usize) {
55 self.write_u64(value as u64);
56 }
57 #[inline]
58 fn write_u32(&mut self, value: u32) {
59 self.write_u64(u64::from(value));
60 }
61 #[inline]
62 fn write_i32(&mut self, value: i32) {
63 self.write_u64(u64::from(i32::cast_unsigned(value)));
64 }
65 #[inline]
66 fn finish(&self) -> u64 {
67 self.hash
68 }
69}
70
71type FxBuildHasher = BuildHasherDefault<FxHasher>;
72#[allow(clippy::disallowed_types)]
73type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;
74#[allow(clippy::disallowed_types)]
75type FxHashSet<K> = HashSet<K, FxBuildHasher>;
76
77use crate::atn::AtnStateKind;
78use crate::atn::parser::{
79 ParserAtnPrediction, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
80 ParserAtnSimulatorError, ParserSemanticCandidate,
81};
82use crate::atn::parser_atn::{
83 ParserAtn as Atn, ParserAtnState as AtnState, ParserIntervalSet, ParserTransition,
84 ParserTransitionData as Transition, ParserTransitionKind,
85};
86#[cfg(test)]
87use crate::atn::parser_atn::{ParserAtnBuilder, ParserTransitionSpec};
88use crate::char_stream::CharStream;
89use crate::errors::{AntlrError, SyntaxErrorEvent};
90use crate::int_stream::IntStream;
91use crate::lexer::{LexerCustomAction, LexerLifecycleCtx, LexerSemCtx};
92use crate::prediction::SemanticContext;
93use crate::recognizer::{Recognizer, RecognizerData};
94use crate::semir::{self, AStmt, ArithOp, CmpOp, ExprId, HookId, MemberEnv, PExpr, SemIr, StmtId};
95use crate::token::{
96 TOKEN_EOF, Token, TokenId, TokenSource, TokenSourceError, TokenSpec, TokenStore, TokenView,
97};
98use crate::token_stream::CommonTokenStream;
99use crate::tree::{
100 Node, NodeId, ParseTreeCheckpoint, ParseTreeStorage, ParsedFile, ParserRuleContext,
101};
102use crate::vocabulary::Vocabulary;
103
104type ParseTree = NodeId;
105
106const RECOGNITION_DEPTH_LIMIT: usize = 32_768;
110const FAST_RECOGNIZE_STACK_CHECK_INTERVAL: usize = 8;
113const FAST_RECOGNIZE_RED_ZONE: usize = 1024 * 1024;
114const FAST_RECOGNIZE_STACK_SIZE: usize = 4 * 1024 * 1024;
115const GENERATED_RULE_STACK_CHECK_INTERVAL: usize = 8;
120const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
124
125pub fn grow_generated_rule_stack<R>(body: impl FnOnce() -> R) -> R {
132 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, body)
133}
134
135#[doc(hidden)]
142#[macro_export]
143macro_rules! __antlr4_rust_generated_rule {
144 (
145 ordinary $parser:ident, $state:expr, $rule:expr, $allow_fallback:expr,
146 $atn:expr, $fatal:path;
147 retry [$($retry:tt)*];
148 bind ($ctx:ident, $rule_start:ident, $consumed_eof:ident, $sync_error:ident);
149 setup { $($setup:tt)* }
150 body { $($body:tt)* }
151 success { $($success:tt)* }
152 recovery { $($recovery:tt)* }
153 ) => {
154 $crate::__antlr4_rust_generated_rule! {
155 @body
156 parser $parser;
157 enter $parser.base.enter_rule($state, $rule);
158 finish finish_rule;
159 abort exit_rule;
160 allow_fallback $allow_fallback;
161 atn $atn;
162 fatal $fatal;
163 retry [$($retry)*];
164 bind ($ctx, $rule_start, $consumed_eof, $sync_error);
165 setup { $($setup)* }
166 body { $($body)* }
167 success { $($success)* }
168 recovery { $($recovery)* }
169 }
170 };
171 (
172 recursive $parser:ident, $state:expr, $rule:expr, $precedence:expr,
173 $allow_fallback:expr, $atn:expr, $fatal:path;
174 retry [$($retry:tt)*];
175 bind ($ctx:ident, $rule_start:ident, $consumed_eof:ident, $sync_error:ident);
176 setup { $($setup:tt)* }
177 body { $($body:tt)* }
178 success { $($success:tt)* }
179 recovery { $($recovery:tt)* }
180 ) => {
181 $crate::__antlr4_rust_generated_rule! {
182 @body
183 parser $parser;
184 enter $parser.base.enter_recursion_rule($state, $rule, $precedence);
185 finish finish_recursion_rule;
186 abort unroll_recursion_context;
187 allow_fallback $allow_fallback;
188 atn $atn;
189 fatal $fatal;
190 retry [$($retry)*];
191 bind ($ctx, $rule_start, $consumed_eof, $sync_error);
192 setup { $($setup)* }
193 body { $($body)* }
194 success { $($success)* }
195 recovery { $($recovery)* }
196 }
197 };
198 (
199 @body
200 parser $parser:ident;
201 enter $enter:expr;
202 finish $finish:ident;
203 abort $abort:ident;
204 allow_fallback $allow_fallback:expr;
205 atn $atn:expr;
206 fatal $fatal:path;
207 retry [$($retry:tt)*];
208 bind ($ctx:ident, $rule_start:ident, $consumed_eof:ident, $sync_error:ident);
209 setup { $($setup:tt)* }
210 body { $($body:tt)* }
211 success { $($success:tt)* }
212 recovery { $($recovery:tt)* }
213 ) => {{
214 let __generated_diagnostic_marker =
215 $parser.base.generated_diagnostics_checkpoint();
216 let mut $ctx = $enter;
217 let $rule_start = $crate::IntStream::index($parser.base.input());
218 $($setup)*
219 let mut $consumed_eof = false;
220 let mut $sync_error: Option<$crate::AntlrError> = None;
221 let __result = (|| -> Result<(), $crate::AntlrError> {
224 $($body)*
225 Ok(())
226 })();
227 match __result {
228 Ok(()) => {
229 $($success)*
230 let __tree = $parser.base.$finish($ctx, $consumed_eof);
231 Ok(__tree)
232 }
233 Err(__error) => {
234 $crate::__antlr4_rust_generated_rule! {
235 @retry
236 [$($retry)*]
237 parser $parser;
238 marker __generated_diagnostic_marker;
239 abort $abort;
240 }
241 let __error = if let Some(__sync_error) = $sync_error {
242 if $allow_fallback {
243 $parser.base.$abort();
244 $parser
245 .base
246 .rollback_generated_tree(__generated_diagnostic_marker);
247 $parser.base.record_generated_syntax_error();
248 return Err($fatal(__sync_error));
249 }
250 __sync_error
251 } else {
252 __error
253 };
254 $parser
255 .base
256 .recover_generated_rule(&mut $ctx, $atn, __error);
257 $($recovery)*
258 let __tree = $parser.base.$finish($ctx, $consumed_eof);
259 Ok(__tree)
260 }
261 }
262 }};
263 (
264 @retry
265 [none]
266 parser $parser:ident;
267 marker $marker:ident;
268 abort $abort:ident;
269 ) => {};
270 (
271 @retry
272 [adaptive]
273 parser $parser:ident;
274 marker $marker:ident;
275 abort $abort:ident;
276 ) => {
277 if $parser.adaptive_atn.retry_pending() {
281 $parser.base.$abort();
282 $parser.base.restore_generated_diagnostics($marker);
283 return Err($crate::generated::GeneratedRuleError::AdaptiveRetry);
284 }
285 };
286}
287
288#[macro_export]
304#[doc(hidden)]
305macro_rules! __antlr4_rust_invoke_subrule {
306 ($parser:ident, $state:expr, $call:expr, $ctx:ident) => {{
307 let __invoking_marker = $parser.base.push_invoking_state($state);
308 let __child = $call;
309 $parser.base.discard_invoking_state(__invoking_marker);
310 let __child = __child?;
311 $parser.base.add_parse_child(&mut $ctx, __child);
312 }};
313}
314
315pub trait ParseListener: Send {
363 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError>;
368
369 fn exit_every_rule(&mut self, rule_index: usize) {
373 let _ = rule_index;
374 }
375}
376
377impl<T: ParseListener + ?Sized> ParseListener for Box<T> {
381 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
382 (**self).enter_every_rule(event)
383 }
384
385 fn exit_every_rule(&mut self, rule_index: usize) {
386 (**self).exit_every_rule(rule_index);
387 }
388}
389
390#[derive(Debug)]
395#[non_exhaustive]
396pub struct EnterRuleEvent<'a> {
397 pub rule_index: usize,
400 pub current: Option<TokenView<'a>>,
403}
404
405struct ParseListenerSlot(Box<dyn ParseListener>);
406
407impl std::fmt::Debug for ParseListenerSlot {
408 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
409 f.write_str("ParseListener")
410 }
411}
412const CLEAN_MEMO_PROBE_LIMIT: usize = 4096;
416const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
417const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
420const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
421const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
422const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
423const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
424
425#[derive(Clone, Copy, Debug, Eq, PartialEq)]
426enum CleanMemoMode {
427 Probe,
428 Promote,
429 Sparse,
430}
431
432fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
433 intervals
434 .iter()
435 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
436}
437
438fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
439 let mut symbols = BTreeSet::new();
440 for (start, stop) in intervals {
441 symbols.extend(*start..=*stop);
442 }
443 symbols
444}
445
446fn interval_complement_symbols(
447 intervals: &[(i32, i32)],
448 min_vocabulary: i32,
449 max_vocabulary: i32,
450) -> BTreeSet<i32> {
451 (min_vocabulary..=max_vocabulary)
452 .filter(|symbol| !interval_set_contains(intervals, *symbol))
453 .collect()
454}
455
456#[cfg(feature = "perf-counters")]
457mod perf_counters {
458 use std::cell::Cell;
459 thread_local! {
460 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
461 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
462 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
463 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
464 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
465 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
466 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
467 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
468 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
469 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
470 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
471 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
472 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
473 }
474 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
475 c.with(|v| v.set(v.get() + n));
476 }
477 thread_local! {
478 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
479 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
480 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
481 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
482 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
483 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
484 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
485 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
486 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
487 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
488 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
489 }
490 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
491 [
492 ("rfs_calls", RFS_CALLS.with(Cell::get)),
493 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
494 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
495 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
496 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
497 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
498 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
499 (
500 "outcome_dedupe_inputs",
501 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
502 ),
503 (
504 "outcome_dedupe_removed",
505 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
506 ),
507 (
508 "outcome_dedupe_inline",
509 OUTCOME_DEDUPE_INLINE.with(Cell::get),
510 ),
511 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
512 (
513 "outcome_dedupe_sparse",
514 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
515 ),
516 (
517 "outcome_dedupe_dense_words",
518 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
519 ),
520 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
521 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
522 (
523 "atom_range_transitions",
524 ATOM_RANGE_TRANSITIONS.with(Cell::get),
525 ),
526 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
527 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
528 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
529 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
530 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
531 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
532 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
533 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
534 ]
535 }
536 pub fn reset() {
537 RFS_CALLS.with(|c| c.set(0));
538 RFS_MEMO_HITS.with(|c| c.set(0));
539 RFS_MEMO_MISSES.with(|c| c.set(0));
540 RFS_VISITING_CYCLE.with(|c| c.set(0));
541 MEMO_INSERTED.with(|c| c.set(0));
542 OUTCOMES_PUSHED.with(|c| c.set(0));
543 OUTCOMES_CLONED.with(|c| c.set(0));
544 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
545 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
546 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
547 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
548 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
549 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
550 EPSILON_TRANSITIONS.with(|c| c.set(0));
551 RULE_TRANSITIONS.with(|c| c.set(0));
552 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
553 SINGLE_TRANS_BODY.with(|c| c.set(0));
554 MULTI_TRANS_BODY.with(|c| c.set(0));
555 SINGLE_TRANS_RULE.with(|c| c.set(0));
556 SINGLE_TRANS_ATOM.with(|c| c.set(0));
557 SINGLE_TRANS_OTHER.with(|c| c.set(0));
558 OUTCOMES_RETURN_0.with(|c| c.set(0));
559 OUTCOMES_RETURN_1.with(|c| c.set(0));
560 OUTCOMES_RETURN_N.with(|c| c.set(0));
561 }
562 pub fn dump() {
563 for (name, value) in snapshot() {
564 #[allow(clippy::print_stderr)]
565 {
566 eprintln!("perf {name}={value}");
567 }
568 }
569 }
570}
571
572#[cfg(feature = "perf-counters")]
573pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
574const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
579#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
588pub struct ParserAction {
589 source_state: usize,
590 rule_index: usize,
591 action_index: Option<usize>,
592 start_index: usize,
593 stop_index: Option<usize>,
594 rule_init: bool,
595 expected_state: Option<usize>,
596}
597
598impl ParserAction {
599 pub const fn new(
601 source_state: usize,
602 rule_index: usize,
603 start_index: usize,
604 stop_index: Option<usize>,
605 ) -> Self {
606 Self {
607 source_state,
608 rule_index,
609 action_index: None,
610 start_index,
611 stop_index,
612 rule_init: false,
613 expected_state: None,
614 }
615 }
616
617 pub const fn new_indexed(
619 source_state: usize,
620 rule_index: usize,
621 action_index: usize,
622 start_index: usize,
623 stop_index: Option<usize>,
624 ) -> Self {
625 Self {
626 source_state,
627 rule_index,
628 action_index: Some(action_index),
629 start_index,
630 stop_index,
631 rule_init: false,
632 expected_state: None,
633 }
634 }
635
636 pub const fn new_rule_init(
638 rule_index: usize,
639 start_index: usize,
640 expected_state: Option<usize>,
641 ) -> Self {
642 Self {
643 source_state: usize::MAX,
644 rule_index,
645 action_index: None,
646 start_index,
647 stop_index: None,
648 rule_init: true,
649 expected_state,
650 }
651 }
652
653 pub const fn source_state(&self) -> usize {
655 self.source_state
656 }
657
658 pub const fn rule_index(&self) -> usize {
660 self.rule_index
661 }
662
663 pub const fn action_index(&self) -> Option<usize> {
665 self.action_index
666 }
667
668 pub const fn start_index(&self) -> usize {
670 self.start_index
671 }
672
673 pub const fn stop_index(&self) -> Option<usize> {
675 self.stop_index
676 }
677
678 pub const fn is_rule_init(&self) -> bool {
680 self.rule_init
681 }
682
683 pub const fn expected_state(&self) -> Option<usize> {
685 self.expected_state
686 }
687}
688
689pub struct ParserSemCtx<'a, S>
697where
698 S: TokenSource,
699{
700 input: &'a mut CommonTokenStream<S>,
701 tree_storage: &'a ParseTreeStorage,
702 rule_index: usize,
703 coordinate_index: usize,
704 rule_name: Option<String>,
705 context: Option<&'a ParserRuleContext>,
706 tree: Option<ParseTree>,
707 local_int_arg: Option<(usize, i64)>,
708 member_values: &'a MemberEnv,
709 action: Option<ParserAction>,
710}
711
712impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
713where
714 S: TokenSource,
715{
716 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
717 f.debug_struct("ParserSemCtx")
718 .field("rule_index", &self.rule_index)
719 .field("coordinate_index", &self.coordinate_index)
720 .field("rule_name", &self.rule_name)
721 .field("context", &self.context)
722 .field("tree", &self.tree)
723 .field("local_int_arg", &self.local_int_arg)
724 .field("member_values", &self.member_values)
725 .field("action", &self.action)
726 .finish_non_exhaustive()
727 }
728}
729
730impl<'a, S> ParserSemCtx<'a, S>
731where
732 S: TokenSource,
733{
734 #[must_use]
736 pub const fn rule_index(&self) -> usize {
737 self.rule_index
738 }
739
740 #[must_use]
742 pub fn rule_name(&self) -> Option<&str> {
743 self.rule_name.as_deref()
744 }
745
746 #[must_use]
749 pub const fn coordinate_index(&self) -> usize {
750 self.coordinate_index
751 }
752
753 #[must_use]
755 pub fn input_index(&self) -> usize {
756 self.input.index()
757 }
758
759 pub fn la(&mut self, offset: isize) -> i32 {
761 self.input.la(offset)
762 }
763
764 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
766 self.input.lt(offset)
767 }
768
769 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
771 self.lt(offset)
772 }
773
774 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
781 self.input.get(index)
782 }
783
784 #[must_use]
787 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
788 self.context
789 }
790
791 #[must_use]
793 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
794 self.tree_storage
795 }
796
797 #[must_use]
799 pub const fn token_store(&self) -> &TokenStore {
800 self.input.token_store()
801 }
802
803 #[must_use]
805 pub const fn tree_id(&self) -> Option<NodeId> {
806 self.tree
807 }
808
809 #[must_use]
812 pub fn tree(&self) -> Option<Node<'_>> {
813 self.tree
814 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
815 }
816
817 #[must_use]
819 pub fn local_int_arg(&self) -> Option<i64> {
820 self.local_int_arg.map(|(_, value)| value)
821 }
822
823 #[must_use]
825 pub fn member_int(&self, member: usize) -> Option<i64> {
826 self.member_values.scalar(member)
827 }
828
829 #[must_use]
832 pub fn member_stack_top(&self, member: usize) -> Option<i64> {
833 self.member_values.stack_top(member)
834 }
835
836 #[must_use]
838 pub fn member_stack_len(&self, member: usize) -> usize {
839 self.member_values.stack_len(member)
840 }
841
842 #[must_use]
845 pub const fn action(&self) -> Option<ParserAction> {
846 self.action
847 }
848
849 pub fn action_text(&self) -> String {
857 let Some(action) = self.action else {
858 return String::new();
859 };
860 let Some(stop) = action.stop_index() else {
861 return String::new();
862 };
863 let stop = if self
864 .input
865 .get(stop)
866 .is_some_and(|token| token.token_type() == TOKEN_EOF)
867 {
868 let Some(previous) = self.input.previous_visible_token_index(stop) else {
869 return String::new();
870 };
871 previous
872 } else {
873 stop
874 };
875 self.input.text(action.start_index(), stop)
876 }
877}
878
879pub trait SemanticHooks {
886 const ENABLES_LEXER_LIFECYCLE: bool = true;
893
894 fn observes_parser_predicates(&self) -> bool {
899 true
900 }
901
902 fn observes_parser_decisions(&self) -> bool {
907 false
908 }
909
910 fn parser_decision_override(
916 &mut self,
917 decision: usize,
918 input_index: usize,
919 alternative_count: usize,
920 ) -> Option<usize> {
921 let _ = (decision, input_index, alternative_count);
922 None
923 }
924
925 fn sempred<S>(
926 &mut self,
927 ctx: &mut ParserSemCtx<'_, S>,
928 rule_index: usize,
929 pred_index: usize,
930 ) -> Option<bool>
931 where
932 S: TokenSource,
933 {
934 let _ = (ctx, rule_index, pred_index);
935 None
936 }
937
938 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
939 where
940 S: TokenSource,
941 {
942 let _ = (ctx, action);
943 false
944 }
945
946 fn lexer_sempred<I>(
947 &mut self,
948 ctx: &mut LexerSemCtx<'_, I>,
949 rule_index: usize,
950 pred_index: usize,
951 ) -> Option<bool>
952 where
953 I: CharStream,
954 {
955 let _ = (ctx, rule_index, pred_index);
956 None
957 }
958
959 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
969 where
970 I: CharStream,
971 {
972 let _ = (ctx, action);
973 false
974 }
975
976 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
980 where
981 I: CharStream,
982 {
983 let _ = ctx;
984 }
985
986 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
992 where
993 I: CharStream,
994 {
995 let _ = ctx;
996 }
997
998 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
1007 where
1008 I: CharStream,
1009 {
1010 let _ = ctx;
1011 }
1012
1013 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
1020 let _ = token;
1021 }
1022}
1023
1024#[derive(Clone, Copy, Debug, Default)]
1027pub struct NoSemanticHooks;
1028
1029impl SemanticHooks for NoSemanticHooks {
1030 const ENABLES_LEXER_LIFECYCLE: bool = false;
1031
1032 fn observes_parser_predicates(&self) -> bool {
1033 false
1034 }
1035}
1036
1037#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1044pub enum ParserPredicate {
1045 True,
1046 False,
1047 FalseWithMessage {
1049 message: &'static str,
1050 },
1051 Invoke {
1054 value: bool,
1055 },
1056 LookaheadTextEquals {
1057 offset: isize,
1058 text: &'static str,
1059 },
1060 LookaheadNotEquals {
1061 offset: isize,
1062 token_type: i32,
1063 },
1064 TokenPairAdjacent,
1067 ContextChildRuleTextNotEquals {
1072 rule_index: usize,
1073 text: &'static str,
1074 },
1075 LocalIntEquals {
1078 value: i64,
1079 },
1080 LocalIntLessOrEqual {
1083 value: i64,
1084 },
1085 MemberModuloEquals {
1087 member: usize,
1088 modulus: i64,
1089 value: i64,
1090 equals: bool,
1091 },
1092 MemberEquals {
1094 member: usize,
1095 value: i64,
1096 equals: bool,
1097 },
1098}
1099
1100impl ParserPredicate {
1101 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
1107 match self {
1108 Self::True => ir.expr(PExpr::Bool(true)),
1109 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
1110 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
1111 Self::LookaheadTextEquals { offset, text } => {
1112 let token = ir.expr(PExpr::TokenText(offset));
1113 let text = ir.intern(text);
1114 let text = ir.expr(PExpr::Str(text));
1115 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
1116 }
1117 Self::LookaheadNotEquals { offset, token_type } => {
1118 let actual = ir.expr(PExpr::La(offset));
1119 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
1120 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
1121 }
1122 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
1123 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
1124 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
1125 let expected = ir.intern(text);
1126 let expected = ir.expr(PExpr::Str(expected));
1127 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
1128 }
1129 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
1130 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
1131 Self::MemberModuloEquals {
1132 member,
1133 modulus,
1134 value,
1135 equals,
1136 } => {
1137 if modulus == 0 {
1138 return ir.expr(PExpr::Bool(false));
1139 }
1140 let member = ir.expr(PExpr::Member(member));
1141 let modulus = ir.expr(PExpr::Int(modulus));
1142 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
1143 let expected = ir.expr(PExpr::Int(value));
1144 ir.expr(PExpr::Cmp(
1145 if equals { CmpOp::Eq } else { CmpOp::Ne },
1146 actual,
1147 expected,
1148 ))
1149 }
1150 Self::MemberEquals {
1151 member,
1152 value,
1153 equals,
1154 } => {
1155 let actual = ir.expr(PExpr::Member(member));
1156 let expected = ir.expr(PExpr::Int(value));
1157 ir.expr(PExpr::Cmp(
1158 if equals { CmpOp::Eq } else { CmpOp::Ne },
1159 actual,
1160 expected,
1161 ))
1162 }
1163 }
1164 }
1165
1166 #[must_use]
1167 pub const fn failure_message(self) -> Option<&'static str> {
1168 match self {
1169 Self::FalseWithMessage { message } => Some(message),
1170 Self::True
1171 | Self::False
1172 | Self::Invoke { .. }
1173 | Self::LookaheadTextEquals { .. }
1174 | Self::LookaheadNotEquals { .. }
1175 | Self::TokenPairAdjacent
1176 | Self::ContextChildRuleTextNotEquals { .. }
1177 | Self::LocalIntEquals { .. }
1178 | Self::LocalIntLessOrEqual { .. }
1179 | Self::MemberModuloEquals { .. }
1180 | Self::MemberEquals { .. } => None,
1181 }
1182 }
1183}
1184
1185fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
1186 let local = ir.expr(PExpr::LocalArg);
1187 let absent = ir.expr(PExpr::IsNull(local));
1188 let expected = ir.expr(PExpr::Int(value));
1189 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
1190 ir.expr(PExpr::Or([absent, comparison].into()))
1191}
1192
1193#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1206pub enum UnknownSemanticPolicy {
1207 #[default]
1209 AssumeTrue,
1210 AssumeFalse,
1212 Error,
1215}
1216
1217fn apply_unknown_predicate_policy(
1226 policy: UnknownSemanticPolicy,
1227 rule_index: usize,
1228 pred_index: usize,
1229 hits: &mut Vec<(usize, usize)>,
1230) -> bool {
1231 match policy {
1232 UnknownSemanticPolicy::AssumeTrue => true,
1233 UnknownSemanticPolicy::AssumeFalse => false,
1234 UnknownSemanticPolicy::Error => {
1235 let coordinate = (rule_index, pred_index);
1236 if !hits.contains(&coordinate) {
1237 hits.push(coordinate);
1238 }
1239 false
1240 }
1241 }
1242}
1243
1244#[derive(Clone, Debug, Eq, PartialEq)]
1248pub struct ExpectedTokenSet {
1249 symbols: BTreeSet<i32>,
1250}
1251
1252impl ExpectedTokenSet {
1253 #[must_use]
1255 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
1256 expected_symbols_display(&self.symbols, vocabulary)
1257 }
1258}
1259
1260#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1265pub struct BailErrorStrategy;
1266
1267impl BailErrorStrategy {
1268 #[must_use]
1269 pub const fn new() -> Self {
1270 Self
1271 }
1272}
1273
1274#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1276pub enum PredictionMode {
1277 Ll,
1280 Sll,
1283 LlExactAmbigDetection,
1285}
1286
1287#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1293pub struct ParserRuleArg {
1294 pub source_state: usize,
1296 pub rule_index: usize,
1298 pub value: i64,
1300 pub inherit_local: bool,
1302}
1303
1304#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1306pub struct ParserMemberAction {
1307 pub source_state: usize,
1309 pub member: usize,
1311 pub delta: i64,
1313}
1314
1315#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1322pub struct ParserReturnAction {
1323 pub source_state: usize,
1325 pub rule_index: usize,
1327 pub name: &'static str,
1329 pub value: i64,
1331}
1332
1333impl ParserMemberAction {
1334 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1336 let delta = ir.expr(PExpr::Int(self.delta));
1337 ParserSemanticAction {
1338 source_state: self.source_state,
1339 rule_index: usize::MAX,
1340 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
1341 speculative: true,
1342 }
1343 }
1344}
1345
1346impl ParserReturnAction {
1347 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1349 let name = ir.intern(self.name);
1350 let value = ir.expr(PExpr::Int(self.value));
1351 ParserSemanticAction {
1352 source_state: self.source_state,
1353 rule_index: self.rule_index,
1354 stmt: ir.stmt(AStmt::SetReturn(name, value)),
1355 speculative: false,
1356 }
1357 }
1358}
1359
1360#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1362pub struct ParserSemanticPredicate {
1363 pub rule_index: usize,
1365 pub pred_index: usize,
1367 pub expr: ExprId,
1369 pub failure_message: Option<&'static str>,
1371}
1372
1373#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1375pub struct ParserSemanticAction {
1376 pub source_state: usize,
1378 pub rule_index: usize,
1380 pub stmt: StmtId,
1382 pub speculative: bool,
1384}
1385
1386#[derive(Clone, Debug, Default, Eq, PartialEq)]
1393pub struct ParserSemantics {
1394 pub ir: SemIr,
1395 pub predicates: Vec<ParserSemanticPredicate>,
1396 pub actions: Vec<ParserSemanticAction>,
1397}
1398
1399#[derive(Clone, Copy, Debug, Default)]
1401pub struct ParserRuntimeOptions<'a> {
1402 pub init_action_rules: &'a [usize],
1405 pub action_indices: &'a [(usize, usize)],
1411 pub track_alt_numbers: bool,
1413 #[doc(hidden)]
1418 pub track_context_alt_numbers: bool,
1419 pub predicates: &'a [(usize, usize, ParserPredicate)],
1421 pub semantics: Option<&'a ParserSemantics>,
1423 pub rule_args: &'a [ParserRuleArg],
1425 pub member_actions: &'a [ParserMemberAction],
1427 pub return_actions: &'a [ParserReturnAction],
1429 pub unknown_predicate_policy: UnknownSemanticPolicy,
1432}
1433
1434pub trait Parser: Recognizer {
1435 fn build_parse_trees(&self) -> bool;
1438
1439 fn set_build_parse_trees(&mut self, build: bool);
1441
1442 fn number_of_syntax_errors(&self) -> usize {
1445 0
1446 }
1447
1448 fn report_diagnostic_errors(&self) -> bool {
1451 false
1452 }
1453
1454 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1457
1458 fn prediction_mode(&self) -> PredictionMode {
1460 PredictionMode::Ll
1461 }
1462
1463 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1465
1466 fn max_rule_depth(&self) -> Option<usize> {
1469 None
1470 }
1471
1472 fn set_max_rule_depth(&mut self, _depth: Option<usize>) {}
1488
1489 fn add_parse_listener(&mut self, _listener: Box<dyn ParseListener>) {}
1494
1495 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
1498 Vec::new()
1499 }
1500}
1501
1502#[derive(Debug)]
1503struct LeftRecursiveCallerOverlap {
1504 atn_key: SharedAtnCacheKey,
1505 state_number: usize,
1506 symbol: i32,
1507 context_version: usize,
1508 overlaps: bool,
1509}
1510
1511const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1512
1513#[derive(Debug)]
1514pub struct BaseParser<S, H = NoSemanticHooks> {
1515 input: CommonTokenStream<S>,
1516 tree: ParseTreeStorage,
1517 data: RecognizerData,
1518 semantic_hooks: H,
1519 decision_override_generation: usize,
1520 build_parse_trees: bool,
1521 syntax_errors: usize,
1522 report_diagnostic_errors: bool,
1523 prediction_mode: PredictionMode,
1524 prediction_diagnostics: Vec<ParserDiagnostic>,
1525 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1526 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1527 generated_sync_expected: Option<TokenBitSet>,
1528 generated_recovery_error_index: Option<usize>,
1529 generated_recovery_error_states: BTreeSet<isize>,
1530 int_members: MemberEnv,
1531 rule_context_stack: Vec<RuleContextFrame>,
1532 rule_context_version: usize,
1533 left_recursive_caller_overlap_cache:
1534 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1535 pending_invoking_states: Vec<isize>,
1536 precedence_stack: Vec<i32>,
1537 invoked_predicates: Vec<(usize, usize)>,
1541 bail_on_error: bool,
1545 parse_listeners: Vec<ParseListenerSlot>,
1550 parse_listener_abort: Option<AntlrError>,
1555 max_rule_depth: Option<usize>,
1559 rule_depth_error: Option<AntlrError>,
1564 recursion_expansions: usize,
1570 recursion_expansion_marks: Vec<usize>,
1574 unknown_predicate_policy: UnknownSemanticPolicy,
1577 unknown_predicate_hits: Vec<(usize, usize)>,
1580 unhandled_action_hits: Vec<(usize, usize)>,
1585 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1590 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1596 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1601 rule_stop_reach_cache: Vec<Option<bool>>,
1606 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1611 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1617 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1623 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1627 empty_cycle_cache: Vec<Option<bool>>,
1633 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1634 clean_memo_mode: CleanMemoMode,
1637 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1638 clean_memo_probe_samples: usize,
1639 clean_memo_probe_repeats: usize,
1640 clean_memo_sparse_samples: usize,
1641 fast_recognize_scratch: FastRecognizeTopScratch,
1643 fast_outcome_dedup: FastOutcomeDedupScratch,
1645 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1648 fast_first_set_prefilter: bool,
1656 fast_recovery_enabled: bool,
1660 fast_token_nodes_enabled: bool,
1665 fast_track_alt_numbers: bool,
1668 recognition_arena: RecognitionArena,
1672 last_recognition_arena_root: NodeSeqId,
1673 last_recognition_arena_diagnostics: DiagnosticSeqId,
1674}
1675
1676#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1678pub struct GeneratedDiagnosticsCheckpoint {
1679 diagnostics_len: usize,
1680 syntax_errors: usize,
1681 tree: ParseTreeCheckpoint,
1682}
1683
1684#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1687pub struct RecognitionArenaStats {
1688 pub total_nodes: usize,
1689 pub live_nodes: usize,
1690 pub dead_nodes: usize,
1691 pub node_capacity: usize,
1692 pub total_links: usize,
1693 pub live_links: usize,
1694 pub dead_links: usize,
1695 pub link_capacity: usize,
1696 pub total_extras: usize,
1697 pub live_extras: usize,
1698 pub dead_extras: usize,
1699 pub extra_capacity: usize,
1700}
1701
1702#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1703struct RuleContextFrame {
1704 rule_index: usize,
1705 invoking_state: isize,
1706}
1707
1708#[derive(Clone, Debug, Eq, PartialEq)]
1709struct RecognizeOutcome {
1710 index: usize,
1711 consumed_eof: bool,
1712 alt_number: usize,
1713 member_values: MemberEnv,
1714 return_values: BTreeMap<String, i64>,
1715 diagnostics: DiagnosticSeqId,
1716 decisions: Vec<usize>,
1717 actions: Vec<ParserAction>,
1718 nodes: NodeSeqId,
1719}
1720
1721#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1722struct FastRecognizeOutcome {
1723 index: usize,
1724 consumed_eof: bool,
1725 diagnostics: DiagnosticSeqId,
1726 deferred_nodes: FastDeferredNodeId,
1727 nodes: NodeSeqId,
1731}
1732
1733#[derive(Debug, Default)]
1734struct FastRecognizeTopScratch {
1735 visiting: FxHashSet<FastRecognizeKey>,
1736 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1737}
1738
1739impl FastRecognizeTopScratch {
1740 fn prepare(&mut self, memo_capacity: usize) {
1741 self.visiting.clear();
1742 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1743 self.memo.clear();
1744 self.memo.reserve(memo_capacity);
1745 }
1746
1747 fn release_oversized_memo(&mut self) {
1748 self.memo.clear();
1749 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1750 self.memo = FxHashMap::default();
1751 }
1752 }
1753}
1754
1755fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1756 buffered_tokens.saturating_mul(8).clamp(
1757 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1758 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1759 )
1760}
1761
1762#[derive(Debug, Default)]
1763struct FastOutcomeDedupScratch {
1764 dense_words: Vec<u64>,
1765 touched_dense_words: Vec<u32>,
1766 sparse_keys: FxHashSet<(usize, bool)>,
1767}
1768
1769#[repr(transparent)]
1774#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1775struct FastDeferredNodeId(u32);
1776
1777impl FastDeferredNodeId {
1778 const EMPTY: Self = Self(u32::MAX);
1779
1780 const fn is_empty(self) -> bool {
1781 self.0 == Self::EMPTY.0
1782 }
1783}
1784
1785impl Default for FastDeferredNodeId {
1786 fn default() -> Self {
1787 Self::EMPTY
1788 }
1789}
1790
1791#[repr(transparent)]
1792#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1793struct FastDeferredRuleId(u32);
1794
1795#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1797enum FastDeferredNode {
1798 Fragment(NodeSeqId),
1799 Rule(FastDeferredRuleId),
1800 Alternative(u32),
1801 LeftRecursiveBoundary {
1802 rule_index: u32,
1803 },
1804 Concat {
1805 prefix: FastDeferredNodeId,
1806 suffix: FastDeferredNodeId,
1807 },
1808}
1809
1810#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1811struct FastDeferredRule {
1812 rule_index: u32,
1813 invoking_state: i32,
1814 start_index: u32,
1815 stop_index: Option<u32>,
1816 deferred_children: FastDeferredNodeId,
1817 children: NodeSeqId,
1818}
1819
1820#[repr(transparent)]
1821#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1822struct RecognizedNodeId(u32);
1823
1824#[repr(transparent)]
1825#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1826struct NodeSeqId(u32);
1827
1828impl NodeSeqId {
1829 const EMPTY: Self = Self(u32::MAX);
1830
1831 const fn is_empty(self) -> bool {
1832 self.0 == Self::EMPTY.0
1833 }
1834}
1835
1836impl Default for NodeSeqId {
1837 fn default() -> Self {
1838 Self::EMPTY
1839 }
1840}
1841
1842#[repr(transparent)]
1843#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1844struct DiagnosticSeqId(u32);
1845
1846impl DiagnosticSeqId {
1847 const EMPTY: Self = Self(u32::MAX);
1848
1849 const fn is_empty(self) -> bool {
1850 self.0 == Self::EMPTY.0
1851 }
1852}
1853
1854impl Default for DiagnosticSeqId {
1855 fn default() -> Self {
1856 Self::EMPTY
1857 }
1858}
1859
1860#[repr(transparent)]
1861#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1862struct RecognitionExtraId(u32);
1863
1864#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1865struct SeqLink {
1866 head: RecognizedNodeId,
1867 tail: NodeSeqId,
1868}
1869
1870#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1871struct DiagnosticLink {
1872 head: RecognitionExtraId,
1873 tail: DiagnosticSeqId,
1874}
1875
1876struct ArenaRuleSpec {
1877 rule_index: usize,
1878 invoking_state: isize,
1879 alt_number: usize,
1880 start_index: usize,
1881 stop_index: Option<usize>,
1882 return_values: BTreeMap<String, i64>,
1883 children: NodeSeqId,
1884}
1885
1886#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1889enum ArenaRecognizedNode {
1890 Token {
1891 token: TokenId,
1892 },
1893 ErrorToken {
1894 token: TokenId,
1895 },
1896 MissingToken {
1897 extra: RecognitionExtraId,
1898 },
1899 Rule {
1900 rule_index: u32,
1901 invoking_state: i32,
1902 alt_number: u32,
1903 start_index: u32,
1904 stop_index: Option<u32>,
1905 return_values: Option<RecognitionExtraId>,
1906 children: NodeSeqId,
1907 },
1908 LeftRecursiveBoundary {
1912 rule_index: u32,
1913 alt_number: u32,
1914 },
1915}
1916
1917#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1918enum RecognitionExtra {
1919 MissingToken {
1920 token_type: i32,
1921 at_index: u32,
1922 text: String,
1923 },
1924 ReturnValues(BTreeMap<String, i64>),
1925 Diagnostic(ParserDiagnostic),
1926}
1927
1928#[derive(Debug, Default)]
1929struct RecognitionArena {
1930 nodes: Vec<ArenaRecognizedNode>,
1931 seq_links: Vec<SeqLink>,
1932 diagnostic_links: Vec<DiagnosticLink>,
1933 extras: Vec<RecognitionExtra>,
1934 deferred_nodes: Vec<FastDeferredNode>,
1935 deferred_rules: Vec<FastDeferredRule>,
1936}
1937
1938const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1941const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1942const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1943const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1944const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1945const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1946
1947impl RecognitionArena {
1948 fn reset(&mut self) {
1949 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1950 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1951 reset_arena_vec(
1952 &mut self.diagnostic_links,
1953 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1954 );
1955 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1956 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1957 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1958 }
1959
1960 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1961 let id = RecognizedNodeId(
1962 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1963 );
1964 self.nodes.push(node);
1965 id
1966 }
1967
1968 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1969 let id = RecognitionExtraId(
1970 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1971 );
1972 self.extras.push(extra);
1973 id
1974 }
1975
1976 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1977 let id = NodeSeqId(
1978 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1979 );
1980 self.seq_links.push(SeqLink { head, tail });
1981 id
1982 }
1983
1984 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1985 let id = FastDeferredNodeId(
1986 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1987 );
1988 self.deferred_nodes.push(node);
1989 id
1990 }
1991
1992 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1993 let id = FastDeferredRuleId(
1994 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1995 );
1996 self.deferred_rules.push(rule);
1997 id
1998 }
1999
2000 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
2001 if nodes.is_empty() {
2002 FastDeferredNodeId::EMPTY
2003 } else {
2004 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
2005 }
2006 }
2007
2008 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
2009 let rule = self.push_deferred_rule(rule);
2010 self.push_deferred_node(FastDeferredNode::Rule(rule))
2011 }
2012
2013 fn deferred_alternative(&mut self, alt_number: usize) -> FastDeferredNodeId {
2014 self.push_deferred_node(FastDeferredNode::Alternative(
2015 u32::try_from(alt_number).expect("alternative number fits in u32"),
2016 ))
2017 }
2018
2019 fn deferred_left_recursive_boundary(&mut self, rule_index: usize) -> FastDeferredNodeId {
2020 self.push_deferred_node(FastDeferredNode::LeftRecursiveBoundary {
2021 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
2022 })
2023 }
2024
2025 fn concat_deferred_nodes(
2026 &mut self,
2027 prefix: FastDeferredNodeId,
2028 suffix: FastDeferredNodeId,
2029 ) -> FastDeferredNodeId {
2030 if prefix.is_empty() {
2031 return suffix;
2032 }
2033 if suffix.is_empty() {
2034 return prefix;
2035 }
2036 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
2037 }
2038
2039 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
2040 self.deferred_nodes[id.0 as usize]
2041 }
2042
2043 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
2044 self.deferred_rules[id.0 as usize]
2045 }
2046
2047 fn prepend_diagnostic(
2048 &mut self,
2049 tail: DiagnosticSeqId,
2050 diagnostic: ParserDiagnostic,
2051 ) -> DiagnosticSeqId {
2052 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
2053 self.prepend_diagnostic_id(tail, head)
2054 }
2055
2056 fn prepend_diagnostic_id(
2057 &mut self,
2058 tail: DiagnosticSeqId,
2059 head: RecognitionExtraId,
2060 ) -> DiagnosticSeqId {
2061 let id = DiagnosticSeqId(
2062 u32::try_from(self.diagnostic_links.len())
2063 .expect("diagnostic sequence arena fits in u32"),
2064 );
2065 self.diagnostic_links.push(DiagnosticLink { head, tail });
2066 id
2067 }
2068
2069 fn concat_diagnostics(
2070 &mut self,
2071 prefix: DiagnosticSeqId,
2072 mut suffix: DiagnosticSeqId,
2073 ) -> DiagnosticSeqId {
2074 if prefix.is_empty() {
2075 return suffix;
2076 }
2077 if suffix.is_empty() {
2078 return prefix;
2079 }
2080 let mut reversed = DiagnosticSeqId::EMPTY;
2081 let mut cursor = prefix;
2082 while let Some(link) = self.diagnostic_link(cursor) {
2083 reversed = self.prepend_diagnostic_id(reversed, link.head);
2084 cursor = link.tail;
2085 }
2086 while let Some(link) = self.diagnostic_link(reversed) {
2087 suffix = self.prepend_diagnostic_id(suffix, link.head);
2088 reversed = link.tail;
2089 }
2090 suffix
2091 }
2092
2093 #[cfg(test)]
2094 fn diagnostic_sequence(
2095 &mut self,
2096 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
2097 ) -> DiagnosticSeqId {
2098 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
2099 let mut sequence = DiagnosticSeqId::EMPTY;
2100 for diagnostic in diagnostics.into_iter().rev() {
2101 sequence = self.prepend_diagnostic(sequence, diagnostic);
2102 }
2103 sequence
2104 }
2105
2106 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
2107 self.nodes[id.0 as usize]
2108 }
2109
2110 fn set_boundary_alt_number(&mut self, id: RecognizedNodeId, alt_number: u32) {
2111 let ArenaRecognizedNode::LeftRecursiveBoundary {
2112 alt_number: stored, ..
2113 } = &mut self.nodes[id.0 as usize]
2114 else {
2115 unreachable!("deferred boundary must materialize as a boundary node");
2116 };
2117 *stored = alt_number;
2118 }
2119
2120 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
2121 &self.extras[id.0 as usize]
2122 }
2123
2124 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
2125 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
2126 }
2127
2128 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
2129 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
2130 }
2131
2132 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
2133 NodeSeqIter {
2134 arena: self,
2135 cursor: sequence,
2136 }
2137 }
2138
2139 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
2140 DiagnosticSeqIter {
2141 arena: self,
2142 cursor: sequence,
2143 }
2144 }
2145
2146 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
2147 self.diagnostics(sequence).count()
2148 }
2149
2150 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
2151 self.diagnostics(sequence)
2152 .filter(|diagnostic| {
2153 diagnostic.message.starts_with("mismatched input ")
2154 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
2155 })
2156 .count()
2157 }
2158
2159 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
2160 self.diagnostics(left).cmp(self.diagnostics(right))
2161 }
2162
2163 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
2164 self.iter(sequence).count()
2165 }
2166
2167 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
2168 self.iter(sequence).any(|node| match self.node(node) {
2169 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
2170 ArenaRecognizedNode::Rule { children, .. } => {
2171 self.sequence_has_left_recursive_boundary(children)
2172 }
2173 ArenaRecognizedNode::Token { .. }
2174 | ArenaRecognizedNode::ErrorToken { .. }
2175 | ArenaRecognizedNode::MissingToken { .. } => false,
2176 })
2177 }
2178
2179 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
2180 self.iter(sequence).any(|node| {
2181 matches!(
2182 self.node(node),
2183 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
2184 )
2185 })
2186 }
2187
2188 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
2189 self.iter(sequence).any(|node| {
2190 matches!(
2191 self.node(node),
2192 ArenaRecognizedNode::Token { .. }
2193 | ArenaRecognizedNode::ErrorToken { .. }
2194 | ArenaRecognizedNode::MissingToken { .. }
2195 )
2196 })
2197 }
2198
2199 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
2200 match self.node(node) {
2201 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
2202 Some(token.index())
2203 }
2204 ArenaRecognizedNode::MissingToken { extra } => {
2205 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
2206 unreachable!("missing-token node must reference missing-token extra");
2207 };
2208 Some(*at_index as usize)
2209 }
2210 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
2211 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
2212 }
2213 }
2214
2215 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
2216 match self.node(node) {
2217 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
2218 Some(token.index())
2219 }
2220 ArenaRecognizedNode::MissingToken { extra } => {
2221 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
2222 unreachable!("missing-token node must reference missing-token extra");
2223 };
2224 (*at_index as usize).checked_sub(1)
2225 }
2226 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
2227 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
2228 }
2229 }
2230
2231 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
2232 let start = self.node_start_index(node)?;
2233 let stop = self.node_stop_index(node);
2234 Some((start, stop))
2235 }
2236
2237 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
2238 self.iter(sequence)
2239 .find_map(|node| self.node_start_index(node))
2240 }
2241
2242 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
2243 let mut stop = None;
2244 for node in self.iter(sequence) {
2245 if let Some(index) = self.node_stop_index(node) {
2246 stop = Some(index);
2247 }
2248 }
2249 stop
2250 }
2251
2252 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
2253 self.iter(sequence)
2254 .any(|node| self.node_needs_stable_tie(node))
2255 }
2256
2257 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
2258 match self.node(node) {
2259 ArenaRecognizedNode::Token { .. }
2260 | ArenaRecognizedNode::ErrorToken { .. }
2261 | ArenaRecognizedNode::MissingToken { .. } => false,
2262 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
2263 ArenaRecognizedNode::Rule {
2264 rule_index,
2265 children,
2266 ..
2267 } => self.iter(children).any(|child| {
2268 matches!(
2269 self.node(child),
2270 ArenaRecognizedNode::Rule {
2271 rule_index: child_rule,
2272 ..
2273 } if child_rule == rule_index
2274 ) || self.node_needs_stable_tie(child)
2275 }),
2276 }
2277 }
2278
2279 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
2280 loop {
2281 match (self.link(left), self.link(right)) {
2282 (Some(left_link), Some(right_link)) => {
2283 let order = self.compare_nodes(left_link.head, right_link.head);
2284 if order != Ordering::Equal {
2285 return order;
2286 }
2287 left = left_link.tail;
2288 right = right_link.tail;
2289 }
2290 (None, None) => return Ordering::Equal,
2291 (None, Some(_)) => return Ordering::Less,
2292 (Some(_), None) => return Ordering::Greater,
2293 }
2294 }
2295 }
2296
2297 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
2298 let left = self.node(left);
2299 let right = self.node(right);
2300 match (left, right) {
2301 (
2302 ArenaRecognizedNode::Token { token: left },
2303 ArenaRecognizedNode::Token { token: right },
2304 )
2305 | (
2306 ArenaRecognizedNode::ErrorToken { token: left },
2307 ArenaRecognizedNode::ErrorToken { token: right },
2308 ) => left.cmp(&right),
2309 (
2310 ArenaRecognizedNode::MissingToken { extra: left },
2311 ArenaRecognizedNode::MissingToken { extra: right },
2312 ) => self.extra(left).cmp(self.extra(right)),
2313 (
2314 ArenaRecognizedNode::Rule {
2315 rule_index: left_rule,
2316 invoking_state: left_invoking,
2317 alt_number: left_alt,
2318 start_index: left_start,
2319 stop_index: left_stop,
2320 return_values: left_returns,
2321 children: left_children,
2322 },
2323 ArenaRecognizedNode::Rule {
2324 rule_index: right_rule,
2325 invoking_state: right_invoking,
2326 alt_number: right_alt,
2327 start_index: right_start,
2328 stop_index: right_stop,
2329 return_values: right_returns,
2330 children: right_children,
2331 },
2332 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
2333 .cmp(&(
2334 right_rule,
2335 right_invoking,
2336 right_alt,
2337 right_start,
2338 right_stop,
2339 ))
2340 .then_with(|| {
2341 left_returns
2342 .map(|id| self.extra(id))
2343 .cmp(&right_returns.map(|id| self.extra(id)))
2344 })
2345 .then_with(|| self.compare_sequences(left_children, right_children)),
2346 (
2347 ArenaRecognizedNode::LeftRecursiveBoundary {
2348 rule_index: left_rule,
2349 alt_number: left_alt,
2350 },
2351 ArenaRecognizedNode::LeftRecursiveBoundary {
2352 rule_index: right_rule,
2353 alt_number: right_alt,
2354 },
2355 ) => (left_rule, left_alt).cmp(&(right_rule, right_alt)),
2356 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
2357 }
2358 }
2359
2360 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2361 let mut reversed = NodeSeqId::EMPTY;
2362 while let Some(link) = self.link(sequence) {
2363 reversed = self.prepend(reversed, link.head);
2364 sequence = link.tail;
2365 }
2366 reversed
2367 }
2368
2369 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2370 if !self.sequence_has_direct_boundary(sequence) {
2371 return sequence;
2372 }
2373 let mut reversed = NodeSeqId::EMPTY;
2374 while let Some(link) = self.link(sequence) {
2375 match self.node(link.head) {
2376 ArenaRecognizedNode::LeftRecursiveBoundary {
2377 rule_index,
2378 alt_number,
2379 } => {
2380 if !reversed.is_empty() {
2381 let children = self.reverse_sequence(reversed);
2382 let start_index = self.sequence_start_index(children).unwrap_or_default();
2383 let stop_index = self.sequence_stop_index(children);
2384 let rule = self.push_node(ArenaRecognizedNode::Rule {
2385 rule_index,
2386 invoking_state: -1,
2387 alt_number,
2388 start_index: u32::try_from(start_index)
2389 .expect("left-recursive start index fits in u32"),
2390 stop_index: stop_index.map(|index| {
2391 u32::try_from(index).expect("left-recursive stop index fits in u32")
2392 }),
2393 return_values: None,
2394 children,
2395 });
2396 reversed = self.prepend(NodeSeqId::EMPTY, rule);
2397 }
2398 }
2399 _ => {
2400 reversed = self.prepend(reversed, link.head);
2401 }
2402 }
2403 sequence = link.tail;
2404 }
2405 self.reverse_sequence(reversed)
2406 }
2407
2408 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
2409 let mut live_nodes = vec![false; self.nodes.len()];
2410 let mut live_links = vec![false; self.seq_links.len()];
2411 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
2412 let mut live_extras = vec![false; self.extras.len()];
2413 let mut pending = vec![root];
2414 while let Some(mut sequence) = pending.pop() {
2415 while let Some(link) = self.link(sequence) {
2416 let link_index = sequence.0 as usize;
2417 if live_links[link_index] {
2418 break;
2419 }
2420 live_links[link_index] = true;
2421 let node_index = link.head.0 as usize;
2422 if !live_nodes[node_index] {
2423 live_nodes[node_index] = true;
2424 match self.node(link.head) {
2425 ArenaRecognizedNode::MissingToken { extra } => {
2426 live_extras[extra.0 as usize] = true;
2427 }
2428 ArenaRecognizedNode::Rule {
2429 return_values,
2430 children,
2431 ..
2432 } => {
2433 if let Some(extra) = return_values {
2434 live_extras[extra.0 as usize] = true;
2435 }
2436 pending.push(children);
2437 }
2438 ArenaRecognizedNode::Token { .. }
2439 | ArenaRecognizedNode::ErrorToken { .. }
2440 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
2441 }
2442 }
2443 sequence = link.tail;
2444 }
2445 }
2446 let mut diagnostics = diagnostics;
2447 while let Some(link) = self.diagnostic_link(diagnostics) {
2448 let link_index = diagnostics.0 as usize;
2449 if live_diagnostic_links[link_index] {
2450 break;
2451 }
2452 live_diagnostic_links[link_index] = true;
2453 live_extras[link.head.0 as usize] = true;
2454 diagnostics = link.tail;
2455 }
2456 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
2457 let live_link_count = live_links.into_iter().filter(|live| *live).count()
2458 + live_diagnostic_links
2459 .into_iter()
2460 .filter(|live| *live)
2461 .count();
2462 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
2463 let total_links = self.seq_links.len() + self.diagnostic_links.len();
2464 RecognitionArenaStats {
2465 total_nodes: self.nodes.len(),
2466 live_nodes: live_node_count,
2467 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
2468 node_capacity: self.nodes.capacity(),
2469 total_links,
2470 live_links: live_link_count,
2471 dead_links: total_links.saturating_sub(live_link_count),
2472 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
2473 total_extras: self.extras.len(),
2474 live_extras: live_extra_count,
2475 dead_extras: self.extras.len().saturating_sub(live_extra_count),
2476 extra_capacity: self.extras.capacity(),
2477 }
2478 }
2479}
2480
2481fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
2482 if storage.capacity() > max_retained_capacity {
2483 *storage = Vec::new();
2484 } else {
2485 storage.clear();
2486 }
2487}
2488
2489const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2490 match node {
2491 ArenaRecognizedNode::Token { .. } => 0,
2492 ArenaRecognizedNode::ErrorToken { .. } => 1,
2493 ArenaRecognizedNode::MissingToken { .. } => 2,
2494 ArenaRecognizedNode::Rule { .. } => 3,
2495 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2496 }
2497}
2498
2499struct NodeSeqIter<'a> {
2500 arena: &'a RecognitionArena,
2501 cursor: NodeSeqId,
2502}
2503
2504impl Iterator for NodeSeqIter<'_> {
2505 type Item = RecognizedNodeId;
2506
2507 fn next(&mut self) -> Option<Self::Item> {
2508 let link = self.arena.link(self.cursor)?;
2509 self.cursor = link.tail;
2510 Some(link.head)
2511 }
2512}
2513
2514struct DiagnosticSeqIter<'a> {
2515 arena: &'a RecognitionArena,
2516 cursor: DiagnosticSeqId,
2517}
2518
2519impl<'a> Iterator for DiagnosticSeqIter<'a> {
2520 type Item = &'a ParserDiagnostic;
2521
2522 fn next(&mut self) -> Option<Self::Item> {
2523 let link = self.arena.diagnostic_link(self.cursor)?;
2524 self.cursor = link.tail;
2525 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2526 unreachable!("diagnostic link must reference diagnostic extra");
2527 };
2528 Some(diagnostic)
2529 }
2530}
2531
2532#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2533struct ParserDiagnostic {
2534 line: usize,
2535 column: usize,
2536 message: String,
2537 offending: Option<TokenId>,
2541}
2542
2543#[derive(Clone, Debug, Default, Eq, PartialEq)]
2544struct ExpectedTokens {
2545 index: Option<usize>,
2546 symbols: BTreeSet<i32>,
2547 no_viable: Option<NoViableAlternative>,
2548}
2549
2550#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2551struct NoViableAlternative {
2552 start_index: usize,
2553 error_index: usize,
2554}
2555
2556impl ExpectedTokens {
2557 fn record_transition(
2560 &mut self,
2561 index: usize,
2562 transition: ParserTransition<'_>,
2563 max_token_type: i32,
2564 ) {
2565 let symbols = transition_expected_symbols(transition, max_token_type);
2566 match self.index {
2567 Some(current) if index < current => {}
2568 Some(current) if index == current => self.symbols.extend(symbols),
2569 _ => {
2570 self.index = Some(index);
2571 self.symbols = symbols;
2572 }
2573 }
2574 }
2575
2576 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2579 match self.no_viable {
2580 Some(current) if error_index < current.error_index => {}
2581 _ => {
2582 self.no_viable = Some(NoViableAlternative {
2583 start_index,
2584 error_index,
2585 });
2586 }
2587 }
2588 }
2589}
2590
2591#[derive(Clone, Debug, Default, Eq, PartialEq)]
2598struct TokenBitSet {
2599 words: Vec<u64>,
2600}
2601
2602impl TokenBitSet {
2603 fn insert(&mut self, symbol: i32) {
2604 let Some(slot) = token_bit_slot(symbol) else {
2605 return;
2606 };
2607 let word = slot / u64::BITS as usize;
2608 if word >= self.words.len() {
2609 self.words.resize(word + 1, 0);
2610 }
2611 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2612 }
2613
2614 fn extend_range(&mut self, start: i32, stop: i32) {
2615 let (start, stop) = if start <= stop {
2616 (start, stop)
2617 } else {
2618 (stop, start)
2619 };
2620 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2621 self.insert(TOKEN_EOF);
2622 }
2623 let positive_start = start.max(1);
2624 if positive_start > stop {
2625 return;
2626 }
2627 let Some(start_slot) = token_bit_slot(positive_start) else {
2628 return;
2629 };
2630 let Some(stop_slot) = token_bit_slot(stop) else {
2631 return;
2632 };
2633 self.extend_slot_range(start_slot, stop_slot);
2634 }
2635
2636 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2637 if start_slot > stop_slot {
2638 return;
2639 }
2640 let start_word = start_slot / u64::BITS as usize;
2641 let stop_word = stop_slot / u64::BITS as usize;
2642 if stop_word >= self.words.len() {
2643 self.words.resize(stop_word + 1, 0);
2644 }
2645 let start_offset = start_slot % u64::BITS as usize;
2646 let stop_offset = stop_slot % u64::BITS as usize;
2647 if start_word == stop_word {
2648 self.words[start_word] |=
2649 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2650 return;
2651 }
2652 self.words[start_word] |= !0_u64 << start_offset;
2653 for word in &mut self.words[(start_word + 1)..stop_word] {
2654 *word = !0_u64;
2655 }
2656 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2657 }
2658
2659 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2660 for symbol in symbols {
2661 self.insert(symbol);
2662 }
2663 }
2664
2665 fn extend_from(&mut self, other: &Self) {
2666 if other.words.len() > self.words.len() {
2667 self.words.resize(other.words.len(), 0);
2668 }
2669 for (left, right) in self.words.iter_mut().zip(&other.words) {
2670 *left |= *right;
2671 }
2672 }
2673
2674 fn contains(&self, symbol: i32) -> bool {
2675 let Some(slot) = token_bit_slot(symbol) else {
2676 return false;
2677 };
2678 let word = slot / u64::BITS as usize;
2679 self.words
2680 .get(word)
2681 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2682 }
2683
2684 fn is_empty(&self) -> bool {
2685 self.words.iter().all(|word| *word == 0)
2686 }
2687
2688 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2689 self.words
2690 .iter()
2691 .copied()
2692 .enumerate()
2693 .flat_map(|(word_index, mut bits)| {
2694 std::iter::from_fn(move || {
2695 while bits != 0 {
2696 let bit = bits.trailing_zeros() as usize;
2697 bits &= bits - 1;
2698 if let Some(symbol) =
2699 token_bit_symbol(word_index * u64::BITS as usize + bit)
2700 {
2701 return Some(symbol);
2702 }
2703 }
2704 None
2705 })
2706 })
2707 }
2708
2709 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2710 target.extend(self.symbols());
2711 }
2712
2713 fn to_btree_set(&self) -> BTreeSet<i32> {
2714 let mut out = BTreeSet::new();
2715 self.extend_btree_set(&mut out);
2716 out
2717 }
2718}
2719
2720fn token_bit_slot(symbol: i32) -> Option<usize> {
2721 if symbol == TOKEN_EOF {
2722 Some(0)
2723 } else if symbol > 0 {
2724 usize::try_from(symbol).ok()
2725 } else {
2726 None
2727 }
2728}
2729
2730fn token_bit_symbol(slot: usize) -> Option<i32> {
2731 if slot == 0 {
2732 Some(TOKEN_EOF)
2733 } else {
2734 i32::try_from(slot).ok()
2735 }
2736}
2737
2738fn transition_expected_symbols(
2741 transition: ParserTransition<'_>,
2742 max_token_type: i32,
2743) -> BTreeSet<i32> {
2744 let mut symbols = BTreeSet::new();
2745 match &transition.data() {
2746 Transition::Atom { label, .. } => {
2747 symbols.insert(*label);
2748 }
2749 Transition::Range { start, stop, .. } => {
2750 symbols.extend(*start..=*stop);
2751 }
2752 Transition::Set { set, .. } => {
2753 for (start, stop) in set.ranges() {
2754 symbols.extend(start..=stop);
2755 }
2756 }
2757 Transition::NotSet { set, .. } => {
2758 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2759 }
2760 Transition::Wildcard { .. } => {
2761 symbols.extend(1..=max_token_type);
2762 }
2763 Transition::Epsilon { .. }
2764 | Transition::Rule { .. }
2765 | Transition::Predicate { .. }
2766 | Transition::Action { .. }
2767 | Transition::Precedence { .. } => {}
2768 }
2769 symbols
2770}
2771
2772fn transition_expected_token_set(
2773 transition: ParserTransition<'_>,
2774 max_token_type: i32,
2775) -> TokenBitSet {
2776 let mut symbols = TokenBitSet::default();
2777 match &transition.data() {
2778 Transition::Atom { label, .. } => {
2779 symbols.insert(*label);
2780 }
2781 Transition::Range { start, stop, .. } => {
2782 symbols.extend_range(*start, *stop);
2783 }
2784 Transition::Set { set, .. } => {
2785 for (start, stop) in set.ranges() {
2786 symbols.extend_range(start, stop);
2787 }
2788 }
2789 Transition::NotSet { set, .. } => {
2790 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2791 }
2792 Transition::Wildcard { .. } => {
2793 symbols.extend_range(1, max_token_type);
2794 }
2795 Transition::Epsilon { .. }
2796 | Transition::Rule { .. }
2797 | Transition::Predicate { .. }
2798 | Transition::Action { .. }
2799 | Transition::Precedence { .. } => {}
2800 }
2801 symbols
2802}
2803
2804fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2808 let mut symbols = BTreeSet::new();
2809 let mut stack = vec![state_number];
2810 let mut visited = BTreeSet::new();
2811 while let Some(current) = stack.pop() {
2812 if !visited.insert(current) {
2813 continue;
2814 }
2815 let Some(state) = atn.state(current) else {
2816 continue;
2817 };
2818 for transition in &state.transitions() {
2819 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2820 if transition_symbols.is_empty() {
2821 if transition.is_epsilon() {
2822 stack.push(transition.target());
2823 }
2824 } else {
2825 symbols.extend(transition_symbols);
2826 }
2827 }
2828 }
2829 symbols
2830}
2831
2832fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2833 let mut symbols = TokenBitSet::default();
2834 let mut stack = vec![state_number];
2835 let mut visited = BTreeSet::new();
2836 while let Some(current) = stack.pop() {
2837 if !visited.insert(current) {
2838 continue;
2839 }
2840 let Some(state) = atn.state(current) else {
2841 continue;
2842 };
2843 for transition in &state.transitions() {
2844 let transition_symbols =
2845 transition_expected_token_set(transition, atn.max_token_type());
2846 if transition_symbols.is_empty() {
2847 if transition.is_epsilon() {
2848 stack.push(transition.target());
2849 }
2850 } else {
2851 symbols.extend_from(&transition_symbols);
2852 }
2853 }
2854 }
2855 symbols
2856}
2857
2858fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2859 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2860 return false;
2861 };
2862 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2863 return false;
2864 };
2865 epsilon_reaches_state(atn, state_number, stop_state)
2866}
2867
2868fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2869 let mut stack = vec![start];
2870 let mut visited = BTreeSet::new();
2871 while let Some(current) = stack.pop() {
2872 if current == target {
2873 return true;
2874 }
2875 if !visited.insert(current) {
2876 continue;
2877 }
2878 let Some(state) = atn.state(current) else {
2879 continue;
2880 };
2881 stack.extend(
2882 state
2883 .transitions()
2884 .iter()
2885 .filter(|transition| transition.is_epsilon())
2886 .map(ParserTransition::target),
2887 );
2888 }
2889 false
2890}
2891
2892#[derive(Clone, Debug, Default, Eq, PartialEq)]
2899struct FirstSet {
2900 symbols: TokenBitSet,
2901 nullable: bool,
2902}
2903
2904type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2911
2912type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2919
2920#[derive(Debug, Default)]
2921struct LeftRecursiveOperatorLookahead {
2922 single_token: TokenBitSet,
2926 multi_token_prefix: TokenBitSet,
2931 predicate_dependent: TokenBitSet,
2932}
2933
2934#[derive(Default)]
2935struct SharedAtnCache {
2936 first_set: FirstSetCache,
2937 decision_lookahead: DecisionLookaheadCache,
2938 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2939 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2940 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2941 rule_stop_reach: FxHashMap<usize, bool>,
2942 observable_action_transitions: Option<bool>,
2943 predicate_transitions: Option<bool>,
2944}
2945
2946thread_local! {
2947 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2948 RefCell::new(FxHashMap::default());
2949}
2950
2951#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2962struct SharedAtnCacheKey {
2963 atn: usize,
2964 states: usize,
2965 state_count: usize,
2966 max_token_type: i32,
2967}
2968
2969impl SharedAtnCacheKey {
2970 fn for_atn(atn: &Atn) -> Self {
2971 let (states, state_count) = atn.storage_identity();
2972 Self {
2973 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2974 states,
2975 state_count,
2976 max_token_type: atn.max_token_type(),
2977 }
2978 }
2979}
2980
2981fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2982 SHARED_ATN_CACHES.with(|cell| {
2983 let key = SharedAtnCacheKey::for_atn(atn);
2984 let mut map = cell.borrow_mut();
2985 let cache = map.entry(key).or_default();
2986 f(&mut cache.first_set)
2987 })
2988}
2989
2990fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2991 SHARED_ATN_CACHES.with(|cell| {
2992 let key = SharedAtnCacheKey::for_atn(atn);
2993 let mut map = cell.borrow_mut();
2994 let cache = map.entry(key).or_default();
2995 f(cache)
2996 })
2997}
2998
2999#[derive(Debug, Default)]
3008struct DecisionLookahead {
3009 transitions: Vec<TransitionLookSet>,
3010}
3011
3012#[derive(Clone, Debug, Default)]
3019struct TransitionLookSet {
3020 symbols: TokenBitSet,
3021 nullable: bool,
3022}
3023
3024struct FirstSetCtx<'a> {
3028 cache: &'a mut FirstSetCache,
3029 in_progress: BTreeSet<(usize, usize)>,
3030 hit_cycle: bool,
3031}
3032
3033fn rule_first_set(
3042 atn: &Atn,
3043 target: usize,
3044 rule_stop_state: usize,
3045 cache: &mut FirstSetCache,
3046) -> Rc<FirstSet> {
3047 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
3048 return Rc::clone(cached);
3049 }
3050 let mut ctx = FirstSetCtx {
3051 cache,
3052 in_progress: BTreeSet::new(),
3053 hit_cycle: false,
3054 };
3055 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
3056}
3057
3058fn rule_first_set_cached(
3059 atn: &Atn,
3060 target: usize,
3061 rule_stop_state: usize,
3062 ctx: &mut FirstSetCtx<'_>,
3063) -> Rc<FirstSet> {
3064 let key = (target, rule_stop_state);
3065 if let Some(cached) = ctx.cache.get(&key) {
3066 return Rc::clone(cached);
3067 }
3068 if !ctx.in_progress.insert(key) {
3069 return Rc::new(FirstSet::default());
3073 }
3074 let saved_hit_cycle = ctx.hit_cycle;
3075 ctx.hit_cycle = false;
3076 let mut first = FirstSet::default();
3077 let mut visited = BTreeSet::new();
3078 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
3079 ctx.in_progress.remove(&key);
3080 let entry = Rc::new(first);
3081 if !ctx.hit_cycle {
3082 ctx.cache.insert(key, Rc::clone(&entry));
3083 }
3084 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3085 entry
3086}
3087
3088fn transition_first_set(
3092 atn: &Atn,
3093 transition: ParserTransition<'_>,
3094 rule_stop_state: usize,
3095 cache: &mut FirstSetCache,
3096) -> TransitionLookSet {
3097 match &transition.data() {
3098 Transition::Atom { label, .. } => {
3099 let mut symbols = TokenBitSet::default();
3100 symbols.insert(*label);
3101 TransitionLookSet {
3102 symbols,
3103 nullable: false,
3104 }
3105 }
3106 Transition::Range { start, stop, .. } => {
3107 let mut symbols = TokenBitSet::default();
3108 symbols.extend_range(*start, *stop);
3109 TransitionLookSet {
3110 symbols,
3111 nullable: false,
3112 }
3113 }
3114 Transition::Set { set, .. } => {
3115 let mut symbols = TokenBitSet::default();
3116 for (start, stop) in set.ranges() {
3117 symbols.extend_range(start, stop);
3118 }
3119 TransitionLookSet {
3120 symbols,
3121 nullable: false,
3122 }
3123 }
3124 Transition::NotSet { set, .. } => {
3125 let max = atn.max_token_type();
3126 let mut symbols = TokenBitSet::default();
3127 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
3128 TransitionLookSet {
3129 symbols,
3130 nullable: false,
3131 }
3132 }
3133 Transition::Wildcard { .. } => {
3134 let mut symbols = TokenBitSet::default();
3135 symbols.extend_range(1, atn.max_token_type());
3136 TransitionLookSet {
3137 symbols,
3138 nullable: false,
3139 }
3140 }
3141 Transition::Epsilon { target }
3142 | Transition::Action { target, .. }
3143 | Transition::Predicate { target, .. }
3144 | Transition::Precedence { target, .. } => {
3145 let first = rule_first_set(atn, *target, rule_stop_state, cache);
3148 TransitionLookSet {
3149 symbols: first.symbols.clone(),
3150 nullable: first.nullable,
3151 }
3152 }
3153 Transition::Rule {
3154 target,
3155 rule_index,
3156 follow_state,
3157 ..
3158 } => {
3159 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3160 return TransitionLookSet::default();
3161 };
3162 let child = rule_first_set(atn, *target, child_stop, cache);
3163 let mut symbols = child.symbols.clone();
3164 let nullable = if child.nullable {
3165 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
3166 symbols.extend_from(&follow.symbols);
3167 follow.nullable
3168 } else {
3169 false
3170 };
3171 TransitionLookSet { symbols, nullable }
3172 }
3173 }
3174}
3175
3176fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
3197 let mut chosen: Option<usize> = None;
3198 for (index, transition) in entry.transitions.iter().enumerate() {
3199 if transition.nullable {
3200 return None;
3201 }
3202 if transition.symbols.contains(symbol) {
3203 if chosen.is_some() {
3204 return None;
3205 }
3206 chosen = Some(index);
3207 }
3208 }
3209 chosen
3210}
3211
3212fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
3221 let mut matching_non_nullable_alt = None;
3222 let mut nullable_alt = None;
3223 for (index, transition) in entry.transitions.iter().enumerate() {
3224 if transition.nullable {
3225 if nullable_alt.is_some() {
3226 return None;
3227 }
3228 nullable_alt = Some(index);
3229 }
3230 if transition.symbols.contains(symbol) {
3231 if transition.nullable {
3232 continue;
3233 }
3234 if matching_non_nullable_alt.is_some() {
3235 return None;
3236 }
3237 matching_non_nullable_alt = Some(index);
3238 }
3239 }
3240 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
3241 return None;
3242 }
3243 if non_greedy {
3244 nullable_alt.or(matching_non_nullable_alt)
3245 } else {
3246 matching_non_nullable_alt.or(nullable_alt)
3247 }
3248}
3249
3250fn should_skip_via_lookahead(
3251 transition_kind: ParserTransitionKind,
3252 transition_index: usize,
3253 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
3254 index: usize,
3255 record_expected: bool,
3256 expected: &mut ExpectedTokens,
3257) -> bool {
3258 let prune_non_consuming = matches!(
3259 transition_kind,
3260 ParserTransitionKind::Epsilon
3261 | ParserTransitionKind::Action
3262 | ParserTransitionKind::Predicate
3263 | ParserTransitionKind::Rule
3264 | ParserTransitionKind::Precedence
3265 );
3266 if !prune_non_consuming {
3267 return false;
3268 }
3269 let Some((symbol, entry)) = lookahead_filter else {
3270 return false;
3271 };
3272 let Some(set) = entry.transitions.get(transition_index) else {
3273 return false;
3274 };
3275 if set.symbols.contains(*symbol) || set.nullable {
3276 return false;
3277 }
3278 if record_expected && !set.symbols.is_empty() {
3279 record_pruned_transition_expected(set, index, expected);
3280 }
3281 true
3282}
3283
3284fn should_skip_rule_via_first_set(
3285 first: &FirstSet,
3286 symbol: i32,
3287 record_expected: bool,
3288 index: usize,
3289 expected: &mut ExpectedTokens,
3290) -> bool {
3291 if first.nullable || first.symbols.contains(symbol) {
3292 return false;
3293 }
3294 if record_expected && !first.symbols.is_empty() {
3295 record_token_bit_expected(&first.symbols, index, expected);
3296 }
3297 true
3298}
3299
3300fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
3301 match expected.index {
3302 Some(current) if index < current => {}
3303 Some(current) if index == current => {
3304 symbols.extend_btree_set(&mut expected.symbols);
3305 }
3306 _ => {
3307 expected.index = Some(index);
3308 expected.symbols = symbols.to_btree_set();
3309 }
3310 }
3311}
3312
3313fn record_pruned_transition_expected(
3315 set: &TransitionLookSet,
3316 index: usize,
3317 expected: &mut ExpectedTokens,
3318) {
3319 match expected.index {
3320 Some(current) if index < current => {}
3321 Some(current) if index == current => {
3322 set.symbols.extend_btree_set(&mut expected.symbols);
3323 }
3324 _ => {
3325 expected.index = Some(index);
3326 expected.symbols = set.symbols.to_btree_set();
3327 }
3328 }
3329}
3330
3331fn rule_first_set_inner(
3332 atn: &Atn,
3333 state_number: usize,
3334 rule_stop_state: usize,
3335 ctx: &mut FirstSetCtx<'_>,
3336 visited: &mut BTreeSet<usize>,
3337 first: &mut FirstSet,
3338) {
3339 if !visited.insert(state_number) {
3340 return;
3341 }
3342 if state_number == rule_stop_state {
3343 first.nullable = true;
3344 return;
3345 }
3346 let Some(state) = atn.state(state_number) else {
3347 return;
3348 };
3349 for transition in &state.transitions() {
3350 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3351 if !transition_symbols.is_empty() {
3352 first.symbols.extend_iter(transition_symbols);
3353 continue;
3354 }
3355 match &transition.data() {
3356 Transition::Epsilon { target }
3357 | Transition::Action { target, .. }
3358 | Transition::Predicate { target, .. }
3359 | Transition::Precedence { target, .. } => {
3360 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
3361 }
3362 Transition::Rule {
3363 target,
3364 rule_index,
3365 follow_state,
3366 ..
3367 } => {
3368 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3369 continue;
3370 };
3371 let child_key = (*target, child_stop);
3372 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
3373 ctx.hit_cycle = true;
3374 }
3375 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
3376 first.symbols.extend_from(&child.symbols);
3377 if child.nullable {
3378 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
3379 }
3380 }
3381 Transition::Atom { .. }
3382 | Transition::Range { .. }
3383 | Transition::Set { .. }
3384 | Transition::NotSet { .. }
3385 | Transition::Wildcard { .. } => {}
3386 }
3387 }
3388}
3389
3390fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
3393 let mut symbols = BTreeSet::new();
3394 state_sync_symbols_inner(
3395 atn,
3396 state_number,
3397 stop_state,
3398 &mut BTreeSet::new(),
3399 &mut symbols,
3400 );
3401 symbols
3402}
3403
3404fn state_sync_symbols_inner(
3407 atn: &Atn,
3408 state_number: usize,
3409 stop_state: usize,
3410 visited: &mut BTreeSet<usize>,
3411 symbols: &mut BTreeSet<i32>,
3412) {
3413 if !visited.insert(state_number) {
3414 return;
3415 }
3416 if state_number == stop_state {
3417 symbols.insert(TOKEN_EOF);
3418 return;
3419 }
3420 let Some(state) = atn.state(state_number) else {
3421 return;
3422 };
3423 for transition in &state.transitions() {
3424 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3425 if transition_symbols.is_empty() {
3426 match &transition.data() {
3427 Transition::Rule { target, .. }
3428 | Transition::Epsilon { target }
3429 | Transition::Action { target, .. }
3430 | Transition::Predicate { target, .. }
3431 | Transition::Precedence { target, .. } => {
3432 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
3433 }
3434 Transition::Atom { .. }
3435 | Transition::Range { .. }
3436 | Transition::Set { .. }
3437 | Transition::NotSet { .. }
3438 | Transition::Wildcard { .. } => {}
3439 }
3440 } else {
3441 symbols.extend(transition_symbols);
3442 }
3443 }
3444}
3445
3446#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
3447struct OperatorSymbolReachability {
3448 single_token: bool,
3450 multi_token: bool,
3452 predicate_dependent: bool,
3454}
3455
3456impl OperatorSymbolReachability {
3457 const ADAPTIVE_FALLBACK: Self = Self {
3458 single_token: false,
3459 multi_token: false,
3460 predicate_dependent: true,
3461 };
3462
3463 const fn single_token(predicate_dependent: bool) -> Self {
3464 if predicate_dependent {
3465 Self {
3466 single_token: false,
3467 multi_token: false,
3468 predicate_dependent: true,
3469 }
3470 } else {
3471 Self {
3472 single_token: true,
3473 multi_token: false,
3474 predicate_dependent: false,
3475 }
3476 }
3477 }
3478
3479 const fn multi_token(predicate_dependent: bool) -> Self {
3480 if predicate_dependent {
3481 Self {
3482 single_token: false,
3483 multi_token: false,
3484 predicate_dependent: true,
3485 }
3486 } else {
3487 Self {
3488 single_token: false,
3489 multi_token: true,
3490 predicate_dependent: false,
3491 }
3492 }
3493 }
3494
3495 const fn union(self, other: Self) -> Self {
3496 Self {
3497 single_token: self.single_token || other.single_token,
3498 multi_token: self.multi_token || other.multi_token,
3499 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3500 }
3501 }
3502}
3503
3504#[derive(Clone, Copy)]
3505struct OperatorReachabilityRequest {
3506 symbol: i32,
3507 precedence: i32,
3508 predicate_dependent: bool,
3509 operator_rule_index: usize,
3510}
3511
3512#[derive(Clone, Copy, Debug)]
3513struct OperatorRuleContinuation {
3514 stop_state: usize,
3515 follow_state: usize,
3516 return_precedence: i32,
3517}
3518
3519struct NullablePrecedenceCtx {
3520 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3521 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3522 hit_cycle: bool,
3523}
3524
3525fn state_is_nullable_with_precedence(
3526 atn: &Atn,
3527 state_number: usize,
3528 stop_state_number: usize,
3529 precedence: i32,
3530 allow_predicates: bool,
3531 ctx: &mut NullablePrecedenceCtx,
3532) -> bool {
3533 let saved_hit_cycle = ctx.hit_cycle;
3534 ctx.hit_cycle = false;
3535 let nullable = state_is_nullable_with_precedence_cached(
3536 atn,
3537 state_number,
3538 stop_state_number,
3539 precedence,
3540 allow_predicates,
3541 ctx,
3542 );
3543 ctx.hit_cycle = saved_hit_cycle;
3544 nullable
3545}
3546
3547fn state_is_nullable_with_precedence_cached(
3548 atn: &Atn,
3549 state_number: usize,
3550 stop_state_number: usize,
3551 precedence: i32,
3552 allow_predicates: bool,
3553 ctx: &mut NullablePrecedenceCtx,
3554) -> bool {
3555 if state_number == stop_state_number {
3556 return true;
3557 }
3558 let key = (
3559 state_number,
3560 stop_state_number,
3561 precedence,
3562 allow_predicates,
3563 );
3564 if let Some(cached) = ctx.cache.get(&key) {
3565 return *cached;
3566 }
3567 if !ctx.in_progress.insert(key) {
3568 ctx.hit_cycle = true;
3569 return false;
3570 }
3571 let saved_hit_cycle = ctx.hit_cycle;
3572 ctx.hit_cycle = false;
3573 let nullable = atn.state(state_number).is_some_and(|state| {
3574 state
3575 .transitions()
3576 .iter()
3577 .any(|transition| match &transition.data() {
3578 Transition::Rule {
3579 target,
3580 rule_index,
3581 follow_state,
3582 precedence: rule_precedence,
3583 } => {
3584 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3585 return false;
3586 };
3587 state_is_nullable_with_precedence_cached(
3588 atn,
3589 *target,
3590 child_stop,
3591 *rule_precedence,
3592 allow_predicates,
3593 ctx,
3594 ) && state_is_nullable_with_precedence_cached(
3595 atn,
3596 *follow_state,
3597 stop_state_number,
3598 precedence,
3599 allow_predicates,
3600 ctx,
3601 )
3602 }
3603 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3604 state_is_nullable_with_precedence_cached(
3605 atn,
3606 *target,
3607 stop_state_number,
3608 precedence,
3609 allow_predicates,
3610 ctx,
3611 )
3612 }
3613 Transition::Predicate { target, .. } if allow_predicates => {
3614 state_is_nullable_with_precedence_cached(
3615 atn,
3616 *target,
3617 stop_state_number,
3618 precedence,
3619 allow_predicates,
3620 ctx,
3621 )
3622 }
3623 Transition::Precedence {
3624 target,
3625 precedence: transition_precedence,
3626 } if *transition_precedence >= precedence => {
3627 state_is_nullable_with_precedence_cached(
3628 atn,
3629 *target,
3630 stop_state_number,
3631 precedence,
3632 allow_predicates,
3633 ctx,
3634 )
3635 }
3636 Transition::Atom { .. }
3637 | Transition::Range { .. }
3638 | Transition::Set { .. }
3639 | Transition::NotSet { .. }
3640 | Transition::Wildcard { .. }
3641 | Transition::Predicate { .. }
3642 | Transition::Precedence { .. } => false,
3643 })
3644 });
3645 ctx.in_progress.remove(&key);
3646 if !ctx.hit_cycle {
3647 ctx.cache.insert(key, nullable);
3648 }
3649 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3650 nullable
3651}
3652
3653fn state_operator_token_prefix_reachability(
3655 atn: &Atn,
3656 state_number: usize,
3657 request: OperatorReachabilityRequest,
3658 continuations: &[OperatorRuleContinuation],
3659 visited: &mut BTreeSet<(usize, i32, bool)>,
3660) -> OperatorSymbolReachability {
3661 let key = (
3662 state_number,
3663 request.precedence,
3664 request.predicate_dependent,
3665 );
3666 if !visited.insert(key) {
3667 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3671 }
3672 if let Some((continuation, remaining)) = continuations.split_last()
3673 && state_number == continuation.stop_state
3674 {
3675 let result = state_operator_token_prefix_reachability(
3676 atn,
3677 continuation.follow_state,
3678 OperatorReachabilityRequest {
3679 precedence: continuation.return_precedence,
3680 ..request
3681 },
3682 remaining,
3683 visited,
3684 );
3685 visited.remove(&key);
3686 return result;
3687 }
3688 let Some(state) = atn.state(state_number) else {
3689 visited.remove(&key);
3690 return OperatorSymbolReachability::default();
3691 };
3692 let completes_operator = match state.kind() {
3693 AtnStateKind::RuleStop => continuations.is_empty(),
3694 AtnStateKind::StarLoopBack
3695 | AtnStateKind::StarLoopEntry
3696 | AtnStateKind::PlusLoopBack
3697 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3698 _ => false,
3699 };
3700 if completes_operator {
3701 visited.remove(&key);
3702 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3703 }
3704 let mut reachability = OperatorSymbolReachability::default();
3705 for transition in &state.transitions() {
3706 let transition_reachability = match &transition.data() {
3707 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3708 OperatorSymbolReachability::single_token(request.predicate_dependent)
3709 }
3710 Transition::Rule {
3711 target,
3712 rule_index,
3713 follow_state,
3714 precedence: rule_precedence,
3715 } => {
3716 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3717 continue;
3718 };
3719 let mut nested = continuations.to_vec();
3720 nested.push(OperatorRuleContinuation {
3721 stop_state: child_stop,
3722 follow_state: *follow_state,
3723 return_precedence: request.precedence,
3724 });
3725 state_operator_token_prefix_reachability(
3726 atn,
3727 *target,
3728 OperatorReachabilityRequest {
3729 precedence: *rule_precedence,
3730 ..request
3731 },
3732 &nested,
3733 visited,
3734 )
3735 }
3736 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3737 state_operator_token_prefix_reachability(
3738 atn,
3739 *target,
3740 request,
3741 continuations,
3742 visited,
3743 )
3744 }
3745 Transition::Precedence {
3746 target,
3747 precedence: transition_precedence,
3748 } => {
3749 if *transition_precedence < request.precedence {
3750 OperatorSymbolReachability::default()
3751 } else {
3752 state_operator_token_prefix_reachability(
3753 atn,
3754 *target,
3755 request,
3756 continuations,
3757 visited,
3758 )
3759 }
3760 }
3761 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3762 atn,
3763 *target,
3764 OperatorReachabilityRequest {
3765 predicate_dependent: true,
3766 ..request
3767 },
3768 continuations,
3769 visited,
3770 ),
3771 Transition::Atom { .. }
3772 | Transition::Range { .. }
3773 | Transition::Set { .. }
3774 | Transition::NotSet { .. }
3775 | Transition::Wildcard { .. } => {
3776 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3777 }
3778 };
3779 reachability = reachability.union(transition_reachability);
3780 }
3781 visited.remove(&key);
3782 reachability
3783}
3784
3785fn state_can_reach_symbol_with_precedence(
3786 atn: &Atn,
3787 state_number: usize,
3788 request: OperatorReachabilityRequest,
3789 nullable_ctx: &mut NullablePrecedenceCtx,
3790 continuations: &mut Vec<OperatorRuleContinuation>,
3791 visited: &mut BTreeSet<(usize, i32, bool)>,
3792) -> OperatorSymbolReachability {
3793 let key = (
3794 state_number,
3795 request.precedence,
3796 request.predicate_dependent,
3797 );
3798 if !visited.insert(key) {
3799 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3800 }
3801 let Some(state) = atn.state(state_number) else {
3802 visited.remove(&key);
3803 return OperatorSymbolReachability::default();
3804 };
3805 let mut reachability = OperatorSymbolReachability::default();
3806 for transition in &state.transitions() {
3807 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3808 reachability = reachability.union(state_operator_token_prefix_reachability(
3809 atn,
3810 transition.target(),
3811 request,
3812 continuations,
3813 &mut BTreeSet::new(),
3814 ));
3815 continue;
3816 }
3817 let transition_reachability = match &transition.data() {
3818 Transition::Rule {
3819 target,
3820 rule_index,
3821 follow_state,
3822 precedence: rule_precedence,
3823 } => {
3824 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3825 continue;
3826 };
3827 continuations.push(OperatorRuleContinuation {
3828 stop_state: child_stop,
3829 follow_state: *follow_state,
3830 return_precedence: request.precedence,
3831 });
3832 let mut result = state_can_reach_symbol_with_precedence(
3833 atn,
3834 *target,
3835 OperatorReachabilityRequest {
3836 precedence: *rule_precedence,
3837 ..request
3838 },
3839 nullable_ctx,
3840 continuations,
3841 visited,
3842 );
3843 continuations.pop();
3844 if state_is_nullable_with_precedence(
3845 atn,
3846 *target,
3847 child_stop,
3848 *rule_precedence,
3849 true,
3850 nullable_ctx,
3851 ) {
3852 let child_predicate_dependent = request.predicate_dependent
3853 || !state_is_nullable_with_precedence(
3854 atn,
3855 *target,
3856 child_stop,
3857 *rule_precedence,
3858 false,
3859 nullable_ctx,
3860 );
3861 result = result.union(state_can_reach_symbol_with_precedence(
3862 atn,
3863 *follow_state,
3864 OperatorReachabilityRequest {
3865 predicate_dependent: child_predicate_dependent,
3866 ..request
3867 },
3868 nullable_ctx,
3869 continuations,
3870 visited,
3871 ));
3872 }
3873 result
3874 }
3875 Transition::Epsilon { target }
3876 | Transition::Action { target, .. }
3877 | Transition::Precedence { target, .. } => {
3878 if matches!(
3879 &transition.data(),
3880 Transition::Precedence {
3881 precedence: transition_precedence,
3882 ..
3883 } if *transition_precedence < request.precedence
3884 ) {
3885 continue;
3886 }
3887 state_can_reach_symbol_with_precedence(
3888 atn,
3889 *target,
3890 request,
3891 nullable_ctx,
3892 continuations,
3893 visited,
3894 )
3895 }
3896 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3897 atn,
3898 *target,
3899 OperatorReachabilityRequest {
3900 predicate_dependent: true,
3901 ..request
3902 },
3903 nullable_ctx,
3904 continuations,
3905 visited,
3906 ),
3907 Transition::Atom { .. }
3908 | Transition::Range { .. }
3909 | Transition::Set { .. }
3910 | Transition::NotSet { .. }
3911 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3912 };
3913 reachability = reachability.union(transition_reachability);
3914 }
3915 visited.remove(&key);
3916 reachability
3917}
3918
3919fn left_recursive_operator_lookahead(
3920 atn: &Atn,
3921 state_number: usize,
3922 precedence: i32,
3923) -> LeftRecursiveOperatorLookahead {
3924 let Some(state) = atn.state(state_number) else {
3925 return LeftRecursiveOperatorLookahead::default();
3926 };
3927 let Some(operator_rule_index) = state.rule_index() else {
3928 return LeftRecursiveOperatorLookahead::default();
3929 };
3930 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3931 let mut nullable_ctx = NullablePrecedenceCtx {
3932 cache: FxHashMap::default(),
3933 in_progress: BTreeSet::new(),
3934 hit_cycle: false,
3935 };
3936 for transition in &state.transitions() {
3937 let target = transition.target();
3938 if atn
3939 .state(target)
3940 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3941 {
3942 continue;
3943 }
3944 for symbol in 1..=atn.max_token_type() {
3945 let reachability = state_can_reach_symbol_with_precedence(
3946 atn,
3947 target,
3948 OperatorReachabilityRequest {
3949 symbol,
3950 precedence,
3951 predicate_dependent: false,
3952 operator_rule_index,
3953 },
3954 &mut nullable_ctx,
3955 &mut Vec::new(),
3956 &mut BTreeSet::new(),
3957 );
3958 if reachability.single_token {
3959 lookahead.single_token.insert(symbol);
3960 }
3961 if reachability.multi_token {
3962 lookahead.multi_token_prefix.insert(symbol);
3963 }
3964 if reachability.predicate_dependent {
3965 lookahead.predicate_dependent.insert(symbol);
3966 }
3967 }
3968 }
3969 lookahead
3970}
3971
3972#[derive(Debug, Default)]
3973struct StateBeforeStopLookahead {
3974 symbols: TokenBitSet,
3975 reaches_context_boundary: bool,
3976}
3977
3978fn state_before_stop_lookahead(
3979 atn: &Atn,
3980 state_number: usize,
3981 stop_state_number: usize,
3982) -> Rc<StateBeforeStopLookahead> {
3983 with_shared_atn_caches(atn, |cache| {
3984 let key = (state_number, stop_state_number);
3985 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3986 return Rc::clone(cached);
3987 }
3988 let mut lookahead = StateBeforeStopLookahead::default();
3989 state_before_stop_lookahead_inner(
3990 atn,
3991 state_number,
3992 stop_state_number,
3993 &mut BTreeSet::new(),
3994 &mut cache.first_set,
3995 &mut lookahead,
3996 );
3997 let lookahead = Rc::new(lookahead);
3998 cache
3999 .state_before_stop_lookahead
4000 .insert(key, Rc::clone(&lookahead));
4001 lookahead
4002 })
4003}
4004
4005fn state_before_stop_lookahead_inner(
4006 atn: &Atn,
4007 state_number: usize,
4008 stop_state_number: usize,
4009 visited: &mut BTreeSet<usize>,
4010 first_set_cache: &mut FirstSetCache,
4011 lookahead: &mut StateBeforeStopLookahead,
4012) {
4013 if state_number == stop_state_number {
4014 lookahead.reaches_context_boundary = true;
4015 return;
4016 }
4017 if !visited.insert(state_number) {
4018 return;
4019 }
4020 let Some(state) = atn.state(state_number) else {
4021 return;
4022 };
4023 if state.kind() == AtnStateKind::RuleStop {
4024 lookahead.reaches_context_boundary = true;
4025 return;
4026 }
4027 for transition in &state.transitions() {
4028 match &transition.data() {
4029 Transition::Epsilon { target }
4030 | Transition::Action { target, .. }
4031 | Transition::Predicate { target, .. }
4032 | Transition::Precedence { target, .. } => {
4033 state_before_stop_lookahead_inner(
4034 atn,
4035 *target,
4036 stop_state_number,
4037 visited,
4038 first_set_cache,
4039 lookahead,
4040 );
4041 }
4042 Transition::Rule {
4043 target,
4044 rule_index,
4045 follow_state,
4046 ..
4047 } => {
4048 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
4049 continue;
4050 };
4051 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
4052 lookahead.symbols.extend_from(&child.symbols);
4053 if child.nullable {
4054 state_before_stop_lookahead_inner(
4055 atn,
4056 *follow_state,
4057 stop_state_number,
4058 visited,
4059 first_set_cache,
4060 lookahead,
4061 );
4062 }
4063 }
4064 Transition::Atom { .. }
4065 | Transition::Range { .. }
4066 | Transition::Set { .. }
4067 | Transition::NotSet { .. }
4068 | Transition::Wildcard { .. } => {
4069 lookahead.symbols.extend_iter(transition_expected_symbols(
4070 transition,
4071 atn.max_token_type(),
4072 ));
4073 }
4074 }
4075 }
4076}
4077
4078fn caller_context_can_match_symbol_before_state(
4079 atn: &Atn,
4080 return_states: impl DoubleEndedIterator<Item = usize>,
4081 stop_state_number: usize,
4082 symbol: i32,
4083) -> bool {
4084 for return_state in return_states.rev() {
4085 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
4086 if lookahead.symbols.contains(symbol) {
4087 return true;
4088 }
4089 if !lookahead.reaches_context_boundary {
4090 return false;
4091 }
4092 }
4093 false
4094}
4095
4096fn next_recovery_context(
4100 atn: &Atn,
4101 state: AtnState<'_>,
4102 inherited: &BTreeSet<i32>,
4103 inherited_state: Option<usize>,
4104) -> (BTreeSet<i32>, Option<usize>) {
4105 let state_symbols = state_expected_symbols(atn, state.state_number());
4106 if state.transitions().len() > 1 && !state_symbols.is_empty() {
4107 let mut symbols = state_symbols;
4108 symbols.extend(inherited.iter().copied());
4109 return (symbols, Some(state.state_number()));
4110 }
4111 (inherited.clone(), inherited_state)
4112}
4113
4114fn recovery_expected_symbols(
4115 atn: &Atn,
4116 state_number: usize,
4117 inherited: &BTreeSet<i32>,
4118) -> BTreeSet<i32> {
4119 let mut symbols = state_expected_symbols(atn, state_number);
4120 symbols.extend(inherited.iter().copied());
4121 symbols
4122}
4123
4124fn fast_next_recovery_context<S, H>(
4128 parser: &mut BaseParser<S, H>,
4129 atn: &Atn,
4130 state: AtnState<'_>,
4131 inherited: &Rc<BTreeSet<i32>>,
4132 inherited_state: Option<usize>,
4133) -> (Rc<BTreeSet<i32>>, Option<usize>)
4134where
4135 S: TokenSource,
4136 H: SemanticHooks,
4137{
4138 if state.transitions().len() <= 1 {
4139 return (Rc::clone(inherited), inherited_state);
4140 }
4141 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
4142 if state_symbols.is_empty() {
4143 return (Rc::clone(inherited), inherited_state);
4144 }
4145 if inherited.is_empty() {
4146 return (state_symbols, Some(state.state_number()));
4147 }
4148 if Rc::ptr_eq(&state_symbols, inherited) {
4149 return (state_symbols, Some(state.state_number()));
4150 }
4151 let mut combined = (*state_symbols).clone();
4152 combined.extend(inherited.iter().copied());
4153 (
4154 parser.intern_recovery_symbols(combined),
4155 Some(state.state_number()),
4156 )
4157}
4158
4159fn fast_recovery_expected_symbols<S, H>(
4163 parser: &mut BaseParser<S, H>,
4164 atn: &Atn,
4165 state_number: usize,
4166 inherited: &Rc<BTreeSet<i32>>,
4167) -> Rc<BTreeSet<i32>>
4168where
4169 S: TokenSource,
4170 H: SemanticHooks,
4171{
4172 let cached = parser.cached_state_expected_symbols(atn, state_number);
4173 if inherited.is_empty() {
4174 return cached;
4175 }
4176 if cached.is_empty() {
4177 return Rc::clone(inherited);
4178 }
4179 if Rc::ptr_eq(&cached, inherited) {
4180 return cached;
4181 }
4182 let mut combined = (*cached).clone();
4183 combined.extend(inherited.iter().copied());
4184 parser.intern_recovery_symbols(combined)
4185}
4186
4187struct ParserTableSemCtx<'a> {
4188 member_values: &'a mut MemberEnv,
4189 return_values: &'a mut BTreeMap<String, i64>,
4190}
4191
4192impl semir::PredContext for ParserTableSemCtx<'_> {
4193 type TokenText<'a>
4194 = &'a str
4195 where
4196 Self: 'a;
4197
4198 fn la(&mut self, _offset: isize) -> i64 {
4199 i64::from(TOKEN_EOF)
4200 }
4201
4202 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
4203 None
4204 }
4205
4206 fn token_index_adjacent(&mut self) -> bool {
4207 false
4208 }
4209
4210 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
4211 None
4212 }
4213
4214 fn member(&self, member: usize) -> Option<i64> {
4215 Some(self.member_values.scalar(member).unwrap_or_default())
4216 }
4217
4218 fn member_top(&self, member: usize) -> Option<i64> {
4219 self.member_values.stack_top(member)
4220 }
4221
4222 fn member_len(&self, member: usize) -> usize {
4223 self.member_values.stack_len(member)
4224 }
4225
4226 fn local_arg(&self) -> Option<i64> {
4227 None
4228 }
4229
4230 fn column(&self) -> Option<i64> {
4231 None
4232 }
4233
4234 fn token_start_column(&self) -> Option<i64> {
4235 None
4236 }
4237
4238 fn token_text_so_far(&self) -> Option<String> {
4239 None
4240 }
4241
4242 fn hook(&mut self, _hook: HookId) -> bool {
4243 false
4244 }
4245}
4246
4247impl semir::ActContext for ParserTableSemCtx<'_> {
4248 fn set_member(&mut self, member: usize, value: i64) {
4249 self.member_values.set_scalar(member, value);
4250 }
4251
4252 fn push_member(&mut self, member: usize, value: i64) {
4253 self.member_values.push_stack(member, value);
4254 }
4255
4256 fn pop_member(&mut self, member: usize) -> Option<i64> {
4257 self.member_values.pop_stack(member)
4258 }
4259
4260 fn set_return(&mut self, name: &str, value: i64) {
4261 self.return_values.insert(name.to_owned(), value);
4262 }
4263
4264 fn action_hook(&mut self, _hook: HookId) {}
4265}
4266
4267fn apply_member_actions(
4269 source_state: usize,
4270 actions: &[ParserMemberAction],
4271 semantics: Option<&ParserSemantics>,
4272 values: &mut MemberEnv,
4273) {
4274 for action in actions
4275 .iter()
4276 .filter(|action| action.source_state == source_state)
4277 {
4278 values.add_scalar(action.member, action.delta);
4279 }
4280 let Some(semantics) = semantics else {
4281 return;
4282 };
4283 let mut return_values = BTreeMap::new();
4284 let mut ctx = ParserTableSemCtx {
4285 member_values: values,
4286 return_values: &mut return_values,
4287 };
4288 for action in semantics
4289 .actions
4290 .iter()
4291 .filter(|action| action.source_state == source_state && action.speculative)
4292 {
4293 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4294 }
4295}
4296
4297fn member_values_after_action(
4299 source_state: usize,
4300 actions: &[ParserMemberAction],
4301 semantics: Option<&ParserSemantics>,
4302 values: &MemberEnv,
4303) -> MemberEnv {
4304 let mut values = values.clone();
4305 apply_member_actions(source_state, actions, semantics, &mut values);
4306 values
4307}
4308
4309fn return_values_after_action(
4311 source_state: usize,
4312 rule_index: usize,
4313 actions: &[ParserReturnAction],
4314 semantics: Option<&ParserSemantics>,
4315 values: &BTreeMap<String, i64>,
4316) -> BTreeMap<String, i64> {
4317 let mut values = values.clone();
4318 for action in actions
4319 .iter()
4320 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
4321 {
4322 values.insert(action.name.to_owned(), action.value);
4323 }
4324 if let Some(semantics) = semantics {
4325 let mut member_values = MemberEnv::new();
4326 let mut ctx = ParserTableSemCtx {
4327 member_values: &mut member_values,
4328 return_values: &mut values,
4329 };
4330 for action in semantics.actions.iter().filter(|action| {
4331 action.source_state == source_state
4332 && action.rule_index == rule_index
4333 && !action.speculative
4334 }) {
4335 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4336 }
4337 }
4338 values
4339}
4340
4341fn rule_local_int_arg(
4343 rule_args: &[ParserRuleArg],
4344 source_state: usize,
4345 rule_index: usize,
4346 local_int_arg: Option<(usize, i64)>,
4347) -> Option<(usize, i64)> {
4348 rule_args
4349 .iter()
4350 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
4351 .map(|arg| {
4352 let value = if arg.inherit_local {
4353 local_int_arg.map_or(arg.value, |(_, value)| value)
4354 } else {
4355 arg.value
4356 };
4357 (rule_index, value)
4358 })
4359}
4360
4361fn stop_outcome(
4364 index: usize,
4365 consumed_eof: bool,
4366 rule_alt_number: usize,
4367 member_values: MemberEnv,
4368 return_values: BTreeMap<String, i64>,
4369) -> Vec<RecognizeOutcome> {
4370 vec![RecognizeOutcome {
4371 index,
4372 consumed_eof,
4373 alt_number: rule_alt_number,
4374 member_values,
4375 return_values,
4376 diagnostics: DiagnosticSeqId::EMPTY,
4377 decisions: Vec::new(),
4378 actions: Vec::new(),
4379 nodes: NodeSeqId::EMPTY,
4380 }]
4381}
4382
4383fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
4384 with_shared_atn_caches(atn, |cache| {
4385 *cache.observable_action_transitions.get_or_insert_with(|| {
4386 atn.states().any(|state| {
4387 state.transitions().iter().any(|transition| {
4388 matches!(
4389 &transition.data(),
4390 Transition::Action {
4391 action_index: Some(_),
4392 ..
4393 }
4394 )
4395 })
4396 })
4397 })
4398 })
4399}
4400
4401fn atn_has_predicate_transitions(atn: &Atn) -> bool {
4402 with_shared_atn_caches(atn, |cache| {
4403 *cache.predicate_transitions.get_or_insert_with(|| {
4404 atn.states().any(|state| {
4405 state
4406 .transitions()
4407 .iter()
4408 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
4409 })
4410 })
4411 })
4412}
4413
4414fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
4419 options.init_action_rules.is_empty()
4420 && options.action_indices.is_empty()
4421 && !options.track_alt_numbers
4422 && options
4423 .predicates
4424 .iter()
4425 .all(|(_, _, predicate)| predicate.failure_message().is_none())
4426 && options.semantics.is_none_or(|semantics| {
4427 semantics.actions.is_empty()
4428 && semantics
4429 .predicates
4430 .iter()
4431 .all(|predicate| predicate.failure_message.is_none())
4432 })
4433 && options.rule_args.is_empty()
4434 && options.member_actions.is_empty()
4435 && options.return_actions.is_empty()
4436 && !atn_has_observable_action_transitions(atn)
4437}
4438
4439#[derive(Clone, Debug, Eq, PartialEq)]
4440struct RecognizeRequest<'a> {
4441 state_number: usize,
4442 stop_state: usize,
4443 index: usize,
4444 rule_start_index: usize,
4445 decision_start_index: Option<usize>,
4446 init_action_rules: &'a BTreeSet<usize>,
4447 predicates: &'a [(usize, usize, ParserPredicate)],
4448 semantics: Option<&'a ParserSemantics>,
4449 rule_args: &'a [ParserRuleArg],
4450 member_actions: &'a [ParserMemberAction],
4451 return_actions: &'a [ParserReturnAction],
4452 local_int_arg: Option<(usize, i64)>,
4453 member_values: MemberEnv,
4454 return_values: BTreeMap<String, i64>,
4455 rule_alt_number: usize,
4456 track_alt_numbers: bool,
4457 consumed_eof: bool,
4458 committed_decision: bool,
4459 precedence: i32,
4462 depth: usize,
4463 recovery_symbols: BTreeSet<i32>,
4464 recovery_state: Option<usize>,
4465}
4466
4467#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4468struct RecognizeKey {
4469 state_number: usize,
4470 stop_state: usize,
4471 index: usize,
4472 rule_start_index: usize,
4473 decision_start_index: Option<usize>,
4474 local_int_arg: Option<(usize, i64)>,
4475 member_values: MemberEnv,
4476 return_values: BTreeMap<String, i64>,
4477 rule_alt_number: usize,
4478 track_alt_numbers: bool,
4479 consumed_eof: bool,
4480 committed_decision: bool,
4481 precedence: i32,
4482 recovery_symbols: BTreeSet<i32>,
4483 recovery_state: Option<usize>,
4484}
4485
4486#[derive(Clone, Debug, Eq, PartialEq)]
4487struct EpsilonActionStep {
4488 source_state: usize,
4489 target: usize,
4490 action_rule_index: Option<usize>,
4491 action_index: Option<usize>,
4492 left_recursive_boundary: Option<usize>,
4493 decision: Option<usize>,
4494 decision_start_index: Option<usize>,
4495 alt_number: usize,
4496 recovery_symbols: BTreeSet<i32>,
4497 recovery_state: Option<usize>,
4498}
4499
4500struct RecognizeScratch<'a> {
4501 visiting: &'a mut BTreeSet<RecognizeKey>,
4502 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4503 expected: &'a mut ExpectedTokens,
4504}
4505
4506#[derive(Clone, Debug, Eq, PartialEq)]
4507struct FastRecognizeRequest {
4508 state_number: usize,
4509 stop_state: usize,
4510 index: usize,
4511 rule_start_index: usize,
4512 decision_start_index: Option<usize>,
4513 precedence: i32,
4514 depth: usize,
4515 recovery_symbols: Rc<BTreeSet<i32>>,
4516 recovery_state: Option<usize>,
4517}
4518
4519#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4520struct FastRecognizeTopRequest {
4521 start_state: usize,
4522 stop_state: usize,
4523 start_index: usize,
4524 precedence: i32,
4525 caller_follow_state: Option<usize>,
4526}
4527
4528#[derive(Clone, Copy, Debug)]
4529struct FastPredicateContext<'a> {
4530 predicates: &'a [(usize, usize, ParserPredicate)],
4531 semantics: Option<&'a ParserSemantics>,
4532 member_values: &'a MemberEnv,
4533}
4534
4535#[derive(Clone, Copy, Debug, Default)]
4536struct AltNumberTracking {
4537 public: bool,
4538 context: bool,
4539}
4540
4541impl AltNumberTracking {
4542 const fn any(self) -> bool {
4543 self.public || self.context
4544 }
4545}
4546
4547struct FastRecognizeScratch<'a, 'b> {
4548 predicate_context: Option<FastPredicateContext<'a>>,
4549 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4550 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4551 expected: &'b mut ExpectedTokens,
4552 native_depth: usize,
4553}
4554
4555#[derive(Clone, Copy, Debug)]
4556struct FastRepetitionShape {
4557 enter_target: usize,
4558 exit_target: usize,
4559 body_stop_state: usize,
4560 enter_transition_index: usize,
4561 exit_transition_index: usize,
4562}
4563
4564#[derive(Clone, Copy, Debug)]
4565struct FastRepetitionPath {
4566 index: usize,
4567 deferred_nodes: FastDeferredNodeId,
4568 diagnostics: DiagnosticSeqId,
4569 consumed_eof: bool,
4570}
4571
4572enum FastRepetitionWork {
4573 Enter(FastRepetitionPath),
4574 Exit(FastRepetitionPath),
4575}
4576
4577struct FastRepetitionCoordinates {
4582 base_index: usize,
4583 base_state: u8,
4584 later_states: Vec<u8>,
4585}
4586
4587impl FastRepetitionCoordinates {
4588 const ENTERED: u8 = 0;
4589 const EXITED: u8 = 2;
4590
4591 const fn new(base_index: usize) -> Self {
4592 Self {
4593 base_index,
4594 base_state: 0,
4595 later_states: Vec::new(),
4596 }
4597 }
4598
4599 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4600 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4601 }
4602
4603 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4604 self.insert(path.index, path.consumed_eof, Self::EXITED)
4605 }
4606
4607 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4608 let Some(offset) = index.checked_sub(self.base_index) else {
4609 return false;
4610 };
4611 let state = if offset == 0 {
4612 &mut self.base_state
4613 } else {
4614 if self.later_states.len() < offset {
4615 self.later_states.resize(offset, 0);
4616 }
4617 &mut self.later_states[offset - 1]
4618 };
4619 let bit = 1 << (base_bit + u8::from(consumed_eof));
4620 let is_new = *state & bit == 0;
4621 *state |= bit;
4622 is_new
4623 }
4624}
4625
4626fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4627 if state.precedence_rule_decision()
4628 || !matches!(
4629 state.kind(),
4630 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4631 )
4632 || state.transitions().len() != 2
4633 {
4634 return None;
4635 }
4636 let mut enter = None;
4637 let mut exit = None;
4638 for (index, transition) in state.transitions().iter().enumerate() {
4639 if transition.kind() != ParserTransitionKind::Epsilon {
4640 return None;
4641 }
4642 let target = transition.target();
4643 if atn
4644 .state(target)
4645 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4646 {
4647 if exit.replace((index, target)).is_some() {
4648 return None;
4649 }
4650 } else if enter.replace((index, target)).is_some() {
4651 return None;
4652 }
4653 }
4654 let (enter_transition_index, enter_target) = enter?;
4655 let (exit_transition_index, exit_target) = exit?;
4656 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4657 atn.state(exit_target)?.loop_back_state()?
4658 } else {
4659 state.state_number()
4660 };
4661 Some(FastRepetitionShape {
4662 enter_target,
4663 exit_target,
4664 body_stop_state,
4665 enter_transition_index,
4666 exit_transition_index,
4667 })
4668}
4669
4670fn push_fast_repetition_work(
4671 work: &mut Vec<FastRepetitionWork>,
4672 shape: FastRepetitionShape,
4673 path: FastRepetitionPath,
4674 lookahead: Option<&DecisionLookahead>,
4675 symbol: i32,
4676) {
4677 let transition_is_viable = |transition_index: usize| {
4680 let Some(entry) = lookahead else {
4681 return true;
4682 };
4683 let Some(transition) = entry.transitions.get(transition_index) else {
4684 return true;
4685 };
4686 transition.nullable || transition.symbols.contains(symbol)
4687 };
4688 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4689 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4690 if shape.enter_transition_index < shape.exit_transition_index {
4691 if exit_is_viable {
4692 work.push(FastRepetitionWork::Exit(path));
4693 }
4694 if enter_is_viable {
4695 work.push(FastRepetitionWork::Enter(path));
4696 }
4697 } else {
4698 if enter_is_viable {
4699 work.push(FastRepetitionWork::Enter(path));
4700 }
4701 if exit_is_viable {
4702 work.push(FastRepetitionWork::Exit(path));
4703 }
4704 }
4705}
4706
4707#[derive(Clone, Debug)]
4714struct FastRecognizeKey {
4715 state_number: usize,
4716 stop_state: usize,
4717 index: usize,
4718 rule_start_index: usize,
4719 decision_start_index: Option<usize>,
4720 precedence: i32,
4721 recovery_symbols_id: usize,
4722 recovery_state: Option<usize>,
4723}
4724
4725impl PartialEq for FastRecognizeKey {
4726 fn eq(&self, other: &Self) -> bool {
4727 if self.state_number != other.state_number
4728 || self.stop_state != other.stop_state
4729 || self.index != other.index
4730 || self.rule_start_index != other.rule_start_index
4731 || self.decision_start_index != other.decision_start_index
4732 || self.precedence != other.precedence
4733 || self.recovery_state != other.recovery_state
4734 || self.recovery_symbols_id != other.recovery_symbols_id
4735 {
4736 return false;
4737 }
4738 true
4739 }
4740}
4741
4742impl Eq for FastRecognizeKey {}
4743
4744impl Hash for FastRecognizeKey {
4745 fn hash<H: Hasher>(&self, hasher: &mut H) {
4746 self.state_number.hash(hasher);
4747 self.stop_state.hash(hasher);
4748 self.index.hash(hasher);
4749 self.rule_start_index.hash(hasher);
4750 self.decision_start_index.hash(hasher);
4751 self.precedence.hash(hasher);
4752 self.recovery_state.hash(hasher);
4753 self.recovery_symbols_id.hash(hasher);
4754 }
4755}
4756
4757struct FastRecoveryRequest<'a, 'b> {
4758 atn: &'a Atn,
4759 transition: ParserTransition<'a>,
4760 expected_symbols: Rc<BTreeSet<i32>>,
4761 target: usize,
4762 request: FastRecognizeRequest,
4763 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4764 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4765 expected: &'b mut ExpectedTokens,
4766}
4767
4768struct FastCurrentTokenDeletionRequest<'a, 'b> {
4769 atn: &'a Atn,
4770 expected_symbols: Rc<BTreeSet<i32>>,
4771 request: FastRecognizeRequest,
4772 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4773 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4774 expected: &'b mut ExpectedTokens,
4775}
4776
4777#[derive(Clone, Copy)]
4778struct FastChildRuleFailureRecoveryRequest<'a> {
4779 atn: &'a Atn,
4780 rule_index: usize,
4781 start_index: usize,
4782 follow_state: usize,
4783 stop_state: usize,
4784 expected: &'a ExpectedTokens,
4785}
4786
4787struct RecoveryRequest<'a, 'b> {
4788 atn: &'a Atn,
4789 transition: ParserTransition<'a>,
4790 expected_symbols: BTreeSet<i32>,
4791 target: usize,
4792 request: RecognizeRequest<'a>,
4793 visiting: &'b mut BTreeSet<RecognizeKey>,
4794 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4795 expected: &'b mut ExpectedTokens,
4796}
4797
4798struct CurrentTokenDeletionRequest<'a, 'b> {
4799 atn: &'a Atn,
4800 expected_symbols: BTreeSet<i32>,
4801 request: RecognizeRequest<'a>,
4802 visiting: &'b mut BTreeSet<RecognizeKey>,
4803 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4804 expected: &'b mut ExpectedTokens,
4805}
4806
4807struct ConsumingFailureFallback<'a> {
4810 atn: &'a Atn,
4811 target: usize,
4812 request: RecognizeRequest<'a>,
4813 symbol: i32,
4814 expected_symbols: BTreeSet<i32>,
4815 decision_start_index: Option<usize>,
4816 decision: Option<usize>,
4817}
4818
4819struct ChildRuleFailureRecovery<'a> {
4822 atn: &'a Atn,
4823 rule_index: usize,
4824 start_index: usize,
4825 follow_state: usize,
4826 stop_state: usize,
4827 member_values: MemberEnv,
4828 expected: &'a ExpectedTokens,
4829}
4830
4831#[derive(Clone, Copy, Debug)]
4833struct PredicateEval<'a> {
4834 index: usize,
4835 rule_index: usize,
4836 pred_index: usize,
4837 predicates: &'a [(usize, usize, ParserPredicate)],
4838 semantics: Option<&'a ParserSemantics>,
4839 context: Option<&'a ParserRuleContext>,
4840 local_int_arg: Option<(usize, i64)>,
4841 member_values: &'a MemberEnv,
4842}
4843
4844#[derive(Clone, Copy, Debug)]
4845struct ParserSemanticHookRequest<'a> {
4846 index: usize,
4847 rule_index: usize,
4848 pred_index: usize,
4849 context: Option<&'a ParserRuleContext>,
4850 local_int_arg: Option<(usize, i64)>,
4851 member_values: &'a MemberEnv,
4852}
4853
4854struct ParserSemIrCtx<'a, S, H>
4863where
4864 S: TokenSource,
4865 H: SemanticHooks,
4866{
4867 input: &'a mut CommonTokenStream<S>,
4868 tree_storage: &'a ParseTreeStorage,
4869 semantic_hooks: &'a mut H,
4870 rule_index: usize,
4871 coordinate_index: usize,
4872 rule_name: Option<&'a str>,
4873 context: Option<&'a ParserRuleContext>,
4874 local_int_arg: Option<(usize, i64)>,
4875 member_values: &'a MemberEnv,
4876 invoked_predicates: &'a mut Vec<(usize, usize)>,
4877 unknown_predicate_policy: UnknownSemanticPolicy,
4881 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4882}
4883
4884impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4885where
4886 S: TokenSource,
4887 H: SemanticHooks,
4888{
4889 type TokenText<'a>
4890 = TokenView<'a>
4891 where
4892 Self: 'a;
4893
4894 fn la(&mut self, offset: isize) -> i64 {
4895 i64::from(self.input.la(offset))
4896 }
4897
4898 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4899 self.input.lt(offset)
4900 }
4901
4902 fn token_index_adjacent(&mut self) -> bool {
4903 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4904 return false;
4905 };
4906 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4907 return false;
4908 };
4909 first + 1 == second
4910 }
4911
4912 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4913 self.context.and_then(|context| {
4914 context
4915 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4916 .next()
4917 .map(crate::tree::RuleNodeView::text)
4918 })
4919 }
4920
4921 fn member(&self, member: usize) -> Option<i64> {
4922 Some(self.member_values.scalar(member).unwrap_or_default())
4923 }
4924
4925 fn member_top(&self, member: usize) -> Option<i64> {
4926 self.member_values.stack_top(member)
4927 }
4928
4929 fn member_len(&self, member: usize) -> usize {
4930 self.member_values.stack_len(member)
4931 }
4932
4933 fn local_arg(&self) -> Option<i64> {
4934 self.local_int_arg.map(|(_, value)| value)
4935 }
4936
4937 fn column(&self) -> Option<i64> {
4938 None
4939 }
4940
4941 fn token_start_column(&self) -> Option<i64> {
4942 None
4943 }
4944
4945 fn token_text_so_far(&self) -> Option<String> {
4946 None
4947 }
4948
4949 fn hook(&mut self, _hook: HookId) -> bool {
4950 let mut ctx = ParserSemCtx {
4951 input: &mut *self.input,
4952 tree_storage: self.tree_storage,
4953 rule_index: self.rule_index,
4954 coordinate_index: self.coordinate_index,
4955 rule_name: self.rule_name.map(str::to_owned),
4956 context: self.context,
4957 tree: None,
4958 local_int_arg: self.local_int_arg,
4959 member_values: self.member_values,
4960 action: None,
4961 };
4962 match self
4963 .semantic_hooks
4964 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4965 {
4966 Some(result) => result,
4967 None => apply_unknown_predicate_policy(
4971 self.unknown_predicate_policy,
4972 self.rule_index,
4973 self.coordinate_index,
4974 self.unknown_predicate_hits,
4975 ),
4976 }
4977 }
4978
4979 fn trace_bool(&mut self, value: bool) -> bool {
4980 let key = (self.rule_index, self.coordinate_index);
4981 if !self.invoked_predicates.contains(&key) {
4982 self.invoked_predicates.push(key);
4983 use std::io::Write as _;
4984 let mut stdout = std::io::stdout().lock();
4985 let _ = writeln!(stdout, "eval={value}");
4986 }
4987 value
4988 }
4989}
4990
4991struct PredicateFailureRecovery<'a> {
4993 rule_index: usize,
4994 index: usize,
4995 message: &'a str,
4996 member_values: MemberEnv,
4997 return_values: BTreeMap<String, i64>,
4998 rule_alt_number: usize,
4999}
5000
5001#[derive(Debug)]
5002enum DirectAdaptiveParseControl {
5003 Fallback(DirectAdaptiveFallback),
5004}
5005
5006#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5007enum DirectAdaptiveFallback {
5008 Action,
5009 InvalidAlt,
5010 LeftRecursiveBoundary,
5011 MissingAtn,
5012 NoTransition,
5013 Predicate,
5014 Prediction,
5015 Precedence,
5016 RuleStop,
5017 SemanticContext,
5018 StepLimit,
5019 TokenMismatch,
5020 UnknownDecision,
5021}
5022
5023type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
5024
5025struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
5026where
5027 S: TokenSource,
5028 H: SemanticHooks,
5029{
5030 parser: &'sim mut BaseParser<S, H>,
5031 atn: &'atn Atn,
5032 simulator: &'sim mut ParserAtnSimulator<'atn>,
5033 decision_by_state: Vec<Option<usize>>,
5034 steps: usize,
5035}
5036
5037struct CommittedAtnParser<'atn, 'sim, 'options, S, H = NoSemanticHooks>
5038where
5039 S: TokenSource,
5040 H: SemanticHooks,
5041{
5042 parser: &'sim mut BaseParser<S, H>,
5043 atn: &'atn Atn,
5044 simulator: ParserAtnSimulator<'atn>,
5045 options: ParserRuntimeOptions<'options>,
5046 decision_by_state: Vec<Option<usize>>,
5047 action_index_by_state: FxHashMap<usize, usize>,
5048 deferred_actions: Vec<ParserAction>,
5049}
5050
5051struct CommittedRuleOutcome {
5052 tree: ParseTree,
5053 consumed_eof: bool,
5054}
5055
5056struct CommittedDecisionContext<'a> {
5057 precedence: i32,
5058 local_int_arg: Option<(usize, i64)>,
5059 context: &'a mut ParserRuleContext,
5060 entered_loops: &'a mut BTreeSet<usize>,
5061}
5062
5063#[derive(Clone, Debug, Eq, PartialEq)]
5073pub struct GeneratedMatch {
5074 children: GeneratedMatchChildren,
5075 consumed_eof: bool,
5076}
5077
5078#[derive(Clone, Copy)]
5079enum GeneratedExpectedSymbols<'a> {
5080 Tree(&'a BTreeSet<i32>),
5081 TokenSet(ParserIntervalSet<'a>),
5082 TokenSetComplement {
5083 set: ParserIntervalSet<'a>,
5084 min_vocabulary: i32,
5085 max_vocabulary: i32,
5086 },
5087}
5088
5089impl GeneratedExpectedSymbols<'_> {
5090 fn is_empty(self) -> bool {
5091 match self {
5092 Self::Tree(symbols) => symbols.is_empty(),
5093 Self::TokenSet(set) => set.is_empty(),
5094 Self::TokenSetComplement {
5095 set,
5096 min_vocabulary,
5097 max_vocabulary,
5098 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
5099 }
5100 }
5101
5102 fn first(self) -> Option<i32> {
5103 match self {
5104 Self::Tree(symbols) => symbols.iter().next().copied(),
5105 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
5106 Self::TokenSetComplement {
5107 set,
5108 min_vocabulary,
5109 max_vocabulary,
5110 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
5111 }
5112 }
5113
5114 fn display(self, vocabulary: &Vocabulary) -> String {
5115 match self {
5116 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
5117 Self::TokenSet(set) => expected_symbols_display_iter(
5118 set.ranges().flat_map(|(start, stop)| start..=stop),
5119 vocabulary,
5120 ),
5121 Self::TokenSetComplement {
5122 set,
5123 min_vocabulary,
5124 max_vocabulary,
5125 } => expected_symbols_display_iter(
5126 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
5127 vocabulary,
5128 ),
5129 }
5130 }
5131}
5132
5133#[derive(Clone, Debug, Eq, PartialEq)]
5134enum GeneratedMatchChildren {
5135 One(ParseTree),
5136 Many(Vec<ParseTree>),
5137}
5138
5139struct GeneratedMatchChildrenIntoIter {
5140 one: Option<ParseTree>,
5141 many: Option<std::vec::IntoIter<ParseTree>>,
5142}
5143
5144impl Iterator for GeneratedMatchChildrenIntoIter {
5145 type Item = ParseTree;
5146
5147 fn next(&mut self) -> Option<Self::Item> {
5148 self.one
5149 .take()
5150 .or_else(|| self.many.as_mut().and_then(Iterator::next))
5151 }
5152}
5153
5154impl GeneratedMatch {
5155 #[must_use]
5159 pub fn children(&self) -> &[ParseTree] {
5160 match &self.children {
5161 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
5162 GeneratedMatchChildren::Many(children) => children,
5163 }
5164 }
5165
5166 #[must_use]
5169 pub fn into_children(self) -> Vec<ParseTree> {
5170 match self.children {
5171 GeneratedMatchChildren::One(child) => vec![child],
5172 GeneratedMatchChildren::Many(children) => children,
5173 }
5174 }
5175
5176 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
5178 match self.children {
5179 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
5180 one: Some(child),
5181 many: None,
5182 },
5183 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
5184 one: None,
5185 many: Some(children.into_iter()),
5186 },
5187 }
5188 }
5189
5190 #[must_use]
5192 pub const fn consumed_eof(&self) -> bool {
5193 self.consumed_eof
5194 }
5195}
5196
5197impl<S> BaseParser<S, NoSemanticHooks>
5198where
5199 S: TokenSource,
5200{
5201 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
5204 Self::with_semantic_hooks(input, data, NoSemanticHooks)
5205 }
5206}
5207
5208impl<S, H> BaseParser<S, H>
5209where
5210 S: TokenSource,
5211 H: SemanticHooks,
5212{
5213 pub fn with_semantic_hooks(
5215 input: CommonTokenStream<S>,
5216 data: RecognizerData,
5217 semantic_hooks: H,
5218 ) -> Self {
5219 Self {
5220 input,
5221 tree: ParseTreeStorage::new(),
5222 data,
5223 semantic_hooks,
5224 decision_override_generation: 0,
5225 build_parse_trees: true,
5226 syntax_errors: 0,
5227 report_diagnostic_errors: false,
5228 prediction_mode: PredictionMode::Ll,
5229 prediction_diagnostics: Vec::new(),
5230 reported_prediction_diagnostics: BTreeSet::new(),
5231 generated_parser_diagnostics: Vec::new(),
5232 generated_sync_expected: None,
5233 generated_recovery_error_index: None,
5234 generated_recovery_error_states: BTreeSet::new(),
5235 int_members: MemberEnv::new(),
5236 rule_context_stack: Vec::new(),
5237 rule_context_version: 0,
5238 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
5239 pending_invoking_states: Vec::new(),
5240 precedence_stack: vec![0],
5241 invoked_predicates: Vec::new(),
5242 bail_on_error: false,
5243 parse_listeners: Vec::new(),
5244 parse_listener_abort: None,
5245 max_rule_depth: None,
5246 rule_depth_error: None,
5247 recursion_expansions: 0,
5248 recursion_expansion_marks: Vec::new(),
5249 unknown_predicate_policy: UnknownSemanticPolicy::default(),
5250 unknown_predicate_hits: Vec::new(),
5251 unhandled_action_hits: Vec::new(),
5252 rule_first_set_cache: Vec::new(),
5253 state_expected_cache: FxHashMap::default(),
5254 state_expected_token_cache: FxHashMap::default(),
5255 rule_stop_reach_cache: Vec::new(),
5256 recovery_symbols_intern: FxHashMap::default(),
5257 decision_lookahead_cache: FxHashMap::default(),
5258 ll1_decision_cache: FxHashMap::default(),
5259 fast_predicate_cache: FxHashMap::default(),
5260 empty_cycle_cache: Vec::new(),
5261 empty_cycle_cache_atn: None,
5262 clean_memo_mode: CleanMemoMode::Probe,
5263 clean_memo_probe_seen: FxHashSet::default(),
5264 clean_memo_probe_samples: 0,
5265 clean_memo_probe_repeats: 0,
5266 clean_memo_sparse_samples: 0,
5267 fast_recognize_scratch: FastRecognizeTopScratch::default(),
5268 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
5269 empty_recovery_symbols: Rc::new(BTreeSet::new()),
5270 fast_first_set_prefilter: true,
5271 fast_recovery_enabled: true,
5272 fast_token_nodes_enabled: true,
5273 fast_track_alt_numbers: false,
5274 recognition_arena: RecognitionArena::default(),
5275 last_recognition_arena_root: NodeSeqId::EMPTY,
5276 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
5277 }
5278 }
5279
5280 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
5281 &mut self.input
5282 }
5283
5284 pub fn reset(&mut self) {
5289 self.input.seek(0);
5290 self.tree.reset();
5291 self.data.set_state(-1);
5292 self.syntax_errors = 0;
5293 self.prediction_diagnostics.clear();
5294 self.reported_prediction_diagnostics.clear();
5295 self.generated_parser_diagnostics.clear();
5296 self.generated_sync_expected = None;
5297 self.reset_generated_recovery_state();
5298 self.rule_context_stack.clear();
5299 self.advance_rule_context_version();
5300 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
5301 self.pending_invoking_states.clear();
5302 self.precedence_stack.clear();
5303 self.precedence_stack.push(0);
5304 self.invoked_predicates.clear();
5305 self.decision_override_generation = 0;
5306 self.unknown_predicate_hits.clear();
5307 self.unhandled_action_hits.clear();
5308 self.parse_listener_abort = None;
5309 self.rule_depth_error = None;
5310 self.recursion_expansions = 0;
5311 self.recursion_expansion_marks.clear();
5312 self.reset_per_parse_caches();
5313 self.fast_first_set_prefilter = true;
5314 self.fast_recovery_enabled = true;
5315 self.fast_token_nodes_enabled = self.build_parse_trees;
5316 self.fast_track_alt_numbers = false;
5317 self.reset_recognition_arena();
5318 }
5319
5320 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
5322 self.input = input;
5323 self.reset();
5324 }
5325
5326 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
5337 self.unknown_predicate_policy = policy;
5338 }
5339
5340 #[must_use]
5346 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
5347 let error = self.unknown_semantic_error();
5348 self.unknown_predicate_hits.clear();
5349 self.unhandled_action_hits.clear();
5350 error
5351 }
5352
5353 pub fn reset_unknown_semantic_hits(&mut self) {
5360 self.unknown_predicate_hits.clear();
5361 self.unhandled_action_hits.clear();
5362 }
5363
5364 #[must_use]
5366 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
5367 &self.input
5368 }
5369
5370 #[must_use]
5372 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
5373 &mut self.input
5374 }
5375
5376 #[must_use]
5378 pub const fn token_store(&self) -> &TokenStore {
5379 self.input.token_store()
5380 }
5381
5382 #[must_use]
5384 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
5385 &self.tree
5386 }
5387
5388 #[must_use]
5390 pub fn node(&self, id: NodeId) -> Node<'_> {
5391 self.tree
5392 .node(self.input.token_store(), id)
5393 .expect("parser-produced node ID should remain valid")
5394 }
5395
5396 #[must_use]
5398 pub fn into_token_stream(self) -> CommonTokenStream<S> {
5399 self.input
5400 }
5401
5402 #[must_use]
5404 pub fn into_token_store(self) -> TokenStore {
5405 self.input.into_token_store()
5406 }
5407
5408 #[must_use]
5410 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
5411 ParsedFile::new(self.input.into_token_store(), self.tree, root)
5412 }
5413
5414 pub const fn number_of_syntax_errors(&self) -> usize {
5417 self.syntax_errors
5418 }
5419
5420 #[must_use]
5426 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
5427 self.recognition_arena.stats(
5428 self.last_recognition_arena_root,
5429 self.last_recognition_arena_diagnostics,
5430 )
5431 }
5432
5433 pub const fn record_generated_syntax_error(&mut self) {
5436 self.record_syntax_errors(1);
5437 }
5438
5439 const fn record_syntax_errors(&mut self, count: usize) {
5440 self.syntax_errors = self.syntax_errors.saturating_add(count);
5441 }
5442
5443 const fn is_top_level_entry(&self) -> bool {
5445 self.rule_context_stack.is_empty() && self.pending_invoking_states.is_empty()
5446 }
5447
5448 pub fn report_token_source_errors(&mut self) {
5451 let errors = self.input.drain_source_errors();
5452 self.dispatch_token_source_errors(&errors);
5453 }
5454
5455 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
5458 GeneratedDiagnosticsCheckpoint {
5459 diagnostics_len: self.generated_parser_diagnostics.len(),
5460 syntax_errors: self.syntax_errors,
5461 tree: self.tree.checkpoint(),
5462 }
5463 }
5464
5465 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5467 self.generated_parser_diagnostics
5468 .truncate(marker.diagnostics_len);
5469 self.syntax_errors = marker.syntax_errors;
5470 self.rollback_generated_tree(marker);
5471 }
5472
5473 pub fn rollback_generated_tree(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5479 self.generated_sync_expected = None;
5480 self.tree.rollback(marker.tree);
5481 }
5482
5483 pub fn report_generated_parser_diagnostics(&mut self) {
5485 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
5486 let token_errors = self.input.drain_source_errors();
5487 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
5488 }
5489
5490 fn syntax_error_event<'a>(
5491 &'a self,
5492 offending: Option<TokenId>,
5493 line: usize,
5494 column: usize,
5495 message: &'a str,
5496 error: Option<&'a AntlrError>,
5497 ) -> SyntaxErrorEvent<'a> {
5498 let offending = offending.and_then(|token| self.token_store().view(token));
5499 SyntaxErrorEvent {
5500 offending,
5501 line,
5502 column,
5503 span: offending.and_then(|token| token.byte_span()),
5504 message,
5505 error,
5506 }
5507 }
5508
5509 pub fn report_unrecovered_parser_error(&self, error: &AntlrError) {
5514 let AntlrError::ParserError {
5515 line,
5516 column,
5517 message,
5518 offending,
5519 } = error
5520 else {
5521 return;
5522 };
5523 self.notify_error_listeners(self.syntax_error_event(
5524 *offending,
5525 *line,
5526 *column,
5527 message,
5528 Some(error),
5529 ));
5530 }
5531
5532 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
5533 self.notify_error_listeners(self.syntax_error_event(
5534 diagnostic.offending,
5535 diagnostic.line,
5536 diagnostic.column,
5537 &diagnostic.message,
5538 None,
5539 ));
5540 }
5541
5542 fn dispatch_parser_diagnostics<'a>(
5543 &self,
5544 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
5545 ) {
5546 for diagnostic in diagnostics {
5547 self.dispatch_parser_diagnostic(diagnostic);
5548 }
5549 }
5550
5551 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
5552 if self.input.token_source().report_error(source_error) {
5553 return;
5554 }
5555 self.notify_error_listeners(source_error.into());
5558 }
5559
5560 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
5561 for error in errors {
5562 self.dispatch_token_source_error(error);
5563 }
5564 }
5565
5566 fn dispatch_generated_diagnostics(
5569 &self,
5570 parser_diagnostics: &[ParserDiagnostic],
5571 token_errors: &[TokenSourceError],
5572 ) {
5573 let mut token_iter = token_errors.iter().peekable();
5579 for diagnostic in parser_diagnostics {
5580 while let Some(error) = token_iter.peek() {
5581 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
5582 self.dispatch_token_source_error(error);
5583 token_iter.next();
5584 } else {
5585 break;
5586 }
5587 }
5588 self.dispatch_parser_diagnostic(diagnostic);
5589 }
5590 for error in token_iter {
5591 self.dispatch_token_source_error(error);
5592 }
5593 }
5594
5595 pub fn record_generated_ambiguity_diagnostic(
5598 &mut self,
5599 atn: &Atn,
5600 state_number: usize,
5601 start_index: usize,
5602 stop_index: usize,
5603 alts: &[usize],
5604 ) {
5605 if !self.report_diagnostic_errors || alts.len() < 2 {
5606 return;
5607 }
5608 let Some(decision) = atn
5609 .decision_to_state()
5610 .iter()
5611 .position(|candidate| candidate == state_number)
5612 else {
5613 return;
5614 };
5615 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5616 return;
5617 };
5618 let rule_name = self
5619 .rule_names()
5620 .get(rule_index)
5621 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5622 let input = display_input_text(&self.input.text(start_index, stop_index));
5623 let alts = alts
5624 .iter()
5625 .map(usize::to_string)
5626 .collect::<Vec<_>>()
5627 .join(", ");
5628 let key = (decision, start_index, format!("{alts}:{input}"));
5629 if !self.reported_prediction_diagnostics.insert(key) {
5630 return;
5631 }
5632 let start_diagnostic = diagnostic_for_token(
5633 self.token_at(start_index),
5634 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5635 );
5636 let stop_diagnostic = diagnostic_for_token(
5637 self.token_at(stop_index),
5638 format!(
5639 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5640 ),
5641 );
5642 self.generated_parser_diagnostics.push(start_diagnostic);
5643 self.generated_parser_diagnostics.push(stop_diagnostic);
5644 }
5645
5646 pub fn record_generated_prediction_diagnostic(
5649 &mut self,
5650 atn: &Atn,
5651 state_number: usize,
5652 prediction: &ParserAtnPrediction,
5653 ) {
5654 if self.prediction_mode == PredictionMode::Sll {
5655 return;
5656 }
5657 let Some(diagnostic) = &prediction.diagnostic else {
5658 return;
5659 };
5660 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5661 return;
5662 }
5663 let Some(decision) = atn
5664 .decision_to_state()
5665 .iter()
5666 .position(|candidate| candidate == state_number)
5667 else {
5668 return;
5669 };
5670 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5671 return;
5672 };
5673 let rule_name = self
5674 .rule_names()
5675 .get(rule_index)
5676 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5677 let attempt_input = display_input_text(
5678 &self
5679 .input
5680 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5681 );
5682 let result_input = display_input_text(
5683 &self
5684 .input
5685 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5686 );
5687 let alts = diagnostic
5688 .conflicting_alts
5689 .iter()
5690 .map(usize::to_string)
5691 .collect::<Vec<_>>()
5692 .join(", ");
5693 let key = (
5694 decision,
5695 diagnostic.start_index,
5696 format!(
5697 "{:?}:{alts}:{attempt_input}:{result_input}",
5698 diagnostic.kind
5699 ),
5700 );
5701 if !self.reported_prediction_diagnostics.insert(key) {
5702 return;
5703 }
5704 let local_exact_ambiguity = !prediction.requires_full_context
5705 && diagnostic.kind == ParserAtnPredictionDiagnosticKind::Ambiguity
5706 && diagnostic.exact;
5707 if !local_exact_ambiguity {
5708 let attempt_diagnostic = diagnostic_for_token(
5709 self.token_at(diagnostic.sll_stop_index),
5710 format!(
5711 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5712 ),
5713 );
5714 self.generated_parser_diagnostics.push(attempt_diagnostic);
5715 }
5716 let message = match diagnostic.kind {
5717 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5718 if !diagnostic.exact {
5723 return;
5724 }
5725 format!(
5726 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5727 )
5728 }
5729 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5730 format!(
5731 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5732 )
5733 }
5734 };
5735 let result_diagnostic =
5736 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5737 self.generated_parser_diagnostics.push(result_diagnostic);
5738 }
5739
5740 pub fn la(&self, offset: isize) -> i32 {
5741 self.input.la_token(offset)
5742 }
5743
5744 pub fn consume(&mut self) {
5745 IntStream::consume(&mut self.input);
5746 }
5747
5748 pub fn set_int_member(&mut self, member: usize, value: i64) {
5750 self.int_members.set_scalar(member, value);
5751 }
5752
5753 pub fn int_member(&self, member: usize) -> Option<i64> {
5755 self.int_members.scalar(member)
5756 }
5757
5758 pub fn push_stack_member(&mut self, member: usize, value: i64) {
5760 self.int_members.push_stack(member, value);
5761 }
5762
5763 pub fn pop_stack_member(&mut self, member: usize) -> Option<i64> {
5766 self.int_members.pop_stack(member)
5767 }
5768
5769 #[must_use]
5772 pub fn stack_member_top(&self, member: usize) -> Option<i64> {
5773 self.int_members.stack_top(member)
5774 }
5775
5776 #[must_use]
5778 pub fn stack_member_len(&self, member: usize) -> usize {
5779 self.int_members.stack_len(member)
5780 }
5781
5782 pub fn set_initial_members(&mut self, initial: impl IntoIterator<Item = (usize, i64)>) {
5789 self.int_members = MemberEnv::with_initial_scalars(initial);
5790 }
5791
5792 #[must_use]
5798 pub fn int_members_checkpoint(&self) -> MemberEnv {
5799 self.int_members.clone()
5800 }
5801
5802 pub fn restore_int_members(&mut self, members: MemberEnv) {
5804 self.int_members = members;
5805 }
5806
5807 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5809 self.int_members.add_scalar(member, delta)
5810 }
5811
5812 fn token_type_for_id(&self, id: TokenId) -> i32 {
5813 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5814 }
5815
5816 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5817 if self.build_parse_trees {
5818 self.tree.terminal(id)
5819 } else {
5820 NodeId::placeholder()
5821 }
5822 }
5823
5824 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5825 if self.build_parse_trees {
5826 self.tree.error(id)
5827 } else {
5828 NodeId::placeholder()
5829 }
5830 }
5831
5832 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5833 context.set_start_id(id);
5834 }
5835
5836 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5837 context.set_stop_id(id);
5838 }
5839
5840 fn insert_synthetic_token(
5841 &mut self,
5842 token_type: i32,
5843 text: String,
5844 line: usize,
5845 column: usize,
5846 ) -> Result<TokenId, AntlrError> {
5847 self.input
5848 .insert(
5849 TokenSpec::explicit(token_type, text)
5850 .with_span(usize::MAX, usize::MAX)
5851 .with_position(line, column),
5852 )
5853 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5854 }
5855
5856 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5863 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5864 line: 0,
5865 column: 0,
5866 message: "missing current token".to_owned(),
5867 offending: None,
5868 })?;
5869 let current_type = self.token_type_for_id(current);
5870 if current_type == token_type {
5871 self.reset_generated_recovery_state();
5872 self.consume();
5873 Ok(self.terminal_tree(current))
5874 } else {
5875 Err(AntlrError::MismatchedInput {
5876 expected: self.vocabulary().display_name(token_type),
5877 found: self.vocabulary().display_name(current_type),
5878 })
5879 }
5880 }
5881
5882 pub fn match_token_recovering(
5886 &mut self,
5887 token_type: i32,
5888 follow_state: usize,
5889 atn: &Atn,
5890 ) -> Result<GeneratedMatch, AntlrError> {
5891 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5892 line: 0,
5893 column: 0,
5894 message: "missing current token".to_owned(),
5895 offending: None,
5896 })?;
5897 let current_type = self.token_type_for_id(current);
5898 if current_type == token_type {
5899 self.generated_sync_expected = None;
5900 self.reset_generated_recovery_state();
5901 let consumed_eof = current_type == TOKEN_EOF;
5902 self.consume();
5903 return Ok(GeneratedMatch {
5904 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5905 consumed_eof,
5906 });
5907 }
5908 let mut expected_symbols = BTreeSet::new();
5909 expected_symbols.insert(token_type);
5910 self.recover_generated_match(
5911 current,
5912 GeneratedExpectedSymbols::Tree(&expected_symbols),
5913 follow_state,
5914 atn,
5915 |symbol| symbol == token_type,
5916 )
5917 }
5918
5919 pub fn match_set_recovering(
5920 &mut self,
5921 intervals: &[(i32, i32)],
5922 follow_state: usize,
5923 atn: &Atn,
5924 ) -> Result<GeneratedMatch, AntlrError> {
5925 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5926 line: 0,
5927 column: 0,
5928 message: "missing current token".to_owned(),
5929 offending: None,
5930 })?;
5931 let current_type = self.token_type_for_id(current);
5932 if interval_set_contains(intervals, current_type) {
5933 self.generated_sync_expected = None;
5934 self.reset_generated_recovery_state();
5935 let consumed_eof = current_type == TOKEN_EOF;
5936 self.consume();
5937 return Ok(GeneratedMatch {
5938 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5939 consumed_eof,
5940 });
5941 }
5942 let expected_symbols = interval_symbols(intervals);
5943 self.recover_generated_match(
5944 current,
5945 GeneratedExpectedSymbols::Tree(&expected_symbols),
5946 follow_state,
5947 atn,
5948 |symbol| interval_set_contains(intervals, symbol),
5949 )
5950 }
5951
5952 pub fn match_token_set_recovering(
5953 &mut self,
5954 set: ParserIntervalSet<'_>,
5955 follow_state: usize,
5956 atn: &Atn,
5957 ) -> Result<GeneratedMatch, AntlrError> {
5958 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5959 line: 0,
5960 column: 0,
5961 message: "missing current token".to_owned(),
5962 offending: None,
5963 })?;
5964 let current_type = self.token_type_for_id(current);
5965 if set.contains(current_type) {
5966 self.generated_sync_expected = None;
5967 self.reset_generated_recovery_state();
5968 let consumed_eof = current_type == TOKEN_EOF;
5969 self.consume();
5970 return Ok(GeneratedMatch {
5971 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5972 consumed_eof,
5973 });
5974 }
5975 self.recover_generated_match(
5976 current,
5977 GeneratedExpectedSymbols::TokenSet(set),
5978 follow_state,
5979 atn,
5980 |symbol| set.contains(symbol),
5981 )
5982 }
5983
5984 pub fn match_not_set_recovering(
5985 &mut self,
5986 intervals: &[(i32, i32)],
5987 min_vocabulary: i32,
5988 max_vocabulary: i32,
5989 follow_state: usize,
5990 atn: &Atn,
5991 ) -> Result<GeneratedMatch, AntlrError> {
5992 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5993 line: 0,
5994 column: 0,
5995 message: "missing current token".to_owned(),
5996 offending: None,
5997 })?;
5998 let current_type = self.token_type_for_id(current);
5999 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
6000 && !interval_set_contains(intervals, current_type)
6001 {
6002 self.generated_sync_expected = None;
6003 self.reset_generated_recovery_state();
6004 let consumed_eof = current_type == TOKEN_EOF;
6005 self.consume();
6006 return Ok(GeneratedMatch {
6007 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
6008 consumed_eof,
6009 });
6010 }
6011 let expected_symbols =
6012 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
6013 self.recover_generated_match(
6014 current,
6015 GeneratedExpectedSymbols::Tree(&expected_symbols),
6016 follow_state,
6017 atn,
6018 |symbol| {
6019 (min_vocabulary..=max_vocabulary).contains(&symbol)
6020 && !interval_set_contains(intervals, symbol)
6021 },
6022 )
6023 }
6024
6025 pub fn match_not_token_set_recovering(
6026 &mut self,
6027 set: ParserIntervalSet<'_>,
6028 min_vocabulary: i32,
6029 max_vocabulary: i32,
6030 follow_state: usize,
6031 atn: &Atn,
6032 ) -> Result<GeneratedMatch, AntlrError> {
6033 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6034 line: 0,
6035 column: 0,
6036 message: "missing current token".to_owned(),
6037 offending: None,
6038 })?;
6039 let current_type = self.token_type_for_id(current);
6040 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
6041 {
6042 self.generated_sync_expected = None;
6043 self.reset_generated_recovery_state();
6044 let consumed_eof = current_type == TOKEN_EOF;
6045 self.consume();
6046 return Ok(GeneratedMatch {
6047 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
6048 consumed_eof,
6049 });
6050 }
6051 self.recover_generated_match(
6052 current,
6053 GeneratedExpectedSymbols::TokenSetComplement {
6054 set,
6055 min_vocabulary,
6056 max_vocabulary,
6057 },
6058 follow_state,
6059 atn,
6060 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
6061 )
6062 }
6063
6064 fn recover_generated_match(
6065 &mut self,
6066 current: TokenId,
6067 expected_symbols: GeneratedExpectedSymbols<'_>,
6068 follow_state: usize,
6069 atn: &Atn,
6070 matches: impl Fn(i32) -> bool,
6071 ) -> Result<GeneratedMatch, AntlrError> {
6072 let expected_display = expected_symbols.display(self.vocabulary());
6073 let (current_type, current_line, current_column, current_display) = {
6074 let token = self
6075 .input
6076 .token_view(current)
6077 .expect("current token ID should be valid");
6078 (
6079 token.token_type(),
6080 token.line(),
6081 token.column(),
6082 token_input_display(&token),
6083 )
6084 };
6085 if self.bail_on_error {
6086 return Err(AntlrError::ParserError {
6087 line: current_line,
6088 column: current_column,
6089 message: format!("mismatched input {current_display} expecting {expected_display}"),
6090 offending: Some(current),
6091 });
6092 }
6093 if current_type != TOKEN_EOF
6094 && let Some(next) = self.input.lt_id(2)
6095 && matches(self.token_type_for_id(next))
6096 {
6097 let message =
6098 format!("extraneous input {current_display} expecting {expected_display}");
6099 self.push_generated_parser_diagnostic(ParserDiagnostic {
6100 line: current_line,
6101 column: current_column,
6102 message,
6103 offending: Some(current),
6104 });
6105 self.record_syntax_errors(1);
6106 self.generated_sync_expected = None;
6107 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
6110 self.consume();
6111 self.consume();
6112 self.reset_generated_recovery_state();
6113 return Ok(GeneratedMatch {
6114 children: GeneratedMatchChildren::Many(vec![
6115 self.error_tree(current),
6116 self.terminal_tree(next),
6117 ]),
6118 consumed_eof,
6119 });
6120 }
6121 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
6122 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
6131 && self
6132 .cached_state_expected_symbols(atn, follow_state)
6133 .contains(&TOKEN_EOF);
6134 if follow_symbols.contains(¤t_type)
6135 && (current_type != TOKEN_EOF
6136 || self.rule_context_stack.len() > 1
6137 || expected_symbols.is_empty()
6138 || follow_explicitly_expects_eof)
6139 {
6140 let message = format!("missing {expected_display} at {current_display}");
6141 self.push_generated_parser_diagnostic(ParserDiagnostic {
6142 line: current_line,
6143 column: current_column,
6144 message,
6145 offending: Some(current),
6146 });
6147 self.record_syntax_errors(1);
6148 self.generated_sync_expected = None;
6149 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
6150 let missing_display = expected_symbol_display(token_type, self.vocabulary());
6151 let token = self.insert_synthetic_token(
6152 token_type,
6153 format!("<missing {missing_display}>"),
6154 current_line,
6155 current_column,
6156 )?;
6157 return Ok(GeneratedMatch {
6162 children: GeneratedMatchChildren::One(self.error_tree(token)),
6163 consumed_eof: false,
6164 });
6165 }
6166 let mismatch_expected_display = self
6167 .generated_sync_expected
6168 .take()
6169 .map_or(expected_display, |symbols| {
6170 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
6171 });
6172 Err(AntlrError::ParserError {
6173 line: current_line,
6174 column: current_column,
6175 message: format!(
6176 "mismatched input {current_display} expecting {mismatch_expected_display}"
6177 ),
6178 offending: Some(current),
6179 })
6180 }
6181
6182 fn generated_recovery_follow_symbols(
6183 &mut self,
6184 atn: &Atn,
6185 follow_state: usize,
6186 ) -> BTreeSet<i32> {
6187 let mut follow = self
6188 .cached_state_expected_symbols(atn, follow_state)
6189 .as_ref()
6190 .clone();
6191 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
6192 follow.extend(self.context_expected_symbols(atn));
6193 }
6194 follow
6195 }
6196
6197 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
6198 self.match_token(TOKEN_EOF)
6199 }
6200
6201 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
6202 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
6203 }
6204
6205 pub fn match_not_set(
6206 &mut self,
6207 intervals: &[(i32, i32)],
6208 min_vocabulary: i32,
6209 max_vocabulary: i32,
6210 ) -> Result<ParseTree, AntlrError> {
6211 self.match_interval_condition(intervals, |symbol| {
6212 (min_vocabulary..=max_vocabulary).contains(&symbol)
6213 && !interval_set_contains(intervals, symbol)
6214 })
6215 }
6216
6217 fn match_interval_condition(
6218 &mut self,
6219 intervals: &[(i32, i32)],
6220 matches: impl FnOnce(i32) -> bool,
6221 ) -> Result<ParseTree, AntlrError> {
6222 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6223 line: 0,
6224 column: 0,
6225 message: "missing current token".to_owned(),
6226 offending: None,
6227 })?;
6228 let current_type = self.token_type_for_id(current);
6229 if matches(current_type) {
6230 self.reset_generated_recovery_state();
6231 self.consume();
6232 Ok(self.terminal_tree(current))
6233 } else {
6234 Err(AntlrError::MismatchedInput {
6235 expected: self.interval_display(intervals),
6236 found: self.vocabulary().display_name(current_type),
6237 })
6238 }
6239 }
6240
6241 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
6242 let values = intervals
6243 .iter()
6244 .map(|(start, stop)| {
6245 if start == stop {
6246 self.vocabulary().display_name(*start)
6247 } else {
6248 format!(
6249 "{}..{}",
6250 self.vocabulary().display_name(*start),
6251 self.vocabulary().display_name(*stop)
6252 )
6253 }
6254 })
6255 .collect::<Vec<_>>()
6256 .join(", ");
6257 format!("{{{values}}}")
6258 }
6259
6260 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
6261 if self.build_parse_trees {
6262 self.tree.finish_rule(context)
6263 } else {
6264 NodeId::placeholder()
6265 }
6266 }
6267
6268 #[must_use]
6277 pub const fn generated_rule_stack_check_due(&self) -> bool {
6278 self.rule_context_stack
6279 .len()
6280 .is_multiple_of(GENERATED_RULE_STACK_CHECK_INTERVAL)
6281 }
6282
6283 #[inline]
6301 pub fn rule_depth_cap_violation(&mut self) -> Option<AntlrError> {
6302 let max = self.max_rule_depth?;
6303 if self.rule_depth_error.is_none()
6306 && self.rule_context_stack.len() + self.recursion_expansions < max
6307 {
6308 return None;
6309 }
6310 Some(self.rule_depth_cap_violation_cold(max))
6311 }
6312
6313 #[cold]
6314 fn rule_depth_cap_violation_cold(&mut self, max: usize) -> AntlrError {
6315 if let Some(error) = &self.rule_depth_error {
6316 return error.clone();
6317 }
6318 let current = self.input.lt(1);
6319 let (line, column) = current
6320 .as_ref()
6321 .map_or((0, 0), |token| (token.line(), token.column()));
6322 let error = AntlrError::ParserError {
6323 line,
6324 column,
6325 message: format!("rule nesting depth limit of {max} exceeded"),
6326 offending: current.as_ref().map(Token::token_id),
6327 };
6328 self.rule_depth_error = Some(error.clone());
6329 error
6330 }
6331
6332 pub const fn take_rule_depth_error(&mut self) -> Option<AntlrError> {
6339 self.rule_depth_error.take()
6340 }
6341
6342 #[must_use]
6349 pub const fn has_rule_depth_cap(&self) -> bool {
6350 self.max_rule_depth.is_some()
6351 }
6352
6353 pub fn add_parse_listener<L>(&mut self, listener: L)
6357 where
6358 L: ParseListener + 'static,
6359 {
6360 self.parse_listeners
6361 .push(ParseListenerSlot(Box::new(listener)));
6362 }
6363
6364 pub fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
6371 self.parse_listener_abort = None;
6372 self.parse_listeners.drain(..).map(|slot| slot.0).collect()
6373 }
6374
6375 #[must_use]
6381 pub const fn has_parse_listeners(&self) -> bool {
6382 !self.parse_listeners.is_empty()
6383 }
6384
6385 #[doc(hidden)]
6390 #[must_use]
6391 pub fn observes_parser_decisions(&self) -> bool {
6392 self.semantic_hooks.observes_parser_decisions()
6393 }
6394
6395 pub fn parse_listener_enter_rule(&mut self, rule_index: usize) -> Option<AntlrError> {
6406 if self.parse_listeners.is_empty() {
6407 return None;
6408 }
6409 self.parse_listener_enter_rule_dispatch(rule_index)
6410 }
6411
6412 fn parse_listener_enter_rule_dispatch(&mut self, rule_index: usize) -> Option<AntlrError> {
6413 if let Some(error) = &self.parse_listener_abort {
6414 return Some(error.clone());
6415 }
6416 let event = EnterRuleEvent {
6417 rule_index,
6418 current: self.input.lt(1),
6419 };
6420 let mut listeners = std::mem::take(&mut self.parse_listeners);
6424 let mut abort = None;
6425 for slot in &mut listeners {
6426 if let Err(error) = slot.0.enter_every_rule(&event) {
6427 abort = Some(error);
6428 break;
6429 }
6430 }
6431 self.parse_listeners = listeners;
6432 if let Some(error) = abort {
6433 self.parse_listener_abort = Some(error.clone());
6434 return Some(error);
6435 }
6436 None
6437 }
6438
6439 pub fn parse_listener_exit_rule(&mut self, rule_index: usize) {
6446 if self.parse_listeners.is_empty() {
6447 return;
6448 }
6449 for slot in self.parse_listeners.iter_mut().rev() {
6452 slot.0.exit_every_rule(rule_index);
6453 }
6454 }
6455
6456 pub const fn take_parse_listener_abort(&mut self) -> Option<AntlrError> {
6463 self.parse_listener_abort.take()
6464 }
6465
6466 pub fn take_parse_abort(&mut self) -> Option<AntlrError> {
6475 if let Some(error) = self.rule_depth_error.take() {
6476 self.parse_listener_abort = None;
6477 return Some(error);
6478 }
6479 self.parse_listener_abort.take()
6480 }
6481
6482 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
6485 self.set_state(state);
6486 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
6487 self.rule_context_stack.push(RuleContextFrame {
6488 rule_index,
6489 invoking_state,
6490 });
6491 self.advance_rule_context_version();
6492 let start_index = self.current_visible_index();
6493 let mut context = ParserRuleContext::new(rule_index, invoking_state);
6494 if let Some(token) = self.token_id_at(start_index) {
6495 self.set_context_start(&mut context, token);
6496 }
6497 context
6498 }
6499
6500 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
6507 let marker = self.pending_invoking_states.len();
6508 self.pending_invoking_states.push(invoking_state);
6509 marker
6510 }
6511
6512 pub fn discard_invoking_state(&mut self, marker: usize) {
6514 self.pending_invoking_states.truncate(marker);
6515 }
6516
6517 pub fn exit_rule(&mut self) {
6519 self.rule_context_stack.pop();
6520 self.advance_rule_context_version();
6521 }
6522
6523 pub fn prediction_context_return_states<'a>(
6528 &'a self,
6529 atn: &'a Atn,
6530 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
6531 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
6532 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
6533 return None;
6534 };
6535 let transition = atn
6536 .state(state_number)
6537 .and_then(|state| state.transitions().first())?;
6538 if transition.is_tail_call() {
6539 return None;
6540 }
6541 let Transition::Rule { follow_state, .. } = transition.data() else {
6542 return None;
6543 };
6544 Some(follow_state)
6545 })
6546 }
6547
6548 pub const fn rule_context_version(&self) -> usize {
6553 self.rule_context_version
6554 }
6555
6556 const fn advance_rule_context_version(&mut self) {
6557 self.rule_context_version = self.rule_context_version.wrapping_add(1);
6558 }
6559
6560 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
6565 if self.build_parse_trees {
6566 self.tree.add_child(context, child);
6567 } else {
6568 context.note_matched_child();
6569 }
6570 }
6571
6572 #[inline]
6578 pub fn sync_into(
6579 &mut self,
6580 atn: &Atn,
6581 state_number: usize,
6582 context: &mut ParserRuleContext,
6583 loop_back: bool,
6584 sync_error: &mut Option<AntlrError>,
6585 ) -> Result<(), AntlrError> {
6586 let current_context_empty = !context.has_matched_child();
6587 match self.sync_decision(atn, state_number, current_context_empty, loop_back) {
6588 Ok(children) => {
6589 for child in children {
6590 self.add_parse_child(context, child);
6591 }
6592 Ok(())
6593 }
6594 Err(error) => {
6595 *sync_error = Some(error.clone());
6596 Err(error)
6597 }
6598 }
6599 }
6600
6601 #[inline]
6605 pub fn match_token_into(
6606 &mut self,
6607 token_type: i32,
6608 follow_state: usize,
6609 atn: &Atn,
6610 context: &mut ParserRuleContext,
6611 consumed_eof: &mut bool,
6612 ) -> Result<(), AntlrError> {
6613 let m = self.match_token_recovering(token_type, follow_state, atn)?;
6614 *consumed_eof |= m.consumed_eof();
6615 for child in m.into_child_iter() {
6616 self.add_parse_child(context, child);
6617 }
6618 Ok(())
6619 }
6620
6621 #[inline]
6624 pub fn match_token_set_into(
6625 &mut self,
6626 token_set: ParserIntervalSet<'_>,
6627 follow_state: usize,
6628 atn: &Atn,
6629 context: &mut ParserRuleContext,
6630 consumed_eof: &mut bool,
6631 ) -> Result<(), AntlrError> {
6632 let m = self.match_token_set_recovering(token_set, follow_state, atn)?;
6633 *consumed_eof |= m.consumed_eof();
6634 for child in m.into_child_iter() {
6635 self.add_parse_child(context, child);
6636 }
6637 Ok(())
6638 }
6639
6640 #[inline]
6643 pub fn match_set_into(
6644 &mut self,
6645 intervals: &[(i32, i32)],
6646 follow_state: usize,
6647 atn: &Atn,
6648 context: &mut ParserRuleContext,
6649 consumed_eof: &mut bool,
6650 ) -> Result<(), AntlrError> {
6651 let m = self.match_set_recovering(intervals, follow_state, atn)?;
6652 *consumed_eof |= m.consumed_eof();
6653 for child in m.into_child_iter() {
6654 self.add_parse_child(context, child);
6655 }
6656 Ok(())
6657 }
6658
6659 #[allow(clippy::too_many_arguments)]
6662 #[inline]
6663 pub fn match_not_token_set_into(
6664 &mut self,
6665 token_set: ParserIntervalSet<'_>,
6666 min_vocabulary: i32,
6667 max_vocabulary: i32,
6668 follow_state: usize,
6669 atn: &Atn,
6670 context: &mut ParserRuleContext,
6671 consumed_eof: &mut bool,
6672 ) -> Result<(), AntlrError> {
6673 let m = self.match_not_token_set_recovering(
6674 token_set,
6675 min_vocabulary,
6676 max_vocabulary,
6677 follow_state,
6678 atn,
6679 )?;
6680 *consumed_eof |= m.consumed_eof();
6681 for child in m.into_child_iter() {
6682 self.add_parse_child(context, child);
6683 }
6684 Ok(())
6685 }
6686
6687 #[allow(clippy::too_many_arguments)]
6690 #[inline]
6691 pub fn match_not_set_into(
6692 &mut self,
6693 intervals: &[(i32, i32)],
6694 min_vocabulary: i32,
6695 max_vocabulary: i32,
6696 follow_state: usize,
6697 atn: &Atn,
6698 context: &mut ParserRuleContext,
6699 consumed_eof: &mut bool,
6700 ) -> Result<(), AntlrError> {
6701 let m = self.match_not_set_recovering(
6702 intervals,
6703 min_vocabulary,
6704 max_vocabulary,
6705 follow_state,
6706 atn,
6707 )?;
6708 *consumed_eof |= m.consumed_eof();
6709 for child in m.into_child_iter() {
6710 self.add_parse_child(context, child);
6711 }
6712 Ok(())
6713 }
6714
6715 fn release_tree_scratch_if_idle(&mut self) {
6716 if self.rule_context_stack.is_empty() {
6717 self.tree.release_scratch();
6718 }
6719 }
6720
6721 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
6723 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6724 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6725 self.set_context_stop(&mut context, token);
6726 }
6727 let node = self.rule_node(context);
6728 self.exit_rule();
6729 self.release_tree_scratch_if_idle();
6730 node
6731 }
6732
6733 pub fn recover_generated_rule(
6740 &mut self,
6741 context: &mut ParserRuleContext,
6742 atn: &Atn,
6743 error: AntlrError,
6744 ) {
6745 let diagnostic = self.generated_rule_error_diagnostic(error);
6746 self.push_generated_parser_diagnostic(diagnostic);
6747 self.generated_sync_expected = None;
6748 let error_index = self.input.index();
6749 let error_state = self.data.state();
6750 if self.generated_recovery_error_index == Some(error_index)
6755 && self.generated_recovery_error_states.contains(&error_state)
6756 && self.la(1) != TOKEN_EOF
6757 && let Some(token) = self.input.lt_id(1)
6758 {
6759 self.consume();
6760 let child = self.error_tree(token);
6761 self.add_parse_child(context, child);
6762 }
6763 let recovery_index = self.input.index();
6764 if self.generated_recovery_error_index != Some(recovery_index) {
6765 self.generated_recovery_error_index = Some(recovery_index);
6766 self.generated_recovery_error_states.clear();
6767 }
6768 self.generated_recovery_error_states.insert(error_state);
6769 let recovery_symbols = self.context_expected_symbols(atn);
6770 loop {
6771 let symbol = self.la(1);
6772 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
6773 break;
6774 }
6775 let Some(token) = self.input.lt_id(1) else {
6776 break;
6777 };
6778 self.consume();
6779 let child = self.error_tree(token);
6780 self.add_parse_child(context, child);
6781 }
6782 self.record_syntax_errors(1);
6783 }
6784
6785 fn reset_generated_recovery_state(&mut self) {
6786 if self.generated_recovery_error_index.is_some() {
6787 self.generated_recovery_error_index = None;
6788 self.generated_recovery_error_states.clear();
6789 }
6790 }
6791
6792 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
6793 if self
6794 .generated_parser_diagnostics
6795 .iter()
6796 .any(|existing| existing == &diagnostic)
6797 {
6798 return;
6799 }
6800 self.generated_parser_diagnostics.push(diagnostic);
6801 }
6802
6803 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
6804 match error {
6805 AntlrError::ParserError {
6809 line,
6810 column,
6811 message,
6812 offending,
6813 } => ParserDiagnostic {
6814 line,
6815 column,
6816 message,
6817 offending,
6818 },
6819 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
6820 self.input.lt(1),
6821 format!("mismatched input {found} expecting {expected}"),
6822 ),
6823 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
6824 self.input.lt(1),
6825 format!("no viable alternative at input {input}"),
6826 ),
6827 AntlrError::LexerError {
6828 line,
6829 column,
6830 message,
6831 } => ParserDiagnostic {
6832 line,
6833 column,
6834 message,
6835 offending: None,
6836 },
6837 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
6838 }
6839 }
6840
6841 pub fn finish_recursion_rule(
6843 &mut self,
6844 mut context: ParserRuleContext,
6845 consumed_eof: bool,
6846 ) -> ParseTree {
6847 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6848 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6849 self.set_context_stop(&mut context, token);
6850 }
6851 let node = self.rule_node(context);
6852 self.unroll_recursion_context();
6853 self.release_tree_scratch_if_idle();
6854 node
6855 }
6856
6857 pub fn enter_recursion_rule(
6859 &mut self,
6860 state: isize,
6861 rule_index: usize,
6862 precedence: i32,
6863 ) -> ParserRuleContext {
6864 self.precedence_stack.push(precedence);
6865 self.recursion_expansion_marks
6866 .push(self.recursion_expansions);
6867 self.enter_rule(state, rule_index)
6868 }
6869
6870 pub fn push_new_recursion_context(
6872 &mut self,
6873 state: isize,
6874 rule_index: usize,
6875 ) -> ParserRuleContext {
6876 self.set_state(state);
6877 self.recursion_expansions += 1;
6880 ParserRuleContext::new(rule_index, state)
6881 }
6882
6883 pub fn push_new_recursion_context_with_previous(
6886 &mut self,
6887 state: isize,
6888 rule_index: usize,
6889 current: &mut ParserRuleContext,
6890 ) {
6891 self.set_state(state);
6892 self.recursion_expansions += 1;
6898 if let Some(stop) = self
6899 .rule_stop_token_index(self.input.index(), false)
6900 .and_then(|index| self.token_id_at(index))
6901 {
6902 self.set_context_stop(current, stop);
6903 }
6904 let invoking_state = current.invoking_state();
6905 let start = current.start_id();
6906 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
6907 if start.is_some() {
6908 replacement.set_start_from_context(current);
6909 }
6910 let previous = std::mem::replace(current, replacement);
6911 if self.build_parse_trees {
6912 let previous = self.rule_node(previous);
6913 self.tree.add_child(current, previous);
6914 }
6915 }
6916
6917 pub fn unroll_recursion_context(&mut self) {
6919 if self.precedence_stack.len() > 1 {
6920 self.precedence_stack.pop();
6921 }
6922 if let Some(mark) = self.recursion_expansion_marks.pop() {
6928 self.recursion_expansions = mark;
6929 }
6930 self.exit_rule();
6931 }
6932
6933 pub fn left_recursive_loop_enter_prediction(
6947 &mut self,
6948 atn: &Atn,
6949 state_number: usize,
6950 precedence: i32,
6951 ) -> Option<bool> {
6952 let symbol = self.la(1);
6953 if symbol == TOKEN_EOF {
6954 return Some(false);
6955 }
6956 let operator_lookahead =
6957 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
6958 let can_single = operator_lookahead.single_token.contains(symbol);
6959 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
6960 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
6961 if !can_single && !can_multi && !can_predicate {
6962 return Some(false);
6963 }
6964 if can_predicate && !can_single {
6965 return None;
6966 }
6967 if !can_single && can_multi && precedence > 0 {
6971 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
6972 if baseline.single_token.contains(symbol) {
6973 return None;
6974 }
6975 }
6976 let atn_key = SharedAtnCacheKey::for_atn(atn);
6977 let cached_overlap = self
6978 .left_recursive_caller_overlap_cache
6979 .iter()
6980 .flatten()
6981 .find(|entry| {
6982 entry.atn_key == atn_key
6983 && entry.state_number == state_number
6984 && entry.symbol == symbol
6985 && entry.context_version == self.rule_context_version
6986 })
6987 .map(|entry| entry.overlaps);
6988 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
6989 let overlaps = caller_context_can_match_symbol_before_state(
6990 atn,
6991 self.prediction_context_return_states(atn),
6992 state_number,
6993 symbol,
6994 );
6995 if let Some(slot) = self
6996 .left_recursive_caller_overlap_cache
6997 .iter_mut()
6998 .find(|slot| slot.is_none())
6999 {
7000 *slot = Some(LeftRecursiveCallerOverlap {
7001 atn_key,
7002 state_number,
7003 symbol,
7004 context_version: self.rule_context_version,
7005 overlaps,
7006 });
7007 }
7008 overlaps
7009 });
7010 if caller_overlaps {
7011 return None;
7012 }
7013 Some(true)
7014 }
7015
7016 fn cached_left_recursive_operator_lookahead(
7017 atn: &Atn,
7018 state_number: usize,
7019 precedence: i32,
7020 ) -> Rc<LeftRecursiveOperatorLookahead> {
7021 with_shared_atn_caches(atn, |cache| {
7022 let key = (state_number, precedence);
7023 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
7024 return Rc::clone(cached);
7025 }
7026 let lookahead = Rc::new(left_recursive_operator_lookahead(
7027 atn,
7028 state_number,
7029 precedence,
7030 ));
7031 cache
7032 .left_recursive_operator_lookahead
7033 .insert(key, Rc::clone(&lookahead));
7034 lookahead
7035 })
7036 }
7037
7038 pub fn left_recursive_loop_enter_matches(
7041 &mut self,
7042 atn: &Atn,
7043 state_number: usize,
7044 precedence: i32,
7045 ) -> bool {
7046 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
7047 }
7048
7049 pub fn precpred(&self, precedence: i32) -> bool {
7051 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
7052 }
7053
7054 pub fn parser_semantic_predicate_matches(
7057 &mut self,
7058 predicates: &[(usize, usize, ParserPredicate)],
7059 rule_index: usize,
7060 pred_index: usize,
7061 ) -> bool {
7062 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
7063 }
7064
7065 pub fn parser_semantic_predicate_matches_with_local(
7068 &mut self,
7069 predicates: &[(usize, usize, ParserPredicate)],
7070 rule_index: usize,
7071 pred_index: usize,
7072 local_int_arg: i32,
7073 ) -> bool {
7074 self.parser_semantic_predicate_matches_inner(
7075 predicates,
7076 rule_index,
7077 pred_index,
7078 Some((rule_index, i64::from(local_int_arg))),
7079 )
7080 }
7081
7082 fn parser_semantic_predicate_matches_inner(
7083 &mut self,
7084 predicates: &[(usize, usize, ParserPredicate)],
7085 rule_index: usize,
7086 pred_index: usize,
7087 local_int_arg: Option<(usize, i64)>,
7088 ) -> bool {
7089 let index = self.input.index();
7090 let member_values = self.int_members.clone();
7091 self.parser_predicate_matches(PredicateEval {
7092 index,
7093 rule_index,
7094 pred_index,
7095 predicates,
7096 semantics: None,
7097 context: None,
7098 local_int_arg,
7099 member_values: &member_values,
7100 })
7101 }
7102
7103 pub fn parser_semantic_predicate_matches_with_context_and_local(
7106 &mut self,
7107 predicates: &[(usize, usize, ParserPredicate)],
7108 rule_index: usize,
7109 pred_index: usize,
7110 context: &ParserRuleContext,
7111 local_int_arg: i32,
7112 ) -> bool {
7113 let index = self.input.index();
7114 let member_values = self.int_members.clone();
7115 self.parser_predicate_matches(PredicateEval {
7116 index,
7117 rule_index,
7118 pred_index,
7119 predicates,
7120 semantics: None,
7121 context: Some(context),
7122 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
7123 member_values: &member_values,
7124 })
7125 }
7126
7127 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
7130 &mut self,
7131 semantics: &ParserSemantics,
7132 rule_index: usize,
7133 pred_index: usize,
7134 context: &ParserRuleContext,
7135 local_int_arg: i32,
7136 ) -> bool {
7137 let index = self.input.index();
7138 let member_values = self.int_members.clone();
7139 self.parser_predicate_matches(PredicateEval {
7140 index,
7141 rule_index,
7142 pred_index,
7143 predicates: &[],
7144 semantics: Some(semantics),
7145 context: Some(context),
7146 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
7147 member_values: &member_values,
7148 })
7149 }
7150
7151 pub fn parser_semantic_predicate_failure_message(
7154 &self,
7155 rule_index: usize,
7156 pred_index: usize,
7157 predicates: &[(usize, usize, ParserPredicate)],
7158 ) -> Option<&'static str> {
7159 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
7160 }
7161
7162 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
7164 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
7165 line: 0,
7166 column: 0,
7167 message: "missing current token".to_owned(),
7168 offending: None,
7169 })?;
7170 if self.token_type_for_id(current) == TOKEN_EOF {
7171 return Err(AntlrError::MismatchedInput {
7172 expected: "wildcard".to_owned(),
7173 found: self.vocabulary().display_name(TOKEN_EOF),
7174 });
7175 }
7176 self.reset_generated_recovery_state();
7177 self.consume();
7178 Ok(self.terminal_tree(current))
7179 }
7180
7181 #[allow(clippy::unnecessary_wraps)]
7185 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
7186 self.set_state(state);
7187 Ok(())
7188 }
7189
7190 pub fn sync_decision(
7198 &mut self,
7199 atn: &Atn,
7200 state_number: usize,
7201 _current_context_empty: bool,
7202 loop_back: bool,
7203 ) -> Result<Vec<ParseTree>, AntlrError> {
7204 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
7205 self.generated_sync_expected = None;
7206 let Some(state) = atn.state(state_number) else {
7207 return Ok(Vec::new());
7208 };
7209 let Some(rule_index) = state.rule_index() else {
7210 return Ok(Vec::new());
7211 };
7212 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
7213 return Ok(Vec::new());
7214 };
7215 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
7216 let symbol = self.la(1);
7217 let mut has_expected_symbols = false;
7218 let mut nullable = false;
7219 let mut explicit_eof_expected = false;
7227 for transition in &entry.transitions {
7228 if transition.symbols.contains(symbol) {
7229 return Ok(Vec::new());
7230 }
7231 has_expected_symbols |= !transition.symbols.is_empty();
7232 nullable |= transition.nullable;
7233 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
7234 }
7235 if nullable {
7242 if self.context_expected_contains(atn, symbol) {
7246 return Ok(Vec::new());
7247 }
7248 let mut expected = self.context_expected_token_set(atn);
7249 for transition in &entry.transitions {
7250 expected.extend_from(&transition.symbols);
7251 }
7252 self.generated_sync_expected = Some(expected);
7253 return Ok(Vec::new());
7254 }
7255 if !has_expected_symbols {
7256 return Ok(Vec::new());
7257 }
7258 let mut expected = TokenBitSet::default();
7259 for transition in &entry.transitions {
7260 expected.extend_from(&transition.symbols);
7261 }
7262 let loop_sync = loop_back;
7279 if symbol != TOKEN_EOF {
7280 let mut cursor = self.input.index();
7281 let mut skipped = Vec::new();
7282 loop {
7283 let current = self.token_type_at(cursor);
7284 if current == TOKEN_EOF {
7285 break;
7286 }
7287 skipped.push(cursor);
7288 let next = self.consume_index(cursor, current);
7289 if next == cursor {
7290 break;
7291 }
7292 let next_symbol = self.token_type_at(next);
7293 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
7301 explicit_eof_expected
7302 } else {
7303 expected.contains(next_symbol)
7304 };
7305 if next_is_expected_stop {
7306 let current_token = self.input.lt(1);
7307 let expected_symbols = expected.to_btree_set();
7308 let message = format!(
7309 "extraneous input {} expecting {}",
7310 current_token
7311 .as_ref()
7312 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7313 self.expected_symbols_display(&expected_symbols)
7314 );
7315 self.push_generated_parser_diagnostic(diagnostic_for_token(
7316 current_token,
7317 message,
7318 ));
7319 self.record_syntax_errors(1);
7320 let mut children = Vec::with_capacity(skipped.len());
7321 for index in skipped {
7322 if let Some(token) = self.token_id_at(index) {
7323 self.consume();
7324 children.push(self.error_tree(token));
7325 }
7326 }
7327 if !loop_sync {
7328 self.reset_generated_recovery_state();
7329 }
7330 return Ok(children);
7331 }
7332 if !loop_sync {
7336 break;
7337 }
7338 cursor = next;
7339 }
7340 }
7341 let current = self.input.lt(1);
7342 let expected_symbols = expected.to_btree_set();
7343 Err(AntlrError::ParserError {
7344 line: current.as_ref().map(Token::line).unwrap_or_default(),
7345 column: current.as_ref().map(Token::column).unwrap_or_default(),
7346 message: format!(
7347 "mismatched input {} expecting {}",
7348 current
7349 .as_ref()
7350 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7351 self.expected_symbols_display(&expected_symbols)
7352 ),
7353 offending: current.as_ref().map(Token::token_id),
7354 })
7355 }
7356
7357 pub fn ll1_decision_prediction(
7364 &mut self,
7365 atn: &Atn,
7366 state_number: usize,
7367 ) -> Option<ParserAtnPrediction> {
7368 let state = atn.state(state_number)?;
7369 if state.precedence_rule_decision() {
7370 return None;
7371 }
7372 let rule_stop = state
7373 .rule_index()
7374 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
7375 let symbol = self.la(1);
7376 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
7377 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
7378 alt: alt + 1,
7379 requires_full_context: false,
7380 has_semantic_context: false,
7381 diagnostic: None,
7382 })
7383 }
7384
7385 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
7386 let mut expected = BTreeSet::new();
7387 for index in (1..self.rule_context_stack.len()).rev() {
7388 let invoking_state = self.rule_context_stack[index].invoking_state;
7389 let Ok(state_number) = usize::try_from(invoking_state) else {
7390 continue;
7391 };
7392 let Some(Transition::Rule { follow_state, .. }) = atn
7393 .state(state_number)
7394 .and_then(|state| state.transitions().first())
7395 .map(ParserTransition::data)
7396 else {
7397 continue;
7398 };
7399 let return_state = follow_state;
7400 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
7401 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
7402 return expected;
7403 }
7404 }
7405 expected.insert(TOKEN_EOF);
7406 expected
7407 }
7408
7409 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
7410 let mut expected = TokenBitSet::default();
7411 for index in (1..self.rule_context_stack.len()).rev() {
7412 let invoking_state = self.rule_context_stack[index].invoking_state;
7413 let Ok(state_number) = usize::try_from(invoking_state) else {
7414 continue;
7415 };
7416 let Some(Transition::Rule { follow_state, .. }) = atn
7417 .state(state_number)
7418 .and_then(|state| state.transitions().first())
7419 .map(ParserTransition::data)
7420 else {
7421 continue;
7422 };
7423 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
7424 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7425 return expected;
7426 }
7427 }
7428 expected.insert(TOKEN_EOF);
7429 expected
7430 }
7431
7432 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
7439 for index in (1..self.rule_context_stack.len()).rev() {
7440 let invoking_state = self.rule_context_stack[index].invoking_state;
7441 let Ok(state_number) = usize::try_from(invoking_state) else {
7442 continue;
7443 };
7444 let Some(Transition::Rule { follow_state, .. }) = atn
7445 .state(state_number)
7446 .and_then(|state| state.transitions().first())
7447 .map(ParserTransition::data)
7448 else {
7449 continue;
7450 };
7451 if self
7452 .cached_state_expected_token_set(atn, follow_state)
7453 .contains(symbol)
7454 {
7455 return true;
7456 }
7457 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7458 return false;
7459 }
7460 }
7461 symbol == TOKEN_EOF
7462 }
7463
7464 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
7466 let error_index = self.input.index();
7467 self.no_viable_alternative_error_at(start_index, error_index)
7468 }
7469
7470 pub fn no_viable_alternative_error_at(
7475 &self,
7476 start_index: usize,
7477 error_index: usize,
7478 ) -> AntlrError {
7479 let diagnostic = self.no_viable_alternative(start_index, error_index);
7480 AntlrError::ParserError {
7481 line: diagnostic.line,
7482 column: diagnostic.column,
7483 message: diagnostic.message,
7484 offending: diagnostic.offending,
7485 }
7486 }
7487
7488 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
7490 let current = self.input.lt(1);
7491 AntlrError::ParserError {
7492 line: current.as_ref().map(Token::line).unwrap_or_default(),
7493 column: current.as_ref().map(Token::column).unwrap_or_default(),
7494 message: format!("rule failed predicate: {}", message.into()),
7495 offending: current.as_ref().map(Token::token_id),
7496 }
7497 }
7498
7499 pub fn failed_predicate_option_error(
7502 &self,
7503 rule_index: usize,
7504 message: impl Into<String>,
7505 ) -> AntlrError {
7506 let current = self.input.lt(1);
7507 let rule_name = self
7508 .rule_names()
7509 .get(rule_index)
7510 .map_or_else(|| rule_index.to_string(), Clone::clone);
7511 AntlrError::ParserError {
7512 line: current.as_ref().map(Token::line).unwrap_or_default(),
7513 column: current.as_ref().map(Token::column).unwrap_or_default(),
7514 message: format!("rule {rule_name} {}", message.into()),
7515 offending: current.as_ref().map(Token::token_id),
7516 }
7517 }
7518
7519 pub fn parser_action_at_current(
7521 &mut self,
7522 source_state: usize,
7523 rule_index: usize,
7524 start_index: usize,
7525 consumed_eof: bool,
7526 ) -> ParserAction {
7527 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7528 ParserAction::new(source_state, rule_index, start_index, stop_index)
7529 }
7530
7531 pub fn parser_action_at_current_indexed(
7533 &mut self,
7534 source_state: usize,
7535 rule_index: usize,
7536 action_index: usize,
7537 start_index: usize,
7538 consumed_eof: bool,
7539 ) -> ParserAction {
7540 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7541 ParserAction::new_indexed(
7542 source_state,
7543 rule_index,
7544 action_index,
7545 start_index,
7546 stop_index,
7547 )
7548 }
7549
7550 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
7555 self.parser_action_hook_inner(action, None, Some(tree), None, true)
7556 }
7557
7558 pub fn parser_action_hook_with_context(
7563 &mut self,
7564 action: ParserAction,
7565 context: &ParserRuleContext,
7566 ) -> bool {
7567 self.parser_action_hook_inner(action, Some(context), None, None, true)
7568 }
7569
7570 pub fn parser_action_hook_with_context_and_local(
7576 &mut self,
7577 action: ParserAction,
7578 context: &ParserRuleContext,
7579 local_int_arg: i32,
7580 ) -> bool {
7581 self.parser_action_hook_inner(
7582 action,
7583 Some(context),
7584 None,
7585 Some((action.rule_index(), i64::from(local_int_arg))),
7586 true,
7587 )
7588 }
7589
7590 fn parser_rule_init_hook_with_context(
7595 &mut self,
7596 action: ParserAction,
7597 context: &ParserRuleContext,
7598 local_int_arg: Option<(usize, i64)>,
7599 ) -> bool {
7600 debug_assert!(action.is_rule_init());
7601 self.parser_action_hook_inner(action, Some(context), None, local_int_arg, false)
7602 }
7603
7604 fn parser_action_hook_inner(
7605 &mut self,
7606 action: ParserAction,
7607 context: Option<&ParserRuleContext>,
7608 tree: Option<ParseTree>,
7609 local_int_arg: Option<(usize, i64)>,
7610 record_unhandled: bool,
7611 ) -> bool {
7612 let rule_index = action.rule_index();
7613 let rule_name = self.rule_names().get(rule_index).cloned();
7614 let input = &mut self.input;
7615 let semantic_hooks = &mut self.semantic_hooks;
7616 let member_values = &self.int_members;
7617 let mut ctx = ParserSemCtx {
7618 input,
7619 tree_storage: &self.tree,
7620 rule_index,
7621 coordinate_index: action.action_index().unwrap_or(usize::MAX),
7622 rule_name,
7623 context,
7624 tree,
7625 local_int_arg,
7626 member_values,
7627 action: Some(action),
7628 };
7629 let handled = semantic_hooks.action(&mut ctx, action);
7630 if record_unhandled
7636 && !handled
7637 && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error)
7638 {
7639 let coordinate = (rule_index, action.source_state());
7640 if !self.unhandled_action_hits.contains(&coordinate) {
7641 self.unhandled_action_hits.push(coordinate);
7642 }
7643 }
7644 handled
7645 }
7646
7647 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
7652 &mut self,
7653 atn: &'atn Atn,
7654 simulator: &mut ParserAtnSimulator<'atn>,
7655 rule_index: usize,
7656 ) -> Result<ParseTree, AntlrError> {
7657 let start_index = self.current_visible_index();
7658 self.clear_prediction_diagnostics();
7659 self.reset_per_parse_caches();
7660 self.reset_recognition_arena();
7661 let tree_checkpoint = self.tree.checkpoint();
7662 let mut decision_by_state = vec![None; atn.states().len()];
7663 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
7664 if let Some(slot) = decision_by_state.get_mut(state_number) {
7665 *slot = Some(decision);
7666 }
7667 }
7668
7669 let result = DirectAdaptiveParser {
7670 parser: self,
7671 atn,
7672 simulator,
7673 decision_by_state,
7674 steps: 0,
7675 }
7676 .parse_rule(rule_index, -1, 0);
7677
7678 match result {
7679 Ok(tree) => {
7680 self.report_token_source_errors();
7681 self.release_tree_scratch_if_idle();
7682 Ok(tree)
7683 }
7684 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
7685 let _ = reason;
7686 self.tree.rollback(tree_checkpoint);
7687 self.input.seek(start_index);
7688 self.parse_atn_rule(atn, rule_index)
7689 }
7690 }
7691 }
7692
7693 pub fn parse_atn_rule(
7703 &mut self,
7704 atn: &Atn,
7705 rule_index: usize,
7706 ) -> Result<ParseTree, AntlrError> {
7707 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
7708 }
7709
7710 pub fn parse_atn_rule_with_precedence(
7713 &mut self,
7714 atn: &Atn,
7715 rule_index: usize,
7716 precedence: i32,
7717 ) -> Result<ParseTree, AntlrError> {
7718 self.parse_atn_rule_with_precedence_inner(
7719 atn,
7720 rule_index,
7721 precedence,
7722 None,
7723 AltNumberTracking::default(),
7724 )
7725 }
7726
7727 fn parse_atn_rule_with_precedence_inner(
7728 &mut self,
7729 atn: &Atn,
7730 rule_index: usize,
7731 precedence: i32,
7732 predicate_context: Option<FastPredicateContext<'_>>,
7733 alt_tracking: AltNumberTracking,
7734 ) -> Result<ParseTree, AntlrError> {
7735 let report_unrecovered_error = self.is_top_level_entry();
7736 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7737 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7738 })?;
7739 let stop_state = atn
7740 .rule_to_stop_state()
7741 .get(rule_index)
7742 .filter(|state| *state != usize::MAX)
7743 .ok_or_else(|| {
7744 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7745 })?;
7746
7747 let start_index = self.current_visible_index();
7748 self.clear_prediction_diagnostics();
7749 self.reset_per_parse_caches();
7750 self.reset_recognition_arena();
7751 let caller_follow_state = self.pending_invoking_follow_state(atn);
7752 self.fast_recovery_enabled = false;
7753 self.fast_token_nodes_enabled = false;
7754 self.fast_track_alt_numbers = alt_tracking.any();
7755 let top_request = FastRecognizeTopRequest {
7756 start_state,
7757 stop_state,
7758 start_index,
7759 precedence,
7760 caller_follow_state,
7761 };
7762 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
7763 self.fast_token_nodes_enabled = self.build_parse_trees;
7764 let needs_tree_retry = matches!(
7765 &first_pass,
7766 Ok((outcome, _, _))
7767 if self.build_parse_trees
7768 && self
7769 .recognition_arena
7770 .sequence_has_left_recursive_boundary(outcome.nodes)
7771 );
7772 let needs_retry = match &first_pass {
7773 Err(_) => true,
7786 Ok((outcome, _, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
7787 };
7788 let (outcome, _expected, alt_number) = if needs_retry {
7789 self.fast_first_set_prefilter = false;
7790 self.fast_recovery_enabled = false;
7791 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7792 let clean_selected = if needs_tree_retry {
7793 match clean_retry {
7794 ok @ Ok(_) => ok,
7795 Err(_) => first_pass,
7796 }
7797 } else {
7798 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
7799 };
7800 let selected = if clean_selected.is_err()
7801 || matches!(&clean_selected, Ok((outcome, _, _)) if !outcome.diagnostics.is_empty())
7802 {
7803 self.fast_recovery_enabled = true;
7804 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7805 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
7806 } else {
7807 clean_selected
7808 };
7809 self.fast_first_set_prefilter = true;
7810 self.fast_recovery_enabled = true;
7811 selected.map_err(|expected| {
7812 if predicate_context.is_some()
7813 && let Some(error) = self.unknown_semantic_error()
7814 {
7815 self.report_token_source_errors();
7816 return error;
7817 }
7818 let error = self.recognition_error(rule_index, start_index, &expected);
7819 self.record_syntax_errors(1);
7820 self.report_token_source_errors();
7821 if report_unrecovered_error {
7822 self.report_unrecovered_parser_error(&error);
7823 }
7824 error
7825 })?
7826 } else {
7827 first_pass.expect("first_pass is Ok in the no-retry branch")
7828 };
7829 if predicate_context.is_some()
7830 && let Some(error) = self.unknown_semantic_error()
7831 {
7832 self.report_token_source_errors();
7833 return Err(error);
7834 }
7835 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7836 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7837 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7838 self.report_token_source_errors();
7839 let mut context = ParserRuleContext::with_child_capacity(
7840 rule_index,
7841 self.state(),
7842 if self.build_parse_trees {
7843 self.recognition_arena.sequence_len(outcome.nodes)
7844 } else {
7845 0
7846 },
7847 );
7848 if alt_tracking.public {
7849 context.set_alt_number(alt_number.max(1));
7850 }
7851 if alt_tracking.context {
7852 context.set_context_alt_number(alt_number);
7853 }
7854 if let Some(token) = self.token_id_at(start_index) {
7855 self.set_context_start(&mut context, token);
7856 }
7857 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
7858 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
7859 self.set_context_stop(&mut context, token);
7860 }
7861 let live_root = if self.build_parse_trees {
7862 self.recognition_arena
7863 .fold_left_recursive_boundaries(outcome.nodes)
7864 } else {
7865 outcome.nodes
7866 };
7867 if self.build_parse_trees {
7868 if self
7869 .recognition_arena
7870 .sequence_has_explicit_token(live_root)
7871 {
7872 let mut cursor = live_root;
7873 while let Some(link) = self.recognition_arena.link(cursor) {
7874 let child = self.arena_recognized_node_tree(
7875 link.head,
7876 alt_tracking.public,
7877 alt_tracking.context,
7878 )?;
7879 self.tree.add_child(&mut context, child);
7880 cursor = link.tail;
7881 }
7882 } else {
7883 self.add_arena_implicit_token_children(
7884 &mut context,
7885 start_index,
7886 stop_index,
7887 live_root,
7888 alt_tracking,
7889 )?;
7890 }
7891 }
7892 self.finish_recognition_arena(live_root, outcome.diagnostics);
7893 self.input.seek(outcome.index);
7894
7895 let tree = self.rule_node(context);
7896 self.release_tree_scratch_if_idle();
7897 Ok(tree)
7898 }
7899
7900 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
7901 let invoking_state = self.pending_invoking_states.last().copied()?;
7902 let state_number = usize::try_from(invoking_state).ok()?;
7903 match atn.state(state_number)?.transitions().first()?.data() {
7904 Transition::Rule { follow_state, .. } => Some(follow_state),
7905 _ => None,
7906 }
7907 }
7908
7909 #[cfg(test)]
7910 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
7911 caller_follow_token_info_for_stream(&mut self.input, index)
7912 }
7913
7914 fn fast_recognize_top(
7919 &mut self,
7920 atn: &Atn,
7921 request: FastRecognizeTopRequest,
7922 predicate_context: Option<FastPredicateContext<'_>>,
7923 ) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
7924 let FastRecognizeTopRequest {
7925 start_state,
7926 stop_state,
7927 start_index,
7928 precedence,
7929 caller_follow_state,
7930 } = request;
7931 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
7940 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
7941 recognize_scratch.prepare(memo_capacity);
7942 let mut expected = ExpectedTokens::default();
7943 let empty_recovery = self.empty_recovery_symbols();
7944 let outcomes = self.recognize_state_fast(
7945 atn,
7946 FastRecognizeRequest {
7947 state_number: start_state,
7948 stop_state,
7949 index: start_index,
7950 rule_start_index: start_index,
7951 decision_start_index: None,
7952 precedence,
7953 depth: 0,
7954 recovery_symbols: empty_recovery,
7955 recovery_state: None,
7956 },
7957 FastRecognizeScratch {
7958 predicate_context,
7959 visiting: &mut recognize_scratch.visiting,
7960 memo: &mut recognize_scratch.memo,
7961 expected: &mut expected,
7962 native_depth: 0,
7963 },
7964 );
7965 recognize_scratch.release_oversized_memo();
7966 self.fast_recognize_scratch = recognize_scratch;
7967 #[cfg(feature = "perf-counters")]
7968 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
7969 perf_counters::dump();
7970 perf_counters::reset();
7971 }
7972 let caller_follow =
7973 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
7974 let selected = {
7975 let arena = &self.recognition_arena;
7976 let input = &mut self.input;
7977 select_best_fast_outcome(
7978 outcomes.into_iter(),
7979 self.prediction_mode,
7980 caller_follow.as_deref(),
7981 |index| caller_follow_token_info_for_stream(input, index),
7982 arena,
7983 )
7984 };
7985 match selected {
7986 Some(mut outcome) => {
7987 let alt_number = if self.build_parse_trees || self.fast_track_alt_numbers {
7988 self.materialize_fast_outcome_nodes(&mut outcome)
7989 } else {
7990 0
7991 };
7992 Ok((outcome, expected, alt_number))
7993 }
7994 None => Err(expected),
7995 }
7996 }
7997
7998 fn arena_recognized_node_tree(
8000 &mut self,
8001 node_id: RecognizedNodeId,
8002 track_alt_numbers: bool,
8003 track_context_alt_numbers: bool,
8004 ) -> Result<ParseTree, AntlrError> {
8005 let node = self.recognition_arena.node(node_id);
8006 match node {
8007 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
8008 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
8009 ArenaRecognizedNode::MissingToken { extra } => {
8010 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
8011 RecognitionExtra::MissingToken {
8012 token_type,
8013 at_index,
8014 text,
8015 } => (*token_type, *at_index as usize, text.clone()),
8016 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
8017 unreachable!("missing-token node must reference missing-token extra")
8018 }
8019 };
8020 let (line, column) = self
8021 .token_at(at_index)
8022 .map_or((0, 0), |token| (token.line(), token.column()));
8023 let token = self.insert_synthetic_token(token_type, text, line, column)?;
8024 Ok(self.error_tree(token))
8025 }
8026 ArenaRecognizedNode::Rule {
8027 rule_index,
8028 invoking_state,
8029 alt_number,
8030 start_index,
8031 stop_index,
8032 return_values,
8033 children,
8034 } => {
8035 let mut context = ParserRuleContext::with_child_capacity(
8036 rule_index as usize,
8037 invoking_state as isize,
8038 self.recognition_arena.sequence_len(children),
8039 );
8040 if track_alt_numbers {
8041 context.set_alt_number((alt_number as usize).max(1));
8042 }
8043 if track_context_alt_numbers {
8044 context.set_context_alt_number(alt_number as usize);
8045 }
8046 if let Some(extra) = return_values {
8047 let RecognitionExtra::ReturnValues(values) =
8048 self.recognition_arena.extra(extra)
8049 else {
8050 unreachable!("rule node must reference return-values extra");
8051 };
8052 for (name, value) in values {
8053 context.set_int_return(name.clone(), *value);
8054 }
8055 }
8056 if let Some(token) = self.token_id_at(start_index as usize) {
8057 self.set_context_start(&mut context, token);
8058 }
8059 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
8060 self.set_context_stop(&mut context, token);
8061 }
8062 let mut cursor = self
8063 .recognition_arena
8064 .fold_left_recursive_boundaries(children);
8065 while let Some(link) = self.recognition_arena.link(cursor) {
8066 let child = self.arena_recognized_node_tree(
8067 link.head,
8068 track_alt_numbers,
8069 track_context_alt_numbers,
8070 )?;
8071 self.tree.add_child(&mut context, child);
8072 cursor = link.tail;
8073 }
8074 Ok(self.rule_node(context))
8075 }
8076 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
8077 Err(AntlrError::Unsupported(format!(
8078 "unfolded left-recursive boundary for rule {rule_index}"
8079 )))
8080 }
8081 }
8082 }
8083
8084 fn arena_recognized_node_tree_with_implicit_tokens(
8085 &mut self,
8086 node_id: RecognizedNodeId,
8087 alt_tracking: AltNumberTracking,
8088 ) -> Result<ParseTree, AntlrError> {
8089 let node = self.recognition_arena.node(node_id);
8090 match node {
8091 ArenaRecognizedNode::Rule {
8092 rule_index,
8093 invoking_state,
8094 alt_number,
8095 start_index,
8096 stop_index,
8097 children,
8098 ..
8099 } => {
8100 let mut context = ParserRuleContext::with_child_capacity(
8101 rule_index as usize,
8102 invoking_state as isize,
8103 self.recognition_arena.sequence_len(children),
8104 );
8105 if alt_tracking.public {
8106 context.set_alt_number((alt_number as usize).max(1));
8107 }
8108 if alt_tracking.context {
8109 context.set_context_alt_number(alt_number as usize);
8110 }
8111 if let Some(token) = self.token_id_at(start_index as usize) {
8112 self.set_context_start(&mut context, token);
8113 }
8114 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
8115 self.set_context_stop(&mut context, token);
8116 }
8117 let children = self
8118 .recognition_arena
8119 .fold_left_recursive_boundaries(children);
8120 self.add_arena_implicit_token_children(
8121 &mut context,
8122 start_index as usize,
8123 stop_index.map(|index| index as usize),
8124 children,
8125 alt_tracking,
8126 )?;
8127 Ok(self.rule_node(context))
8128 }
8129 _ => {
8130 self.arena_recognized_node_tree(node_id, alt_tracking.public, alt_tracking.context)
8131 }
8132 }
8133 }
8134
8135 fn add_arena_implicit_token_children(
8136 &mut self,
8137 context: &mut ParserRuleContext,
8138 start_index: usize,
8139 stop_index: Option<usize>,
8140 mut children: NodeSeqId,
8141 alt_tracking: AltNumberTracking,
8142 ) -> Result<(), AntlrError> {
8143 let mut cursor = Some(start_index);
8144 while let Some(link) = self.recognition_arena.link(children) {
8145 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
8146 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
8147 let child =
8148 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
8149 self.tree.add_child(context, child);
8150 if let Some(child_stop) = child_stop {
8151 let next = self.next_visible_after_token(child_stop);
8152 cursor = match (cursor, next) {
8153 (None, _) | (_, None) => None,
8154 (Some(current), Some(next)) => Some(current.max(next)),
8155 };
8156 }
8157 } else {
8158 let child =
8159 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
8160 self.tree.add_child(context, child);
8161 }
8162 children = link.tail;
8163 }
8164 if let Some(stop) = stop_index {
8165 self.add_visible_terminals_through(context, cursor, stop)?;
8166 }
8167 Ok(())
8168 }
8169
8170 fn add_visible_terminals_before(
8171 &mut self,
8172 context: &mut ParserRuleContext,
8173 cursor: &mut Option<usize>,
8174 before: usize,
8175 ) -> Result<(), AntlrError> {
8176 let Some(stop) = before.checked_sub(1) else {
8177 return Ok(());
8178 };
8179 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
8180 *cursor = next;
8181 Ok(())
8182 }
8183
8184 fn add_visible_terminals_through(
8185 &mut self,
8186 context: &mut ParserRuleContext,
8187 mut cursor: Option<usize>,
8188 stop: usize,
8189 ) -> Result<Option<usize>, AntlrError> {
8190 while let Some(index) = cursor {
8191 if index > stop {
8192 return Ok(Some(index));
8193 }
8194 let token = self
8195 .input
8196 .get_id(index)
8197 .ok_or_else(|| AntlrError::ParserError {
8198 line: 0,
8199 column: 0,
8200 message: format!("missing token at index {index}"),
8201 offending: None,
8202 })?;
8203 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
8204 let child = self.terminal_tree(token);
8205 self.tree.add_child(context, child);
8206 if is_eof {
8207 return Ok(None);
8208 }
8209 cursor = self.next_visible_after_token(index);
8210 }
8211 Ok(None)
8212 }
8213
8214 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
8215 let next = self.input.next_visible_after(index);
8216 (next != index).then_some(next)
8217 }
8218
8219 pub fn parse_atn_rule_with_actions(
8226 &mut self,
8227 atn: &Atn,
8228 rule_index: usize,
8229 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8230 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
8231 }
8232
8233 pub fn parse_atn_rule_with_action_inits(
8241 &mut self,
8242 atn: &Atn,
8243 rule_index: usize,
8244 init_action_rules: &[usize],
8245 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8246 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
8247 }
8248
8249 pub fn parse_atn_rule_with_action_options(
8255 &mut self,
8256 atn: &Atn,
8257 rule_index: usize,
8258 init_action_rules: &[usize],
8259 track_alt_numbers: bool,
8260 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8261 self.parse_atn_rule_with_runtime_options(
8262 atn,
8263 rule_index,
8264 ParserRuntimeOptions {
8265 init_action_rules,
8266 track_alt_numbers,
8267 ..ParserRuntimeOptions::default()
8268 },
8269 )
8270 }
8271
8272 pub fn parse_atn_rule_with_runtime_options(
8279 &mut self,
8280 atn: &Atn,
8281 rule_index: usize,
8282 options: ParserRuntimeOptions<'_>,
8283 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8284 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
8285 }
8286
8287 fn parse_atn_rule_committed_with_runtime_options(
8288 &mut self,
8289 atn: &Atn,
8290 rule_index: usize,
8291 precedence: i32,
8292 options: ParserRuntimeOptions<'_>,
8293 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8294 let top_level_entry = self.is_top_level_entry();
8295 self.unknown_predicate_policy = options.unknown_predicate_policy;
8296 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8297 let prior_unhandled_action_hits = std::mem::take(&mut self.unhandled_action_hits);
8298 self.clear_prediction_diagnostics();
8299 self.reset_per_parse_caches();
8300 self.reset_recognition_arena();
8301
8302 let mut decision_by_state = vec![None; atn.states().len()];
8303 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
8304 if let Some(slot) = decision_by_state.get_mut(state_number) {
8305 *slot = Some(decision);
8306 }
8307 }
8308 let mut action_index_by_state = FxHashMap::default();
8309 for &(state, index) in options.action_indices {
8310 action_index_by_state.entry(state).or_insert(index);
8311 }
8312 let mut simulator = ParserAtnSimulator::new(atn);
8313 simulator.set_track_prediction_rule_calls(!options.rule_args.is_empty());
8314 let (result, deferred_actions) = {
8315 let mut committed = CommittedAtnParser {
8316 parser: self,
8317 atn,
8318 simulator,
8319 options,
8320 decision_by_state,
8321 action_index_by_state,
8322 deferred_actions: Vec::new(),
8323 };
8324 let result = committed.parse_rule(rule_index, precedence, None, None);
8325 (result, committed.deferred_actions)
8326 };
8327
8328 if top_level_entry {
8329 self.report_generated_parser_diagnostics();
8330 }
8331 let semantic_error = self.unknown_semantic_error();
8332 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8333 self.restore_prior_unhandled_action_hits(prior_unhandled_action_hits);
8334 if top_level_entry && let Some(error) = self.take_parse_abort() {
8335 self.reset_unknown_semantic_hits();
8336 return Err(error);
8337 }
8338 if let Some(error) = semantic_error {
8339 if top_level_entry {
8340 self.reset_unknown_semantic_hits();
8341 }
8342 return Err(error);
8343 }
8344 let result = result.map(|outcome| (outcome.tree, deferred_actions));
8345 if top_level_entry && let Err(error) = &result {
8346 self.report_unrecovered_parser_error(error);
8347 }
8348 result
8349 }
8350
8351 pub fn parse_atn_rule_with_runtime_options_and_precedence(
8354 &mut self,
8355 atn: &Atn,
8356 rule_index: usize,
8357 precedence: i32,
8358 options: ParserRuntimeOptions<'_>,
8359 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8360 if !options.action_indices.is_empty() {
8361 return self.parse_atn_rule_committed_with_runtime_options(
8362 atn, rule_index, precedence, options,
8363 );
8364 }
8365 let report_unrecovered_error = self.is_top_level_entry();
8366 let ParserRuntimeOptions {
8367 init_action_rules,
8368 track_alt_numbers,
8369 track_context_alt_numbers,
8370 predicates,
8371 semantics,
8372 rule_args,
8373 member_actions,
8374 return_actions,
8375 unknown_predicate_policy,
8376 ..
8377 } = options;
8378 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
8379 if init_action_rules.is_empty()
8380 && !capture_alt_numbers
8381 && predicates.is_empty()
8382 && semantics.is_none()
8383 && rule_args.is_empty()
8384 && member_actions.is_empty()
8385 && return_actions.is_empty()
8386 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
8387 && !atn_has_observable_action_transitions(atn)
8388 && !self.semantic_hooks.observes_parser_decisions()
8389 && (!self.semantic_hooks.observes_parser_predicates()
8390 || !atn_has_predicate_transitions(atn))
8391 {
8392 return self
8393 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
8394 .map(|tree| (tree, Vec::new()));
8395 }
8396 if !self.semantic_hooks.observes_parser_decisions()
8397 && can_use_fast_predicate_recognizer(atn, &options)
8398 {
8399 self.unknown_predicate_policy = unknown_predicate_policy;
8400 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8401 let member_values = self.int_members.clone();
8402 let result = self
8403 .parse_atn_rule_with_precedence_inner(
8404 atn,
8405 rule_index,
8406 precedence,
8407 Some(FastPredicateContext {
8408 predicates,
8409 semantics,
8410 member_values: &member_values,
8411 }),
8412 AltNumberTracking {
8413 public: track_alt_numbers,
8414 context: track_context_alt_numbers,
8415 },
8416 )
8417 .map(|tree| (tree, Vec::new()));
8418 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
8419 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8420 }
8421 return result;
8422 }
8423 self.unknown_predicate_policy = unknown_predicate_policy;
8424 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8431 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
8432 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
8433 })?;
8434 let stop_state = atn
8435 .rule_to_stop_state()
8436 .get(rule_index)
8437 .filter(|state| *state != usize::MAX)
8438 .ok_or_else(|| {
8439 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
8440 })?;
8441
8442 let start_index = self.current_visible_index();
8443 self.clear_prediction_diagnostics();
8444 self.reset_per_parse_caches();
8445 self.reset_recognition_arena();
8446 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
8447 let invoking_state = self.pending_invoking_states.pop();
8448 let local_int_arg = invoking_state
8449 .and_then(|state| usize::try_from(state).ok())
8450 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
8451 let mut visiting = BTreeSet::new();
8452 let mut memo = BTreeMap::new();
8453 let mut expected = ExpectedTokens::default();
8454 let member_values = self.int_members.clone();
8455 let return_values = BTreeMap::new();
8456 let outcomes = self.recognize_state(
8457 atn,
8458 RecognizeRequest {
8459 state_number: start_state,
8460 stop_state,
8461 index: start_index,
8462 rule_start_index: start_index,
8463 decision_start_index: None,
8464 init_action_rules: &init_action_rules,
8465 predicates,
8466 semantics,
8467 rule_args,
8468 member_actions,
8469 return_actions,
8470 local_int_arg,
8471 member_values,
8472 return_values,
8473 rule_alt_number: 0,
8474 track_alt_numbers: capture_alt_numbers,
8475 consumed_eof: false,
8476 committed_decision: false,
8477 precedence,
8478 depth: 0,
8479 recovery_symbols: BTreeSet::new(),
8480 recovery_state: None,
8481 },
8482 &mut visiting,
8483 &mut memo,
8484 &mut expected,
8485 );
8486 if let Some(error) = self.unknown_semantic_error() {
8487 self.report_token_source_errors();
8488 return Err(error);
8495 }
8496 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8499 let Some(outcome) = select_best_outcome(
8500 outcomes.into_iter(),
8501 self.prediction_mode,
8502 &self.recognition_arena,
8503 ) else {
8504 let error = self.recognition_error(rule_index, start_index, &expected);
8505 self.record_syntax_errors(1);
8506 self.report_token_source_errors();
8507 if report_unrecovered_error {
8508 self.report_unrecovered_parser_error(&error);
8509 }
8510 return Err(error);
8511 };
8512
8513 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
8514 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
8515 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
8516 self.report_token_source_errors();
8517 let mut actions = outcome.actions;
8518 if init_action_rules.contains(&rule_index) {
8519 actions.insert(
8520 0,
8521 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
8522 );
8523 }
8524 let mut context =
8525 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
8526 if track_alt_numbers {
8527 context.set_alt_number(outcome.alt_number.max(1));
8528 }
8529 if track_context_alt_numbers {
8530 context.set_context_alt_number(outcome.alt_number);
8531 }
8532 for (name, value) in outcome.return_values {
8533 context.set_int_return(name, value);
8534 }
8535 if let Some(token) = self.token_id_at(start_index) {
8536 self.set_context_start(&mut context, token);
8537 }
8538 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
8539 self.set_context_stop(&mut context, token);
8540 }
8541 let live_root = if self.build_parse_trees {
8542 self.recognition_arena
8543 .fold_left_recursive_boundaries(outcome.nodes)
8544 } else {
8545 outcome.nodes
8546 };
8547 if self.build_parse_trees {
8548 let mut nodes = live_root;
8549 while let Some(link) = self.recognition_arena.link(nodes) {
8550 let child = self.arena_recognized_node_tree(
8551 link.head,
8552 track_alt_numbers,
8553 track_context_alt_numbers,
8554 )?;
8555 self.tree.add_child(&mut context, child);
8556 nodes = link.tail;
8557 }
8558 }
8559 self.finish_recognition_arena(live_root, outcome.diagnostics);
8560 self.input.seek(outcome.index);
8561
8562 let tree = self.rule_node(context);
8563 self.release_tree_scratch_if_idle();
8564 Ok((tree, actions))
8565 }
8566
8567 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
8574 let mut context = ParserRuleContext::new(rule_index, self.state());
8575 while self.la(1) != TOKEN_EOF {
8576 let token_type = self.la(1);
8577 let child = self.match_token(token_type)?;
8578 if self.build_parse_trees {
8579 self.tree.add_child(&mut context, child);
8580 }
8581 }
8582 if self.build_parse_trees {
8583 let child = self.match_eof()?;
8584 self.tree.add_child(&mut context, child);
8585 }
8586 let tree = self.rule_node(context);
8587 self.release_tree_scratch_if_idle();
8588 Ok(tree)
8589 }
8590
8591 fn recognition_error(
8594 &mut self,
8595 rule_index: usize,
8596 start_index: usize,
8597 expected: &ExpectedTokens,
8598 ) -> AntlrError {
8599 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
8600 self.input.seek(index);
8601 let current = self.input.lt(1);
8602 let line = current.as_ref().map(Token::line).unwrap_or_default();
8603 let column = current.as_ref().map(Token::column).unwrap_or_default();
8604 AntlrError::ParserError {
8605 line,
8606 column,
8607 message,
8608 offending: current.as_ref().map(Token::token_id),
8609 }
8610 }
8611
8612 fn expected_error_message(
8614 &mut self,
8615 rule_index: usize,
8616 start_index: usize,
8617 expected: &ExpectedTokens,
8618 ) -> (usize, String) {
8619 let index = expected
8620 .index
8621 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
8622 .unwrap_or_else(|| self.input.index());
8623 self.input.seek(index);
8624 let current = self.input.lt(1);
8625 let message = if expected
8626 .no_viable
8627 .as_ref()
8628 .is_some_and(|no_viable| no_viable.error_index == index)
8629 {
8630 let start = expected
8631 .no_viable
8632 .as_ref()
8633 .map_or(start_index, |no_viable| no_viable.start_index);
8634 let text = display_input_text(&self.input.text(start, index));
8635 format!("no viable alternative at input '{text}'")
8636 } else if expected.symbols.is_empty() {
8637 if expected.index.is_some() {
8638 let found = current
8639 .as_ref()
8640 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
8641 if current
8642 .as_ref()
8643 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8644 {
8645 format!(
8646 "missing {} at {found}",
8647 self.expected_symbols_display(&expected.symbols)
8648 )
8649 } else {
8650 format!("mismatched input {found}")
8651 }
8652 } else {
8653 format!("no viable alternative while parsing rule {rule_index}")
8654 }
8655 } else {
8656 format!(
8657 "mismatched input {} expecting {}",
8658 current
8659 .as_ref()
8660 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8661 self.expected_symbols_display(&expected.symbols)
8662 )
8663 };
8664 (index, message)
8665 }
8666
8667 fn child_rule_failure_recovery(
8670 &mut self,
8671 rule_index: usize,
8672 start_index: usize,
8673 sync_symbols: &BTreeSet<i32>,
8674 member_values: MemberEnv,
8675 expected: &ExpectedTokens,
8676 ) -> Option<RecognizeOutcome> {
8677 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8678 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8679 let mut next_index = error_index;
8680 loop {
8681 let symbol = self.token_type_at(next_index);
8682 if sync_symbols.contains(&symbol) {
8683 if next_index == error_index {
8684 return None;
8685 }
8686 break;
8687 }
8688 if symbol == TOKEN_EOF {
8689 break;
8690 }
8691 let after = self.consume_index(next_index, symbol);
8692 if after == next_index {
8693 break;
8694 }
8695 next_index = after;
8696 }
8697 let mut nodes = NodeSeqId::EMPTY;
8698 let error = self.arena_token_node(error_index, true);
8699 self.arena_prepend(&mut nodes, error);
8700 let diagnostics = self
8701 .recognition_arena
8702 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8703 Some(RecognizeOutcome {
8704 index: next_index,
8705 consumed_eof: false,
8706 alt_number: 0,
8707 member_values,
8708 return_values: BTreeMap::new(),
8709 diagnostics,
8710 decisions: Vec::new(),
8711 actions: Vec::new(),
8712 nodes,
8713 })
8714 }
8715
8716 fn child_rule_failure_recovery_outcomes(
8719 &mut self,
8720 request: ChildRuleFailureRecovery<'_>,
8721 ) -> Vec<RecognizeOutcome> {
8722 let sync_symbols =
8723 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
8724 self.child_rule_failure_recovery(
8725 request.rule_index,
8726 request.start_index,
8727 &sync_symbols,
8728 request.member_values,
8729 request.expected,
8730 )
8731 .into_iter()
8732 .collect()
8733 }
8734
8735 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
8737 expected_symbols_display(symbols, self.vocabulary())
8738 }
8739
8740 fn single_token_deletion(
8743 &mut self,
8744 transition: ParserTransition<'_>,
8745 index: usize,
8746 max_token_type: i32,
8747 expected_symbols: &BTreeSet<i32>,
8748 ) -> Option<(ParserDiagnostic, usize, i32)> {
8749 let current_symbol = self.token_type_at(index);
8750 if current_symbol == TOKEN_EOF {
8751 return None;
8752 }
8753 let next_index = self.consume_index(index, current_symbol);
8754 if next_index == index {
8755 return None;
8756 }
8757 let next_symbol = self.token_type_at(next_index);
8758 if !transition.matches(next_symbol, 1, max_token_type) {
8759 return None;
8760 }
8761 let transition_expected = transition_expected_symbols(transition, max_token_type);
8762 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8763 &transition_expected
8764 } else {
8765 expected_symbols
8766 });
8767 let current = self.token_at(index);
8768 let message = format!(
8769 "extraneous input {} expecting {expected_display}",
8770 current
8771 .as_ref()
8772 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8773 );
8774 Some((
8775 diagnostic_for_token(current, message),
8776 next_index,
8777 next_symbol,
8778 ))
8779 }
8780
8781 fn current_token_deletion(
8784 &mut self,
8785 index: usize,
8786 expected_symbols: &BTreeSet<i32>,
8787 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
8788 if expected_symbols.is_empty() {
8789 return None;
8790 }
8791 let current_symbol = self.token_type_at(index);
8792 if current_symbol == TOKEN_EOF {
8793 return None;
8794 }
8795 let current = self.token_at(index);
8796 let message = format!(
8797 "extraneous input {} expecting {}",
8798 current
8799 .as_ref()
8800 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8801 self.expected_symbols_display(expected_symbols)
8802 );
8803 let diagnostic = diagnostic_for_token(current, message);
8804 let mut skipped = Vec::new();
8805 let mut cursor = index;
8806 loop {
8807 let symbol = self.token_type_at(cursor);
8808 if symbol == TOKEN_EOF {
8809 return None;
8810 }
8811 skipped.push(cursor);
8812 let next_index = self.consume_index(cursor, symbol);
8813 if next_index == cursor {
8814 return None;
8815 }
8816 let next_symbol = self.token_type_at(next_index);
8817 if expected_symbols.contains(&next_symbol) {
8818 return Some((diagnostic, next_index, skipped));
8819 }
8820 cursor = next_index;
8821 }
8822 }
8823
8824 fn single_token_insertion(
8828 &mut self,
8829 transition: ParserTransition<'_>,
8830 index: usize,
8831 max_token_type: i32,
8832 expected_symbols: &BTreeSet<i32>,
8833 follow_symbols: &BTreeSet<i32>,
8834 ) -> Option<(ParserDiagnostic, i32, String)> {
8835 let current_symbol = self.token_type_at(index);
8836 if !follow_symbols.contains(¤t_symbol) {
8837 return None;
8838 }
8839 let transition_expected = transition_expected_symbols(transition, max_token_type);
8840 let token_type = transition_expected.iter().next().copied()?;
8841 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8842 &transition_expected
8843 } else {
8844 expected_symbols
8845 });
8846 let mut token_symbols = BTreeSet::new();
8847 token_symbols.insert(token_type);
8848 let missing_token_display = self.expected_symbols_display(&token_symbols);
8849 let current = self.token_at(index);
8850 let message = format!(
8851 "missing {expected_display} at {}",
8852 current
8853 .as_ref()
8854 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8855 );
8856 let text = format!("<missing {missing_token_display}>");
8857 Some((
8858 diagnostic_for_token(current.as_ref(), message),
8859 token_type,
8860 text,
8861 ))
8862 }
8863
8864 fn fast_single_token_deletion_recovery(
8868 &mut self,
8869 recovery: FastRecoveryRequest<'_, '_>,
8870 predicate_context: Option<FastPredicateContext<'_>>,
8871 ) -> Vec<FastRecognizeOutcome> {
8872 let FastRecoveryRequest {
8873 atn,
8874 transition,
8875 expected_symbols,
8876 target,
8877 request,
8878 visiting,
8879 memo,
8880 expected,
8881 } = recovery;
8882 let FastRecognizeRequest {
8883 stop_state,
8884 index,
8885 rule_start_index,
8886 decision_start_index,
8887 precedence,
8888 depth,
8889 ..
8890 } = request;
8891 let Some((diagnostic, next_index, next_symbol)) =
8892 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8893 else {
8894 return Vec::new();
8895 };
8896 let after_next = self.consume_index(next_index, next_symbol);
8897 let empty_recovery = self.empty_recovery_symbols();
8898 self.recognize_state_fast(
8899 atn,
8900 FastRecognizeRequest {
8901 state_number: target,
8902 stop_state,
8903 index: after_next,
8904 rule_start_index,
8905 decision_start_index,
8906 precedence,
8907 depth: depth + 1,
8908 recovery_symbols: empty_recovery,
8909 recovery_state: None,
8910 },
8911 FastRecognizeScratch {
8912 predicate_context,
8913 visiting,
8914 memo,
8915 expected,
8916 native_depth: 0,
8917 },
8918 )
8919 .into_iter()
8920 .map(|mut outcome| {
8921 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
8922 outcome.diagnostics = self
8923 .recognition_arena
8924 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8925 if self.fast_token_nodes_enabled {
8926 let token = self.arena_token_node(next_index, false);
8927 self.defer_fast_outcome_node(&mut outcome, token);
8928 let error = self.arena_token_node(index, true);
8929 self.defer_fast_outcome_node(&mut outcome, error);
8930 }
8931 outcome
8932 })
8933 .collect()
8934 }
8935
8936 fn fast_single_token_insertion_recovery(
8940 &mut self,
8941 recovery: FastRecoveryRequest<'_, '_>,
8942 predicate_context: Option<FastPredicateContext<'_>>,
8943 ) -> Vec<FastRecognizeOutcome> {
8944 let FastRecoveryRequest {
8945 atn,
8946 transition,
8947 expected_symbols,
8948 target,
8949 request,
8950 visiting,
8951 memo,
8952 expected,
8953 } = recovery;
8954 let FastRecognizeRequest {
8955 stop_state,
8956 index,
8957 rule_start_index,
8958 decision_start_index,
8959 precedence,
8960 depth,
8961 ..
8962 } = request;
8963 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
8964 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
8965 transition,
8966 index,
8967 atn.max_token_type(),
8968 &expected_symbols,
8969 &follow_symbols,
8970 ) else {
8971 return Vec::new();
8972 };
8973 let empty_recovery = self.empty_recovery_symbols();
8974 self.recognize_state_fast(
8975 atn,
8976 FastRecognizeRequest {
8977 state_number: target,
8978 stop_state,
8979 index,
8980 rule_start_index,
8981 decision_start_index,
8982 precedence,
8983 depth: depth + 1,
8984 recovery_symbols: empty_recovery,
8985 recovery_state: None,
8986 },
8987 FastRecognizeScratch {
8988 predicate_context,
8989 visiting,
8990 memo,
8991 expected,
8992 native_depth: 0,
8993 },
8994 )
8995 .into_iter()
8996 .map(|mut outcome| {
8997 outcome.diagnostics = self
8998 .recognition_arena
8999 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9000 let missing = self.arena_missing_token_node(token_type, index, text.clone());
9001 self.defer_fast_outcome_node(&mut outcome, missing);
9002 outcome
9003 })
9004 .collect()
9005 }
9006
9007 fn fast_current_token_deletion_recovery(
9010 &mut self,
9011 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
9012 predicate_context: Option<FastPredicateContext<'_>>,
9013 ) -> Vec<FastRecognizeOutcome> {
9014 let FastCurrentTokenDeletionRequest {
9015 atn,
9016 expected_symbols,
9017 mut request,
9018 visiting,
9019 memo,
9020 expected,
9021 } = recovery;
9022 if request.index == request.rule_start_index {
9023 return Vec::new();
9024 }
9025 let Some((diagnostic, next_index, skipped)) =
9026 self.current_token_deletion(request.index, &expected_symbols)
9027 else {
9028 return Vec::new();
9029 };
9030 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9031 request.index = next_index;
9032 request.depth += 1;
9033 request.recovery_state = None;
9034 self.recognize_state_fast(
9035 atn,
9036 request,
9037 FastRecognizeScratch {
9038 predicate_context,
9039 visiting,
9040 memo,
9041 expected,
9042 native_depth: 0,
9043 },
9044 )
9045 .into_iter()
9046 .map(|mut outcome| {
9047 outcome.diagnostics = self
9048 .recognition_arena
9049 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9050 for index in skipped.iter().rev() {
9051 let error = self.arena_token_node(*index, true);
9052 self.defer_fast_outcome_node(&mut outcome, error);
9053 }
9054 outcome
9055 })
9056 .collect()
9057 }
9058
9059 fn fast_child_rule_failure_recovery(
9062 &mut self,
9063 rule_index: usize,
9064 start_index: usize,
9065 sync_symbols: &BTreeSet<i32>,
9066 expected: &ExpectedTokens,
9067 ) -> Option<FastRecognizeOutcome> {
9068 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
9069 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
9070 let mut next_index = error_index;
9071 loop {
9072 let symbol = self.token_type_at(next_index);
9073 if sync_symbols.contains(&symbol) {
9074 if next_index == error_index {
9075 return None;
9076 }
9077 break;
9078 }
9079 if symbol == TOKEN_EOF {
9080 break;
9081 }
9082 let after = self.consume_index(next_index, symbol);
9083 if after == next_index {
9084 break;
9085 }
9086 next_index = after;
9087 }
9088 let diagnostics = self
9089 .recognition_arena
9090 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
9091 let mut nodes = NodeSeqId::EMPTY;
9092 if self.fast_token_nodes_enabled {
9093 let error = self.arena_token_node(error_index, true);
9094 self.arena_prepend(&mut nodes, error);
9095 }
9096 Some(FastRecognizeOutcome {
9097 index: next_index,
9098 consumed_eof: false,
9099 diagnostics,
9100 deferred_nodes: FastDeferredNodeId::EMPTY,
9101 nodes,
9102 })
9103 }
9104
9105 fn fast_child_rule_failure_recovery_outcomes(
9108 &mut self,
9109 request: FastChildRuleFailureRecoveryRequest<'_>,
9110 ) -> Vec<FastRecognizeOutcome> {
9111 let FastChildRuleFailureRecoveryRequest {
9112 atn,
9113 rule_index,
9114 start_index,
9115 follow_state,
9116 stop_state,
9117 expected,
9118 } = request;
9119 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
9120 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
9121 .into_iter()
9122 .collect()
9123 }
9124
9125 fn defer_fast_outcome_node(
9126 &mut self,
9127 outcome: &mut FastRecognizeOutcome,
9128 node: RecognizedNodeId,
9129 ) {
9130 if outcome.deferred_nodes.is_empty() {
9131 self.arena_prepend(&mut outcome.nodes, node);
9132 return;
9133 }
9134 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
9135 let fragment = self.recognition_arena.deferred_fragment(fragment);
9136 outcome.deferred_nodes = self
9137 .recognition_arena
9138 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
9139 }
9140
9141 fn defer_fast_outcome_alternative(
9142 &mut self,
9143 outcome: &mut FastRecognizeOutcome,
9144 alt_number: usize,
9145 ) {
9146 let alternative = self.recognition_arena.deferred_alternative(alt_number);
9147 outcome.deferred_nodes = self
9148 .recognition_arena
9149 .concat_deferred_nodes(alternative, outcome.deferred_nodes);
9150 }
9151
9152 fn defer_fast_outcome_boundary(
9153 &mut self,
9154 outcome: &mut FastRecognizeOutcome,
9155 rule_index: usize,
9156 ) {
9157 let boundary = self
9158 .recognition_arena
9159 .deferred_left_recursive_boundary(rule_index);
9160 outcome.deferred_nodes = self
9161 .recognition_arena
9162 .concat_deferred_nodes(boundary, outcome.deferred_nodes);
9163 }
9164
9165 fn materialize_fast_deferred_nodes(
9166 &mut self,
9167 root: FastDeferredNodeId,
9168 initial_suffix: NodeSeqId,
9169 ) -> (NodeSeqId, usize) {
9170 if root.is_empty() {
9171 return (initial_suffix, 0);
9172 }
9173
9174 enum Frame {
9175 Visit(FastDeferredNodeId),
9176 ContinuePrefix(FastDeferredNodeId),
9177 FinishRule {
9178 rule: FastDeferredRule,
9179 parent_suffix: NodeSeqId,
9180 parent_alt_number: u32,
9181 parent_pending_boundary: Option<RecognizedNodeId>,
9182 },
9183 }
9184
9185 let mut result = initial_suffix;
9186 let mut alt_number = 0;
9190 let mut pending_boundary = None;
9191 let mut pending = Vec::with_capacity(16);
9192 pending.push(Frame::Visit(root));
9193 let mut fragment_nodes = Vec::new();
9194 while let Some(frame) = pending.pop() {
9195 match frame {
9196 Frame::Visit(deferred) => {
9197 if deferred.is_empty() {
9198 continue;
9199 }
9200
9201 match self.recognition_arena.deferred_node(deferred) {
9202 FastDeferredNode::Fragment(sequence) => {
9203 fragment_nodes.clear();
9204 fragment_nodes.extend(self.recognition_arena.iter(sequence));
9205 while let Some(node) = fragment_nodes.pop() {
9206 self.arena_prepend(&mut result, node);
9207 }
9208 }
9209 FastDeferredNode::Rule(rule) => {
9210 let rule = self.recognition_arena.deferred_rule(rule);
9211 let parent_suffix = result;
9212 let parent_alt_number = alt_number;
9213 let parent_pending_boundary = pending_boundary;
9214 result = rule.children;
9215 alt_number = 0;
9216 pending_boundary = None;
9217 pending.push(Frame::FinishRule {
9218 rule,
9219 parent_suffix,
9220 parent_alt_number,
9221 parent_pending_boundary,
9222 });
9223 pending.push(Frame::Visit(rule.deferred_children));
9224 }
9225 FastDeferredNode::Alternative(selected) => {
9226 if let Some(boundary) = pending_boundary {
9227 self.recognition_arena
9228 .set_boundary_alt_number(boundary, selected);
9229 } else {
9230 alt_number = selected;
9231 }
9232 }
9233 FastDeferredNode::LeftRecursiveBoundary { rule_index } => {
9234 let boundary = self.arena_boundary_node(rule_index as usize, 0);
9235 self.arena_prepend(&mut result, boundary);
9236 pending_boundary = Some(boundary);
9237 }
9238 FastDeferredNode::Concat {
9239 prefix,
9240 suffix: deferred_suffix,
9241 } => {
9242 pending.push(Frame::ContinuePrefix(prefix));
9243 pending.push(Frame::Visit(deferred_suffix));
9244 }
9245 }
9246 }
9247 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
9248 Frame::FinishRule {
9249 rule,
9250 parent_suffix,
9251 parent_alt_number,
9252 parent_pending_boundary,
9253 } => {
9254 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
9255 rule_index: rule.rule_index,
9256 invoking_state: rule.invoking_state,
9257 alt_number,
9258 start_index: rule.start_index,
9259 stop_index: rule.stop_index,
9260 return_values: None,
9261 children: result,
9262 });
9263 result = parent_suffix;
9264 self.arena_prepend(&mut result, node);
9265 alt_number = parent_alt_number;
9266 pending_boundary = parent_pending_boundary;
9267 }
9268 }
9269 }
9270 (result, alt_number as usize)
9271 }
9272
9273 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) -> usize {
9274 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
9275 let (nodes, alt_number) =
9276 self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
9277 outcome.nodes = nodes;
9278 alt_number
9279 }
9280
9281 fn recognize_repetition_fast(
9284 &mut self,
9285 atn: &Atn,
9286 request: &FastRecognizeRequest,
9287 shape: FastRepetitionShape,
9288 scratch: FastRecognizeScratch<'_, '_>,
9289 ) -> Vec<FastRecognizeOutcome> {
9290 let FastRecognizeScratch {
9291 predicate_context,
9292 visiting,
9293 memo,
9294 expected,
9295 native_depth,
9296 } = scratch;
9297 let lookahead = if self.fast_first_set_prefilter {
9298 atn.state(request.state_number).and_then(|state| {
9299 state
9300 .rule_index()
9301 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9302 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
9303 })
9304 } else {
9305 None
9306 };
9307 let (enter_alt_number, exit_alt_number) = if self.fast_track_alt_numbers {
9308 let state = atn
9309 .state(request.state_number)
9310 .expect("repetition request state must exist");
9311 (
9312 next_alt_number(state, 2, shape.enter_transition_index, 0, true),
9313 next_alt_number(state, 2, shape.exit_transition_index, 0, true),
9314 )
9315 } else {
9316 (0, 0)
9317 };
9318 let mut work = Vec::with_capacity(2);
9319 push_fast_repetition_work(
9320 &mut work,
9321 shape,
9322 FastRepetitionPath {
9323 index: request.index,
9324 deferred_nodes: FastDeferredNodeId::EMPTY,
9325 diagnostics: DiagnosticSeqId::EMPTY,
9326 consumed_eof: false,
9327 },
9328 lookahead.as_deref(),
9329 self.token_type_at(request.index),
9330 );
9331 let mut coordinates = FastRepetitionCoordinates::new(request.index);
9332 let mut outcomes = Vec::new();
9333 while let Some(item) = work.pop() {
9334 match item {
9335 FastRepetitionWork::Enter(path) => {
9336 if !coordinates.insert_entered(path) {
9337 continue;
9338 }
9339 let path_nodes = if enter_alt_number == 0 {
9340 path.deferred_nodes
9341 } else {
9342 let alternative = self
9343 .recognition_arena
9344 .deferred_alternative(enter_alt_number);
9345 self.recognition_arena
9346 .concat_deferred_nodes(path.deferred_nodes, alternative)
9347 };
9348 let body_outcomes = self.recognize_state_fast(
9349 atn,
9350 FastRecognizeRequest {
9351 state_number: shape.enter_target,
9352 stop_state: shape.body_stop_state,
9353 index: path.index,
9354 rule_start_index: request.rule_start_index,
9355 decision_start_index: request.decision_start_index,
9356 precedence: request.precedence,
9357 depth: request.depth.saturating_add(1),
9358 recovery_symbols: Rc::clone(&request.recovery_symbols),
9359 recovery_state: request.recovery_state,
9360 },
9361 FastRecognizeScratch {
9362 predicate_context,
9363 visiting: &mut *visiting,
9364 memo: &mut *memo,
9365 expected: &mut *expected,
9366 native_depth: native_depth + 1,
9367 },
9368 );
9369 for body in body_outcomes.into_iter().rev() {
9370 if body.index <= path.index {
9374 continue;
9375 }
9376 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
9377 let body_nodes = self
9378 .recognition_arena
9379 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
9380 let deferred_nodes = self
9381 .recognition_arena
9382 .concat_deferred_nodes(path_nodes, body_nodes);
9383 let next_path = FastRepetitionPath {
9384 index: body.index,
9385 deferred_nodes,
9386 diagnostics: self
9387 .recognition_arena
9388 .concat_diagnostics(path.diagnostics, body.diagnostics),
9389 consumed_eof: path.consumed_eof || body.consumed_eof,
9390 };
9391 let symbol = self.token_type_at(next_path.index);
9392 push_fast_repetition_work(
9393 &mut work,
9394 shape,
9395 next_path,
9396 lookahead.as_deref(),
9397 symbol,
9398 );
9399 }
9400 }
9401 FastRepetitionWork::Exit(path) => {
9402 if !coordinates.insert_exited(path) {
9403 continue;
9404 }
9405 let path_nodes = if exit_alt_number == 0 {
9406 path.deferred_nodes
9407 } else {
9408 let alternative =
9409 self.recognition_arena.deferred_alternative(exit_alt_number);
9410 self.recognition_arena
9411 .concat_deferred_nodes(path.deferred_nodes, alternative)
9412 };
9413 let suffixes = self.recognize_state_fast(
9414 atn,
9415 FastRecognizeRequest {
9416 state_number: shape.exit_target,
9417 stop_state: request.stop_state,
9418 index: path.index,
9419 rule_start_index: request.rule_start_index,
9420 decision_start_index: request.decision_start_index,
9421 precedence: request.precedence,
9422 depth: request.depth.saturating_add(1),
9423 recovery_symbols: Rc::clone(&request.recovery_symbols),
9424 recovery_state: request.recovery_state,
9425 },
9426 FastRecognizeScratch {
9427 predicate_context,
9428 visiting: &mut *visiting,
9429 memo: &mut *memo,
9430 expected: &mut *expected,
9431 native_depth: native_depth + 1,
9432 },
9433 );
9434 for mut outcome in suffixes {
9435 outcome.deferred_nodes = self
9436 .recognition_arena
9437 .concat_deferred_nodes(path_nodes, outcome.deferred_nodes);
9438 outcome.diagnostics = self
9439 .recognition_arena
9440 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
9441 outcome.consumed_eof |= path.consumed_eof;
9442 outcomes.push(outcome);
9443 }
9444 }
9445 }
9446 }
9447 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9448 outcomes
9449 }
9450
9451 fn recognize_state_fast(
9454 &mut self,
9455 atn: &Atn,
9456 request: FastRecognizeRequest,
9457 scratch: FastRecognizeScratch<'_, '_>,
9458 ) -> Vec<FastRecognizeOutcome> {
9459 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
9460 return self.recognize_state_fast_inner(atn, request, scratch);
9461 }
9462 self.recognize_state_fast_checked(atn, request, scratch)
9463 }
9464
9465 #[inline(never)]
9466 fn recognize_state_fast_checked(
9467 &mut self,
9468 atn: &Atn,
9469 request: FastRecognizeRequest,
9470 mut scratch: FastRecognizeScratch<'_, '_>,
9471 ) -> Vec<FastRecognizeOutcome> {
9472 scratch.native_depth = 1;
9473 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
9474 self.recognize_state_fast_inner(atn, request, scratch)
9475 })
9476 }
9477
9478 #[allow(clippy::too_many_lines)]
9479 fn recognize_state_fast_inner(
9480 &mut self,
9481 atn: &Atn,
9482 request: FastRecognizeRequest,
9483 scratch: FastRecognizeScratch<'_, '_>,
9484 ) -> Vec<FastRecognizeOutcome> {
9485 #[cfg(feature = "perf-counters")]
9486 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
9487 let FastRecognizeScratch {
9488 predicate_context,
9489 visiting,
9490 memo,
9491 expected,
9492 native_depth,
9493 } = scratch;
9494 let FastRecognizeRequest {
9495 mut state_number,
9496 stop_state,
9497 mut index,
9498 rule_start_index,
9499 decision_start_index,
9500 precedence,
9501 mut depth,
9502 recovery_symbols,
9503 recovery_state,
9504 } = request;
9505 let max_token_type = atn.max_token_type();
9506 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
9525 let mut inline_consumed_eof = false;
9526 loop {
9527 if depth > RECOGNITION_DEPTH_LIMIT {
9528 return Vec::new();
9529 }
9530 if state_number == stop_state {
9531 let mut nodes = NodeSeqId::EMPTY;
9532 if self.fast_token_nodes_enabled {
9533 for token_index in inline_consumed_tokens.iter().rev() {
9534 let token = self.arena_token_node(*token_index, false);
9535 self.arena_prepend(&mut nodes, token);
9536 }
9537 }
9538 return vec![FastRecognizeOutcome {
9539 index,
9540 consumed_eof: inline_consumed_eof,
9541 diagnostics: DiagnosticSeqId::EMPTY,
9542 deferred_nodes: FastDeferredNodeId::EMPTY,
9543 nodes,
9544 }];
9545 }
9546 let Some(state) = atn.state(state_number) else {
9547 return Vec::new();
9548 };
9549 let transitions = state.transitions();
9550 if transitions.len() == 1 && !state.precedence_rule_decision() {
9551 let transition = transitions
9552 .first()
9553 .expect("single transition checked above");
9554 let transition_kind = transition.kind();
9555 let target = transition.target();
9556 match transition_kind {
9557 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
9558 if left_recursive_boundary(atn, state, target).is_none() =>
9559 {
9560 #[cfg(feature = "perf-counters")]
9561 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9562 state_number = target;
9563 depth += 1;
9564 continue;
9565 }
9566 ParserTransitionKind::Predicate
9567 if left_recursive_boundary(atn, state, target).is_none() =>
9568 {
9569 #[cfg(feature = "perf-counters")]
9570 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9571 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
9572 {
9573 record_predicate_no_viable(expected, decision_start_index, index);
9574 return Vec::new();
9575 }
9576 state_number = target;
9577 depth += 1;
9578 continue;
9579 }
9580 ParserTransitionKind::Precedence
9581 if packed_i32(transition.arg0()) >= precedence
9582 && left_recursive_boundary(atn, state, target).is_none() =>
9583 {
9584 #[cfg(feature = "perf-counters")]
9585 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9586 state_number = target;
9587 depth += 1;
9588 continue;
9589 }
9590 ParserTransitionKind::Atom
9600 | ParserTransitionKind::Range
9601 | ParserTransitionKind::Set
9602 | ParserTransitionKind::NotSet
9603 | ParserTransitionKind::Wildcard
9604 if !self.fast_recovery_enabled =>
9605 {
9606 let symbol = self.token_type_at(index);
9607 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9608 #[cfg(feature = "perf-counters")]
9609 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9610 if self.fast_token_nodes_enabled {
9611 inline_consumed_tokens.push(index);
9612 }
9613 inline_consumed_eof |= symbol == TOKEN_EOF;
9614 index = self.consume_index(index, symbol);
9615 state_number = target;
9616 depth += 1;
9617 continue;
9618 }
9619 }
9622 _ => {}
9623 }
9624 }
9625 break;
9626 }
9627 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
9631 let Some(state) = atn.state(state_number) else {
9632 return Vec::new();
9633 };
9634 let transitions = state.transitions();
9635 let transition_count = transitions.len();
9636 if !self.fast_recovery_enabled
9637 && let Some(shape) = fast_repetition_shape(atn, state)
9638 {
9639 let mut outcomes = self.recognize_repetition_fast(
9640 atn,
9641 &FastRecognizeRequest {
9642 state_number,
9643 stop_state,
9644 index,
9645 rule_start_index,
9646 decision_start_index,
9647 precedence,
9648 depth,
9649 recovery_symbols: Rc::clone(&recovery_symbols),
9650 recovery_state,
9651 },
9652 shape,
9653 FastRecognizeScratch {
9654 predicate_context,
9655 visiting: &mut *visiting,
9656 memo: &mut *memo,
9657 expected: &mut *expected,
9658 native_depth: native_depth + 1,
9659 },
9660 );
9661 if inline_pending {
9662 for outcome in &mut outcomes {
9663 outcome.consumed_eof |= inline_consumed_eof;
9664 if self.fast_token_nodes_enabled {
9665 for token_index in inline_consumed_tokens.iter().rev() {
9666 let token = self.arena_token_node(*token_index, false);
9667 self.defer_fast_outcome_node(outcome, token);
9668 }
9669 }
9670 }
9671 }
9672 return outcomes;
9673 }
9674 let key = if self.fast_recovery_enabled {
9684 FastRecognizeKey {
9685 state_number,
9686 stop_state,
9687 index,
9688 rule_start_index,
9689 decision_start_index,
9690 precedence,
9691 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
9692 recovery_state,
9693 }
9694 } else {
9695 FastRecognizeKey {
9696 state_number,
9697 stop_state,
9698 index,
9699 rule_start_index: 0,
9700 decision_start_index: None,
9701 precedence,
9702 recovery_symbols_id: 0,
9703 recovery_state: None,
9704 }
9705 };
9706 let memo_lookup_enabled = self.fast_recovery_enabled
9711 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
9712 if memo_lookup_enabled {
9713 if let Some(outcomes) = memo.get(&key) {
9714 #[cfg(feature = "perf-counters")]
9715 {
9716 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
9717 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
9718 }
9719 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
9723 let inline_eof = inline_consumed_eof;
9724 let inline_tokens = &inline_consumed_tokens;
9725 return outcomes
9726 .iter()
9727 .copied()
9728 .map(|mut outcome| {
9729 if inline_eof {
9730 outcome.consumed_eof = true;
9731 }
9732 if self.fast_token_nodes_enabled {
9733 for token_index in inline_tokens.iter().rev() {
9734 let token = self.arena_token_node(*token_index, false);
9735 self.defer_fast_outcome_node(&mut outcome, token);
9736 }
9737 }
9738 outcome
9739 })
9740 .collect();
9741 }
9742 return outcomes.to_vec();
9743 }
9744 #[cfg(feature = "perf-counters")]
9745 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
9746 }
9747
9748 let needs_cycle_guard = if self.fast_recovery_enabled {
9753 transitions.iter().any(ParserTransition::is_epsilon)
9754 } else {
9755 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
9756 };
9757 #[cfg(feature = "perf-counters")]
9758 if needs_cycle_guard {
9759 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
9760 } else {
9761 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
9762 match state
9763 .transitions()
9764 .first()
9765 .expect("single-transition path requires one transition")
9766 .data()
9767 {
9768 Transition::Rule { .. } => {
9769 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
9770 }
9771 Transition::Atom { .. }
9772 | Transition::Range { .. }
9773 | Transition::Set { .. }
9774 | Transition::NotSet { .. }
9775 | Transition::Wildcard { .. } => {
9776 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
9777 }
9778 _ => {
9779 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
9780 }
9781 }
9782 }
9783 let has_inserted_cycle_guard = if needs_cycle_guard {
9784 if !visiting.insert(key.clone()) {
9785 #[cfg(feature = "perf-counters")]
9786 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
9787 return Vec::new();
9788 }
9789 true
9790 } else {
9791 false
9792 };
9793 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9794 Some(index)
9795 } else {
9796 decision_start_index
9797 };
9798 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
9799 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
9800 } else {
9801 (Rc::clone(&recovery_symbols), recovery_state)
9802 };
9803
9804 let lookahead_filter = if transition_count > 1
9823 && self.fast_first_set_prefilter
9824 && !state.precedence_rule_decision()
9825 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
9826 {
9827 state
9828 .rule_index()
9829 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9830 .map(|rule_stop| {
9831 let symbol = self.token_type_at(index);
9832 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
9833 (symbol, entry)
9834 })
9835 } else {
9836 None
9837 };
9838 let ll1_only_alt: Option<usize> = if transition_count > 1
9847 && let Some((symbol, entry)) = lookahead_filter.as_ref()
9848 {
9849 let key = (state.state_number(), *symbol);
9850 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
9851 cached
9852 } else {
9853 let result = ll1_unique_alt(entry, *symbol);
9854 self.ll1_decision_cache.insert(key, result);
9855 result
9856 }
9857 } else {
9858 None
9859 };
9860 let lookahead_filter = lookahead_filter.as_ref();
9861 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
9867 for (transition_index, transition) in transitions.iter().enumerate() {
9868 if let Some(alt) = ll1_only_alt {
9869 if alt != transition_index {
9871 continue;
9872 }
9873 }
9874 let transition_kind = transition.kind();
9875 if ll1_only_alt.is_none()
9876 && should_skip_via_lookahead(
9877 transition_kind,
9878 transition_index,
9879 lookahead_filter,
9880 index,
9881 self.fast_recovery_enabled,
9882 expected,
9883 )
9884 {
9885 continue;
9886 }
9887 let target = transition.target();
9888 let outcomes_before_transition = outcomes.len();
9889 let left_recursive_boundary = match transition_kind {
9890 ParserTransitionKind::Epsilon
9891 | ParserTransitionKind::Action
9892 | ParserTransitionKind::Predicate
9893 | ParserTransitionKind::Precedence => left_recursive_boundary(atn, state, target),
9894 ParserTransitionKind::Atom
9895 | ParserTransitionKind::Range
9896 | ParserTransitionKind::Set
9897 | ParserTransitionKind::NotSet
9898 | ParserTransitionKind::Wildcard
9899 | ParserTransitionKind::Rule => None,
9900 };
9901 match transition_kind {
9902 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
9903 #[cfg(feature = "perf-counters")]
9904 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9905 outcomes.extend(self.recognize_state_fast(
9906 atn,
9907 FastRecognizeRequest {
9908 state_number: target,
9909 stop_state,
9910 index,
9911 rule_start_index,
9912 decision_start_index: next_decision_start_index,
9913 precedence,
9914 depth: depth + 1,
9915 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9916 recovery_state: epsilon_recovery_state,
9917 },
9918 FastRecognizeScratch {
9919 predicate_context,
9920 visiting,
9921 memo,
9922 expected,
9923 native_depth: native_depth + 1,
9924 },
9925 ));
9926 }
9927 ParserTransitionKind::Predicate => {
9928 #[cfg(feature = "perf-counters")]
9929 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9930 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
9931 outcomes.extend(self.recognize_state_fast(
9932 atn,
9933 FastRecognizeRequest {
9934 state_number: target,
9935 stop_state,
9936 index,
9937 rule_start_index,
9938 decision_start_index: next_decision_start_index,
9939 precedence,
9940 depth: depth + 1,
9941 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9942 recovery_state: epsilon_recovery_state,
9943 },
9944 FastRecognizeScratch {
9945 predicate_context,
9946 visiting,
9947 memo,
9948 expected,
9949 native_depth: native_depth + 1,
9950 },
9951 ));
9952 } else {
9953 record_predicate_no_viable(expected, next_decision_start_index, index);
9954 }
9955 }
9956 ParserTransitionKind::Precedence => {
9957 let transition_precedence = packed_i32(transition.arg0());
9958 if transition_precedence >= precedence {
9959 outcomes.extend(self.recognize_state_fast(
9960 atn,
9961 FastRecognizeRequest {
9962 state_number: target,
9963 stop_state,
9964 index,
9965 rule_start_index,
9966 decision_start_index: next_decision_start_index,
9967 precedence,
9968 depth: depth + 1,
9969 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9970 recovery_state: epsilon_recovery_state,
9971 },
9972 FastRecognizeScratch {
9973 predicate_context,
9974 visiting,
9975 memo,
9976 expected,
9977 native_depth: native_depth + 1,
9978 },
9979 ));
9980 }
9981 }
9982 ParserTransitionKind::Rule => {
9983 let rule_index = transition.arg0() as usize;
9984 let follow_state = transition.arg1() as usize;
9985 let rule_precedence = packed_i32(transition.arg2());
9986 #[cfg(feature = "perf-counters")]
9987 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
9988 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
9989 continue;
9990 };
9991 let symbol = self.token_type_at(index);
10003 if self.fast_first_set_prefilter {
10004 let first = self.cached_rule_first_set(atn, target, child_stop);
10017 if should_skip_rule_via_first_set(
10018 &first,
10019 symbol,
10020 self.fast_recovery_enabled,
10021 index,
10022 expected,
10023 ) {
10024 continue;
10025 }
10026 }
10027 let expected_before_child =
10028 self.fast_recovery_enabled.then(|| expected.clone());
10029 let mut children = self.recognize_state_fast(
10030 atn,
10031 FastRecognizeRequest {
10032 state_number: target,
10033 stop_state: child_stop,
10034 index,
10035 rule_start_index: index,
10036 decision_start_index: None,
10037 precedence: rule_precedence,
10038 depth: depth + 1,
10039 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
10040 recovery_state: epsilon_recovery_state,
10041 },
10042 FastRecognizeScratch {
10043 predicate_context,
10044 visiting,
10045 memo,
10046 expected,
10047 native_depth: native_depth + 1,
10048 },
10049 );
10050 if children.is_empty() && self.fast_recovery_enabled {
10051 children = self.fast_child_rule_failure_recovery_outcomes(
10052 FastChildRuleFailureRecoveryRequest {
10053 atn,
10054 rule_index,
10055 start_index: index,
10056 follow_state,
10057 stop_state,
10058 expected,
10059 },
10060 );
10061 }
10062 if let Some(expected_before_child) = expected_before_child {
10063 if children
10064 .iter()
10065 .any(|child| child.diagnostics.is_empty() && child.index > index)
10066 {
10067 *expected = expected_before_child;
10068 }
10069 }
10070 for child in children {
10071 let child_index = child.index;
10072 let child_consumed_eof = child.consumed_eof;
10073 let child_diagnostics = child.diagnostics;
10074 let empty_recovery = self.empty_recovery_symbols();
10075 let follow_outcomes = self.recognize_state_fast(
10076 atn,
10077 FastRecognizeRequest {
10078 state_number: follow_state,
10079 stop_state,
10080 index: child_index,
10081 rule_start_index,
10082 decision_start_index: next_decision_start_index,
10083 precedence,
10084 depth: depth + 1,
10085 recovery_symbols: empty_recovery,
10086 recovery_state: None,
10087 },
10088 FastRecognizeScratch {
10089 predicate_context,
10090 visiting,
10091 memo,
10092 expected,
10093 native_depth: native_depth + 1,
10094 },
10095 );
10096 if follow_outcomes.is_empty() {
10097 continue;
10098 }
10099 let child_stop_index =
10100 self.rule_stop_token_index(child_index, child_consumed_eof);
10101 let child_node = self.build_parse_trees.then(|| {
10102 self.recognition_arena.deferred_rule_node(FastDeferredRule {
10103 rule_index: u32::try_from(rule_index)
10104 .expect("rule index fits in u32"),
10105 invoking_state: i32::try_from(invoking_state_number(state_number))
10106 .expect("invoking state fits in i32"),
10107 start_index: u32::try_from(index)
10108 .expect("rule start index fits in u32"),
10109 stop_index: child_stop_index.map(|stop_index| {
10110 u32::try_from(stop_index).expect("rule stop index fits in u32")
10111 }),
10112 deferred_children: child.deferred_nodes,
10113 children: child.nodes,
10114 })
10115 });
10116 let child_diags_empty = child_diagnostics.is_empty();
10117 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
10118 outcome.consumed_eof |= child_consumed_eof;
10119 if !child_diags_empty {
10122 outcome.diagnostics = self
10123 .recognition_arena
10124 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
10125 }
10126 if let Some(child_node) = child_node {
10127 outcome.deferred_nodes = self
10128 .recognition_arena
10129 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
10130 }
10131 outcome
10132 }));
10133 }
10134 }
10135 ParserTransitionKind::Atom
10136 | ParserTransitionKind::Range
10137 | ParserTransitionKind::Set
10138 | ParserTransitionKind::NotSet
10139 | ParserTransitionKind::Wildcard => {
10140 #[cfg(feature = "perf-counters")]
10141 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
10142 let symbol = self.token_type_at(index);
10143 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
10144 let next_index = self.consume_index(index, symbol);
10145 let empty_recovery = self.empty_recovery_symbols();
10146 outcomes.extend(
10147 self.recognize_state_fast(
10148 atn,
10149 FastRecognizeRequest {
10150 state_number: target,
10151 stop_state,
10152 index: next_index,
10153 rule_start_index,
10154 decision_start_index: next_decision_start_index,
10155 precedence,
10156 depth: depth + 1,
10157 recovery_symbols: empty_recovery,
10158 recovery_state: None,
10159 },
10160 FastRecognizeScratch {
10161 predicate_context,
10162 visiting,
10163 memo,
10164 expected,
10165 native_depth: native_depth + 1,
10166 },
10167 )
10168 .into_iter()
10169 .map(|mut outcome| {
10170 outcome.consumed_eof |= symbol == TOKEN_EOF;
10171 if self.fast_token_nodes_enabled {
10172 let token = self.arena_token_node(index, false);
10173 self.defer_fast_outcome_node(&mut outcome, token);
10174 }
10175 outcome
10176 }),
10177 );
10178 } else {
10179 if !self.fast_recovery_enabled {
10180 continue;
10188 }
10189 let expected_symbols = fast_recovery_expected_symbols(
10190 self,
10191 atn,
10192 state.state_number(),
10193 &recovery_symbols,
10194 );
10195 if expected_symbols.contains(&symbol) {
10196 continue;
10197 }
10198 {
10199 expected.record_transition(index, transition, max_token_type);
10200 record_no_viable_if_ambiguous(
10201 expected,
10202 next_decision_start_index,
10203 index,
10204 );
10205 outcomes.extend(self.fast_single_token_deletion_recovery(
10206 FastRecoveryRequest {
10207 atn,
10208 transition,
10209 expected_symbols: Rc::clone(&expected_symbols),
10210 target,
10211 request: FastRecognizeRequest {
10212 state_number,
10213 stop_state,
10214 index,
10215 rule_start_index,
10216 decision_start_index,
10217 precedence,
10218 depth,
10219 recovery_symbols: Rc::clone(&recovery_symbols),
10220 recovery_state,
10221 },
10222 visiting,
10223 memo,
10224 expected,
10225 },
10226 predicate_context,
10227 ));
10228 if !state_is_left_recursive_rule(atn, state) {
10229 outcomes.extend(self.fast_single_token_insertion_recovery(
10230 FastRecoveryRequest {
10231 atn,
10232 transition,
10233 expected_symbols: Rc::clone(&expected_symbols),
10234 target,
10235 request: FastRecognizeRequest {
10236 state_number,
10237 stop_state,
10238 index,
10239 rule_start_index,
10240 decision_start_index,
10241 precedence,
10242 depth,
10243 recovery_symbols: Rc::clone(&recovery_symbols),
10244 recovery_state,
10245 },
10246 visiting,
10247 memo,
10248 expected,
10249 },
10250 predicate_context,
10251 ));
10252 }
10253 outcomes.extend(self.fast_current_token_deletion_recovery(
10254 FastCurrentTokenDeletionRequest {
10255 atn,
10256 expected_symbols,
10257 request: FastRecognizeRequest {
10258 state_number,
10259 stop_state,
10260 index,
10261 rule_start_index,
10262 decision_start_index,
10263 precedence,
10264 depth,
10265 recovery_symbols: Rc::clone(&recovery_symbols),
10266 recovery_state,
10267 },
10268 visiting,
10269 memo,
10270 expected,
10271 },
10272 predicate_context,
10273 ));
10274 }
10275 }
10276 }
10277 }
10278 let alt_number = next_alt_number(
10279 state,
10280 transition_count,
10281 transition_index,
10282 0,
10283 self.fast_track_alt_numbers,
10284 );
10285 if alt_number != 0 || left_recursive_boundary.is_some() {
10286 for outcome in &mut outcomes[outcomes_before_transition..] {
10287 if alt_number != 0 {
10288 self.defer_fast_outcome_alternative(outcome, alt_number);
10289 }
10290 if let Some(rule_index) = left_recursive_boundary {
10291 self.defer_fast_outcome_boundary(outcome, rule_index);
10292 }
10293 }
10294 }
10295 }
10296
10297 if has_inserted_cycle_guard {
10298 visiting.remove(&key);
10299 }
10300 if matches!(
10301 self.prediction_mode,
10302 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
10303 ) && self.fast_recovery_enabled
10304 {
10305 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
10309 }
10310 if self.fast_recovery_enabled {
10311 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
10312 } else {
10313 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
10314 }
10315 let should_memoize = self.fast_recovery_enabled
10325 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
10326 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
10330 if inline_consumed_eof {
10331 outcome.consumed_eof = true;
10332 }
10333 if !inline_consumed_tokens.is_empty() {
10334 for token_index in inline_consumed_tokens.iter().rev() {
10335 let token = self.arena_token_node(*token_index, false);
10336 self.defer_fast_outcome_node(&mut outcome, token);
10337 }
10338 }
10339 outcome
10340 };
10341 if should_memoize {
10342 #[cfg(feature = "perf-counters")]
10343 {
10344 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
10345 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
10346 match outcomes.len() {
10347 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
10348 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
10349 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
10350 }
10351 }
10352 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
10357 memo.insert(key, Rc::clone(&stored));
10358 if inline_pending {
10359 return stored
10360 .iter()
10361 .copied()
10362 .map(&mut apply_inline_pending)
10363 .collect();
10364 }
10365 return stored.to_vec();
10366 }
10367 #[cfg(feature = "perf-counters")]
10368 match outcomes.len() {
10369 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
10370 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
10371 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
10372 }
10373 if inline_pending {
10374 return outcomes.into_iter().map(apply_inline_pending).collect();
10375 }
10376 outcomes
10377 }
10378
10379 fn single_token_deletion_recovery(
10382 &mut self,
10383 recovery: RecoveryRequest<'_, '_>,
10384 ) -> Vec<RecognizeOutcome> {
10385 let RecoveryRequest {
10386 atn,
10387 transition,
10388 expected_symbols,
10389 target,
10390 request,
10391 visiting,
10392 memo,
10393 expected,
10394 } = recovery;
10395 let RecognizeRequest {
10396 stop_state,
10397 index,
10398 rule_start_index,
10399 decision_start_index,
10400 init_action_rules,
10401 predicates,
10402 semantics,
10403 rule_args,
10404 member_actions,
10405 return_actions,
10406 local_int_arg,
10407 member_values,
10408 return_values,
10409 rule_alt_number,
10410 track_alt_numbers,
10411 consumed_eof,
10412 precedence,
10413 depth,
10414 ..
10415 } = request;
10416 let Some((diagnostic, next_index, next_symbol)) =
10417 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
10418 else {
10419 return Vec::new();
10420 };
10421 let after_next = self.consume_index(next_index, next_symbol);
10422 self.recognize_state(
10423 atn,
10424 RecognizeRequest {
10425 state_number: target,
10426 stop_state,
10427 index: after_next,
10428 rule_start_index,
10429 decision_start_index,
10430 init_action_rules,
10431 predicates,
10432 semantics,
10433 rule_args,
10434 member_actions,
10435 return_actions,
10436 local_int_arg,
10437 member_values,
10438 return_values,
10439 rule_alt_number,
10440 track_alt_numbers,
10441 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
10442 committed_decision: false,
10443 precedence,
10444 depth: depth + 1,
10445 recovery_symbols: BTreeSet::new(),
10446 recovery_state: None,
10447 },
10448 visiting,
10449 memo,
10450 expected,
10451 )
10452 .into_iter()
10453 .map(|mut outcome| {
10454 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
10455 outcome.diagnostics = self
10456 .recognition_arena
10457 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10458 let token = self.arena_token_node(next_index, false);
10459 self.arena_prepend(&mut outcome.nodes, token);
10460 let error = self.arena_token_node(index, true);
10461 self.arena_prepend(&mut outcome.nodes, error);
10462 outcome
10463 })
10464 .collect()
10465 }
10466
10467 fn current_token_deletion_recovery(
10470 &mut self,
10471 recovery: CurrentTokenDeletionRequest<'_, '_>,
10472 ) -> Vec<RecognizeOutcome> {
10473 let CurrentTokenDeletionRequest {
10474 atn,
10475 expected_symbols,
10476 mut request,
10477 visiting,
10478 memo,
10479 expected,
10480 } = recovery;
10481 let error_index = request.index;
10482 if error_index == request.rule_start_index {
10483 return Vec::new();
10484 }
10485 let Some((diagnostic, next_index, skipped)) =
10486 self.current_token_deletion(error_index, &expected_symbols)
10487 else {
10488 return Vec::new();
10489 };
10490 request.state_number = request.recovery_state.unwrap_or(request.state_number);
10491 request.index = next_index;
10492 request.committed_decision = false;
10493 request.depth += 1;
10494 request.recovery_state = None;
10495 self.recognize_state(atn, request, visiting, memo, expected)
10496 .into_iter()
10497 .map(|mut outcome| {
10498 outcome.diagnostics = self
10499 .recognition_arena
10500 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10501 for index in skipped.iter().rev() {
10502 let error = self.arena_token_node(*index, true);
10503 self.arena_prepend(&mut outcome.nodes, error);
10504 }
10505 outcome
10506 })
10507 .collect()
10508 }
10509
10510 fn consuming_failure_fallback(
10513 &mut self,
10514 fallback: ConsumingFailureFallback<'_>,
10515 visiting: &mut BTreeSet<RecognizeKey>,
10516 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10517 expected: &mut ExpectedTokens,
10518 ) -> Vec<RecognizeOutcome> {
10519 if fallback.expected_symbols.is_empty() {
10520 return Vec::new();
10521 }
10522 if fallback.symbol == TOKEN_EOF {
10523 return self.eof_consuming_failure_fallback(fallback, expected);
10524 }
10525 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
10526 }
10527
10528 fn non_eof_consuming_failure_fallback(
10531 &mut self,
10532 fallback: ConsumingFailureFallback<'_>,
10533 visiting: &mut BTreeSet<RecognizeKey>,
10534 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10535 expected: &mut ExpectedTokens,
10536 ) -> Vec<RecognizeOutcome> {
10537 let ConsumingFailureFallback {
10538 atn,
10539 target,
10540 request,
10541 symbol,
10542 expected_symbols,
10543 decision_start_index,
10544 decision,
10545 } = fallback;
10546 let error_index = request.index;
10547 let diagnostic =
10548 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
10549 let next_index = self.consume_index(error_index, symbol);
10550 self.recognize_state(
10551 atn,
10552 RecognizeRequest {
10553 state_number: target,
10554 stop_state: request.stop_state,
10555 index: next_index,
10556 rule_start_index: request.rule_start_index,
10557 decision_start_index,
10558 init_action_rules: request.init_action_rules,
10559 predicates: request.predicates,
10560 semantics: request.semantics,
10561 rule_args: request.rule_args,
10562 member_actions: request.member_actions,
10563 return_actions: request.return_actions,
10564 local_int_arg: request.local_int_arg,
10565 member_values: request.member_values,
10566 return_values: request.return_values,
10567 rule_alt_number: request.rule_alt_number,
10568 track_alt_numbers: request.track_alt_numbers,
10569 consumed_eof: request.consumed_eof,
10570 committed_decision: false,
10571 precedence: request.precedence,
10572 depth: request.depth + 1,
10573 recovery_symbols: BTreeSet::new(),
10574 recovery_state: None,
10575 },
10576 visiting,
10577 memo,
10578 expected,
10579 )
10580 .into_iter()
10581 .map(|mut outcome| {
10582 prepend_decision(&mut outcome, decision);
10583 outcome.diagnostics = self
10584 .recognition_arena
10585 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10586 let error = self.arena_token_node(error_index, true);
10587 self.arena_prepend(&mut outcome.nodes, error);
10588 outcome
10589 })
10590 .collect()
10591 }
10592
10593 fn eof_consuming_failure_fallback(
10596 &mut self,
10597 fallback: ConsumingFailureFallback<'_>,
10598 expected: &ExpectedTokens,
10599 ) -> Vec<RecognizeOutcome> {
10600 let request = fallback.request;
10601 if request.index == request.rule_start_index {
10602 return Vec::new();
10603 }
10604 let diagnostic =
10605 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
10606 let diagnostics = self
10607 .recognition_arena
10608 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10609 vec![RecognizeOutcome {
10610 index: request.index,
10611 consumed_eof: request.consumed_eof,
10612 alt_number: request.rule_alt_number,
10613 member_values: request.member_values,
10614 return_values: request.return_values,
10615 diagnostics,
10616 decisions: Vec::new(),
10617 actions: Vec::new(),
10618 nodes: NodeSeqId::EMPTY,
10619 }]
10620 }
10621
10622 fn single_token_insertion_recovery(
10625 &mut self,
10626 recovery: RecoveryRequest<'_, '_>,
10627 ) -> Vec<RecognizeOutcome> {
10628 let RecoveryRequest {
10629 atn,
10630 transition,
10631 expected_symbols,
10632 target,
10633 request,
10634 visiting,
10635 memo,
10636 expected,
10637 } = recovery;
10638 let RecognizeRequest {
10639 stop_state,
10640 index,
10641 rule_start_index,
10642 decision_start_index,
10643 init_action_rules,
10644 predicates,
10645 semantics,
10646 rule_args,
10647 member_actions,
10648 return_actions,
10649 local_int_arg,
10650 member_values,
10651 return_values,
10652 rule_alt_number,
10653 track_alt_numbers,
10654 consumed_eof,
10655 precedence,
10656 depth,
10657 ..
10658 } = request;
10659 let follow_symbols = state_expected_symbols(atn, transition.target());
10660 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
10661 transition,
10662 index,
10663 atn.max_token_type(),
10664 &expected_symbols,
10665 &follow_symbols,
10666 ) else {
10667 return Vec::new();
10668 };
10669 self.recognize_state(
10670 atn,
10671 RecognizeRequest {
10672 state_number: target,
10673 stop_state,
10674 index,
10675 rule_start_index,
10676 decision_start_index,
10677 init_action_rules,
10678 predicates,
10679 semantics,
10680 rule_args,
10681 member_actions,
10682 return_actions,
10683 local_int_arg,
10684 member_values,
10685 return_values,
10686 rule_alt_number,
10687 track_alt_numbers,
10688 consumed_eof,
10689 committed_decision: false,
10690 precedence,
10691 depth: depth + 1,
10692 recovery_symbols: BTreeSet::new(),
10693 recovery_state: None,
10694 },
10695 visiting,
10696 memo,
10697 expected,
10698 )
10699 .into_iter()
10700 .map(|mut outcome| {
10701 outcome.diagnostics = self
10702 .recognition_arena
10703 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10704 let missing = self.arena_missing_token_node(token_type, index, text.clone());
10705 self.arena_prepend(&mut outcome.nodes, missing);
10706 outcome
10707 })
10708 .collect()
10709 }
10710
10711 #[allow(clippy::too_many_lines)]
10714 fn recognize_state(
10715 &mut self,
10716 atn: &Atn,
10717 request: RecognizeRequest<'_>,
10718 visiting: &mut BTreeSet<RecognizeKey>,
10719 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10720 expected: &mut ExpectedTokens,
10721 ) -> Vec<RecognizeOutcome> {
10722 let request_template = request.clone();
10723 let RecognizeRequest {
10724 state_number,
10725 stop_state,
10726 index,
10727 rule_start_index,
10728 decision_start_index,
10729 init_action_rules,
10730 predicates,
10731 semantics,
10732 rule_args,
10733 member_actions,
10734 return_actions,
10735 local_int_arg,
10736 member_values,
10737 return_values,
10738 rule_alt_number,
10739 track_alt_numbers,
10740 consumed_eof,
10741 committed_decision,
10742 precedence,
10743 depth,
10744 recovery_symbols,
10745 recovery_state,
10746 } = request;
10747 if depth > RECOGNITION_DEPTH_LIMIT {
10748 return Vec::new();
10749 }
10750 if state_number == stop_state {
10751 return stop_outcome(
10752 index,
10753 consumed_eof,
10754 rule_alt_number,
10755 member_values,
10756 return_values,
10757 );
10758 }
10759 let key = RecognizeKey {
10760 state_number,
10761 stop_state,
10762 index,
10763 rule_start_index,
10764 decision_start_index,
10765 local_int_arg,
10766 member_values: member_values.clone(),
10767 return_values: return_values.clone(),
10768 rule_alt_number,
10769 track_alt_numbers,
10770 consumed_eof,
10771 committed_decision,
10772 precedence,
10773 recovery_symbols: recovery_symbols.clone(),
10774 recovery_state,
10775 };
10776 if let Some(outcomes) = memo.get(&key) {
10777 return outcomes.clone();
10778 }
10779
10780 let visit_key = key.clone();
10781 if !visiting.insert(visit_key.clone()) {
10782 return Vec::new();
10783 }
10784
10785 let Some(state) = atn.state(state_number) else {
10786 visiting.remove(&visit_key);
10787 return Vec::new();
10788 };
10789 let decision_override_generation = self.decision_override_generation;
10790 let transitions = state.transitions();
10791 let transition_count = transitions.len();
10792 let overridden_transition = if transition_count > 1
10793 && self.semantic_hooks.observes_parser_decisions()
10794 {
10795 atn.decision_to_state()
10796 .iter()
10797 .position(|candidate| candidate == state_number)
10798 .and_then(|decision| {
10799 self.semantic_hooks
10800 .parser_decision_override(decision, index, transition_count)
10801 })
10802 .and_then(|alternative| alternative.checked_sub(1))
10803 .filter(|alternative| *alternative < transition_count)
10804 } else {
10805 None
10806 };
10807 if overridden_transition.is_some() {
10808 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
10809 }
10810 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
10811 Some(index)
10812 } else {
10813 decision_start_index
10814 };
10815 let (epsilon_recovery_symbols, epsilon_recovery_state) =
10816 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
10817 let mut outcomes = Vec::new();
10818 for (transition_index, transition) in transitions.iter().enumerate() {
10819 if overridden_transition.is_some_and(|forced| forced != transition_index) {
10820 continue;
10821 }
10822 let transition_committed =
10823 committed_decision || overridden_transition == Some(transition_index);
10824 let mut transition_request = request_template.clone();
10825 transition_request.committed_decision = transition_committed;
10826 let decision =
10827 transition_decision(atn, state, transition_count, transition_index, predicates);
10828 let next_alt_number = next_alt_number(
10829 state,
10830 transition_count,
10831 transition_index,
10832 rule_alt_number,
10833 track_alt_numbers,
10834 );
10835 let transition_data = transition.data();
10836 match &transition_data {
10837 Transition::Epsilon { target } | Transition::Action { target, .. } => {
10838 let (action_rule_index, action_index) = match &transition_data {
10839 Transition::Action {
10840 rule_index,
10841 action_index,
10842 ..
10843 } => (Some(*rule_index), *action_index),
10844 _ => (None, None),
10845 };
10846 outcomes.extend(self.recognize_epsilon_or_action_step(
10847 atn,
10848 &transition_request,
10849 EpsilonActionStep {
10850 source_state: state_number,
10851 target: *target,
10852 action_rule_index,
10853 action_index,
10854 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
10855 decision,
10856 decision_start_index: next_decision_start_index,
10857 alt_number: next_alt_number,
10858 recovery_symbols: epsilon_recovery_symbols.clone(),
10859 recovery_state: epsilon_recovery_state,
10860 },
10861 RecognizeScratch {
10862 visiting,
10863 memo,
10864 expected,
10865 },
10866 ));
10867 }
10868 Transition::Predicate {
10869 target,
10870 rule_index,
10871 pred_index,
10872 ..
10873 } => {
10874 let predicate = PredicateEval {
10875 index,
10876 rule_index: *rule_index,
10877 pred_index: *pred_index,
10878 predicates,
10879 semantics,
10880 context: None,
10881 local_int_arg,
10882 member_values: &member_values,
10883 };
10884 if self.parser_predicate_matches(predicate) {
10885 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
10886 outcomes.extend(
10887 self.recognize_state(
10888 atn,
10889 RecognizeRequest {
10890 state_number: *target,
10891 stop_state,
10892 index,
10893 rule_start_index,
10894 decision_start_index: next_decision_start_index,
10895 init_action_rules,
10896 predicates,
10897 semantics,
10898 rule_args,
10899 member_actions,
10900 return_actions,
10901 local_int_arg,
10902 member_values: member_values.clone(),
10903 return_values: return_values.clone(),
10904 rule_alt_number: next_alt_number,
10905 track_alt_numbers,
10906 consumed_eof,
10907 committed_decision: transition_committed,
10908 precedence,
10909 depth: depth + 1,
10910 recovery_symbols: epsilon_recovery_symbols.clone(),
10911 recovery_state: epsilon_recovery_state,
10912 },
10913 visiting,
10914 memo,
10915 expected,
10916 )
10917 .into_iter()
10918 .map(|mut outcome| {
10919 prepend_decision(&mut outcome, decision);
10920 if let Some(rule_index) = left_recursive_boundary {
10921 let boundary =
10922 self.arena_boundary_node(rule_index, next_alt_number);
10923 self.arena_prepend(&mut outcome.nodes, boundary);
10924 }
10925 outcome
10926 }),
10927 );
10928 } else if let Some(message) = semantics
10929 .and_then(|semantics| {
10930 self.parser_semantic_ir_predicate_failure_message(
10931 *rule_index,
10932 *pred_index,
10933 semantics,
10934 )
10935 })
10936 .or_else(|| {
10937 self.parser_predicate_failure_message(
10938 *rule_index,
10939 *pred_index,
10940 predicates,
10941 )
10942 })
10943 {
10944 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
10945 rule_index: *rule_index,
10946 index,
10947 message,
10948 member_values: member_values.clone(),
10949 return_values: return_values.clone(),
10950 rule_alt_number,
10951 }));
10952 } else {
10953 record_predicate_no_viable(expected, next_decision_start_index, index);
10954 }
10955 }
10956 Transition::Precedence {
10957 target,
10958 precedence: transition_precedence,
10959 } => {
10960 if *transition_precedence >= precedence {
10961 outcomes.extend(
10962 self.recognize_state(
10963 atn,
10964 RecognizeRequest {
10965 state_number: *target,
10966 stop_state,
10967 index,
10968 rule_start_index,
10969 decision_start_index: next_decision_start_index,
10970 init_action_rules,
10971 predicates,
10972 semantics,
10973 rule_args,
10974 member_actions,
10975 return_actions,
10976 local_int_arg,
10977 member_values: member_values.clone(),
10978 return_values: return_values.clone(),
10979 rule_alt_number: next_alt_number,
10980 track_alt_numbers,
10981 consumed_eof,
10982 committed_decision: transition_committed,
10983 precedence,
10984 depth: depth + 1,
10985 recovery_symbols: epsilon_recovery_symbols.clone(),
10986 recovery_state: epsilon_recovery_state,
10987 },
10988 visiting,
10989 memo,
10990 expected,
10991 )
10992 .into_iter()
10993 .map(|mut outcome| {
10994 prepend_decision(&mut outcome, decision);
10995 outcome
10996 }),
10997 );
10998 }
10999 }
11000 Transition::Rule {
11001 target,
11002 rule_index,
11003 follow_state,
11004 precedence: rule_precedence,
11005 ..
11006 } => {
11007 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
11008 continue;
11009 };
11010 let child_local_int_arg =
11011 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
11012 let expected_before_child = expected.clone();
11013 let children = self.recognize_state(
11014 atn,
11015 RecognizeRequest {
11016 state_number: *target,
11017 stop_state: child_stop,
11018 index,
11019 rule_start_index: index,
11020 decision_start_index: None,
11021 init_action_rules,
11022 predicates,
11023 semantics,
11024 rule_args,
11025 member_actions,
11026 return_actions,
11027 local_int_arg: child_local_int_arg,
11028 member_values: member_values.clone(),
11029 return_values: BTreeMap::new(),
11030 rule_alt_number: 0,
11031 track_alt_numbers,
11032 consumed_eof: false,
11033 committed_decision: transition_committed,
11034 precedence: *rule_precedence,
11035 depth: depth + 1,
11036 recovery_symbols: epsilon_recovery_symbols.clone(),
11037 recovery_state: epsilon_recovery_state,
11038 },
11039 visiting,
11040 memo,
11041 expected,
11042 );
11043 let children = if children.is_empty() {
11044 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
11045 atn,
11046 rule_index: *rule_index,
11047 start_index: index,
11048 follow_state: *follow_state,
11049 stop_state,
11050 member_values: member_values.clone(),
11051 expected,
11052 })
11053 } else {
11054 children
11055 };
11056 let preserve_child_expected =
11057 self.child_expected_reaches_clean_eof(&children, expected);
11058 restore_expected(
11059 &children,
11060 index,
11061 expected,
11062 expected_before_child,
11063 preserve_child_expected,
11064 );
11065 for child in children {
11066 let child_stop_index =
11067 self.rule_stop_token_index(child.index, child.consumed_eof);
11068 let child_nodes = self
11069 .recognition_arena
11070 .fold_left_recursive_boundaries(child.nodes);
11071 let child_node = self.arena_rule_node(ArenaRuleSpec {
11072 rule_index: *rule_index,
11073 invoking_state: invoking_state_number(state_number),
11074 alt_number: child.alt_number,
11075 start_index: index,
11076 stop_index: child_stop_index,
11077 return_values: child.return_values.clone(),
11078 children: child_nodes,
11079 });
11080 outcomes.extend(
11081 self.recognize_state(
11082 atn,
11083 RecognizeRequest {
11084 state_number: *follow_state,
11085 stop_state,
11086 index: child.index,
11087 rule_start_index,
11088 decision_start_index: next_decision_start_index,
11089 init_action_rules,
11090 predicates,
11091 semantics,
11092 rule_args,
11093 member_actions,
11094 return_actions,
11095 local_int_arg,
11096 member_values: child.member_values.clone(),
11097 return_values: return_values.clone(),
11098 rule_alt_number,
11099 track_alt_numbers,
11100 consumed_eof: consumed_eof || child.consumed_eof,
11101 committed_decision: transition_committed
11102 && child.index == index,
11103 precedence,
11104 depth: depth + 1,
11105 recovery_symbols: BTreeSet::new(),
11106 recovery_state: None,
11107 },
11108 visiting,
11109 memo,
11110 expected,
11111 )
11112 .into_iter()
11113 .map(|mut outcome| {
11114 outcome.consumed_eof |= child.consumed_eof;
11115 outcome.diagnostics = self
11116 .recognition_arena
11117 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
11118 let mut decisions = child.decisions.clone();
11119 decisions.append(&mut outcome.decisions);
11120 outcome.decisions = decisions;
11121 prepend_decision(&mut outcome, decision);
11122 let mut actions = child.actions.clone();
11123 if init_action_rules.contains(rule_index) {
11124 actions.insert(
11125 0,
11126 ParserAction::new_rule_init(
11127 *rule_index,
11128 index,
11129 Some(*follow_state),
11130 ),
11131 );
11132 }
11133 actions.append(&mut outcome.actions);
11134 outcome.actions = actions;
11135 self.arena_prepend(&mut outcome.nodes, child_node);
11136 outcome
11137 }),
11138 );
11139 }
11140 }
11141 Transition::Atom { target, .. }
11142 | Transition::Range { target, .. }
11143 | Transition::Set { target, .. }
11144 | Transition::NotSet { target, .. }
11145 | Transition::Wildcard { target, .. } => {
11146 let symbol = self.token_type_at(index);
11147 if transition_data.matches(symbol, 1, atn.max_token_type()) {
11148 let next_index = self.consume_index(index, symbol);
11149 outcomes.extend(
11150 self.recognize_state(
11151 atn,
11152 RecognizeRequest {
11153 state_number: *target,
11154 stop_state,
11155 index: next_index,
11156 rule_start_index,
11157 decision_start_index: next_decision_start_index,
11158 init_action_rules,
11159 predicates,
11160 semantics,
11161 rule_args,
11162 member_actions,
11163 return_actions,
11164 local_int_arg,
11165 member_values: member_values.clone(),
11166 return_values: return_values.clone(),
11167 rule_alt_number: next_alt_number,
11168 track_alt_numbers,
11169 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
11170 committed_decision: false,
11171 precedence,
11172 depth: depth + 1,
11173 recovery_symbols: BTreeSet::new(),
11174 recovery_state: None,
11175 },
11176 visiting,
11177 memo,
11178 expected,
11179 )
11180 .into_iter()
11181 .map(|mut outcome| {
11182 prepend_decision(&mut outcome, decision);
11183 outcome.consumed_eof |= symbol == TOKEN_EOF;
11184 let token = self.arena_token_node(index, false);
11185 self.arena_prepend(&mut outcome.nodes, token);
11186 outcome
11187 }),
11188 );
11189 } else {
11190 let expected_symbols =
11191 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
11192 if expected_symbols.contains(&symbol) && !transition_committed {
11193 continue;
11194 }
11195 expected.record_transition(index, transition, atn.max_token_type());
11196 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
11197 let before_recovery = outcomes.len();
11198 let recovery_request = transition_request.clone();
11199 if transition_committed {
11200 outcomes.extend(self.consuming_failure_fallback(
11201 ConsumingFailureFallback {
11202 atn,
11203 target: *target,
11204 request: recovery_request,
11205 symbol,
11206 expected_symbols,
11207 decision_start_index: next_decision_start_index,
11208 decision,
11209 },
11210 visiting,
11211 memo,
11212 expected,
11213 ));
11214 break;
11215 }
11216 outcomes.extend(
11217 self.single_token_deletion_recovery(RecoveryRequest {
11218 atn,
11219 transition,
11220 expected_symbols: expected_symbols.clone(),
11221 target: *target,
11222 request: recovery_request.clone(),
11223 visiting,
11224 memo,
11225 expected,
11226 })
11227 .into_iter()
11228 .map(|mut outcome| {
11229 prepend_decision(&mut outcome, decision);
11230 outcome
11231 }),
11232 );
11233 if !state_is_left_recursive_rule(atn, state) {
11234 outcomes.extend(
11235 self.single_token_insertion_recovery(RecoveryRequest {
11236 atn,
11237 transition,
11238 expected_symbols: expected_symbols.clone(),
11239 target: *target,
11240 request: recovery_request.clone(),
11241 visiting,
11242 memo,
11243 expected,
11244 })
11245 .into_iter()
11246 .map(|mut outcome| {
11247 prepend_decision(&mut outcome, decision);
11248 outcome
11249 }),
11250 );
11251 }
11252 outcomes.extend(self.current_token_deletion_recovery(
11253 CurrentTokenDeletionRequest {
11254 atn,
11255 expected_symbols: expected_symbols.clone(),
11256 request: recovery_request.clone(),
11257 visiting,
11258 memo,
11259 expected,
11260 },
11261 ));
11262 if outcomes.len() == before_recovery {
11263 outcomes.extend(self.consuming_failure_fallback(
11264 ConsumingFailureFallback {
11265 atn,
11266 target: *target,
11267 request: recovery_request,
11268 symbol,
11269 expected_symbols,
11270 decision_start_index: next_decision_start_index,
11271 decision,
11272 },
11273 visiting,
11274 memo,
11275 expected,
11276 ));
11277 }
11278 }
11279 }
11280 }
11281 if self.decision_override_generation != decision_override_generation {
11282 break;
11283 }
11284 }
11285
11286 visiting.remove(&visit_key);
11287 self.record_prediction_diagnostics(atn, state, index, &outcomes);
11288 if matches!(
11289 self.prediction_mode,
11290 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11291 ) {
11292 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
11293 }
11294 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
11295 memo.insert(key, outcomes.clone());
11296 outcomes
11297 }
11298
11299 fn recognize_epsilon_or_action_step(
11302 &mut self,
11303 atn: &Atn,
11304 request: &RecognizeRequest<'_>,
11305 step: EpsilonActionStep,
11306 scratch: RecognizeScratch<'_>,
11307 ) -> Vec<RecognizeOutcome> {
11308 let RecognizeScratch {
11309 visiting,
11310 memo,
11311 expected,
11312 } = scratch;
11313 let action = step.action_rule_index.map(|rule_index| {
11314 let stop_index = self.rule_stop_token_index(request.index, request.consumed_eof);
11315 step.action_index.map_or_else(
11316 || {
11317 ParserAction::new(
11318 step.source_state,
11319 rule_index,
11320 request.rule_start_index,
11321 stop_index,
11322 )
11323 },
11324 |action_index| {
11325 ParserAction::new_indexed(
11326 step.source_state,
11327 rule_index,
11328 action_index,
11329 request.rule_start_index,
11330 stop_index,
11331 )
11332 },
11333 )
11334 });
11335 let next_member_values = if action.is_some() {
11336 member_values_after_action(
11337 step.source_state,
11338 request.member_actions,
11339 request.semantics,
11340 &request.member_values,
11341 )
11342 } else {
11343 request.member_values.clone()
11344 };
11345 let next_return_values = action.map_or_else(
11346 || request.return_values.clone(),
11347 |action| {
11348 return_values_after_action(
11349 step.source_state,
11350 action.rule_index(),
11351 request.return_actions,
11352 request.semantics,
11353 &request.return_values,
11354 )
11355 },
11356 );
11357
11358 self.recognize_state(
11359 atn,
11360 RecognizeRequest {
11361 state_number: step.target,
11362 stop_state: request.stop_state,
11363 index: request.index,
11364 rule_start_index: request.rule_start_index,
11365 decision_start_index: step.decision_start_index,
11366 init_action_rules: request.init_action_rules,
11367 predicates: request.predicates,
11368 semantics: request.semantics,
11369 rule_args: request.rule_args,
11370 member_actions: request.member_actions,
11371 return_actions: request.return_actions,
11372 local_int_arg: request.local_int_arg,
11373 member_values: next_member_values,
11374 return_values: next_return_values,
11375 rule_alt_number: if step.left_recursive_boundary.is_some() {
11376 0
11377 } else {
11378 step.alt_number
11379 },
11380 track_alt_numbers: request.track_alt_numbers,
11381 consumed_eof: request.consumed_eof,
11382 committed_decision: request.committed_decision,
11383 precedence: request.precedence,
11384 depth: request.depth + 1,
11385 recovery_symbols: step.recovery_symbols,
11386 recovery_state: step.recovery_state,
11387 },
11388 visiting,
11389 memo,
11390 expected,
11391 )
11392 .into_iter()
11393 .map(|mut outcome| {
11394 prepend_decision(&mut outcome, step.decision);
11395 if let Some(rule_index) = step.left_recursive_boundary {
11396 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
11397 self.arena_prepend(&mut outcome.nodes, boundary);
11398 }
11399 if let Some(action) = action {
11400 outcome.actions.insert(0, action);
11401 }
11402 outcome
11403 })
11404 .collect()
11405 }
11406
11407 fn token_type_at(&mut self, index: usize) -> i32 {
11412 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
11413 self.input.fill();
11414 }
11415 self.input.token_type_at_index(index)
11416 }
11417
11418 fn cached_state_expected_symbols(
11430 &mut self,
11431 atn: &Atn,
11432 state_number: usize,
11433 ) -> Rc<BTreeSet<i32>> {
11434 if let Some(cached) = self.state_expected_cache.get(&state_number) {
11435 return Rc::clone(cached);
11436 }
11437 let symbols = state_expected_symbols(atn, state_number);
11438 let entry = self.intern_recovery_symbols(symbols);
11439 self.state_expected_cache
11440 .insert(state_number, Rc::clone(&entry));
11441 entry
11442 }
11443
11444 fn cached_state_expected_token_set(
11445 &mut self,
11446 atn: &Atn,
11447 state_number: usize,
11448 ) -> Rc<TokenBitSet> {
11449 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
11450 return Rc::clone(cached);
11451 }
11452 let symbols = with_shared_atn_caches(atn, |cache| {
11456 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
11457 return Rc::clone(cached);
11458 }
11459 let symbols = Rc::new(state_expected_token_set(atn, state_number));
11460 cache
11461 .state_expected_tokens
11462 .insert(state_number, Rc::clone(&symbols));
11463 symbols
11464 });
11465 self.state_expected_token_cache
11466 .insert(state_number, Rc::clone(&symbols));
11467 symbols
11468 }
11469
11470 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
11471 if self.rule_stop_reach_cache.len() <= state_number {
11472 self.rule_stop_reach_cache
11473 .resize_with(atn.states().len().max(state_number + 1), || None);
11474 }
11475 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
11476 return reaches;
11477 }
11478 let reaches = with_shared_atn_caches(atn, |cache| {
11479 *cache
11480 .rule_stop_reach
11481 .entry(state_number)
11482 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
11483 });
11484 self.rule_stop_reach_cache[state_number] = Some(reaches);
11485 reaches
11486 }
11487
11488 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
11491 Rc::clone(&self.empty_recovery_symbols)
11492 }
11493
11494 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
11503 if set.is_empty() {
11504 return Rc::clone(&self.empty_recovery_symbols);
11505 }
11506 let candidate = Rc::new(set);
11507 match self.recovery_symbols_intern.get(&candidate) {
11508 Some(existing) => Rc::clone(existing),
11509 None => {
11510 self.recovery_symbols_intern
11511 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
11512 candidate
11513 }
11514 }
11515 }
11516
11517 fn cached_decision_lookahead(
11522 &mut self,
11523 atn: &Atn,
11524 state: AtnState<'_>,
11525 rule_stop_state: usize,
11526 ) -> Rc<DecisionLookahead> {
11527 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
11534 return Rc::clone(cached);
11535 }
11536 let entry = with_shared_atn_caches(atn, |cache| {
11537 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
11538 return Rc::clone(cached);
11539 }
11540 let mut entry = DecisionLookahead {
11541 transitions: Vec::with_capacity(state.transitions().len()),
11542 };
11543 for transition in &state.transitions() {
11544 entry.transitions.push(transition_first_set(
11545 atn,
11546 transition,
11547 rule_stop_state,
11548 &mut cache.first_set,
11549 ));
11550 }
11551 let entry = Rc::new(entry);
11552 cache
11553 .decision_lookahead
11554 .insert(state.state_number(), Rc::clone(&entry));
11555 entry
11556 });
11557 self.decision_lookahead_cache
11558 .insert(state.state_number(), Rc::clone(&entry));
11559 entry
11560 }
11561
11562 fn cached_rule_first_set(
11563 &mut self,
11564 atn: &Atn,
11565 target: usize,
11566 child_stop: usize,
11567 ) -> Rc<FirstSet> {
11568 if self.rule_first_set_cache.len() <= target {
11569 self.rule_first_set_cache
11570 .resize_with(atn.states().len().max(target + 1), || None);
11571 }
11572 if let Some(cached) = self
11573 .rule_first_set_cache
11574 .get(target)
11575 .and_then(Option::as_ref)
11576 {
11577 return Rc::clone(cached);
11578 }
11579 let first = with_shared_first_set_cache(atn, |cache| {
11580 rule_first_set(atn, target, child_stop, cache)
11581 });
11582 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
11583 first
11584 }
11585
11586 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
11587 let atn_key = SharedAtnCacheKey::for_atn(atn);
11588 if self.empty_cycle_cache_atn != Some(atn_key) {
11589 self.empty_cycle_cache.clear();
11590 self.empty_cycle_cache_atn = Some(atn_key);
11591 }
11592 if self.empty_cycle_cache.len() <= state_number {
11593 self.empty_cycle_cache
11594 .resize_with(atn.state_count().max(state_number + 1), || None);
11595 }
11596 if let Some(cached) = self.empty_cycle_cache[state_number] {
11597 return cached;
11598 }
11599 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
11600 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
11601 self.empty_cycle_cache[state_number] = Some(result);
11602 result
11603 }
11604
11605 fn empty_path_reaches_state(
11606 &mut self,
11607 atn: &Atn,
11608 state_number: usize,
11609 target_state: usize,
11610 visited: &mut FxHashSet<usize>,
11611 ) -> bool {
11612 enum Work {
11613 Visit(usize),
11614 RuleFollow {
11615 target: usize,
11616 rule_index: usize,
11617 follow_state: usize,
11618 },
11619 }
11620
11621 let mut work = vec![Work::Visit(state_number)];
11622 while let Some(item) = work.pop() {
11623 match item {
11624 Work::Visit(state_number) => {
11625 if !visited.insert(state_number) {
11626 continue;
11627 }
11628 let Some(state) = atn.state(state_number) else {
11629 continue;
11630 };
11631 let transitions = state.transitions();
11632 for transition_index in (0..transitions.len()).rev() {
11633 let transition = transitions
11634 .get(transition_index)
11635 .expect("in-bounds parser transition");
11636 let kind = transition.kind();
11637 let target = transition.target();
11638 match kind {
11639 ParserTransitionKind::Atom
11640 | ParserTransitionKind::Range
11641 | ParserTransitionKind::Set
11642 | ParserTransitionKind::NotSet
11643 | ParserTransitionKind::Wildcard => {}
11644 ParserTransitionKind::Rule => {
11645 if target == target_state {
11646 return true;
11647 }
11648 work.push(Work::RuleFollow {
11649 target,
11650 rule_index: transition.arg0() as usize,
11651 follow_state: transition.arg1() as usize,
11652 });
11653 work.push(Work::Visit(target));
11654 }
11655 ParserTransitionKind::Epsilon
11656 | ParserTransitionKind::Predicate
11657 | ParserTransitionKind::Action
11658 | ParserTransitionKind::Precedence => {
11659 if target == target_state {
11660 return true;
11661 }
11662 work.push(Work::Visit(target));
11663 }
11664 }
11665 }
11666 }
11667 Work::RuleFollow {
11668 target,
11669 rule_index,
11670 follow_state,
11671 } => {
11672 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
11673 continue;
11674 };
11675 if self.cached_rule_first_set(atn, target, child_stop).nullable {
11676 if follow_state == target_state {
11677 return true;
11678 }
11679 work.push(Work::Visit(follow_state));
11680 }
11681 }
11682 }
11683 }
11684 false
11685 }
11686
11687 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
11690 match self.clean_memo_mode {
11691 CleanMemoMode::Promote => true,
11692 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
11693 CleanMemoMode::Sparse => {
11694 self.clean_memo_sparse_samples += 1;
11695 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
11696 return false;
11697 }
11698 self.clean_memo_sparse_samples = 0;
11699 self.clean_memo_mode = CleanMemoMode::Probe;
11700 self.clean_memo_probe_samples = 0;
11701 self.clean_memo_probe_repeats = 0;
11702 self.clean_memo_probe_seen.clear();
11703 self.observe_clean_memo_probe(key)
11704 }
11705 }
11706 }
11707
11708 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
11709 self.clean_memo_probe_samples += 1;
11710 if !self.clean_memo_probe_seen.insert(key.clone()) {
11711 self.clean_memo_probe_repeats += 1;
11712 }
11713 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
11714 self.clean_memo_mode = CleanMemoMode::Promote;
11715 self.clean_memo_probe_seen.clear();
11716 return true;
11717 }
11718 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
11719 self.clean_memo_mode = CleanMemoMode::Sparse;
11720 self.clean_memo_sparse_samples = 0;
11721 self.clean_memo_probe_seen.clear();
11722 return false;
11723 }
11724 true
11725 }
11726
11727 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
11729 self.input.get(index)
11730 }
11731
11732 fn token_id_at(&self, index: usize) -> Option<TokenId> {
11734 self.input.get_id(index)
11735 }
11736
11737 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
11738 let token = self
11739 .token_id_at(index)
11740 .expect("recognized token index must exist in the token store");
11741 let node = if error {
11742 ArenaRecognizedNode::ErrorToken { token }
11743 } else {
11744 ArenaRecognizedNode::Token { token }
11745 };
11746 self.recognition_arena.push_node(node)
11747 }
11748
11749 fn arena_missing_token_node(
11750 &mut self,
11751 token_type: i32,
11752 at_index: usize,
11753 text: String,
11754 ) -> RecognizedNodeId {
11755 let extra = self
11756 .recognition_arena
11757 .push_extra(RecognitionExtra::MissingToken {
11758 token_type,
11759 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
11760 text,
11761 });
11762 self.recognition_arena
11763 .push_node(ArenaRecognizedNode::MissingToken { extra })
11764 }
11765
11766 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
11767 let ArenaRuleSpec {
11768 rule_index,
11769 invoking_state,
11770 alt_number,
11771 start_index,
11772 stop_index,
11773 return_values,
11774 children,
11775 } = spec;
11776 let return_values = (!return_values.is_empty()).then(|| {
11777 self.recognition_arena
11778 .push_extra(RecognitionExtra::ReturnValues(return_values))
11779 });
11780 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
11781 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11782 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
11783 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11784 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
11785 stop_index: stop_index
11786 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
11787 return_values,
11788 children,
11789 })
11790 }
11791
11792 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
11793 self.recognition_arena
11794 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
11795 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11796 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11797 })
11798 }
11799
11800 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
11801 *sequence = self.recognition_arena.prepend(*sequence, node);
11802 }
11803
11804 #[allow(clippy::missing_const_for_fn)]
11807 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
11808 self.last_recognition_arena_root = root;
11809 self.last_recognition_arena_diagnostics = diagnostics;
11810 #[cfg(feature = "perf-counters")]
11811 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
11812 let stats = self.recognition_arena_stats();
11813 #[allow(clippy::print_stderr)]
11814 {
11815 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
11816 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
11817 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
11818 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
11819 eprintln!("perf recognition_links_total={}", stats.total_links);
11820 eprintln!("perf recognition_links_live={}", stats.live_links);
11821 eprintln!("perf recognition_links_dead={}", stats.dead_links);
11822 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
11823 eprintln!("perf recognition_extras_total={}", stats.total_extras);
11824 eprintln!("perf recognition_extras_live={}", stats.live_extras);
11825 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
11826 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
11827 }
11828 }
11829 }
11830
11831 fn reset_recognition_arena(&mut self) {
11832 self.recognition_arena.reset();
11833 self.last_recognition_arena_root = NodeSeqId::EMPTY;
11834 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
11835 }
11836
11837 fn current_visible_index(&mut self) -> usize {
11840 let index = self.input.index();
11841 self.input.seek(index);
11842 self.input.index()
11843 }
11844
11845 fn child_expected_reaches_clean_eof(
11848 &mut self,
11849 children: &[RecognizeOutcome],
11850 expected: &ExpectedTokens,
11851 ) -> bool {
11852 let Some(index) = expected.index else {
11853 return false;
11854 };
11855 self.token_type_at(index) == TOKEN_EOF
11856 && children
11857 .iter()
11858 .any(|child| child.diagnostics.is_empty() && child.index == index)
11859 }
11860
11861 fn previous_token_index(&self, index: usize) -> Option<usize> {
11868 self.input.previous_visible_token_index(index)
11869 }
11870
11871 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
11876 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
11877 Some(index)
11878 } else {
11879 self.previous_token_index(index)
11880 }
11881 }
11882
11883 #[must_use]
11900 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
11901 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
11902 self.rule_stop_token_index(current_index, consumed_eof)
11903 }
11904
11905 #[must_use]
11914 pub fn after_action_stop_index_for_tree(
11915 &mut self,
11916 tree: ParseTree,
11917 current_index: usize,
11918 ) -> Option<usize> {
11919 if let Some(stop) = self
11920 .node(tree)
11921 .as_rule()
11922 .and_then(crate::tree::RuleNodeView::stop_id)
11923 {
11924 return Some(stop.index());
11925 }
11926 self.after_action_stop_index(current_index)
11927 }
11928
11929 #[must_use]
11939 pub fn after_action_start_index_for_tree(
11940 &self,
11941 tree: ParseTree,
11942 fallback_index: usize,
11943 ) -> usize {
11944 if let Some(start) = self
11945 .node(tree)
11946 .as_rule()
11947 .and_then(crate::tree::RuleNodeView::start_id)
11948 {
11949 return start.index();
11950 }
11951 fallback_index
11952 }
11953
11954 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
11959 self.rule_stop_token_index(index, consumed_eof)
11960 .and_then(|token_index| self.token_id_at(token_index))
11961 }
11962
11963 fn predicate_failure_recovery(
11970 &mut self,
11971 request: PredicateFailureRecovery<'_>,
11972 ) -> RecognizeOutcome {
11973 let PredicateFailureRecovery {
11974 rule_index,
11975 index,
11976 message,
11977 member_values,
11978 return_values,
11979 rule_alt_number,
11980 } = request;
11981 let rule_name = self
11982 .rule_names()
11983 .get(rule_index)
11984 .map_or_else(|| rule_index.to_string(), Clone::clone);
11985 let diagnostic = diagnostic_for_token(
11986 self.token_at(index).as_ref(),
11987 format!("rule {rule_name} {message}"),
11988 );
11989 let mut reversed_nodes = NodeSeqId::EMPTY;
11990 let mut next_index = index;
11991 loop {
11992 let symbol = self.token_type_at(next_index);
11993 if symbol == TOKEN_EOF {
11994 break;
11995 }
11996 let error = self.arena_token_node(next_index, true);
11997 self.arena_prepend(&mut reversed_nodes, error);
11998 let after = self.consume_index(next_index, symbol);
11999 if after == next_index {
12000 break;
12001 }
12002 next_index = after;
12003 }
12004 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
12005 let diagnostics = self
12006 .recognition_arena
12007 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
12008 RecognizeOutcome {
12009 index: next_index,
12010 consumed_eof: false,
12011 alt_number: rule_alt_number,
12012 member_values,
12013 return_values,
12014 diagnostics,
12015 decisions: Vec::new(),
12016 actions: Vec::new(),
12017 nodes,
12018 }
12019 }
12020
12021 fn parser_semantic_hook_result(
12024 &mut self,
12025 request: ParserSemanticHookRequest<'_>,
12026 ) -> Option<bool> {
12027 let ParserSemanticHookRequest {
12028 index,
12029 rule_index,
12030 pred_index,
12031 context,
12032 local_int_arg,
12033 member_values,
12034 } = request;
12035 let rule_name = self.rule_names().get(rule_index).cloned();
12036 self.input.seek(index);
12037 let input = &mut self.input;
12038 let semantic_hooks = &mut self.semantic_hooks;
12039 let mut ctx = ParserSemCtx {
12040 input,
12041 tree_storage: &self.tree,
12042 rule_index,
12043 coordinate_index: pred_index,
12044 rule_name,
12045 context,
12046 tree: None,
12047 local_int_arg,
12048 member_values,
12049 action: None,
12050 };
12051 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
12052 }
12053
12054 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
12059 if prior.is_empty() {
12060 return;
12061 }
12062 let mut merged = prior;
12063 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
12064 if !merged.contains(&coordinate) {
12065 merged.push(coordinate);
12066 }
12067 }
12068 self.unknown_predicate_hits = merged;
12069 }
12070
12071 fn restore_prior_unhandled_action_hits(&mut self, prior: Vec<(usize, usize)>) {
12074 if prior.is_empty() {
12075 return;
12076 }
12077 let mut merged = prior;
12078 for coordinate in std::mem::take(&mut self.unhandled_action_hits) {
12079 if !merged.contains(&coordinate) {
12080 merged.push(coordinate);
12081 }
12082 }
12083 self.unhandled_action_hits = merged;
12084 }
12085
12086 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
12095 apply_unknown_predicate_policy(
12096 self.unknown_predicate_policy,
12097 rule_index,
12098 pred_index,
12099 &mut self.unknown_predicate_hits,
12100 )
12101 }
12102
12103 fn unknown_semantic_error(&self) -> Option<AntlrError> {
12106 use std::fmt::Write as _;
12107 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
12108 return None;
12109 }
12110 let mut message = String::new();
12111 for (rule_index, pred_index) in &self.unknown_predicate_hits {
12112 if !message.is_empty() {
12113 message.push_str("; ");
12114 }
12115 let _ = match self.rule_names().get(*rule_index) {
12116 Some(rule_name) => write!(
12117 message,
12118 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
12119 ),
12120 None => write!(
12121 message,
12122 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
12123 ),
12124 };
12125 }
12126 for (rule_index, source_state) in &self.unhandled_action_hits {
12127 if !message.is_empty() {
12128 message.push_str("; ");
12129 }
12130 let _ = match self.rule_names().get(*rule_index) {
12131 Some(rule_name) => write!(
12132 message,
12133 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
12134 ),
12135 None => write!(
12136 message,
12137 "unhandled semantic action: rule_index={rule_index} state={source_state}"
12138 ),
12139 };
12140 }
12141 Some(AntlrError::Unsupported(message))
12142 }
12143
12144 fn parser_semir_predicate_matches(
12152 &mut self,
12153 semantics: &ParserSemantics,
12154 predicate: &ParserSemanticPredicate,
12155 request: ParserSemanticHookRequest<'_>,
12156 ) -> bool {
12157 self.input.seek(request.index);
12158 let rule_name = self
12159 .data
12160 .rule_names()
12161 .get(request.rule_index)
12162 .map(String::as_str);
12163 let unknown_predicate_policy = self.unknown_predicate_policy;
12164 let mut ctx = ParserSemIrCtx {
12165 input: &mut self.input,
12166 tree_storage: &self.tree,
12167 semantic_hooks: &mut self.semantic_hooks,
12168 rule_index: request.rule_index,
12169 coordinate_index: request.pred_index,
12170 rule_name,
12171 context: request.context,
12172 local_int_arg: request.local_int_arg,
12173 member_values: request.member_values,
12174 invoked_predicates: &mut self.invoked_predicates,
12175 unknown_predicate_policy,
12176 unknown_predicate_hits: &mut self.unknown_predicate_hits,
12177 };
12178 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
12179 }
12180
12181 fn fast_parser_predicate_matches(
12182 &mut self,
12183 context: Option<FastPredicateContext<'_>>,
12184 transition: ParserTransition<'_>,
12185 index: usize,
12186 ) -> bool {
12187 let Some(context) = context else {
12188 return true;
12189 };
12190 let rule_index = transition.arg0() as usize;
12191 let pred_index = transition.arg1() as usize;
12192 let key = (index, rule_index, pred_index);
12193 if let Some(result) = self.fast_predicate_cache.get(&key) {
12194 return *result;
12195 }
12196 let result = self.parser_predicate_matches(PredicateEval {
12197 index,
12198 rule_index,
12199 pred_index,
12200 predicates: context.predicates,
12201 semantics: context.semantics,
12202 context: None,
12203 local_int_arg: None,
12204 member_values: context.member_values,
12205 });
12206 self.fast_predicate_cache.insert(key, result);
12207 result
12208 }
12209
12210 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
12211 let PredicateEval {
12212 index,
12213 rule_index,
12214 pred_index,
12215 predicates,
12216 semantics,
12217 context,
12218 local_int_arg,
12219 member_values,
12220 } = eval;
12221 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
12222 semantics
12223 .predicates
12224 .iter()
12225 .find(|predicate| {
12226 predicate.rule_index == rule_index && predicate.pred_index == pred_index
12227 })
12228 .map(|predicate| (semantics, predicate))
12229 }) {
12230 return self.parser_semir_predicate_matches(
12231 semantics,
12232 predicate,
12233 ParserSemanticHookRequest {
12234 index,
12235 rule_index,
12236 pred_index,
12237 context,
12238 local_int_arg,
12239 member_values,
12240 },
12241 );
12242 }
12243 let Some((_, _, predicate)) = predicates
12244 .iter()
12245 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
12246 else {
12247 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
12248 index,
12249 rule_index,
12250 pred_index,
12251 context,
12252 local_int_arg,
12253 member_values,
12254 }) {
12255 return result;
12256 }
12257 return self.unknown_predicate_result(rule_index, pred_index);
12258 };
12259 self.input.seek(index);
12260 match predicate {
12261 ParserPredicate::True => true,
12262 ParserPredicate::False => false,
12263 ParserPredicate::FalseWithMessage { .. } => false,
12264 ParserPredicate::Invoke { value } => {
12265 let key = (rule_index, pred_index);
12266 if !self.invoked_predicates.contains(&key) {
12267 self.invoked_predicates.push(key);
12268 use std::io::Write as _;
12269 let mut stdout = std::io::stdout().lock();
12270 let _ = writeln!(stdout, "eval={value}");
12271 }
12272 *value
12273 }
12274 ParserPredicate::LookaheadTextEquals { offset, text } => self
12275 .input
12276 .lt(*offset)
12277 .is_some_and(|token| Token::text(&token) == Some(*text)),
12278 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
12279 self.la(*offset) != *token_type
12280 }
12281 ParserPredicate::TokenPairAdjacent => {
12282 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
12283 return false;
12284 };
12285 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
12286 return false;
12287 };
12288 first + 1 == second
12289 }
12290 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
12291 .and_then(|context| {
12292 context
12293 .child_rules(&self.tree, self.input.token_store(), *rule_index)
12294 .next()
12295 .map(crate::tree::RuleNodeView::text)
12296 })
12297 .is_none_or(|actual| actual != *text),
12298 ParserPredicate::LocalIntEquals { value } => {
12299 local_int_arg.is_none_or(|(_, actual)| actual == *value)
12300 }
12301 ParserPredicate::LocalIntLessOrEqual { value } => {
12302 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
12303 }
12304 ParserPredicate::MemberModuloEquals {
12305 member,
12306 modulus,
12307 value,
12308 equals,
12309 } => {
12310 if *modulus == 0 {
12311 return false;
12312 }
12313 let actual = member_values.scalar(*member).unwrap_or_default() % *modulus;
12314 (actual == *value) == *equals
12315 }
12316 ParserPredicate::MemberEquals {
12317 member,
12318 value,
12319 equals,
12320 } => {
12321 let actual = member_values.scalar(*member).unwrap_or_default();
12322 (actual == *value) == *equals
12323 }
12324 }
12325 }
12326
12327 fn parser_predicate_failure_message(
12329 &self,
12330 rule_index: usize,
12331 pred_index: usize,
12332 predicates: &[(usize, usize, ParserPredicate)],
12333 ) -> Option<&'static str> {
12334 predicates
12335 .iter()
12336 .find_map(|(rule, pred, predicate)| match predicate {
12337 ParserPredicate::FalseWithMessage { message }
12338 if *rule == rule_index && *pred == pred_index =>
12339 {
12340 Some(*message)
12341 }
12342 _ => None,
12343 })
12344 }
12345
12346 pub fn parser_semantic_ir_predicate_failure_message(
12349 &self,
12350 rule_index: usize,
12351 pred_index: usize,
12352 semantics: &ParserSemantics,
12353 ) -> Option<&'static str> {
12354 semantics
12355 .predicates
12356 .iter()
12357 .find(|predicate| {
12358 predicate.rule_index == rule_index && predicate.pred_index == pred_index
12359 })
12360 .and_then(|predicate| predicate.failure_message)
12361 }
12362
12363 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
12372 if symbol == TOKEN_EOF {
12373 return index;
12374 }
12375 self.input.next_visible_after(index)
12376 }
12377
12378 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
12381 let text = display_input_text(&self.input.text(start_index, error_index));
12382 diagnostic_for_token(
12383 self.token_at(error_index).as_ref(),
12384 format!("no viable alternative at input '{text}'"),
12385 )
12386 }
12387
12388 fn recovery_failure_diagnostic(
12391 &self,
12392 index: usize,
12393 decision_start_index: Option<usize>,
12394 expected_symbols: &BTreeSet<i32>,
12395 ) -> ParserDiagnostic {
12396 if expected_symbols.len() > 1 {
12397 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
12398 return self.no_viable_alternative(decision_start, index);
12399 }
12400 }
12401 diagnostic_for_token(
12402 self.token_at(index).as_ref(),
12403 format!(
12404 "mismatched input {} expecting {}",
12405 self.token_at(index)
12406 .as_ref()
12407 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
12408 self.expected_symbols_display(expected_symbols)
12409 ),
12410 )
12411 }
12412
12413 fn eof_rule_recovery_diagnostic(
12416 &self,
12417 index: usize,
12418 expected_symbols: &BTreeSet<i32>,
12419 expected: &ExpectedTokens,
12420 ) -> ParserDiagnostic {
12421 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
12422 &expected.symbols
12423 } else {
12424 expected_symbols
12425 };
12426 diagnostic_for_token(
12427 self.token_at(index).as_ref(),
12428 format!(
12429 "mismatched input {} expecting {}",
12430 self.token_at(index)
12431 .as_ref()
12432 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
12433 self.expected_symbols_display(symbols)
12434 ),
12435 )
12436 }
12437
12438 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
12444 let Some(stop) = stop else {
12445 return String::new();
12446 };
12447 let stop = if self
12448 .token_at(stop)
12449 .is_some_and(|token| token.token_type() == TOKEN_EOF)
12450 {
12451 let Some(previous) = self.previous_token_index(stop) else {
12452 return String::new();
12453 };
12454 previous
12455 } else {
12456 stop
12457 };
12458 self.input.text(start, stop)
12459 }
12460
12461 fn clear_prediction_diagnostics(&mut self) {
12464 self.prediction_diagnostics.clear();
12465 self.reported_prediction_diagnostics.clear();
12466 }
12467
12468 fn reset_per_parse_caches(&mut self) {
12492 self.rule_first_set_cache.clear();
12493 self.decision_lookahead_cache.clear();
12494 self.ll1_decision_cache.clear();
12495 self.fast_predicate_cache.clear();
12496 self.rule_stop_reach_cache.clear();
12497 self.clean_memo_mode = CleanMemoMode::Probe;
12498 self.clean_memo_probe_seen.clear();
12499 self.clean_memo_probe_samples = 0;
12500 self.clean_memo_probe_repeats = 0;
12501 self.clean_memo_sparse_samples = 0;
12502 self.recovery_symbols_intern.clear();
12503 self.state_expected_cache.clear();
12504 self.state_expected_token_cache.clear();
12505 }
12506
12507 fn record_prediction_diagnostics(
12510 &mut self,
12511 atn: &Atn,
12512 state: AtnState<'_>,
12513 start_index: usize,
12514 outcomes: &[RecognizeOutcome],
12515 ) {
12516 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
12517 return;
12518 }
12519 let Some(decision) = atn
12520 .decision_to_state()
12521 .iter()
12522 .position(|state_number| state_number == state.state_number())
12523 else {
12524 return;
12525 };
12526 let Some(rule_index) = state.rule_index() else {
12527 return;
12528 };
12529 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
12530 for outcome in outcomes
12531 .iter()
12532 .filter(|outcome| outcome.diagnostics.is_empty())
12533 {
12534 let Some(alt) = outcome.decisions.first() else {
12535 continue;
12536 };
12537 alts_by_end
12538 .entry(outcome.index)
12539 .or_default()
12540 .insert(alt + 1);
12541 }
12542 let Some((&end_index, ambig_alts)) = alts_by_end
12543 .iter()
12544 .filter(|(_, alts)| alts.len() > 1)
12545 .max_by_key(|(end, _)| *end)
12546 else {
12547 return;
12548 };
12549 let rule_name = self
12550 .rule_names()
12551 .get(rule_index)
12552 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
12553 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
12554 let input = display_input_text(&self.input.text(start_index, stop_index));
12555 let alts = ambig_alts
12556 .iter()
12557 .map(usize::to_string)
12558 .collect::<Vec<_>>()
12559 .join(", ");
12560 let key = (decision, start_index, format!("{alts}:{input}"));
12561 if !self.reported_prediction_diagnostics.insert(key) {
12562 return;
12563 }
12564 let start_diagnostic = diagnostic_for_token(
12565 self.token_at(start_index),
12566 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
12567 );
12568 let stop_diagnostic = diagnostic_for_token(
12569 self.token_at(stop_index),
12570 format!(
12571 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
12572 ),
12573 );
12574 self.prediction_diagnostics.push(start_diagnostic);
12575 self.prediction_diagnostics.push(stop_diagnostic);
12576 }
12577
12578 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
12580 expected_symbols_display(
12581 &state_expected_symbols(atn, state_number),
12582 self.vocabulary(),
12583 )
12584 }
12585
12586 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
12591 let state = usize::try_from(self.data().state()).unwrap_or(0);
12592 ExpectedTokenSet {
12593 symbols: state_expected_symbols(atn, state),
12594 }
12595 }
12596
12597 pub const fn set_bail_on_error(&mut self, bail: bool) {
12600 self.bail_on_error = bail;
12601 }
12602
12603 #[must_use]
12605 pub const fn bail_on_error(&self) -> bool {
12606 self.bail_on_error
12607 }
12608
12609 pub fn rule_invocation_stack(&self) -> Vec<String> {
12612 self.rule_context_stack
12613 .iter()
12614 .rev()
12615 .map(|frame| {
12616 self.data()
12617 .rule_names()
12618 .get(frame.rule_index)
12619 .cloned()
12620 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
12621 })
12622 .collect()
12623 }
12624
12625 pub fn active_invocation_states(&self) -> Vec<isize> {
12629 self.rule_context_stack
12630 .iter()
12631 .skip(1)
12632 .rev()
12633 .map(|frame| frame.invoking_state)
12634 .collect()
12635 }
12636
12637 pub fn token_display_at(&self, index: usize) -> Option<String> {
12639 self.token_at(index).map(|token| format!("{token}"))
12640 }
12641}
12642
12643impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
12644where
12645 S: TokenSource,
12646 H: SemanticHooks,
12647{
12648 fn parse_rule(
12649 &mut self,
12650 rule_index: usize,
12651 invoking_state: isize,
12652 precedence: i32,
12653 ) -> DirectAdaptiveParseResult<ParseTree> {
12654 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
12655 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
12656 )?;
12657 let stop_state = self
12658 .atn
12659 .rule_to_stop_state()
12660 .get(rule_index)
12661 .filter(|state| *state != usize::MAX)
12662 .ok_or(DirectAdaptiveParseControl::Fallback(
12663 DirectAdaptiveFallback::MissingAtn,
12664 ))?;
12665 let start_index = self.parser.current_visible_index();
12666 let mut context = ParserRuleContext::new(rule_index, invoking_state);
12667 if let Some(token) = self.parser.token_id_at(start_index) {
12668 self.parser.set_context_start(&mut context, token);
12669 }
12670 let mut state_number = start_state;
12671 let mut consumed_eof = false;
12672 while state_number != stop_state {
12673 self.step()?;
12674 let (transition, boundary) = self.next_transition(state_number, precedence)?;
12675 if boundary.is_some() {
12676 return Err(DirectAdaptiveParseControl::Fallback(
12677 DirectAdaptiveFallback::LeftRecursiveBoundary,
12678 ));
12679 }
12680 match transition.data() {
12681 Transition::Epsilon { target } => {
12682 state_number = target;
12683 }
12684 Transition::Precedence {
12685 target,
12686 precedence: transition_precedence,
12687 } => {
12688 if transition_precedence < precedence {
12689 return Err(DirectAdaptiveParseControl::Fallback(
12690 DirectAdaptiveFallback::Precedence,
12691 ));
12692 }
12693 state_number = target;
12694 }
12695 Transition::Rule {
12696 rule_index,
12697 follow_state,
12698 precedence: rule_precedence,
12699 ..
12700 } => {
12701 let child = self.parse_rule(
12702 rule_index,
12703 invoking_state_number(state_number),
12704 rule_precedence,
12705 )?;
12706 if self.parser.build_parse_trees {
12707 self.parser.tree.add_child(&mut context, child);
12708 }
12709 state_number = follow_state;
12710 }
12711 Transition::Atom { .. }
12712 | Transition::Range { .. }
12713 | Transition::Set { .. }
12714 | Transition::NotSet { .. }
12715 | Transition::Wildcard { .. } => {
12716 let (matched_eof, child) = self.consume_transition(transition)?;
12717 consumed_eof |= matched_eof;
12718 if let Some(child) = child {
12719 self.parser.tree.add_child(&mut context, child);
12720 }
12721 state_number = transition.target();
12722 }
12723 Transition::Predicate { .. } => {
12724 return Err(DirectAdaptiveParseControl::Fallback(
12725 DirectAdaptiveFallback::Predicate,
12726 ));
12727 }
12728 Transition::Action { .. } => {
12729 return Err(DirectAdaptiveParseControl::Fallback(
12730 DirectAdaptiveFallback::Action,
12731 ));
12732 }
12733 }
12734 }
12735
12736 let stop_index = self
12737 .parser
12738 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
12739 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
12740 self.parser.set_context_stop(&mut context, token);
12741 }
12742 Ok(self.parser.rule_node(context))
12743 }
12744
12745 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
12746 self.steps += 1;
12747 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
12748 return Err(DirectAdaptiveParseControl::Fallback(
12749 DirectAdaptiveFallback::StepLimit,
12750 ));
12751 }
12752 Ok(())
12753 }
12754
12755 fn next_transition(
12756 &mut self,
12757 state_number: usize,
12758 precedence: i32,
12759 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
12760 let state = self
12761 .atn
12762 .state(state_number)
12763 .ok_or(DirectAdaptiveParseControl::Fallback(
12764 DirectAdaptiveFallback::MissingAtn,
12765 ))?;
12766 if state.is_rule_stop() {
12767 return Err(DirectAdaptiveParseControl::Fallback(
12768 DirectAdaptiveFallback::RuleStop,
12769 ));
12770 }
12771 let transition_index =
12772 self.transition_index(state_number, state.transitions().len(), precedence)?;
12773 let transition = state.transitions().get(transition_index).ok_or(
12774 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
12775 )?;
12776 let boundary = match &transition.data() {
12777 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
12778 left_recursive_boundary(self.atn, state, *target)
12779 }
12780 _ => None,
12781 };
12782 Ok((transition, boundary))
12783 }
12784
12785 fn transition_index(
12786 &mut self,
12787 state_number: usize,
12788 transition_count: usize,
12789 precedence: i32,
12790 ) -> DirectAdaptiveParseResult<usize> {
12791 match transition_count {
12792 0 => Err(DirectAdaptiveParseControl::Fallback(
12793 DirectAdaptiveFallback::NoTransition,
12794 )),
12795 1 => Ok(0),
12796 _ => {
12797 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
12798 return Ok(alt);
12799 }
12800 let decision = self
12801 .decision_by_state
12802 .get(state_number)
12803 .and_then(|decision| *decision)
12804 .ok_or(DirectAdaptiveParseControl::Fallback(
12805 DirectAdaptiveFallback::UnknownDecision,
12806 ))?;
12807 let prediction = self
12808 .simulator
12809 .adaptive_predict_stream_info_with_precedence(
12810 decision,
12811 direct_precedence(precedence),
12812 &mut self.parser.input,
12813 )
12814 .map_err(|_| {
12815 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
12816 })?;
12817 if prediction.has_semantic_context {
12818 return Err(DirectAdaptiveParseControl::Fallback(
12819 DirectAdaptiveFallback::SemanticContext,
12820 ));
12821 }
12822 prediction
12823 .alt
12824 .checked_sub(1)
12825 .filter(|index| *index < transition_count)
12826 .ok_or(DirectAdaptiveParseControl::Fallback(
12827 DirectAdaptiveFallback::InvalidAlt,
12828 ))
12829 }
12830 }
12831 }
12832
12833 fn ll1_transition_index(
12834 &mut self,
12835 state_number: usize,
12836 transition_count: usize,
12837 ) -> DirectAdaptiveParseResult<Option<usize>> {
12838 let state = self
12839 .atn
12840 .state(state_number)
12841 .ok_or(DirectAdaptiveParseControl::Fallback(
12842 DirectAdaptiveFallback::MissingAtn,
12843 ))?;
12844 if state.precedence_rule_decision() {
12845 return Ok(None);
12846 }
12847 let Some(rule_stop) = state
12848 .rule_index()
12849 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
12850 else {
12851 return Ok(None);
12852 };
12853 let symbol = self.parser.input.la_token(1);
12854 let entry = self
12855 .parser
12856 .cached_decision_lookahead(self.atn, state, rule_stop);
12857 Ok(
12858 ll1_greedy_alt(&entry, symbol, state.non_greedy())
12859 .filter(|alt| *alt < transition_count),
12860 )
12861 }
12862
12863 fn consume_transition(
12864 &mut self,
12865 transition: ParserTransition<'_>,
12866 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
12867 let symbol = self.parser.input.la_token(1);
12868 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
12869 return Err(DirectAdaptiveParseControl::Fallback(
12870 DirectAdaptiveFallback::TokenMismatch,
12871 ));
12872 }
12873 let token = self
12874 .parser
12875 .input
12876 .lt_id(1)
12877 .ok_or(DirectAdaptiveParseControl::Fallback(
12878 DirectAdaptiveFallback::TokenMismatch,
12879 ))?;
12880 let matched_eof = symbol == TOKEN_EOF;
12881 if !matched_eof {
12882 self.parser.consume();
12883 }
12884 let child = self
12885 .parser
12886 .build_parse_trees
12887 .then(|| self.parser.terminal_tree(token));
12888 Ok((matched_eof, child))
12889 }
12890}
12891
12892impl<S, H> CommittedAtnParser<'_, '_, '_, S, H>
12893where
12894 S: TokenSource,
12895 H: SemanticHooks,
12896{
12897 fn parse_rule(
12898 &mut self,
12899 rule_index: usize,
12900 precedence: i32,
12901 inherited_local_int_arg: Option<(usize, i64)>,
12902 init_expected_state: Option<usize>,
12903 ) -> Result<CommittedRuleOutcome, AntlrError> {
12904 let start_state = self
12905 .atn
12906 .rule_to_start_state()
12907 .get(rule_index)
12908 .ok_or_else(|| {
12909 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
12910 })?;
12911 let stop_state = self
12912 .atn
12913 .rule_to_stop_state()
12914 .get(rule_index)
12915 .filter(|state| *state != usize::MAX)
12916 .ok_or_else(|| {
12917 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
12918 })?;
12919 let left_recursive = self
12920 .atn
12921 .state(start_state)
12922 .is_some_and(AtnState::left_recursive_rule);
12923 if let Some(error) = self.parser.rule_depth_cap_violation() {
12924 return Err(error);
12925 }
12926 if let Some(error) = self.parser.parse_listener_enter_rule(rule_index) {
12927 return Err(error);
12928 }
12929 let mut context = if left_recursive {
12930 self.parser.enter_recursion_rule(
12931 invoking_state_number(start_state),
12932 rule_index,
12933 precedence,
12934 )
12935 } else {
12936 self.parser
12937 .enter_rule(invoking_state_number(start_state), rule_index)
12938 };
12939 let rule_start_index = self.parser.current_visible_index();
12940 let local_int_arg =
12941 usize::try_from(context.invoking_state())
12942 .ok()
12943 .and_then(|source_state| {
12944 rule_local_int_arg(
12945 self.options.rule_args,
12946 source_state,
12947 rule_index,
12948 inherited_local_int_arg,
12949 )
12950 });
12951 if self.options.init_action_rules.contains(&rule_index) {
12952 let action = ParserAction::new_rule_init(
12953 rule_index,
12954 rule_start_index,
12955 init_expected_state.or(Some(start_state)),
12956 );
12957 if !self
12958 .parser
12959 .parser_rule_init_hook_with_context(action, &context, local_int_arg)
12960 {
12961 self.deferred_actions.push(action);
12962 }
12963 }
12964 let mut consumed_eof = false;
12965 let result = self.walk_rule(
12966 rule_index,
12967 start_state,
12968 stop_state,
12969 precedence,
12970 rule_start_index,
12971 local_int_arg,
12972 left_recursive,
12973 &mut context,
12974 &mut consumed_eof,
12975 );
12976
12977 let result = match result {
12978 Ok(()) => Ok(if left_recursive {
12979 self.parser.finish_recursion_rule(context, consumed_eof)
12980 } else {
12981 self.parser.finish_rule(context, consumed_eof)
12982 }),
12983 Err(error) if self.parser.bail_on_error() => {
12984 if left_recursive {
12985 self.parser.unroll_recursion_context();
12986 } else {
12987 self.parser.exit_rule();
12988 }
12989 Err(error)
12990 }
12991 Err(error) => {
12992 self.parser
12993 .recover_generated_rule(&mut context, self.atn, error);
12994 Ok(if left_recursive {
12995 self.parser.finish_recursion_rule(context, consumed_eof)
12996 } else {
12997 self.parser.finish_rule(context, consumed_eof)
12998 })
12999 }
13000 };
13001 self.parser.parse_listener_exit_rule(rule_index);
13002 result.map(|tree| CommittedRuleOutcome { tree, consumed_eof })
13003 }
13004
13005 #[allow(clippy::too_many_arguments)]
13006 fn walk_rule(
13007 &mut self,
13008 rule_index: usize,
13009 mut state_number: usize,
13010 stop_state: usize,
13011 precedence: i32,
13012 rule_start_index: usize,
13013 local_int_arg: Option<(usize, i64)>,
13014 left_recursive: bool,
13015 context: &mut ParserRuleContext,
13016 consumed_eof: &mut bool,
13017 ) -> Result<(), AntlrError> {
13018 let mut entered_loops = BTreeSet::new();
13019 let mut visited_coordinates = FxHashSet::default();
13020 let mut guarded_input_index = self.parser.input.index();
13021 while state_number != stop_state {
13022 let input_index = self.parser.input.index();
13023 if input_index != guarded_input_index {
13024 visited_coordinates.clear();
13025 guarded_input_index = input_index;
13026 }
13027 if !visited_coordinates.insert((state_number, input_index)) {
13028 return Err(AntlrError::Unsupported(format!(
13029 "committed parser encountered a non-consuming ATN cycle at state \
13030 {state_number}"
13031 )));
13032 }
13033 let state = self.atn.state(state_number).ok_or_else(|| {
13034 AntlrError::Unsupported(format!("missing parser ATN state {state_number}"))
13035 })?;
13036 if state.is_rule_stop() {
13037 return Err(AntlrError::Unsupported(format!(
13038 "rule {rule_index} reached unexpected stop state {state_number}"
13039 )));
13040 }
13041 let transition_index = {
13042 let mut decision_context = CommittedDecisionContext {
13043 precedence,
13044 local_int_arg,
13045 context,
13046 entered_loops: &mut entered_loops,
13047 };
13048 self.transition_index(state, &mut decision_context)?
13049 };
13050 let transition = state.transitions().get(transition_index).ok_or_else(|| {
13051 AntlrError::Unsupported(format!(
13052 "missing transition {transition_index} from parser ATN state {state_number}"
13053 ))
13054 })?;
13055
13056 let next_alt = next_alt_number(
13057 state,
13058 state.transitions().len(),
13059 transition_index,
13060 context.alt_number(),
13061 self.options.track_alt_numbers,
13062 );
13063 if self.options.track_alt_numbers && context.alt_number() == 0 && next_alt != 0 {
13064 context.set_alt_number(next_alt);
13065 }
13066 let next_context_alt = next_alt_number(
13067 state,
13068 state.transitions().len(),
13069 transition_index,
13070 context.context_alt_number(),
13071 self.options.track_context_alt_numbers,
13072 );
13073 if self.options.track_context_alt_numbers
13074 && context.context_alt_number() == 0
13075 && next_context_alt != 0
13076 {
13077 context.set_context_alt_number(next_context_alt);
13078 }
13079
13080 if left_recursive
13081 && left_recursive_boundary(self.atn, state, transition.target()).is_some()
13082 {
13083 if let Some(error) = self.parser.rule_depth_cap_violation() {
13084 return Err(error);
13085 }
13086 self.parser.parse_listener_exit_rule(rule_index);
13087 self.parser.push_new_recursion_context_with_previous(
13088 invoking_state_number(
13089 self.atn
13090 .rule_to_start_state()
13091 .get(rule_index)
13092 .unwrap_or(state_number),
13093 ),
13094 rule_index,
13095 context,
13096 );
13097 if let Some(error) = self.parser.parse_listener_enter_rule(rule_index) {
13098 return Err(error);
13099 }
13100 }
13101 state_number = self.apply_transition(
13102 state_number,
13103 transition,
13104 precedence,
13105 rule_start_index,
13106 local_int_arg,
13107 context,
13108 consumed_eof,
13109 )?;
13110 }
13111 Ok(())
13112 }
13113
13114 fn transition_index(
13115 &mut self,
13116 state: AtnState<'_>,
13117 decision_context: &mut CommittedDecisionContext<'_>,
13118 ) -> Result<usize, AntlrError> {
13119 let transition_count = state.transitions().len();
13120 if transition_count == 1 {
13121 return Ok(0);
13122 }
13123 let Some(decision) = self
13124 .decision_by_state
13125 .get(state.state_number())
13126 .copied()
13127 .flatten()
13128 else {
13129 return Err(AntlrError::Unsupported(format!(
13130 "parser ATN state {} has {transition_count} transitions but is not a decision",
13131 state.state_number()
13132 )));
13133 };
13134
13135 let decision_start = self.parser.input.index();
13136 let overridden_transition = if self.parser.semantic_hooks.observes_parser_decisions() {
13137 self.parser
13138 .semantic_hooks
13139 .parser_decision_override(decision, decision_start, transition_count)
13140 .and_then(|alternative| alternative.checked_sub(1))
13141 .filter(|alternative| *alternative < transition_count)
13142 } else {
13143 None
13144 };
13145 if let Some(selected) = overridden_transition {
13146 self.update_loop_selection(state, selected, decision_context);
13147 return Ok(selected);
13148 }
13149
13150 if !state.precedence_rule_decision() {
13151 let loop_back = match state.kind() {
13152 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack => true,
13153 AtnStateKind::StarLoopEntry => decision_context
13154 .entered_loops
13155 .contains(&state.state_number()),
13156 _ => false,
13157 };
13158 let children = self.parser.sync_decision(
13159 self.atn,
13160 state.state_number(),
13161 !decision_context.context.has_matched_child(),
13162 loop_back,
13163 )?;
13164 for child in children {
13165 self.parser.add_parse_child(decision_context.context, child);
13166 }
13167 }
13168
13169 let prediction_precedence = if state.precedence_rule_decision() {
13170 usize::try_from(decision_context.precedence.max(0)).unwrap_or_default()
13171 } else {
13172 0
13173 };
13174 let prediction_context = {
13175 let return_states = self
13176 .parser
13177 .prediction_context_return_states(self.atn)
13178 .collect::<Vec<_>>();
13179 self.simulator
13180 .intern_prediction_context(self.parser.rule_context_version(), return_states)
13181 };
13182 self.simulator.set_exact_ambig_detection(
13183 self.parser.prediction_mode() == PredictionMode::LlExactAmbigDetection,
13184 );
13185 let prediction_mode = self.parser.prediction_mode();
13186 let prediction = match self.simulator.adaptive_predict_stream_info_sll_probe(
13187 decision,
13188 prediction_precedence,
13189 &mut self.parser.input,
13190 ) {
13191 Ok(prediction)
13192 if prediction.requires_full_context && prediction_mode != PredictionMode::Sll =>
13193 {
13194 self.simulator.adaptive_predict_stream_info_with_context(
13195 decision,
13196 prediction_precedence,
13197 &mut self.parser.input,
13198 prediction_context,
13199 )
13200 }
13201 prediction => prediction,
13202 };
13203 let mut prediction = match prediction {
13204 Ok(prediction) => prediction,
13205 Err(ParserAtnSimulatorError::NoViableAlt { index, .. })
13206 if state.precedence_rule_decision() =>
13207 {
13208 let enter_alt = state.transitions().iter().position(|transition| {
13209 self.atn
13210 .state(transition.target())
13211 .is_some_and(|target| target.kind() != AtnStateKind::LoopEnd)
13212 });
13213 let exit_alt = state.transitions().iter().position(|transition| {
13214 self.atn
13215 .state(transition.target())
13216 .is_some_and(|target| target.kind() == AtnStateKind::LoopEnd)
13217 });
13218 let selected = if self.parser.left_recursive_loop_enter_matches(
13219 self.atn,
13220 state.state_number(),
13221 decision_context.precedence,
13222 ) {
13223 enter_alt
13224 } else {
13225 exit_alt
13226 };
13227 let Some(selected) = selected else {
13228 return Err(self
13229 .parser
13230 .no_viable_alternative_error_at(decision_start, index));
13231 };
13232 ParserAtnPrediction {
13233 alt: selected + 1,
13234 requires_full_context: true,
13235 has_semantic_context: true,
13236 diagnostic: None,
13237 }
13238 }
13239 Err(ParserAtnSimulatorError::NoViableAlt { index, .. }) => {
13240 return Err(self
13241 .parser
13242 .no_viable_alternative_error_at(decision_start, index));
13243 }
13244 Err(ParserAtnSimulatorError::PredictionRequiresMoreLookahead) => {
13245 return Err(self.parser.no_viable_alternative_error(decision_start));
13246 }
13247 Err(error) => {
13248 return Err(AntlrError::Unsupported(format!(
13249 "committed parser prediction failed at decision {decision}: {error:?}"
13250 )));
13251 }
13252 };
13253 let mut selected = prediction
13254 .alt
13255 .checked_sub(1)
13256 .filter(|index| *index < transition_count)
13257 .ok_or_else(|| self.parser.no_viable_alternative_error(decision_start))?;
13258
13259 let semantic_candidates = self.simulator.prediction_semantic_candidates();
13260 if !semantic_candidates.is_empty() {
13261 let predicted_alt = prediction.alt;
13262 let mut semantic_results = BTreeMap::new();
13263 let selected_alt = selected + 1;
13264 let selected_matches = self.semantic_alternative_matches(
13265 selected_alt,
13266 decision_context,
13267 &semantic_candidates,
13268 );
13269 semantic_results.insert(selected_alt, selected_matches);
13270 if !selected_matches {
13271 let alternatives = semantic_candidates
13272 .iter()
13273 .map(|candidate| candidate.alt)
13274 .filter(|alternative| *alternative != 0 && *alternative <= transition_count)
13275 .collect::<BTreeSet<_>>();
13276 selected = alternatives
13277 .into_iter()
13278 .find(|alternative| {
13279 let matches = self.semantic_alternative_matches(
13280 *alternative,
13281 decision_context,
13282 &semantic_candidates,
13283 );
13284 semantic_results.insert(*alternative, matches);
13285 matches
13286 })
13287 .and_then(|alternative| alternative.checked_sub(1))
13288 .ok_or_else(|| self.parser.no_viable_alternative_error(decision_start))?;
13289 }
13290 if self.parser.report_diagnostic_errors
13291 && let Some(diagnostic) = prediction.diagnostic.as_ref()
13292 {
13293 for alternative in diagnostic.conflicting_alts.clone() {
13294 if semantic_results.contains_key(&alternative)
13295 || !semantic_candidates
13296 .iter()
13297 .any(|candidate| candidate.alt == alternative)
13298 {
13299 continue;
13300 }
13301 let matches = self.semantic_alternative_matches(
13302 alternative,
13303 decision_context,
13304 &semantic_candidates,
13305 );
13306 semantic_results.insert(alternative, matches);
13307 }
13308 }
13309 Self::filter_prediction_diagnostic(
13310 &mut prediction,
13311 predicted_alt,
13312 selected + 1,
13313 &semantic_results,
13314 );
13315 }
13316 self.parser.record_generated_prediction_diagnostic(
13317 self.atn,
13318 state.state_number(),
13319 &prediction,
13320 );
13321
13322 self.update_loop_selection(state, selected, decision_context);
13323 Ok(selected)
13324 }
13325
13326 fn semantic_alternative_matches(
13327 &mut self,
13328 alternative: usize,
13329 decision_context: &CommittedDecisionContext<'_>,
13330 candidates: &[ParserSemanticCandidate],
13331 ) -> bool {
13332 candidates
13333 .iter()
13334 .filter(|candidate| candidate.alt == alternative)
13335 .any(|candidate| {
13336 self.semantic_context_matches(&candidate.context, decision_context, candidate)
13337 })
13338 }
13339
13340 fn filter_prediction_diagnostic(
13341 prediction: &mut ParserAtnPrediction,
13342 predicted_alt: usize,
13343 selected_alt: usize,
13344 semantic_results: &BTreeMap<usize, bool>,
13345 ) {
13346 prediction.alt = selected_alt;
13347 if selected_alt != predicted_alt {
13348 prediction.diagnostic = None;
13349 return;
13350 }
13351 if let Some(diagnostic) = prediction.diagnostic.as_mut() {
13352 diagnostic
13353 .conflicting_alts
13354 .retain(|alternative| semantic_results.get(alternative).copied().unwrap_or(true));
13355 if diagnostic.conflicting_alts.len() < 2 {
13356 prediction.diagnostic = None;
13357 }
13358 }
13359 }
13360
13361 fn semantic_context_matches(
13362 &mut self,
13363 semantic_context: &SemanticContext,
13364 decision_context: &CommittedDecisionContext<'_>,
13365 candidate: &ParserSemanticCandidate,
13366 ) -> bool {
13367 match semantic_context {
13368 SemanticContext::None => true,
13369 SemanticContext::Predicate {
13370 rule_index,
13371 pred_index,
13372 ..
13373 } => {
13374 let mut matched_provenance = false;
13375 for predicate_call in candidate
13376 .predicate_calls
13377 .iter()
13378 .filter(|call| call.rule_index == *rule_index && call.pred_index == *pred_index)
13379 {
13380 matched_provenance = true;
13381 let mut local_int_arg = decision_context.local_int_arg;
13382 for rule_call in &predicate_call.rule_calls {
13383 local_int_arg = rule_local_int_arg(
13384 self.options.rule_args,
13385 rule_call.source_state,
13386 rule_call.rule_index,
13387 local_int_arg,
13388 );
13389 }
13390 if !self.semantic_predicate_matches(
13391 *rule_index,
13392 *pred_index,
13393 decision_context,
13394 local_int_arg,
13395 ) {
13396 return false;
13397 }
13398 }
13399 if matched_provenance {
13400 true
13401 } else {
13402 self.semantic_predicate_matches(
13403 *rule_index,
13404 *pred_index,
13405 decision_context,
13406 decision_context.local_int_arg,
13407 )
13408 }
13409 }
13410 SemanticContext::Precedence { precedence } => {
13411 *precedence >= decision_context.precedence
13412 }
13413 SemanticContext::And(children) => {
13414 for child in children {
13415 if !self.semantic_context_matches(child, decision_context, candidate) {
13416 return false;
13417 }
13418 }
13419 true
13420 }
13421 SemanticContext::Or(children) => {
13422 for child in children {
13423 if self.semantic_context_matches(child, decision_context, candidate) {
13424 return true;
13425 }
13426 }
13427 false
13428 }
13429 }
13430 }
13431
13432 fn semantic_predicate_matches(
13433 &mut self,
13434 rule_index: usize,
13435 pred_index: usize,
13436 decision_context: &CommittedDecisionContext<'_>,
13437 local_int_arg: Option<(usize, i64)>,
13438 ) -> bool {
13439 let member_values = self.parser.int_members.clone();
13440 self.parser.parser_predicate_matches(PredicateEval {
13441 index: self.parser.input.index(),
13442 rule_index,
13443 pred_index,
13444 predicates: self.options.predicates,
13445 semantics: self.options.semantics,
13446 context: Some(&*decision_context.context),
13447 local_int_arg,
13448 member_values: &member_values,
13449 })
13450 }
13451
13452 fn update_loop_selection(
13453 &self,
13454 state: AtnState<'_>,
13455 selected: usize,
13456 decision_context: &mut CommittedDecisionContext<'_>,
13457 ) {
13458 if state.kind() == AtnStateKind::StarLoopEntry {
13459 let enters = self
13460 .atn
13461 .state(
13462 state
13463 .transitions()
13464 .get(selected)
13465 .expect("selected transition is in bounds")
13466 .target(),
13467 )
13468 .is_some_and(|target| target.kind() != AtnStateKind::LoopEnd);
13469 if enters {
13470 decision_context.entered_loops.insert(state.state_number());
13471 } else {
13472 decision_context.entered_loops.remove(&state.state_number());
13473 }
13474 }
13475 }
13476
13477 #[allow(clippy::too_many_arguments)]
13478 fn apply_transition(
13479 &mut self,
13480 source_state: usize,
13481 transition: ParserTransition<'_>,
13482 precedence: i32,
13483 rule_start_index: usize,
13484 local_int_arg: Option<(usize, i64)>,
13485 context: &mut ParserRuleContext,
13486 consumed_eof: &mut bool,
13487 ) -> Result<usize, AntlrError> {
13488 self.parser.set_state(invoking_state_number(source_state));
13489 match transition.data() {
13490 Transition::Epsilon { target } => Ok(target),
13491 Transition::Atom { target, label } => {
13492 let matched = self
13493 .parser
13494 .match_token_recovering(label, target, self.atn)?;
13495 *consumed_eof |= matched.consumed_eof();
13496 for child in matched.into_child_iter() {
13497 self.parser.add_parse_child(context, child);
13498 }
13499 Ok(target)
13500 }
13501 Transition::Range {
13502 target,
13503 start,
13504 stop,
13505 } => {
13506 let matched =
13507 self.parser
13508 .match_set_recovering(&[(start, stop)], target, self.atn)?;
13509 *consumed_eof |= matched.consumed_eof();
13510 for child in matched.into_child_iter() {
13511 self.parser.add_parse_child(context, child);
13512 }
13513 Ok(target)
13514 }
13515 Transition::Set { target, set } => {
13516 let matched = self
13517 .parser
13518 .match_token_set_recovering(set, target, self.atn)?;
13519 *consumed_eof |= matched.consumed_eof();
13520 for child in matched.into_child_iter() {
13521 self.parser.add_parse_child(context, child);
13522 }
13523 Ok(target)
13524 }
13525 Transition::NotSet { target, set } => {
13526 let matched = self.parser.match_not_token_set_recovering(
13527 set,
13528 1,
13529 self.atn.max_token_type(),
13530 target,
13531 self.atn,
13532 )?;
13533 *consumed_eof |= matched.consumed_eof();
13534 for child in matched.into_child_iter() {
13535 self.parser.add_parse_child(context, child);
13536 }
13537 Ok(target)
13538 }
13539 Transition::Wildcard { target } => {
13540 let matched = self.parser.match_not_set_recovering(
13541 &[],
13542 1,
13543 self.atn.max_token_type(),
13544 target,
13545 self.atn,
13546 )?;
13547 *consumed_eof |= matched.consumed_eof();
13548 for child in matched.into_child_iter() {
13549 self.parser.add_parse_child(context, child);
13550 }
13551 Ok(target)
13552 }
13553 Transition::Rule {
13554 rule_index,
13555 follow_state,
13556 precedence: rule_precedence,
13557 ..
13558 } => {
13559 let marker = self
13560 .parser
13561 .push_invoking_state(invoking_state_number(source_state));
13562 let child = if self.parser.generated_rule_stack_check_due() {
13563 grow_generated_rule_stack(|| {
13564 self.parse_rule(
13565 rule_index,
13566 rule_precedence,
13567 local_int_arg,
13568 Some(follow_state),
13569 )
13570 })
13571 } else {
13572 self.parse_rule(
13573 rule_index,
13574 rule_precedence,
13575 local_int_arg,
13576 Some(follow_state),
13577 )
13578 };
13579 self.parser.discard_invoking_state(marker);
13580 let child = child?;
13581 *consumed_eof |= child.consumed_eof;
13582 self.parser.add_parse_child(context, child.tree);
13583 Ok(follow_state)
13584 }
13585 Transition::Predicate {
13586 target,
13587 rule_index,
13588 pred_index,
13589 ..
13590 } => {
13591 let member_values = self.parser.int_members.clone();
13592 if self.parser.parser_predicate_matches(PredicateEval {
13593 index: self.parser.input.index(),
13594 rule_index,
13595 pred_index,
13596 predicates: self.options.predicates,
13597 semantics: self.options.semantics,
13598 context: Some(context),
13599 local_int_arg,
13600 member_values: &member_values,
13601 }) {
13602 return Ok(target);
13603 }
13604 if let Some(message) = self
13605 .options
13606 .semantics
13607 .and_then(|semantics| {
13608 self.parser.parser_semantic_ir_predicate_failure_message(
13609 rule_index, pred_index, semantics,
13610 )
13611 })
13612 .or_else(|| {
13613 self.parser.parser_predicate_failure_message(
13614 rule_index,
13615 pred_index,
13616 self.options.predicates,
13617 )
13618 })
13619 {
13620 return Err(self
13621 .parser
13622 .failed_predicate_option_error(rule_index, message));
13623 }
13624 Err(self.parser.failed_predicate_error("semantic predicate"))
13625 }
13626 Transition::Action {
13627 target, rule_index, ..
13628 } => {
13629 self.apply_translated_actions(source_state, rule_index, context);
13630 if let Some(action_index) = self.action_index(source_state) {
13631 let action = self.parser.parser_action_at_current_indexed(
13632 source_state,
13633 rule_index,
13634 action_index,
13635 rule_start_index,
13636 *consumed_eof,
13637 );
13638 let _ = self.parser.parser_action_hook_inner(
13639 action,
13640 Some(context),
13641 None,
13642 local_int_arg,
13643 true,
13644 );
13645 }
13646 Ok(target)
13647 }
13648 Transition::Precedence {
13649 target,
13650 precedence: transition_precedence,
13651 } => {
13652 if transition_precedence >= precedence {
13653 Ok(target)
13654 } else {
13655 Err(self
13656 .parser
13657 .failed_predicate_error(format!("precpred(_ctx, {transition_precedence})")))
13658 }
13659 }
13660 }
13661 }
13662
13663 fn apply_translated_actions(
13664 &mut self,
13665 source_state: usize,
13666 rule_index: usize,
13667 context: &mut ParserRuleContext,
13668 ) {
13669 apply_member_actions(
13670 source_state,
13671 self.options.member_actions,
13672 self.options.semantics,
13673 &mut self.parser.int_members,
13674 );
13675 let return_values = return_values_after_action(
13676 source_state,
13677 rule_index,
13678 self.options.return_actions,
13679 self.options.semantics,
13680 &BTreeMap::new(),
13681 );
13682 for (name, value) in return_values {
13683 context.set_int_return(name, value);
13684 }
13685 }
13686
13687 fn action_index(&self, source_state: usize) -> Option<usize> {
13688 self.action_index_by_state.get(&source_state).copied()
13689 }
13690}
13691
13692fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
13695 if !state.precedence_rule_decision() {
13696 return None;
13697 }
13698 let target_state = atn.state(target)?;
13699 if target_state.kind() == AtnStateKind::LoopEnd {
13700 return None;
13701 }
13702 state.rule_index()
13703}
13704
13705fn next_alt_number(
13712 state: AtnState<'_>,
13713 transition_count: usize,
13714 transition_index: usize,
13715 current_alt_number: usize,
13716 track_alt_numbers: bool,
13717) -> usize {
13718 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
13719 return current_alt_number;
13720 }
13721 if matches!(
13722 state.kind(),
13723 AtnStateKind::Basic
13724 | AtnStateKind::BlockStart
13725 | AtnStateKind::PlusBlockStart
13726 | AtnStateKind::StarBlockStart
13727 | AtnStateKind::StarLoopEntry
13728 ) && !state.precedence_rule_decision()
13729 {
13730 return transition_index + 1;
13731 }
13732 current_alt_number
13733}
13734
13735fn invoking_state_number(state_number: usize) -> isize {
13738 isize::try_from(state_number).unwrap_or(isize::MAX)
13739}
13740
13741const fn packed_i32(value: u32) -> i32 {
13742 i32::from_le_bytes(value.to_le_bytes())
13743}
13744
13745fn direct_precedence(precedence: i32) -> usize {
13746 usize::try_from(precedence.max(0)).unwrap_or_default()
13747}
13748
13749fn token_input_display(token: &impl Token) -> String {
13750 format!("'{}'", token.text().unwrap_or("<EOF>"))
13751}
13752
13753fn display_input_text(text: &str) -> String {
13754 let mut out = String::new();
13755 for ch in text.chars() {
13756 match ch {
13757 '\n' => out.push_str("\\n"),
13758 '\r' => out.push_str("\\r"),
13759 '\t' => out.push_str("\\t"),
13760 other => out.push(other),
13761 }
13762 }
13763 out
13764}
13765
13766fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
13767 let (line, column, offending) = token.map_or((0, 0, None), |token| {
13768 (token.line(), token.column(), Some(token.token_id()))
13769 });
13770 ParserDiagnostic {
13771 line,
13772 column,
13773 message,
13774 offending,
13775 }
13776}
13777
13778fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
13779 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
13780}
13781
13782fn expected_symbols_display_iter(
13783 symbols: impl IntoIterator<Item = i32>,
13784 vocabulary: &Vocabulary,
13785) -> String {
13786 let items = symbols
13787 .into_iter()
13788 .map(|symbol| expected_symbol_display(symbol, vocabulary))
13789 .collect::<Vec<_>>();
13790 if let [single] = items.as_slice() {
13791 return single.clone();
13792 }
13793 format!("{{{}}}", items.join(", "))
13794}
13795
13796fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
13797 if symbol == TOKEN_EOF {
13798 return "<EOF>".to_owned();
13799 }
13800 vocabulary.display_name(symbol)
13801}
13802
13803fn caller_follow_token_info_for_stream<S: TokenSource>(
13804 input: &mut CommonTokenStream<S>,
13805 index: usize,
13806) -> (i32, bool, bool) {
13807 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
13810 input.fill();
13811 }
13812 let token_type = input.token_type_at_index(index);
13813 let visible_channel = input.channel();
13814 let token = input.get(index);
13815 let is_boundary = token
13816 .as_ref()
13817 .and_then(Token::text)
13818 .is_some_and(is_caller_follow_boundary_text);
13819 let is_boundary_gap = token.as_ref().is_some_and(|token| {
13820 token.channel() != visible_channel
13821 || is_caller_follow_boundary_gap_text(token.text_or_empty())
13822 });
13823 (token_type, is_boundary, is_boundary_gap)
13824}
13825
13826fn is_caller_follow_boundary_text(text: &str) -> bool {
13827 text.chars().any(|ch| ch == ';' || ch == '\n')
13828 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
13829}
13830
13831fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
13832 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
13833}
13834
13835fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
13839 let Some(rule_index) = state.rule_index() else {
13840 return false;
13841 };
13842 atn.rule_to_start_state()
13843 .get(rule_index)
13844 .and_then(|state_number| atn.state(state_number))
13845 .is_some_and(AtnState::left_recursive_rule)
13846}
13847
13848fn select_better_top_outcome(
13855 first: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
13856 second: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
13857 arena: &RecognitionArena,
13858) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
13859 match (first, second) {
13860 (Ok(first), Ok(second)) => {
13861 if arena.diagnostics(first.0.diagnostics).next().is_none() {
13862 Ok(first)
13863 } else {
13864 Ok(second)
13865 }
13866 }
13867 (Ok(first), Err(_)) => Ok(first),
13868 (Err(_), Ok(second)) => Ok(second),
13869 (Err(_), Err(second_expected)) => Err(second_expected),
13870 }
13871}
13872
13873fn select_best_fast_outcome(
13879 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
13880 prediction_mode: PredictionMode,
13881 caller_follow: Option<&TokenBitSet>,
13882 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
13883 arena: &RecognitionArena,
13884) -> Option<FastRecognizeOutcome> {
13885 let mut best = None;
13886 let mut best_caller_follow = None;
13887 for outcome in outcomes {
13888 if matches!(
13889 prediction_mode,
13890 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
13891 ) && outcome.diagnostics.is_empty()
13892 && let Some(follow) = caller_follow
13893 {
13894 let (token_type, is_boundary, _) = token_info_at(outcome.index);
13895 if is_boundary && follow.contains(token_type) {
13896 let replace =
13897 best_caller_follow
13898 .as_ref()
13899 .is_none_or(|existing: &FastRecognizeOutcome| {
13900 (outcome.index, outcome.consumed_eof)
13901 < (existing.index, existing.consumed_eof)
13902 });
13903 if replace {
13904 best_caller_follow = Some(outcome);
13905 }
13906 }
13907 }
13908 let Some(existing) = best else {
13909 best = Some(outcome);
13910 continue;
13911 };
13912 let outcome_position = (outcome.index, outcome.consumed_eof);
13913 let best_position = (existing.index, existing.consumed_eof);
13914 let better = match prediction_mode {
13915 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
13916 outcome_position,
13917 outcome.diagnostics,
13918 best_position,
13919 existing.diagnostics,
13920 arena,
13921 ),
13922 PredictionMode::Sll => outcome.index > existing.index,
13923 };
13924 best = Some(if better { outcome } else { existing });
13925 }
13926 let should_use_caller_follow =
13927 best_caller_follow
13928 .as_ref()
13929 .zip(best.as_ref())
13930 .is_some_and(|(candidate, selected)| {
13931 if !selected.diagnostics.is_empty() {
13932 return true;
13933 }
13934 candidate.index < selected.index
13935 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
13936 });
13937 if should_use_caller_follow {
13938 best_caller_follow
13939 } else {
13940 best
13941 }
13942}
13943
13944fn select_best_outcome(
13945 outcomes: impl Iterator<Item = RecognizeOutcome>,
13946 prediction_mode: PredictionMode,
13947 arena: &RecognitionArena,
13948) -> Option<RecognizeOutcome> {
13949 let outcomes = outcomes.collect::<Vec<_>>();
13950 let prefer_first_tie = outcomes
13951 .iter()
13952 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
13953 outcomes.into_iter().reduce(|best, outcome| {
13954 let outcome_position = (outcome.index, outcome.consumed_eof);
13955 let best_position = (best.index, best.consumed_eof);
13956 let better = match prediction_mode {
13957 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
13958 outcome_is_better(
13959 outcome_position,
13960 outcome.diagnostics,
13961 best_position,
13962 best.diagnostics,
13963 arena,
13964 ) || (outcome_position == best_position
13965 && arena.diagnostics_len(outcome.diagnostics)
13966 == arena.diagnostics_len(best.diagnostics)
13967 && arena.diagnostics_recovery_rank(outcome.diagnostics)
13968 == arena.diagnostics_recovery_rank(best.diagnostics)
13969 && (outcome.decisions < best.decisions
13970 || (!prefer_first_tie
13971 && outcome.decisions == best.decisions
13972 && outcome.actions > best.actions)))
13973 }
13974 PredictionMode::Sll => {
13975 outcome_position > best_position
13976 || (outcome_position == best_position
13977 && !prefer_first_tie
13978 && (outcome.decisions < best.decisions
13979 || (outcome.decisions == best.decisions
13980 && outcome_is_better(
13981 outcome_position,
13982 outcome.diagnostics,
13983 best_position,
13984 best.diagnostics,
13985 arena,
13986 ))))
13987 }
13988 };
13989 if better {
13990 return outcome;
13991 }
13992 best
13993 })
13994}
13995
13996fn transition_decision(
14003 atn: &Atn,
14004 state: AtnState<'_>,
14005 transition_count: usize,
14006 transition_index: usize,
14007 predicates: &[(usize, usize, ParserPredicate)],
14008) -> Option<usize> {
14009 if transition_count <= 1 || decision_reaches_unsupported_predicate(atn, state, predicates) {
14010 return None;
14011 }
14012 Some(transition_index)
14013}
14014
14015fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
14021 transition_count > 1
14022 && !matches!(
14023 state.kind(),
14024 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
14025 )
14026}
14027
14028fn record_no_viable_if_ambiguous(
14031 expected: &mut ExpectedTokens,
14032 decision_start_index: Option<usize>,
14033 index: usize,
14034) {
14035 if expected.index == Some(index) && expected.symbols.len() > 1 {
14036 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
14037 expected.record_no_viable(decision_start, index);
14038 }
14039 }
14040}
14041
14042const fn record_predicate_no_viable(
14045 expected: &mut ExpectedTokens,
14046 decision_start_index: Option<usize>,
14047 index: usize,
14048) {
14049 if let Some(decision_start) = decision_start_index {
14050 expected.record_no_viable(decision_start, index);
14051 }
14052}
14053
14054const fn no_viable_decision_start(
14056 decision_start_index: Option<usize>,
14057 index: usize,
14058) -> Option<usize> {
14059 match decision_start_index {
14060 Some(start) if index > start => Some(start),
14061 _ => None,
14062 }
14063}
14064
14065fn restore_expected(
14069 children: &[RecognizeOutcome],
14070 child_start_index: usize,
14071 expected: &mut ExpectedTokens,
14072 snapshot: ExpectedTokens,
14073 preserve_child_expected: bool,
14074) {
14075 if preserve_child_expected {
14076 return;
14077 }
14078 if children
14079 .iter()
14080 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
14081 {
14082 *expected = snapshot;
14083 }
14084}
14085
14086fn decision_reaches_unsupported_predicate(
14089 atn: &Atn,
14090 state: AtnState<'_>,
14091 predicates: &[(usize, usize, ParserPredicate)],
14092) -> bool {
14093 state.transitions().iter().any(|transition| {
14094 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
14095 })
14096}
14097
14098fn transition_reaches_unsupported_predicate(
14100 atn: &Atn,
14101 transition: ParserTransition<'_>,
14102 predicates: &[(usize, usize, ParserPredicate)],
14103 visited: &mut BTreeSet<usize>,
14104) -> bool {
14105 match &transition.data() {
14106 Transition::Predicate {
14107 rule_index,
14108 pred_index,
14109 ..
14110 } => !predicates
14111 .iter()
14112 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
14113 Transition::Epsilon { target }
14114 | Transition::Action { target, .. }
14115 | Transition::Rule { target, .. } => {
14116 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
14117 }
14118 Transition::Precedence { .. }
14119 | Transition::Atom { .. }
14120 | Transition::Range { .. }
14121 | Transition::Set { .. }
14122 | Transition::NotSet { .. }
14123 | Transition::Wildcard { .. } => false,
14124 }
14125}
14126
14127fn state_reaches_unsupported_predicate(
14129 atn: &Atn,
14130 state_number: usize,
14131 predicates: &[(usize, usize, ParserPredicate)],
14132 visited: &mut BTreeSet<usize>,
14133) -> bool {
14134 if !visited.insert(state_number) {
14135 return false;
14136 }
14137 let Some(state) = atn.state(state_number) else {
14138 return false;
14139 };
14140 state.transitions().iter().any(|transition| {
14141 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
14142 })
14143}
14144
14145fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
14147 if let Some(decision) = decision {
14148 outcome.decisions.insert(0, decision);
14149 }
14150}
14151
14152fn outcome_is_better(
14153 outcome_position: (usize, bool),
14154 outcome_diagnostics: DiagnosticSeqId,
14155 best_position: (usize, bool),
14156 best_diagnostics: DiagnosticSeqId,
14157 arena: &RecognitionArena,
14158) -> bool {
14159 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
14160 let best_len = arena.diagnostics_len(best_diagnostics);
14161 outcome_position > best_position
14162 || (outcome_position == best_position
14163 && (outcome_len < best_len
14164 || (outcome_len == best_len
14165 && arena.diagnostics_recovery_rank(outcome_diagnostics)
14166 < arena.diagnostics_recovery_rank(best_diagnostics))))
14167}
14168
14169fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
14170 if outcomes
14171 .iter()
14172 .any(|outcome| outcome.diagnostics.is_empty())
14173 {
14174 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
14175 }
14176}
14177
14178fn discard_recovered_outcomes_if_clean_path_exists(
14179 outcomes: &mut Vec<RecognizeOutcome>,
14180 arena: &RecognitionArena,
14181) {
14182 if outcomes
14183 .iter()
14184 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
14185 {
14186 return;
14187 }
14188 if outcomes
14189 .iter()
14190 .any(|outcome| outcome.diagnostics.is_empty())
14191 {
14192 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
14193 }
14194}
14195
14196fn outcome_has_rule_failure_diagnostic(
14199 outcome: &RecognizeOutcome,
14200 arena: &RecognitionArena,
14201) -> bool {
14202 arena
14203 .diagnostics(outcome.diagnostics)
14204 .any(|diagnostic| diagnostic.message.starts_with("rule "))
14205}
14206
14207fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
14221 if outcomes.len() < 2 {
14222 return;
14223 }
14224 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
14225 outcomes.retain(|outcome| {
14226 seen.insert((
14227 outcome.index,
14228 outcome.consumed_eof,
14229 arena.diagnostics_len(outcome.diagnostics),
14230 arena.diagnostics_recovery_rank(outcome.diagnostics),
14231 ))
14232 });
14233}
14234
14235const FAST_OUTCOME_INLINE_KEYS: usize = 8;
14236const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
14237const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
14238const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
14239
14240#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14241enum FastOutcomeDedupStrategy {
14242 Inline,
14243 Dense,
14244 Sparse,
14245}
14246
14247impl FastOutcomeDedupScratch {
14248 fn prepare_dense(&mut self, word_count: usize) {
14249 while let Some(word_index) = self.touched_dense_words.pop() {
14250 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
14251 }
14252 if self.dense_words.len() < word_count {
14253 self.dense_words.resize(word_count, 0);
14254 }
14255 }
14256}
14257
14258fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
14259 let first_index = outcomes.first()?.index;
14260 let (min_index, max_index) = outcomes[1..].iter().fold(
14261 (first_index, first_index),
14262 |(min_index, max_index), outcome| {
14263 (min_index.min(outcome.index), max_index.max(outcome.index))
14264 },
14265 );
14266 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
14267 let bit_count = index_span.checked_mul(2)?;
14268 let word_count =
14269 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
14270 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
14271 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
14272 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
14273 .then_some((min_index, word_count))
14274}
14275
14276#[cfg(feature = "perf-counters")]
14277fn record_clean_fast_outcome_dedup(
14278 strategy: FastOutcomeDedupStrategy,
14279 input_len: usize,
14280 output_len: usize,
14281 dense_words: usize,
14282) {
14283 let counter = match strategy {
14284 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
14285 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
14286 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
14287 };
14288 perf_counters::inc(
14289 &perf_counters::OUTCOME_DEDUPE_INPUTS,
14290 u64::try_from(input_len).unwrap_or(u64::MAX),
14291 );
14292 perf_counters::inc(
14293 &perf_counters::OUTCOME_DEDUPE_REMOVED,
14294 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
14295 );
14296 perf_counters::inc(counter, 1);
14297 perf_counters::inc(
14298 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
14299 u64::try_from(dense_words).unwrap_or(u64::MAX),
14300 );
14301}
14302
14303fn dedupe_clean_fast_outcomes(
14307 outcomes: &mut Vec<FastRecognizeOutcome>,
14308 scratch: &mut FastOutcomeDedupScratch,
14309) -> FastOutcomeDedupStrategy {
14310 #[cfg(feature = "perf-counters")]
14311 let input_len = outcomes.len();
14312 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
14313 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
14314 let mut inline_len = 0_usize;
14315 outcomes.retain(|outcome| {
14316 let key = (outcome.index, outcome.consumed_eof);
14317 if inline_keys[..inline_len].contains(&key) {
14318 return false;
14319 }
14320 inline_keys[inline_len] = key;
14321 inline_len += 1;
14322 true
14323 });
14324 #[cfg(feature = "perf-counters")]
14325 record_clean_fast_outcome_dedup(
14326 FastOutcomeDedupStrategy::Inline,
14327 input_len,
14328 outcomes.len(),
14329 0,
14330 );
14331 return FastOutcomeDedupStrategy::Inline;
14332 }
14333
14334 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
14335 scratch.prepare_dense(word_count);
14336 outcomes.retain(|outcome| {
14337 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
14338 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
14339 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
14340 let word = &mut scratch.dense_words[word_index];
14341 if *word & bit != 0 {
14342 return false;
14343 }
14344 if *word == 0 {
14345 scratch
14346 .touched_dense_words
14347 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
14348 }
14349 *word |= bit;
14350 true
14351 });
14352 #[cfg(feature = "perf-counters")]
14353 record_clean_fast_outcome_dedup(
14354 FastOutcomeDedupStrategy::Dense,
14355 input_len,
14356 outcomes.len(),
14357 word_count,
14358 );
14359 return FastOutcomeDedupStrategy::Dense;
14360 }
14361
14362 scratch.sparse_keys.clear();
14363 scratch.sparse_keys.reserve(outcomes.len());
14364 outcomes.retain(|outcome| {
14365 scratch
14366 .sparse_keys
14367 .insert((outcome.index, outcome.consumed_eof))
14368 });
14369 #[cfg(feature = "perf-counters")]
14370 record_clean_fast_outcome_dedup(
14371 FastOutcomeDedupStrategy::Sparse,
14372 input_len,
14373 outcomes.len(),
14374 0,
14375 );
14376 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
14377 scratch.sparse_keys = FxHashSet::default();
14378 }
14379 FastOutcomeDedupStrategy::Sparse
14380}
14381
14382fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
14385 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
14386 outcomes
14387 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
14388}
14389
14390fn compare_recognize_outcomes(
14391 left: &RecognizeOutcome,
14392 right: &RecognizeOutcome,
14393 arena: &RecognitionArena,
14394) -> Ordering {
14395 left.index
14396 .cmp(&right.index)
14397 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
14398 .then_with(|| left.alt_number.cmp(&right.alt_number))
14399 .then_with(|| left.member_values.cmp(&right.member_values))
14400 .then_with(|| left.return_values.cmp(&right.return_values))
14401 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
14402 .then_with(|| left.decisions.cmp(&right.decisions))
14403 .then_with(|| left.actions.cmp(&right.actions))
14404 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
14405}
14406
14407impl<S, H> Recognizer for BaseParser<S, H>
14408where
14409 S: TokenSource,
14410 H: SemanticHooks,
14411{
14412 fn data(&self) -> &RecognizerData {
14413 &self.data
14414 }
14415
14416 fn data_mut(&mut self) -> &mut RecognizerData {
14417 &mut self.data
14418 }
14419}
14420
14421impl<S, H> Parser for BaseParser<S, H>
14422where
14423 S: TokenSource,
14424 H: SemanticHooks,
14425{
14426 fn build_parse_trees(&self) -> bool {
14427 self.build_parse_trees
14428 }
14429
14430 fn set_build_parse_trees(&mut self, build: bool) {
14431 self.build_parse_trees = build;
14432 }
14433
14434 fn number_of_syntax_errors(&self) -> usize {
14435 Self::number_of_syntax_errors(self)
14436 }
14437
14438 fn report_diagnostic_errors(&self) -> bool {
14439 self.report_diagnostic_errors
14440 }
14441
14442 fn set_report_diagnostic_errors(&mut self, report: bool) {
14443 self.report_diagnostic_errors = report;
14444 }
14445
14446 fn prediction_mode(&self) -> PredictionMode {
14447 self.prediction_mode
14448 }
14449
14450 fn set_prediction_mode(&mut self, mode: PredictionMode) {
14451 self.prediction_mode = mode;
14452 }
14453
14454 fn max_rule_depth(&self) -> Option<usize> {
14455 self.max_rule_depth
14456 }
14457
14458 fn set_max_rule_depth(&mut self, depth: Option<usize>) {
14459 self.max_rule_depth = depth;
14460 }
14461
14462 fn add_parse_listener(&mut self, listener: Box<dyn ParseListener>) {
14463 self.parse_listeners.push(ParseListenerSlot(listener));
14464 }
14465
14466 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
14467 Self::remove_parse_listeners(self)
14468 }
14469}
14470
14471#[cfg(test)]
14472#[allow(clippy::disallowed_methods)] mod tests {
14474 use super::*;
14475 use crate::atn::parser::{
14476 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
14477 context_containment_test_atn,
14478 };
14479 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
14480 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
14481 use crate::token_stream::CommonTokenStream;
14482 use crate::tree::{NodeKind, ParseTreeStats};
14483 use crate::vocabulary::Vocabulary;
14484 use std::cell::RefCell;
14485 use std::mem::size_of;
14486 use std::rc::Rc;
14487 use std::sync::{Arc, Mutex};
14488
14489 #[test]
14490 fn fx_hasher_write_matches_typed_methods_for_full_words() {
14491 let value: u64 = 0x0102_0304_0506_0708;
14498 let mut typed = FxHasher::default();
14499 typed.write_u64(value);
14500 let mut bytewise = FxHasher::default();
14501 bytewise.write(&value.to_le_bytes());
14502 assert_eq!(typed.finish(), bytewise.finish());
14503 }
14504
14505 #[derive(Clone, Debug)]
14506 struct TestToken {
14507 spec: TokenSpec,
14508 id: TokenId,
14509 source_name: String,
14510 }
14511
14512 impl TestToken {
14513 fn new(token_type: i32) -> Self {
14514 Self {
14515 spec: TokenSpec::explicit(token_type, ""),
14516 id: TokenId::try_from(0).expect("zero token ID"),
14517 source_name: String::new(),
14518 }
14519 }
14520
14521 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
14522 Self {
14523 spec: TokenSpec::eof(index, index, line, column),
14524 id: TokenId::try_from(0).expect("zero token ID"),
14525 source_name: source_name.to_owned(),
14526 }
14527 }
14528
14529 fn with_text(mut self, text: impl Into<String>) -> Self {
14530 self.spec.text = Some(text.into());
14531 self
14532 }
14533
14534 const fn with_channel(mut self, channel: i32) -> Self {
14535 self.spec.channel = channel;
14536 self
14537 }
14538
14539 fn with_span(mut self, start: usize, stop: usize) -> Self {
14540 self.spec = self.spec.with_span(start, stop);
14541 self
14542 }
14543
14544 fn with_byte_span(mut self, start: usize, stop: usize) -> Self {
14545 self.spec = self.spec.with_byte_span(start, stop);
14546 self
14547 }
14548
14549 const fn with_position(mut self, line: usize, column: usize) -> Self {
14550 self.spec.line = line;
14551 self.spec.column = column;
14552 self
14553 }
14554
14555 fn set_token_index(&mut self, index: isize) {
14556 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
14557 }
14558 }
14559
14560 impl Token for TestToken {
14561 fn token_id(&self) -> TokenId {
14562 self.id
14563 }
14564
14565 fn token_type(&self) -> i32 {
14566 self.spec.token_type
14567 }
14568
14569 fn channel(&self) -> i32 {
14570 self.spec.channel
14571 }
14572
14573 fn start(&self) -> usize {
14574 self.spec.start
14575 }
14576
14577 fn stop(&self) -> usize {
14578 self.spec.stop
14579 }
14580
14581 fn line(&self) -> usize {
14582 self.spec.line
14583 }
14584
14585 fn column(&self) -> usize {
14586 self.spec.column
14587 }
14588
14589 fn text(&self) -> Option<&str> {
14590 self.spec.text.as_deref()
14591 }
14592
14593 fn source_name(&self) -> &str {
14594 &self.source_name
14595 }
14596
14597 fn start_byte(&self) -> Option<usize> {
14598 (self.spec.start_byte != usize::MAX).then_some(self.spec.start_byte)
14599 }
14600
14601 fn stop_byte(&self) -> Option<usize> {
14602 (self.spec.stop_byte != usize::MAX).then_some(self.spec.stop_byte)
14603 }
14604 }
14605
14606 #[derive(Debug)]
14607 struct Source {
14608 tokens: Vec<TestToken>,
14609 index: usize,
14610 }
14611
14612 impl TokenSource for Source {
14613 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
14614 let token = self
14615 .tokens
14616 .get(self.index)
14617 .cloned()
14618 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
14619 self.index += 1;
14620 sink.push(token.spec)
14621 }
14622
14623 fn line(&self) -> usize {
14624 1
14625 }
14626
14627 fn column(&self) -> usize {
14628 self.index
14629 }
14630
14631 fn source_name(&self) -> &'static str {
14632 "parser-test"
14633 }
14634 }
14635
14636 #[derive(Clone, Debug, Eq, PartialEq)]
14637 struct RecordedDiagnostic {
14638 grammar_file_name: String,
14639 offending_text: Option<String>,
14640 line: usize,
14641 column: usize,
14642 span: Option<std::ops::Range<usize>>,
14643 message: String,
14644 error: Option<AntlrError>,
14645 }
14646
14647 #[derive(Clone, Debug)]
14648 struct RecordingErrorListener {
14649 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
14650 }
14651
14652 impl<R> crate::ErrorListener<R> for RecordingErrorListener
14653 where
14654 R: Recognizer + ?Sized,
14655 {
14656 fn syntax_error(&mut self, recognizer: &R, event: &SyntaxErrorEvent<'_>) {
14657 self.diagnostics
14658 .lock()
14659 .expect("recorded diagnostics lock")
14660 .push(RecordedDiagnostic {
14661 grammar_file_name: recognizer.grammar_file_name().to_owned(),
14662 offending_text: event
14663 .offending
14664 .and_then(|token| token.text().map(str::to_owned)),
14665 line: event.line,
14666 column: event.column,
14667 span: event.span.clone(),
14668 message: event.message.to_owned(),
14669 error: event.error.cloned(),
14670 });
14671 }
14672 }
14673
14674 #[derive(Debug)]
14675 struct ReportingSource {
14676 source: Source,
14677 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
14678 }
14679
14680 impl TokenSource for ReportingSource {
14681 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
14682 self.source.next_token(sink)
14683 }
14684
14685 fn line(&self) -> usize {
14686 self.source.line()
14687 }
14688
14689 fn column(&self) -> usize {
14690 self.source.column()
14691 }
14692
14693 fn source_name(&self) -> &str {
14694 self.source.source_name()
14695 }
14696
14697 fn report_error(&self, error: &TokenSourceError) -> bool {
14698 self.diagnostics.borrow_mut().push(error.clone());
14699 true
14700 }
14701 }
14702
14703 fn mini_parser_data() -> RecognizerData {
14704 RecognizerData::new(
14705 "Mini.g4",
14706 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14707 )
14708 .with_rule_names(["s"])
14709 }
14710
14711 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
14712 let data = mini_parser_data();
14713 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
14714 }
14715
14716 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
14717 where
14718 H: SemanticHooks,
14719 {
14720 BaseParser::with_semantic_hooks(
14721 CommonTokenStream::new(Source { tokens, index: 0 }),
14722 mini_parser_data(),
14723 hooks,
14724 )
14725 }
14726
14727 #[test]
14728 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
14729 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
14730 parser.remove_error_listeners();
14731 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14732 parser.add_error_listener(RecordingErrorListener {
14733 diagnostics: Arc::clone(&diagnostics),
14734 });
14735 let parser_diagnostics = [ParserDiagnostic {
14736 line: 1,
14737 column: 2,
14738 message: "missing 'x' at 'y'".to_owned(),
14739 offending: None,
14740 }];
14741 let token_errors = [
14742 TokenSourceError::new(1, 1, "token recognition error at: '@'").with_span(1..2),
14743 TokenSourceError::new(1, 3, "token recognition error at: '#'").with_span(3..4),
14744 ];
14745
14746 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
14747
14748 insta::assert_debug_snapshot!(
14751 "parser_dispatches_recovery_diagnostics_through_registered_listeners",
14752 *diagnostics.lock().expect("recorded diagnostics lock")
14753 );
14754
14755 parser.remove_error_listeners();
14756 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
14757 assert_eq!(
14758 diagnostics.lock().expect("recorded diagnostics lock").len(),
14759 3
14760 );
14761 }
14762
14763 #[test]
14764 fn recovery_diagnostics_expose_the_offending_token_to_listeners() {
14765 let mut parser = mini_parser(vec![
14766 TestToken::new(7)
14767 .with_text("oops")
14768 .with_span(0, 3)
14769 .with_byte_span(0, 4)
14770 .with_position(1, 2),
14771 TestToken::eof("parser-test", 4, 1, 6),
14772 ]);
14773 parser.remove_error_listeners();
14774 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14775 parser.add_error_listener(RecordingErrorListener {
14776 diagnostics: Arc::clone(&diagnostics),
14777 });
14778 let offending = parser.input.lt_id(1);
14779 assert!(offending.is_some(), "current token should be buffered");
14780 let parser_diagnostics = [ParserDiagnostic {
14781 line: 1,
14782 column: 2,
14783 message: "extraneous input 'oops'".to_owned(),
14784 offending,
14785 }];
14786
14787 parser.dispatch_generated_diagnostics(&parser_diagnostics, &[]);
14788
14789 let recorded = diagnostics
14793 .lock()
14794 .expect("recorded diagnostics lock")
14795 .clone();
14796 insta::assert_debug_snapshot!(
14797 "recovery_diagnostics_expose_the_offending_token_to_listeners",
14798 recorded
14799 );
14800 }
14801
14802 #[test]
14803 fn recovery_diagnostics_preserve_unknown_custom_token_span() {
14804 let mut parser = mini_parser(vec![
14805 TestToken::new(7)
14806 .with_text("oops")
14807 .with_span(0, 3)
14808 .with_position(1, 2),
14809 TestToken::eof("parser-test", 4, 1, 6),
14810 ]);
14811 parser.remove_error_listeners();
14812 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14813 parser.add_error_listener(RecordingErrorListener {
14814 diagnostics: Arc::clone(&diagnostics),
14815 });
14816 let offending = parser.input.lt_id(1);
14817 assert!(offending.is_some(), "current token should be buffered");
14818
14819 parser.dispatch_parser_diagnostic(&ParserDiagnostic {
14820 line: 1,
14821 column: 2,
14822 message: "extraneous input 'oops'".to_owned(),
14823 offending,
14824 });
14825
14826 let span = {
14827 let diagnostics = diagnostics.lock().expect("recorded diagnostics lock");
14828 assert_eq!(diagnostics.len(), 1);
14829 diagnostics[0].span.clone()
14830 };
14831 assert_eq!(span, None);
14832 }
14833
14834 #[test]
14835 fn parser_leaves_token_errors_to_source_owned_listeners() {
14836 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
14837 let source = ReportingSource {
14838 source: Source {
14839 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
14840 index: 0,
14841 },
14842 diagnostics: Rc::clone(&source_diagnostics),
14843 };
14844 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
14845 parser.remove_error_listeners();
14846 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
14847 parser.add_error_listener(RecordingErrorListener {
14848 diagnostics: Arc::clone(&parser_diagnostics),
14849 });
14850 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
14851
14852 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
14853
14854 assert_eq!(*source_diagnostics.borrow(), [source_error]);
14855 assert!(
14856 parser_diagnostics
14857 .lock()
14858 .expect("recorded diagnostics lock")
14859 .is_empty()
14860 );
14861 }
14862
14863 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
14864 builder.finish().expect("valid packed parser ATN")
14865 }
14866
14867 fn nested_rule_chain_atn(depth: usize) -> Atn {
14868 nested_rule_graph_atn(depth, false, false)
14869 }
14870
14871 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
14872 assert!(depth > 0);
14873 let mut atn = ParserAtnBuilder::new(2);
14874 let mut starts = Vec::with_capacity(depth);
14875 let mut stops = Vec::with_capacity(depth);
14876 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
14877 for rule_index in 0..depth {
14878 starts.push(
14879 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
14880 .expect("rule start")
14881 .index(),
14882 );
14883 }
14884 for rule_index in 0..depth {
14885 stops.push(
14886 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
14887 .expect("rule stop")
14888 .index(),
14889 );
14890 }
14891 if consuming_follows {
14892 for rule_index in 0..depth - 1 {
14893 follows.push(
14894 atn.add_state(AtnStateKind::Basic, Some(rule_index))
14895 .expect("rule follow")
14896 .index(),
14897 );
14898 }
14899 }
14900 atn.set_rule_to_start_state(starts.clone())
14901 .expect("rule start states");
14902 atn.set_rule_to_stop_state(stops.clone())
14903 .expect("rule stop states");
14904 for rule_index in 0..depth - 1 {
14905 let follow_state = if consuming_follows {
14906 follows[rule_index]
14907 } else {
14908 stops[rule_index]
14909 };
14910 atn.add_transition(
14911 starts[rule_index],
14912 ParserTransitionSpec::Rule {
14913 target: starts[rule_index + 1],
14914 rule_index: rule_index + 1,
14915 follow_state,
14916 precedence: 0,
14917 },
14918 )
14919 .expect("nested rule transition");
14920 if branching {
14921 atn.add_transition(
14922 starts[rule_index],
14923 ParserTransitionSpec::Atom {
14924 target: stops[rule_index],
14925 label: 2,
14926 },
14927 )
14928 .expect("dead branch transition");
14929 }
14930 if consuming_follows {
14931 atn.add_transition(
14932 follow_state,
14933 ParserTransitionSpec::Atom {
14934 target: stops[rule_index],
14935 label: 1,
14936 },
14937 )
14938 .expect("consuming follow transition");
14939 }
14940 }
14941 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
14942 atn.add_transition(
14943 starts[depth - 1],
14944 ParserTransitionSpec::Set {
14945 target: stops[depth - 1],
14946 set: token_set,
14947 },
14948 )
14949 .expect("terminal set transition");
14950 if branching {
14951 atn.add_transition(
14952 starts[depth - 1],
14953 ParserTransitionSpec::Atom {
14954 target: stops[depth - 1],
14955 label: 2,
14956 },
14957 )
14958 .expect("dead leaf branch transition");
14959 }
14960 finish_atn(atn)
14961 }
14962
14963 fn ordinary_star_loop_atn() -> Atn {
14964 let mut atn = ParserAtnBuilder::new(2);
14965 for (state_number, kind, rule_index) in [
14966 (0, AtnStateKind::RuleStart, 0),
14967 (1, AtnStateKind::StarLoopEntry, 0),
14968 (2, AtnStateKind::Basic, 0),
14969 (3, AtnStateKind::StarLoopBack, 0),
14970 (4, AtnStateKind::LoopEnd, 0),
14971 (5, AtnStateKind::Basic, 0),
14972 (6, AtnStateKind::RuleStop, 0),
14973 (7, AtnStateKind::RuleStart, 1),
14974 (8, AtnStateKind::Basic, 1),
14975 (9, AtnStateKind::RuleStop, 1),
14976 ] {
14977 assert_eq!(
14978 atn.add_state(kind, Some(rule_index))
14979 .expect("state")
14980 .index(),
14981 state_number
14982 );
14983 }
14984 atn.set_rule_to_start_state(vec![0, 7])
14985 .expect("rule start states");
14986 atn.set_rule_to_stop_state(vec![6, 9])
14987 .expect("rule stop states");
14988 atn.add_decision_state(1).expect("decision state");
14989 atn.set_loop_back_state(4, 3).expect("loop back state");
14990 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14991 .expect("transition");
14992 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14993 .expect("transition");
14994 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
14995 .expect("transition");
14996 atn.add_transition(
14997 2,
14998 ParserTransitionSpec::Rule {
14999 target: 7,
15000 rule_index: 1,
15001 follow_state: 3,
15002 precedence: 0,
15003 },
15004 )
15005 .expect("transition");
15006 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
15007 .expect("transition");
15008 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15009 .expect("transition");
15010 atn.add_transition(
15011 5,
15012 ParserTransitionSpec::Atom {
15013 target: 6,
15014 label: TOKEN_EOF,
15015 },
15016 )
15017 .expect("transition");
15018 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
15019 .expect("transition");
15020 atn.add_transition(
15021 8,
15022 ParserTransitionSpec::Atom {
15023 target: 9,
15024 label: 1,
15025 },
15026 )
15027 .expect("transition");
15028 finish_atn(atn)
15029 }
15030
15031 fn ambiguous_ordinary_star_loop_atn() -> Atn {
15033 let mut atn = ParserAtnBuilder::new(1);
15034 for (state_number, kind) in [
15035 (0, AtnStateKind::RuleStart),
15036 (1, AtnStateKind::StarLoopEntry),
15037 (2, AtnStateKind::StarBlockStart),
15038 (3, AtnStateKind::Basic),
15039 (4, AtnStateKind::BlockEnd),
15040 (5, AtnStateKind::StarLoopBack),
15041 (6, AtnStateKind::LoopEnd),
15042 (7, AtnStateKind::Basic),
15043 (8, AtnStateKind::RuleStop),
15044 ] {
15045 assert_eq!(
15046 atn.add_state(kind, Some(0)).expect("state").index(),
15047 state_number
15048 );
15049 }
15050 atn.set_rule_to_start_state(vec![0])
15051 .expect("rule start states");
15052 atn.set_rule_to_stop_state(vec![8])
15053 .expect("rule stop states");
15054 atn.set_end_state(2, 4).expect("block end state");
15055 atn.set_loop_back_state(6, 5).expect("loop back state");
15056 atn.add_decision_state(1).expect("decision state");
15057 atn.add_decision_state(2).expect("decision state");
15058 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15059 .expect("transition");
15060 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15061 .expect("transition");
15062 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
15063 .expect("transition");
15064 atn.add_transition(
15065 2,
15066 ParserTransitionSpec::Atom {
15067 target: 4,
15068 label: 1,
15069 },
15070 )
15071 .expect("transition");
15072 atn.add_transition(
15073 2,
15074 ParserTransitionSpec::Atom {
15075 target: 3,
15076 label: 1,
15077 },
15078 )
15079 .expect("transition");
15080 atn.add_transition(
15081 3,
15082 ParserTransitionSpec::Atom {
15083 target: 4,
15084 label: 1,
15085 },
15086 )
15087 .expect("transition");
15088 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15089 .expect("transition");
15090 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
15091 .expect("transition");
15092 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15093 .expect("transition");
15094 atn.add_transition(
15095 7,
15096 ParserTransitionSpec::Atom {
15097 target: 8,
15098 label: TOKEN_EOF,
15099 },
15100 )
15101 .expect("transition");
15102 finish_atn(atn)
15103 }
15104
15105 fn ordinary_plus_loop_atn() -> Atn {
15106 let mut atn = ParserAtnBuilder::new(2);
15107 for (state_number, kind, rule_index) in [
15108 (0, AtnStateKind::RuleStart, 0),
15109 (1, AtnStateKind::Basic, 0),
15110 (2, AtnStateKind::PlusLoopBack, 0),
15111 (3, AtnStateKind::LoopEnd, 0),
15112 (4, AtnStateKind::Basic, 0),
15113 (5, AtnStateKind::RuleStop, 0),
15114 (6, AtnStateKind::RuleStart, 1),
15115 (7, AtnStateKind::Basic, 1),
15116 (8, AtnStateKind::RuleStop, 1),
15117 ] {
15118 assert_eq!(
15119 atn.add_state(kind, Some(rule_index))
15120 .expect("state")
15121 .index(),
15122 state_number
15123 );
15124 }
15125 atn.set_rule_to_start_state(vec![0, 6])
15126 .expect("rule start states");
15127 atn.set_rule_to_stop_state(vec![5, 8])
15128 .expect("rule stop states");
15129 atn.add_decision_state(2).expect("decision state");
15130 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15131 .expect("transition");
15132 atn.add_transition(
15133 1,
15134 ParserTransitionSpec::Rule {
15135 target: 6,
15136 rule_index: 1,
15137 follow_state: 2,
15138 precedence: 0,
15139 },
15140 )
15141 .expect("transition");
15142 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
15143 .expect("transition");
15144 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15145 .expect("transition");
15146 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15147 .expect("transition");
15148 atn.add_transition(
15149 4,
15150 ParserTransitionSpec::Atom {
15151 target: 5,
15152 label: TOKEN_EOF,
15153 },
15154 )
15155 .expect("transition");
15156 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15157 .expect("transition");
15158 atn.add_transition(
15159 7,
15160 ParserTransitionSpec::Atom {
15161 target: 8,
15162 label: 1,
15163 },
15164 )
15165 .expect("transition");
15166 finish_atn(atn)
15167 }
15168
15169 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
15170 let mut tokens = (0..count)
15171 .map(|_| TestToken::new(1).with_text("x"))
15172 .collect::<Vec<_>>();
15173 tokens.push(TestToken::eof("parser-test", count, 1, count));
15174 tokens
15175 }
15176
15177 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
15178 let mut atn = ParserAtnBuilder::new(2);
15179 assert_eq!(
15180 atn.add_state(AtnStateKind::RuleStart, Some(0))
15181 .expect("state")
15182 .index(),
15183 0
15184 );
15185 assert_eq!(
15186 atn.add_state(AtnStateKind::Basic, Some(0))
15187 .expect("state")
15188 .index(),
15189 1
15190 );
15191 assert_eq!(
15192 atn.add_state(AtnStateKind::Basic, Some(0))
15193 .expect("state")
15194 .index(),
15195 2
15196 );
15197 assert_eq!(
15198 atn.add_state(AtnStateKind::RuleStart, Some(1))
15199 .expect("state")
15200 .index(),
15201 3
15202 );
15203 atn.set_left_recursive_rule(3)
15204 .expect("left-recursive rule start");
15205 assert_eq!(
15206 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
15207 .expect("state")
15208 .index(),
15209 4
15210 );
15211 atn.set_precedence_rule_decision(4)
15212 .expect("precedence decision");
15213 assert_eq!(
15214 atn.add_state(AtnStateKind::Basic, Some(1))
15215 .expect("state")
15216 .index(),
15217 5
15218 );
15219 assert_eq!(
15220 atn.add_state(AtnStateKind::Basic, Some(1))
15221 .expect("state")
15222 .index(),
15223 6
15224 );
15225 assert_eq!(
15226 atn.add_state(AtnStateKind::LoopEnd, Some(1))
15227 .expect("state")
15228 .index(),
15229 7
15230 );
15231 assert_eq!(
15232 atn.add_state(AtnStateKind::RuleStop, Some(1))
15233 .expect("state")
15234 .index(),
15235 8
15236 );
15237 assert_eq!(
15238 atn.add_state(AtnStateKind::RuleStop, Some(0))
15239 .expect("state")
15240 .index(),
15241 9
15242 );
15243 atn.set_rule_to_start_state(vec![0, 3])
15244 .expect("rule start states");
15245 atn.set_rule_to_stop_state(vec![9, 8])
15246 .expect("rule stop states");
15247 atn.add_transition(
15248 1,
15249 ParserTransitionSpec::Rule {
15250 target: 3,
15251 rule_index: 1,
15252 follow_state: 2,
15253 precedence: 0,
15254 },
15255 )
15256 .expect("transition");
15257 atn.add_transition(
15258 2,
15259 ParserTransitionSpec::Atom {
15260 target: 9,
15261 label: caller_symbol,
15262 },
15263 )
15264 .expect("transition");
15265 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15266 .expect("transition");
15267 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
15268 .expect("transition");
15269 atn.add_transition(
15270 5,
15271 ParserTransitionSpec::Precedence {
15272 target: 6,
15273 precedence: 1,
15274 },
15275 )
15276 .expect("transition");
15277 atn.add_transition(
15278 6,
15279 ParserTransitionSpec::Atom {
15280 target: 4,
15281 label: 1,
15282 },
15283 )
15284 .expect("transition");
15285 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
15286 .expect("transition");
15287 finish_atn(atn)
15288 }
15289
15290 fn labeled_left_recursive_operator_atn() -> Atn {
15291 let mut atn = ParserAtnBuilder::new(4);
15292 for (state, kind) in [
15293 (0, AtnStateKind::RuleStart),
15294 (1, AtnStateKind::BlockStart),
15295 (2, AtnStateKind::StarLoopEntry),
15296 (3, AtnStateKind::StarBlockStart),
15297 (4, AtnStateKind::Basic),
15298 (5, AtnStateKind::Basic),
15299 (6, AtnStateKind::Basic),
15300 (7, AtnStateKind::StarLoopBack),
15301 (8, AtnStateKind::LoopEnd),
15302 (9, AtnStateKind::RuleStop),
15303 ] {
15304 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15305 }
15306 atn.set_left_recursive_rule(0)
15307 .expect("left-recursive rule start");
15308 atn.set_precedence_rule_decision(2)
15309 .expect("precedence decision");
15310 atn.set_loop_back_state(8, 7).expect("loop-back state");
15311 atn.set_rule_to_start_state(vec![0])
15312 .expect("rule start states");
15313 atn.set_rule_to_stop_state(vec![9])
15314 .expect("rule stop states");
15315 for state in [1, 2, 3] {
15316 atn.add_decision_state(state).expect("decision state");
15317 }
15318 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
15319 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
15320 .expect("epsilon transition");
15321 }
15322 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3), (6, 7, 1)] {
15323 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
15324 .expect("token transition");
15325 }
15326 for (target, precedence) in [(4, 2), (5, 1)] {
15327 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
15328 .expect("operator precedence");
15329 }
15330 finish_atn(atn)
15331 }
15332
15333 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
15334 let mut parser = mini_parser(vec![
15335 TestToken::new(symbol).with_text("lookahead"),
15336 TestToken::eof("parser-test", 1, 1, 1),
15337 ]);
15338 parser.rule_context_stack = vec![
15339 RuleContextFrame {
15340 rule_index: 0,
15341 invoking_state: -1,
15342 },
15343 RuleContextFrame {
15344 rule_index: 1,
15345 invoking_state: 1,
15346 },
15347 ];
15348 parser
15349 }
15350
15351 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
15352 let mut atn = ParserAtnBuilder::new(1);
15356 for (state, kind, rule) in [
15357 (0, AtnStateKind::RuleStart, 0),
15358 (1, AtnStateKind::StarLoopEntry, 0),
15359 (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),
15366 (9, AtnStateKind::RuleStop, 0),
15367 ] {
15368 assert_eq!(
15369 atn.add_state(kind, Some(rule)).expect("state").index(),
15370 state
15371 );
15372 if state == 0 {
15373 atn.set_left_recursive_rule(state)
15374 .expect("left-recursive rule start");
15375 } else if state == 1 {
15376 atn.set_precedence_rule_decision(state)
15377 .expect("precedence decision");
15378 }
15379 }
15380 atn.set_rule_to_start_state(vec![0])
15381 .expect("rule start states");
15382 atn.set_rule_to_stop_state(vec![9])
15383 .expect("rule stop states");
15384 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15385 .expect("ops");
15386 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
15387 .expect("exit");
15388 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15389 .expect("to shift");
15390 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15391 .expect("to rel");
15392 atn.add_transition(
15393 3,
15394 ParserTransitionSpec::Precedence {
15395 target: 4,
15396 precedence: 2,
15397 },
15398 )
15399 .expect("shift prec");
15400 atn.add_transition(
15401 4,
15402 ParserTransitionSpec::Atom {
15403 target: 5,
15404 label: 1,
15405 },
15406 )
15407 .expect("shift first >");
15408 atn.add_transition(
15409 5,
15410 ParserTransitionSpec::Atom {
15411 target: 1,
15412 label: 1,
15413 },
15414 )
15415 .expect("shift second >");
15416 atn.add_transition(
15417 6,
15418 ParserTransitionSpec::Precedence {
15419 target: 7,
15420 precedence: 1,
15421 },
15422 )
15423 .expect("rel prec");
15424 atn.add_transition(
15425 7,
15426 ParserTransitionSpec::Atom {
15427 target: 1,
15428 label: 1,
15429 },
15430 )
15431 .expect("rel >");
15432 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15433 .expect("loop end");
15434 finish_atn(atn)
15435 }
15436
15437 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
15438 let mut atn = ParserAtnBuilder::new(2);
15439 for (state, kind, rule) in [
15440 (0, AtnStateKind::RuleStart, 0),
15441 (1, AtnStateKind::StarLoopEntry, 0),
15442 (2, AtnStateKind::Basic, 0),
15443 (3, AtnStateKind::Basic, 0),
15444 (4, AtnStateKind::Basic, 0),
15445 (5, AtnStateKind::Basic, 0),
15446 (6, AtnStateKind::Basic, 0),
15447 (7, AtnStateKind::Basic, 0),
15448 (8, AtnStateKind::LoopEnd, 0),
15449 (9, AtnStateKind::RuleStop, 0),
15450 (10, AtnStateKind::RuleStart, 1),
15451 (11, AtnStateKind::Basic, 1),
15452 (12, AtnStateKind::RuleStop, 1),
15453 ] {
15454 assert_eq!(
15455 atn.add_state(kind, Some(rule)).expect("state").index(),
15456 state
15457 );
15458 if state == 0 {
15459 atn.set_left_recursive_rule(state)
15460 .expect("left-recursive rule start");
15461 } else if state == 1 {
15462 atn.set_precedence_rule_decision(state)
15463 .expect("precedence decision");
15464 }
15465 }
15466 atn.set_rule_to_start_state(vec![0, 10])
15467 .expect("rule start states");
15468 atn.set_rule_to_stop_state(vec![9, 12])
15469 .expect("rule stop states");
15470 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15471 .expect("ops");
15472 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
15473 .expect("exit");
15474 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15475 .expect("to shift");
15476 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15477 .expect("to relational");
15478 atn.add_transition(
15479 3,
15480 ParserTransitionSpec::Precedence {
15481 target: 4,
15482 precedence: 2,
15483 },
15484 )
15485 .expect("shift precedence");
15486 atn.add_transition(
15487 4,
15488 ParserTransitionSpec::Rule {
15489 target: 10,
15490 rule_index: 1,
15491 follow_state: 5,
15492 precedence: 0,
15493 },
15494 )
15495 .expect("first shift token helper");
15496 atn.add_transition(
15497 5,
15498 ParserTransitionSpec::Atom {
15499 target: 1,
15500 label: 1,
15501 },
15502 )
15503 .expect("second shift token");
15504 atn.add_transition(
15505 6,
15506 ParserTransitionSpec::Precedence {
15507 target: 7,
15508 precedence: 1,
15509 },
15510 )
15511 .expect("relational precedence");
15512 atn.add_transition(
15513 7,
15514 ParserTransitionSpec::Atom {
15515 target: 1,
15516 label: 1,
15517 },
15518 )
15519 .expect("relational token");
15520 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15521 .expect("loop end");
15522 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
15523 .expect("helper entry");
15524 atn.add_transition(
15525 11,
15526 ParserTransitionSpec::Atom {
15527 target: 12,
15528 label: 1,
15529 },
15530 )
15531 .expect("first shift token");
15532 finish_atn(atn)
15533 }
15534
15535 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
15536 let mut atn = ParserAtnBuilder::new(1);
15537 for (state, kind) in [
15538 (0, AtnStateKind::RuleStart),
15539 (1, AtnStateKind::StarLoopEntry),
15540 (2, AtnStateKind::Basic),
15541 (3, AtnStateKind::Basic),
15542 (4, AtnStateKind::Basic),
15543 (5, AtnStateKind::Basic),
15544 (6, AtnStateKind::Basic),
15545 (7, AtnStateKind::Basic),
15546 (8, AtnStateKind::Basic),
15547 (9, AtnStateKind::LoopEnd),
15548 (10, AtnStateKind::RuleStop),
15549 ] {
15550 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15551 if state == 0 {
15552 atn.set_left_recursive_rule(state)
15553 .expect("left-recursive rule start");
15554 } else if state == 1 {
15555 atn.set_precedence_rule_decision(state)
15556 .expect("precedence decision");
15557 }
15558 }
15559 atn.set_rule_to_start_state(vec![0])
15560 .expect("rule start states");
15561 atn.set_rule_to_stop_state(vec![10])
15562 .expect("rule stop states");
15563 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15564 .expect("ops");
15565 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
15566 .expect("exit");
15567 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15568 .expect("to multi-token operator");
15569 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15570 .expect("to predicate operator");
15571 atn.add_transition(
15572 3,
15573 ParserTransitionSpec::Precedence {
15574 target: 4,
15575 precedence: 2,
15576 },
15577 )
15578 .expect("multi-token precedence");
15579 atn.add_transition(
15580 4,
15581 ParserTransitionSpec::Atom {
15582 target: 5,
15583 label: 1,
15584 },
15585 )
15586 .expect("multi-token first");
15587 atn.add_transition(
15588 5,
15589 ParserTransitionSpec::Atom {
15590 target: 1,
15591 label: 1,
15592 },
15593 )
15594 .expect("multi-token second");
15595 atn.add_transition(
15596 6,
15597 ParserTransitionSpec::Precedence {
15598 target: 7,
15599 precedence: 2,
15600 },
15601 )
15602 .expect("predicate precedence");
15603 atn.add_transition(
15604 7,
15605 ParserTransitionSpec::Predicate {
15606 target: 8,
15607 rule_index: 0,
15608 pred_index: 0,
15609 context_dependent: false,
15610 },
15611 )
15612 .expect("operator predicate");
15613 atn.add_transition(
15614 8,
15615 ParserTransitionSpec::Atom {
15616 target: 1,
15617 label: 1,
15618 },
15619 )
15620 .expect("predicate single token");
15621 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15622 .expect("loop end");
15623 finish_atn(atn)
15624 }
15625
15626 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
15627 let mut atn = ParserAtnBuilder::new(2);
15628 for (state, kind, rule) in [
15629 (0, AtnStateKind::RuleStart, 0),
15630 (1, AtnStateKind::StarLoopEntry, 0),
15631 (2, AtnStateKind::Basic, 0),
15632 (3, AtnStateKind::Basic, 0),
15633 (4, AtnStateKind::Basic, 0),
15634 (5, AtnStateKind::LoopEnd, 0),
15635 (6, AtnStateKind::RuleStop, 0),
15636 (7, AtnStateKind::RuleStart, 1),
15637 (8, AtnStateKind::RuleStop, 1),
15638 (9, AtnStateKind::Basic, 1),
15639 ] {
15640 assert_eq!(
15641 atn.add_state(kind, Some(rule)).expect("state").index(),
15642 state
15643 );
15644 if state == 0 {
15645 atn.set_left_recursive_rule(state)
15646 .expect("left-recursive rule start");
15647 } else if state == 1 {
15648 atn.set_precedence_rule_decision(state)
15649 .expect("precedence decision");
15650 }
15651 }
15652 atn.set_rule_to_start_state(vec![0, 7])
15653 .expect("rule start states");
15654 atn.set_rule_to_stop_state(vec![6, 8])
15655 .expect("rule stop states");
15656 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15657 .expect("transition");
15658 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
15659 .expect("transition");
15660 atn.add_transition(
15661 2,
15662 ParserTransitionSpec::Precedence {
15663 target: 3,
15664 precedence: 3,
15665 },
15666 )
15667 .expect("transition");
15668 atn.add_transition(
15669 3,
15670 ParserTransitionSpec::Rule {
15671 target: 7,
15672 rule_index: 1,
15673 follow_state: 4,
15674 precedence: 0,
15675 },
15676 )
15677 .expect("transition");
15678 atn.add_transition(
15679 4,
15680 ParserTransitionSpec::Atom {
15681 target: 1,
15682 label: 1,
15683 },
15684 )
15685 .expect("transition");
15686 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15687 .expect("transition");
15688 atn.add_transition(
15689 7,
15690 ParserTransitionSpec::Precedence {
15691 target: 9,
15692 precedence: 1,
15693 },
15694 )
15695 .expect("transition");
15696 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
15697 .expect("transition");
15698 finish_atn(atn)
15699 }
15700
15701 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
15702 let mut atn = ParserAtnBuilder::new(2);
15703 for (state, kind) in [
15704 (0, AtnStateKind::RuleStart),
15705 (1, AtnStateKind::StarLoopEntry),
15706 (2, AtnStateKind::Basic),
15707 (3, AtnStateKind::Basic),
15708 (4, AtnStateKind::Basic),
15709 (5, AtnStateKind::LoopEnd),
15710 (6, AtnStateKind::RuleStop),
15711 ] {
15712 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15713 if state == 0 {
15714 atn.set_left_recursive_rule(state)
15715 .expect("left-recursive rule start");
15716 } else if state == 1 {
15717 atn.set_precedence_rule_decision(state)
15718 .expect("precedence decision");
15719 }
15720 }
15721 atn.set_rule_to_start_state(vec![0])
15722 .expect("rule start states");
15723 atn.set_rule_to_stop_state(vec![6])
15724 .expect("rule stop states");
15725 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15726 .expect("transition");
15727 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
15728 .expect("transition");
15729 atn.add_transition(
15730 2,
15731 ParserTransitionSpec::Precedence {
15732 target: 3,
15733 precedence: 1,
15734 },
15735 )
15736 .expect("transition");
15737 atn.add_transition(
15738 3,
15739 ParserTransitionSpec::Predicate {
15740 target: 4,
15741 rule_index: 0,
15742 pred_index: 0,
15743 context_dependent: false,
15744 },
15745 )
15746 .expect("transition");
15747 atn.add_transition(
15748 4,
15749 ParserTransitionSpec::Atom {
15750 target: 1,
15751 label: 1,
15752 },
15753 )
15754 .expect("transition");
15755 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15756 .expect("transition");
15757 finish_atn(atn)
15758 }
15759
15760 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
15761 let mut atn = ParserAtnBuilder::new(2);
15762 for (state, kind, rule) in [
15763 (0, AtnStateKind::RuleStart, 0),
15764 (1, AtnStateKind::Basic, 0),
15765 (2, AtnStateKind::Basic, 0),
15766 (3, AtnStateKind::Basic, 0),
15767 (4, AtnStateKind::RuleStop, 0),
15768 (5, AtnStateKind::RuleStart, 1),
15769 (6, AtnStateKind::StarLoopEntry, 1),
15770 (7, AtnStateKind::Basic, 1),
15771 (8, AtnStateKind::Basic, 1),
15772 (9, AtnStateKind::LoopEnd, 1),
15773 (10, AtnStateKind::RuleStop, 1),
15774 (11, AtnStateKind::RuleStart, 2),
15775 (12, AtnStateKind::RuleStop, 2),
15776 ] {
15777 assert_eq!(
15778 atn.add_state(kind, Some(rule)).expect("state").index(),
15779 state
15780 );
15781 if state == 5 {
15782 atn.set_left_recursive_rule(state)
15783 .expect("left-recursive rule start");
15784 } else if state == 6 {
15785 atn.set_precedence_rule_decision(state)
15786 .expect("precedence decision");
15787 }
15788 }
15789 atn.set_rule_to_start_state(vec![0, 5, 11])
15790 .expect("rule start states");
15791 atn.set_rule_to_stop_state(vec![4, 10, 12])
15792 .expect("rule stop states");
15793 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15794 .expect("transition");
15795 atn.add_transition(
15796 1,
15797 ParserTransitionSpec::Rule {
15798 target: 5,
15799 rule_index: 1,
15800 follow_state: 2,
15801 precedence: 0,
15802 },
15803 )
15804 .expect("transition");
15805 atn.add_transition(
15806 2,
15807 ParserTransitionSpec::Rule {
15808 target: 11,
15809 rule_index: 2,
15810 follow_state: 3,
15811 precedence: 0,
15812 },
15813 )
15814 .expect("transition");
15815 atn.add_transition(
15816 3,
15817 ParserTransitionSpec::Atom {
15818 target: 4,
15819 label: caller_symbol,
15820 },
15821 )
15822 .expect("transition");
15823 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15824 .expect("transition");
15825 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
15826 .expect("transition");
15827 atn.add_transition(
15828 7,
15829 ParserTransitionSpec::Precedence {
15830 target: 8,
15831 precedence: 1,
15832 },
15833 )
15834 .expect("transition");
15835 atn.add_transition(
15836 8,
15837 ParserTransitionSpec::Atom {
15838 target: 6,
15839 label: 1,
15840 },
15841 )
15842 .expect("transition");
15843 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15844 .expect("transition");
15845 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
15846 .expect("transition");
15847 finish_atn(atn)
15848 }
15849
15850 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
15851 let mut atn = ParserAtnBuilder::new(2);
15852 for (state, kind, rule) in [
15853 (0, AtnStateKind::RuleStart, 0),
15854 (1, AtnStateKind::Basic, 0),
15855 (2, AtnStateKind::Basic, 0),
15856 (3, AtnStateKind::RuleStop, 0),
15857 (4, AtnStateKind::RuleStart, 1),
15858 (5, AtnStateKind::Basic, 1),
15859 (6, AtnStateKind::Basic, 1),
15860 (7, AtnStateKind::RuleStop, 1),
15861 (8, AtnStateKind::RuleStart, 2),
15862 (9, AtnStateKind::StarLoopEntry, 2),
15863 (10, AtnStateKind::Basic, 2),
15864 (11, AtnStateKind::Basic, 2),
15865 (12, AtnStateKind::LoopEnd, 2),
15866 (13, AtnStateKind::RuleStop, 2),
15867 ] {
15868 assert_eq!(
15869 atn.add_state(kind, Some(rule)).expect("state").index(),
15870 state
15871 );
15872 if state == 8 {
15873 atn.set_left_recursive_rule(state)
15874 .expect("left-recursive rule start");
15875 } else if state == 9 {
15876 atn.set_precedence_rule_decision(state)
15877 .expect("precedence decision");
15878 }
15879 }
15880 atn.set_rule_to_start_state(vec![0, 4, 8])
15881 .expect("rule start states");
15882 atn.set_rule_to_stop_state(vec![3, 7, 13])
15883 .expect("rule stop states");
15884 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15885 .expect("transition");
15886 atn.add_transition(
15887 1,
15888 ParserTransitionSpec::Rule {
15889 target: 4,
15890 rule_index: 1,
15891 follow_state: 2,
15892 precedence: 0,
15893 },
15894 )
15895 .expect("transition");
15896 atn.add_transition(
15897 2,
15898 ParserTransitionSpec::Atom {
15899 target: 3,
15900 label: caller_symbol,
15901 },
15902 )
15903 .expect("transition");
15904 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15905 .expect("transition");
15906 atn.add_transition(
15907 5,
15908 ParserTransitionSpec::Rule {
15909 target: 8,
15910 rule_index: 2,
15911 follow_state: 6,
15912 precedence: 0,
15913 },
15914 )
15915 .expect("transition");
15916 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15917 .expect("transition");
15918 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15919 .expect("transition");
15920 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
15921 .expect("transition");
15922 atn.add_transition(
15923 10,
15924 ParserTransitionSpec::Precedence {
15925 target: 11,
15926 precedence: 1,
15927 },
15928 )
15929 .expect("transition");
15930 atn.add_transition(
15931 11,
15932 ParserTransitionSpec::Atom {
15933 target: 9,
15934 label: 1,
15935 },
15936 )
15937 .expect("transition");
15938 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
15939 .expect("transition");
15940 finish_atn(atn)
15941 }
15942
15943 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
15944 let mut atn = ParserAtnBuilder::new(2);
15945 for (state, kind, rule) in [
15946 (0, AtnStateKind::RuleStart, 0),
15947 (1, AtnStateKind::Basic, 0),
15948 (2, AtnStateKind::Basic, 0),
15949 (3, AtnStateKind::RuleStop, 0),
15950 (4, AtnStateKind::RuleStart, 1),
15951 (5, AtnStateKind::StarLoopEntry, 1),
15952 (6, AtnStateKind::Basic, 1),
15953 (7, AtnStateKind::Basic, 1),
15954 (8, AtnStateKind::Basic, 1),
15955 (9, AtnStateKind::Basic, 1),
15956 (10, AtnStateKind::LoopEnd, 1),
15957 (11, AtnStateKind::RuleStop, 1),
15958 ] {
15959 assert_eq!(
15960 atn.add_state(kind, Some(rule)).expect("state").index(),
15961 state
15962 );
15963 if state == 4 {
15964 atn.set_left_recursive_rule(state)
15965 .expect("left-recursive rule start");
15966 } else if state == 5 {
15967 atn.set_precedence_rule_decision(state)
15968 .expect("precedence decision");
15969 }
15970 }
15971 atn.set_rule_to_start_state(vec![0, 4])
15972 .expect("rule start states");
15973 atn.set_rule_to_stop_state(vec![3, 11])
15974 .expect("rule stop states");
15975 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15976 .expect("transition");
15977 atn.add_transition(
15978 1,
15979 ParserTransitionSpec::Rule {
15980 target: 4,
15981 rule_index: 1,
15982 follow_state: 2,
15983 precedence: 0,
15984 },
15985 )
15986 .expect("transition");
15987 atn.add_transition(
15988 2,
15989 ParserTransitionSpec::Atom {
15990 target: 3,
15991 label: caller_symbol,
15992 },
15993 )
15994 .expect("transition");
15995 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15996 .expect("transition");
15997 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
15998 .expect("transition");
15999 atn.add_transition(
16000 6,
16001 ParserTransitionSpec::Precedence {
16002 target: 7,
16003 precedence: 1,
16004 },
16005 )
16006 .expect("transition");
16007 atn.add_transition(
16008 7,
16009 ParserTransitionSpec::Atom {
16010 target: 8,
16011 label: 1,
16012 },
16013 )
16014 .expect("transition");
16015 atn.add_transition(
16016 8,
16017 ParserTransitionSpec::Rule {
16018 target: 4,
16019 rule_index: 1,
16020 follow_state: 9,
16021 precedence: 2,
16022 },
16023 )
16024 .expect("transition");
16025 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
16026 .expect("transition");
16027 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
16028 .expect("transition");
16029 finish_atn(atn)
16030 }
16031
16032 #[test]
16033 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
16034 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
16035 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
16036
16037 let mut overlapping = parser_inside_left_recursive_callee(1);
16038 assert_eq!(
16039 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
16040 None
16041 );
16042
16043 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
16044 assert_eq!(
16045 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
16046 Some(true)
16047 );
16048
16049 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
16050 assert_eq!(
16051 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
16052 Some(false)
16053 );
16054
16055 assert_eq!(
16056 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
16057 Some(true),
16058 "overlap results must not leak across ATNs"
16059 );
16060 }
16061
16062 #[test]
16063 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
16064 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
16065 let mut parser = mini_parser(vec![
16066 TestToken::new(1).with_text("operator"),
16067 TestToken::eof("parser-test", 1, 1, 1),
16068 ]);
16069 parser.rule_context_stack = vec![RuleContextFrame {
16070 rule_index: 0,
16071 invoking_state: -1,
16072 }];
16073
16074 assert_eq!(
16075 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16076 Some(true)
16077 );
16078 assert_eq!(
16079 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16080 Some(true),
16081 "cached operator lookahead must preserve the nullable prefix return path"
16082 );
16083 assert_eq!(
16084 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16085 Some(true),
16086 "the nullable child must use its rule-call precedence, not the caller precedence"
16087 );
16088 }
16089
16090 #[test]
16091 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
16092 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
16097 let mut parser = mini_parser(vec![
16098 TestToken::new(1).with_text(">"),
16099 TestToken::new(2).with_text("id"),
16100 TestToken::eof("parser-test", 1, 1, 1),
16101 ]);
16102 parser.rule_context_stack = vec![RuleContextFrame {
16103 rule_index: 0,
16104 invoking_state: -1,
16105 }];
16106
16107 assert_eq!(
16108 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16109 Some(true),
16110 "at low precedence relational `>` is a single-token operator"
16111 );
16112 assert_eq!(
16113 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
16114 Some(true),
16115 "relational remains single-token at its own precedence"
16116 );
16117 assert_eq!(
16118 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16119 None,
16120 "at shift precedence, bare `>` must not force enter"
16121 );
16122 }
16123
16124 #[test]
16125 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
16126 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
16127 let mut parser = mini_parser(vec![
16128 TestToken::new(1).with_text(">"),
16129 TestToken::new(2).with_text("id"),
16130 TestToken::eof("parser-test", 1, 1, 1),
16131 ]);
16132 parser.rule_context_stack = vec![RuleContextFrame {
16133 rule_index: 0,
16134 invoking_state: -1,
16135 }];
16136
16137 assert_eq!(
16138 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16139 Some(true),
16140 "the direct relational alternative remains a one-token operator"
16141 );
16142 assert_eq!(
16143 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16144 None,
16145 "a token matched in the helper rule must return to the second shift token"
16146 );
16147 }
16148
16149 #[test]
16150 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
16151 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
16152 let mut parser = mini_parser(vec![
16153 TestToken::new(1).with_text(">"),
16154 TestToken::new(2).with_text("id"),
16155 TestToken::eof("parser-test", 1, 1, 1),
16156 ]);
16157 parser.rule_context_stack = vec![RuleContextFrame {
16158 rule_index: 0,
16159 invoking_state: -1,
16160 }];
16161
16162 assert_eq!(
16163 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16164 None,
16165 "a predicate-gated single-token path must not be hidden by a multi-token path"
16166 );
16167 }
16168
16169 #[test]
16170 fn left_recursive_loop_defers_predicate_guarded_operator() {
16171 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
16172 let mut parser = mini_parser_with_hooks(
16173 vec![
16174 TestToken::new(1).with_text("operator"),
16175 TestToken::eof("parser-test", 1, 1, 1),
16176 ],
16177 RejectingPredicateHooks::default(),
16178 );
16179 parser.rule_context_stack = vec![RuleContextFrame {
16180 rule_index: 0,
16181 invoking_state: -1,
16182 }];
16183
16184 assert_eq!(
16185 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16186 None,
16187 "a false predicate must be evaluated before entering the operator alternative"
16188 );
16189 assert_eq!(
16190 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16191 None,
16192 "cached predicate-dependent lookahead must keep deferring"
16193 );
16194 }
16195
16196 #[test]
16197 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
16198 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
16199 let mut parser = parser_inside_left_recursive_callee(1);
16200
16201 assert_eq!(
16202 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
16203 None
16204 );
16205 assert_eq!(
16206 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
16207 None,
16208 "the cached overlap must preserve the nullable child return path"
16209 );
16210 }
16211
16212 #[test]
16213 fn left_recursive_loop_defers_through_nullable_parent_return() {
16214 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
16215 let mut parser = mini_parser(vec![
16216 TestToken::new(1).with_text("lookahead"),
16217 TestToken::eof("parser-test", 1, 1, 1),
16218 ]);
16219 parser.rule_context_stack = vec![
16220 RuleContextFrame {
16221 rule_index: 0,
16222 invoking_state: -1,
16223 },
16224 RuleContextFrame {
16225 rule_index: 1,
16226 invoking_state: 1,
16227 },
16228 RuleContextFrame {
16229 rule_index: 2,
16230 invoking_state: 5,
16231 },
16232 ];
16233
16234 assert_eq!(
16235 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
16236 None,
16237 "a nullable caller must unwind to its parent's consuming follow path"
16238 );
16239 assert_eq!(
16240 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
16241 None,
16242 "the caller-overlap cache must not retain a false negative"
16243 );
16244 }
16245
16246 #[test]
16247 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
16248 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
16249 let mut parser = mini_parser(vec![
16250 TestToken::new(1).with_text("lookahead"),
16251 TestToken::eof("parser-test", 1, 1, 1),
16252 ]);
16253 parser.rule_context_stack = vec![
16254 RuleContextFrame {
16255 rule_index: 0,
16256 invoking_state: -1,
16257 },
16258 RuleContextFrame {
16259 rule_index: 1,
16260 invoking_state: 1,
16261 },
16262 RuleContextFrame {
16263 rule_index: 1,
16264 invoking_state: 8,
16265 },
16266 ];
16267
16268 assert_eq!(
16269 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
16270 None,
16271 "a recursive operand return must preserve its parent caller context"
16272 );
16273 assert_eq!(
16274 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
16275 None,
16276 "the caller-overlap cache must preserve the loop-boundary return"
16277 );
16278 }
16279
16280 fn token_then_eof_atn() -> Atn {
16281 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16282 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, ]))
16298 .deserialize_parser()
16299 .expect("artificial parser ATN should deserialize")
16300 }
16301
16302 fn epsilon_cycle_atn() -> Atn {
16303 let mut atn = ParserAtnBuilder::new(1);
16304 for (state_number, kind) in [
16305 (0, AtnStateKind::RuleStart),
16306 (1, AtnStateKind::Basic),
16307 (2, AtnStateKind::RuleStop),
16308 ] {
16309 assert_eq!(
16310 atn.add_state(kind, Some(0)).expect("state").index(),
16311 state_number
16312 );
16313 }
16314 atn.set_rule_to_start_state(vec![0])
16315 .expect("rule start states");
16316 atn.set_rule_to_stop_state(vec![2])
16317 .expect("rule stop states");
16318 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16319 .expect("transition");
16320 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
16321 .expect("self-cycle transition");
16322 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16323 .expect("exit transition");
16324 finish_atn(atn)
16325 }
16326
16327 fn committed_non_consuming_cycle_atn() -> Atn {
16328 let mut atn = ParserAtnBuilder::new(1);
16329 for (state_number, kind) in [
16330 (0, AtnStateKind::RuleStart),
16331 (1, AtnStateKind::Basic),
16332 (2, AtnStateKind::RuleStop),
16333 ] {
16334 assert_eq!(
16335 atn.add_state(kind, Some(0)).expect("state").index(),
16336 state_number
16337 );
16338 }
16339 atn.set_rule_to_start_state(vec![0])
16340 .expect("rule start states");
16341 atn.set_rule_to_stop_state(vec![2])
16342 .expect("rule stop states");
16343 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16344 .expect("cycle entry");
16345 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
16346 .expect("self-cycle transition");
16347 finish_atn(atn)
16348 }
16349
16350 fn eof_then_action_atn() -> Atn {
16351 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16352 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, ]))
16368 .deserialize_parser()
16369 .expect("artificial parser ATN should deserialize")
16370 }
16371
16372 fn noop_action_then_token_then_eof_atn() -> Atn {
16373 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16374 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, ]))
16392 .deserialize_parser()
16393 .expect("artificial no-op action ATN should deserialize")
16394 }
16395
16396 fn committed_action_then_predicate_atn() -> Atn {
16397 let mut atn = ParserAtnBuilder::new(1);
16398 for (state_number, kind) in [
16399 (0, AtnStateKind::RuleStart),
16400 (1, AtnStateKind::Basic),
16401 (2, AtnStateKind::Basic),
16402 (3, AtnStateKind::Basic),
16403 (4, AtnStateKind::RuleStop),
16404 ] {
16405 assert_eq!(
16406 atn.add_state(kind, Some(0)).expect("state").index(),
16407 state_number
16408 );
16409 }
16410 atn.set_rule_to_start_state(vec![0])
16411 .expect("rule start states");
16412 atn.set_rule_to_stop_state(vec![4])
16413 .expect("rule stop states");
16414 atn.add_transition(
16415 0,
16416 ParserTransitionSpec::Action {
16417 target: 1,
16418 rule_index: 0,
16419 action_index: None,
16420 context_dependent: false,
16421 },
16422 )
16423 .expect("action transition");
16424 atn.add_transition(
16425 1,
16426 ParserTransitionSpec::Predicate {
16427 target: 2,
16428 rule_index: 0,
16429 pred_index: 0,
16430 context_dependent: false,
16431 },
16432 )
16433 .expect("predicate transition");
16434 atn.add_transition(
16435 2,
16436 ParserTransitionSpec::Atom {
16437 target: 3,
16438 label: 1,
16439 },
16440 )
16441 .expect("token transition");
16442 atn.add_transition(
16443 3,
16444 ParserTransitionSpec::Atom {
16445 target: 4,
16446 label: TOKEN_EOF,
16447 },
16448 )
16449 .expect("EOF transition");
16450 finish_atn(atn)
16451 }
16452
16453 fn parameterized_child_action_eof_atn() -> Atn {
16455 let mut atn = ParserAtnBuilder::new(1);
16456 for (state_number, kind, rule_index) in [
16457 (0, AtnStateKind::RuleStart, 0),
16458 (1, AtnStateKind::Basic, 0),
16459 (2, AtnStateKind::Basic, 0),
16460 (3, AtnStateKind::RuleStop, 0),
16461 (4, AtnStateKind::RuleStart, 1),
16462 (5, AtnStateKind::Basic, 1),
16463 (6, AtnStateKind::RuleStop, 1),
16464 ] {
16465 assert_eq!(
16466 atn.add_state(kind, Some(rule_index))
16467 .expect("state")
16468 .index(),
16469 state_number
16470 );
16471 }
16472 atn.set_rule_to_start_state(vec![0, 4])
16473 .expect("rule start states");
16474 atn.set_rule_to_stop_state(vec![3, 6])
16475 .expect("rule stop states");
16476 atn.add_transition(
16477 0,
16478 ParserTransitionSpec::Rule {
16479 target: 4,
16480 rule_index: 1,
16481 follow_state: 1,
16482 precedence: 0,
16483 },
16484 )
16485 .expect("parameterized child call");
16486 atn.add_transition(
16487 1,
16488 ParserTransitionSpec::Action {
16489 target: 2,
16490 rule_index: 0,
16491 action_index: None,
16492 context_dependent: false,
16493 },
16494 )
16495 .expect("parent action");
16496 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
16497 .expect("parent stop");
16498 atn.add_transition(
16499 4,
16500 ParserTransitionSpec::Action {
16501 target: 5,
16502 rule_index: 1,
16503 action_index: None,
16504 context_dependent: false,
16505 },
16506 )
16507 .expect("child action");
16508 atn.add_transition(
16509 5,
16510 ParserTransitionSpec::Atom {
16511 target: 6,
16512 label: TOKEN_EOF,
16513 },
16514 )
16515 .expect("child EOF");
16516 finish_atn(atn)
16517 }
16518
16519 fn action_then_nested_rule_atn() -> Atn {
16520 let mut atn = ParserAtnBuilder::new(1);
16521 for (state_number, kind, rule_index) in [
16522 (0, AtnStateKind::RuleStart, 0),
16523 (1, AtnStateKind::Basic, 0),
16524 (2, AtnStateKind::Basic, 0),
16525 (3, AtnStateKind::RuleStop, 0),
16526 (4, AtnStateKind::RuleStart, 1),
16527 (5, AtnStateKind::RuleStop, 1),
16528 ] {
16529 assert_eq!(
16530 atn.add_state(kind, Some(rule_index))
16531 .expect("state")
16532 .index(),
16533 state_number
16534 );
16535 }
16536 atn.set_rule_to_start_state(vec![0, 4])
16537 .expect("rule start states");
16538 atn.set_rule_to_stop_state(vec![3, 5])
16539 .expect("rule stop states");
16540 atn.add_transition(
16541 0,
16542 ParserTransitionSpec::Action {
16543 target: 1,
16544 rule_index: 0,
16545 action_index: None,
16546 context_dependent: false,
16547 },
16548 )
16549 .expect("parent action");
16550 atn.add_transition(
16551 1,
16552 ParserTransitionSpec::Rule {
16553 target: 4,
16554 rule_index: 1,
16555 follow_state: 2,
16556 precedence: 0,
16557 },
16558 )
16559 .expect("nested rule call");
16560 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
16561 .expect("parent stop");
16562 atn.add_transition(
16563 4,
16564 ParserTransitionSpec::Atom {
16565 target: 5,
16566 label: TOKEN_EOF,
16567 },
16568 )
16569 .expect("child EOF");
16570 finish_atn(atn)
16571 }
16572
16573 fn losing_alternative_action_atn() -> Atn {
16574 let mut atn = ParserAtnBuilder::new(2);
16575 for (state_number, kind) in [
16576 (0, AtnStateKind::RuleStart),
16577 (1, AtnStateKind::BlockStart),
16578 (2, AtnStateKind::Basic),
16579 (3, AtnStateKind::Basic),
16580 (4, AtnStateKind::BlockEnd),
16581 (5, AtnStateKind::RuleStop),
16582 ] {
16583 assert_eq!(
16584 atn.add_state(kind, Some(0)).expect("state").index(),
16585 state_number
16586 );
16587 }
16588 atn.set_rule_to_start_state(vec![0])
16589 .expect("rule start states");
16590 atn.set_rule_to_stop_state(vec![5])
16591 .expect("rule stop states");
16592 atn.set_end_state(1, 4).expect("block end state");
16593 atn.add_decision_state(1).expect("decision state");
16594 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16595 .expect("entry transition");
16596 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16597 .expect("first alternative");
16598 atn.add_transition(
16599 1,
16600 ParserTransitionSpec::Atom {
16601 target: 4,
16602 label: 2,
16603 },
16604 )
16605 .expect("second alternative");
16606 atn.add_transition(
16607 2,
16608 ParserTransitionSpec::Action {
16609 target: 3,
16610 rule_index: 0,
16611 action_index: None,
16612 context_dependent: false,
16613 },
16614 )
16615 .expect("losing action");
16616 atn.add_transition(
16617 3,
16618 ParserTransitionSpec::Atom {
16619 target: 4,
16620 label: 1,
16621 },
16622 )
16623 .expect("first alternative token");
16624 atn.add_transition(
16625 4,
16626 ParserTransitionSpec::Atom {
16627 target: 5,
16628 label: TOKEN_EOF,
16629 },
16630 )
16631 .expect("EOF transition");
16632 finish_atn(atn)
16633 }
16634
16635 fn committed_action_star_loop_atn() -> Atn {
16636 let mut atn = ParserAtnBuilder::new(1);
16637 for (state_number, kind) in [
16638 (0, AtnStateKind::RuleStart),
16639 (1, AtnStateKind::StarLoopEntry),
16640 (2, AtnStateKind::Basic),
16641 (3, AtnStateKind::Basic),
16642 (4, AtnStateKind::StarLoopBack),
16643 (5, AtnStateKind::LoopEnd),
16644 (6, AtnStateKind::RuleStop),
16645 ] {
16646 assert_eq!(
16647 atn.add_state(kind, Some(0)).expect("state").index(),
16648 state_number
16649 );
16650 }
16651 atn.set_rule_to_start_state(vec![0])
16652 .expect("rule start states");
16653 atn.set_rule_to_stop_state(vec![6])
16654 .expect("rule stop states");
16655 atn.add_decision_state(1).expect("decision state");
16656 atn.set_loop_back_state(5, 4).expect("loop back state");
16657 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16658 .expect("entry transition");
16659 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16660 .expect("loop body");
16661 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
16662 .expect("loop exit");
16663 atn.add_transition(
16664 2,
16665 ParserTransitionSpec::Action {
16666 target: 3,
16667 rule_index: 0,
16668 action_index: None,
16669 context_dependent: false,
16670 },
16671 )
16672 .expect("loop action");
16673 atn.add_transition(
16674 3,
16675 ParserTransitionSpec::Atom {
16676 target: 4,
16677 label: 1,
16678 },
16679 )
16680 .expect("loop token");
16681 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
16682 .expect("loop back");
16683 atn.add_transition(
16684 5,
16685 ParserTransitionSpec::Atom {
16686 target: 6,
16687 label: TOKEN_EOF,
16688 },
16689 )
16690 .expect("EOF transition");
16691 finish_atn(atn)
16692 }
16693
16694 fn committed_action_left_recursive_atn() -> Atn {
16695 let mut atn = ParserAtnBuilder::new(4);
16696 for (state, kind) in [
16697 (0, AtnStateKind::RuleStart),
16698 (1, AtnStateKind::BlockStart),
16699 (2, AtnStateKind::StarLoopEntry),
16700 (3, AtnStateKind::StarBlockStart),
16701 (4, AtnStateKind::Basic),
16702 (5, AtnStateKind::Basic),
16703 (6, AtnStateKind::Basic),
16704 (7, AtnStateKind::StarLoopBack),
16705 (8, AtnStateKind::LoopEnd),
16706 (9, AtnStateKind::RuleStop),
16707 (10, AtnStateKind::Basic),
16708 ] {
16709 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
16710 }
16711 atn.set_left_recursive_rule(0)
16712 .expect("left-recursive rule start");
16713 atn.set_precedence_rule_decision(2)
16714 .expect("precedence decision");
16715 atn.set_loop_back_state(8, 7).expect("loop-back state");
16716 atn.set_rule_to_start_state(vec![0])
16717 .expect("rule start states");
16718 atn.set_rule_to_stop_state(vec![9])
16719 .expect("rule stop states");
16720 for state in [1, 2, 3] {
16721 atn.add_decision_state(state).expect("decision state");
16722 }
16723 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
16724 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
16725 .expect("epsilon transition");
16726 }
16727 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3)] {
16728 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
16729 .expect("token transition");
16730 }
16731 for (target, precedence) in [(4, 2), (5, 1)] {
16732 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
16733 .expect("operator precedence");
16734 }
16735 atn.add_transition(
16736 6,
16737 ParserTransitionSpec::Action {
16738 target: 10,
16739 rule_index: 0,
16740 action_index: None,
16741 context_dependent: false,
16742 },
16743 )
16744 .expect("operator action");
16745 atn.add_transition(
16746 10,
16747 ParserTransitionSpec::Atom {
16748 target: 7,
16749 label: 1,
16750 },
16751 )
16752 .expect("right operand");
16753 finish_atn(atn)
16754 }
16755
16756 fn two_alt_decision_atn() -> Atn {
16757 let mut atn = ParserAtnBuilder::new(2);
16758 assert_eq!(
16759 atn.add_state(AtnStateKind::RuleStart, Some(0))
16760 .expect("state")
16761 .index(),
16762 0
16763 );
16764 assert_eq!(
16765 atn.add_state(AtnStateKind::BlockStart, Some(0))
16766 .expect("state")
16767 .index(),
16768 1
16769 );
16770 assert_eq!(
16771 atn.add_state(AtnStateKind::Basic, Some(0))
16772 .expect("state")
16773 .index(),
16774 2
16775 );
16776 assert_eq!(
16777 atn.add_state(AtnStateKind::Basic, Some(0))
16778 .expect("state")
16779 .index(),
16780 3
16781 );
16782 assert_eq!(
16783 atn.add_state(AtnStateKind::BlockEnd, Some(0))
16784 .expect("state")
16785 .index(),
16786 4
16787 );
16788 assert_eq!(
16789 atn.add_state(AtnStateKind::RuleStop, Some(0))
16790 .expect("state")
16791 .index(),
16792 5
16793 );
16794 atn.set_rule_to_start_state(vec![0])
16795 .expect("rule start states");
16796 atn.set_rule_to_stop_state(vec![5])
16797 .expect("rule stop states");
16798 atn.add_decision_state(1).expect("decision state");
16799 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16800 .expect("transition");
16801 atn.add_transition(
16802 1,
16803 ParserTransitionSpec::Atom {
16804 target: 2,
16805 label: 1,
16806 },
16807 )
16808 .expect("transition");
16809 atn.add_transition(
16810 1,
16811 ParserTransitionSpec::Atom {
16812 target: 3,
16813 label: 2,
16814 },
16815 )
16816 .expect("transition");
16817 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
16818 .expect("transition");
16819 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
16820 .expect("transition");
16821 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
16822 .expect("transition");
16823 finish_atn(atn)
16824 }
16825
16826 fn optional_then_b_eof_atn() -> Atn {
16829 let mut atn = ParserAtnBuilder::new(3);
16830 assert_eq!(
16831 atn.add_state(AtnStateKind::RuleStart, Some(0))
16832 .expect("state")
16833 .index(),
16834 0
16835 );
16836 assert_eq!(
16837 atn.add_state(AtnStateKind::BlockStart, Some(0))
16838 .expect("state")
16839 .index(),
16840 1
16841 );
16842 assert_eq!(
16843 atn.add_state(AtnStateKind::Basic, Some(0))
16844 .expect("state")
16845 .index(),
16846 2
16847 );
16848 assert_eq!(
16849 atn.add_state(AtnStateKind::Basic, Some(0))
16850 .expect("state")
16851 .index(),
16852 3
16853 );
16854 assert_eq!(
16855 atn.add_state(AtnStateKind::Basic, Some(0))
16856 .expect("state")
16857 .index(),
16858 4
16859 );
16860 assert_eq!(
16861 atn.add_state(AtnStateKind::RuleStop, Some(0))
16862 .expect("state")
16863 .index(),
16864 5
16865 );
16866 atn.set_rule_to_start_state(vec![0])
16867 .expect("rule start states");
16868 atn.set_rule_to_stop_state(vec![5])
16869 .expect("rule stop states");
16870 atn.add_decision_state(1).expect("decision state");
16871 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16872 .expect("transition");
16873 atn.add_transition(
16875 1,
16876 ParserTransitionSpec::Atom {
16877 target: 3,
16878 label: 1,
16879 },
16880 )
16881 .expect("transition");
16882 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
16883 .expect("transition");
16884 atn.add_transition(
16886 3,
16887 ParserTransitionSpec::Atom {
16888 target: 4,
16889 label: 2,
16890 },
16891 )
16892 .expect("transition");
16893 atn.add_transition(
16894 4,
16895 ParserTransitionSpec::Atom {
16896 target: 5,
16897 label: TOKEN_EOF,
16898 },
16899 )
16900 .expect("transition");
16901 finish_atn(atn)
16902 }
16903
16904 #[test]
16905 fn sync_decision_deletes_only_a_single_token() {
16906 let atn = optional_then_b_eof_atn();
16914
16915 let mut single = mini_parser(vec![
16916 TestToken::new(3).with_text("c"),
16917 TestToken::new(2).with_text("b"),
16918 TestToken::eof("parser-test", 1, 2, 2),
16919 ]);
16920 single.rule_context_stack = vec![RuleContextFrame {
16921 rule_index: 0,
16922 invoking_state: 0,
16923 }];
16924 let children = single
16925 .sync_decision(&atn, 1, true, false)
16926 .expect("single extraneous token recovers");
16927 assert_eq!(children.len(), 1);
16928 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
16929 assert_eq!(single.number_of_syntax_errors(), 1);
16930 assert_eq!(single.la(1), 2);
16932
16933 let mut double = mini_parser(vec![
16934 TestToken::new(3).with_text("c"),
16935 TestToken::new(3).with_text("c"),
16936 TestToken::new(2).with_text("b"),
16937 TestToken::eof("parser-test", 1, 3, 3),
16938 ]);
16939 double.rule_context_stack = vec![RuleContextFrame {
16940 rule_index: 0,
16941 invoking_state: 0,
16942 }];
16943 let result = double.sync_decision(&atn, 1, true, false);
16944 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
16949 match error {
16950 AntlrError::ParserError { message, .. } => {
16951 assert!(message.starts_with("mismatched input"), "got: {message}");
16952 }
16953 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
16954 }
16955 assert_eq!(double.la(1), 3);
16956 }
16957
16958 fn star_loop_then_eof_atn() -> Atn {
16962 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16963 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,
16964 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,
16965 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,
16966 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
16967 ]))
16968 .deserialize_parser()
16969 .expect("star-loop-then-EOF ATN should deserialize")
16970 }
16971
16972 fn nested_star_rule_atn() -> Atn {
16976 let mut atn = ParserAtnBuilder::new(2);
16977 for (state_number, kind, rule_index) in [
16978 (0, AtnStateKind::RuleStart, 0),
16979 (1, AtnStateKind::Basic, 0),
16980 (2, AtnStateKind::Basic, 0),
16981 (3, AtnStateKind::RuleStop, 0),
16982 (4, AtnStateKind::RuleStart, 1),
16983 (5, AtnStateKind::StarLoopEntry, 1),
16984 (6, AtnStateKind::Basic, 1),
16985 (7, AtnStateKind::StarLoopBack, 1),
16986 (8, AtnStateKind::LoopEnd, 1),
16987 (9, AtnStateKind::RuleStop, 1),
16988 ] {
16989 assert_eq!(
16990 atn.add_state(kind, Some(rule_index))
16991 .expect("state")
16992 .index(),
16993 state_number
16994 );
16995 }
16996 atn.set_rule_to_start_state(vec![0, 4])
16997 .expect("rule start states");
16998 atn.set_rule_to_stop_state(vec![3, 9])
16999 .expect("rule stop states");
17000 atn.add_decision_state(5).expect("decision state");
17001 atn.set_loop_back_state(8, 7).expect("loop back state");
17002 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17003 .expect("transition");
17004 atn.add_transition(
17005 1,
17006 ParserTransitionSpec::Rule {
17007 target: 4,
17008 rule_index: 1,
17009 follow_state: 2,
17010 precedence: 0,
17011 },
17012 )
17013 .expect("transition");
17014 atn.add_transition(
17015 2,
17016 ParserTransitionSpec::Atom {
17017 target: 3,
17018 label: TOKEN_EOF,
17019 },
17020 )
17021 .expect("transition");
17022 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
17023 .expect("transition");
17024 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
17025 .expect("transition");
17026 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 8 })
17027 .expect("transition");
17028 atn.add_transition(
17029 6,
17030 ParserTransitionSpec::Atom {
17031 target: 7,
17032 label: 1,
17033 },
17034 )
17035 .expect("transition");
17036 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 5 })
17037 .expect("transition");
17038 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17039 .expect("transition");
17040 finish_atn(atn)
17041 }
17042
17043 fn plus_loop_with_recovering_body_atn() -> Atn {
17049 let mut atn = ParserAtnBuilder::new(2);
17050 assert_eq!(
17051 atn.add_state(AtnStateKind::RuleStart, Some(0))
17052 .expect("state")
17053 .index(),
17054 0
17055 );
17056 assert_eq!(
17057 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
17058 .expect("state")
17059 .index(),
17060 1
17061 );
17062 assert_eq!(
17063 atn.add_state(AtnStateKind::Basic, Some(0))
17064 .expect("state")
17065 .index(),
17066 2
17067 );
17068 assert_eq!(
17069 atn.add_state(AtnStateKind::BlockEnd, Some(0))
17070 .expect("state")
17071 .index(),
17072 3
17073 );
17074 assert_eq!(
17075 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
17076 .expect("state")
17077 .index(),
17078 4
17079 );
17080 assert_eq!(
17081 atn.add_state(AtnStateKind::LoopEnd, Some(0))
17082 .expect("state")
17083 .index(),
17084 5
17085 );
17086 assert_eq!(
17087 atn.add_state(AtnStateKind::RuleStop, Some(0))
17088 .expect("state")
17089 .index(),
17090 6
17091 );
17092 assert_eq!(
17093 atn.add_state(AtnStateKind::RuleStart, Some(1))
17094 .expect("state")
17095 .index(),
17096 7
17097 );
17098 assert_eq!(
17099 atn.add_state(AtnStateKind::Basic, Some(1))
17100 .expect("state")
17101 .index(),
17102 8
17103 );
17104 assert_eq!(
17105 atn.add_state(AtnStateKind::RuleStop, Some(1))
17106 .expect("state")
17107 .index(),
17108 9
17109 );
17110 atn.set_rule_to_start_state(vec![0, 7])
17111 .expect("rule start states");
17112 atn.set_rule_to_stop_state(vec![6, 9])
17113 .expect("rule stop states");
17114 atn.set_end_state(1, 3).expect("block end state");
17115 atn.set_loop_back_state(5, 4).expect("loop back state");
17116 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17117 .expect("transition");
17118 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17119 .expect("transition");
17120 atn.add_transition(
17121 2,
17122 ParserTransitionSpec::Rule {
17123 target: 7,
17124 rule_index: 1,
17125 follow_state: 3,
17126 precedence: 0,
17127 },
17128 )
17129 .expect("transition");
17130 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
17131 .expect("transition");
17132 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
17133 .expect("transition");
17134 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
17135 .expect("transition");
17136 atn.add_transition(
17137 5,
17138 ParserTransitionSpec::Atom {
17139 target: 6,
17140 label: 2,
17141 },
17142 )
17143 .expect("transition");
17144 atn.add_transition(
17145 7,
17146 ParserTransitionSpec::Atom {
17147 target: 8,
17148 label: 1,
17149 },
17150 )
17151 .expect("transition");
17152 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17153 .expect("transition");
17154 finish_atn(atn)
17155 }
17156
17157 #[test]
17158 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
17159 let atn = plus_loop_with_recovering_body_atn();
17160 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17161
17162 let error = parser
17163 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17164 .expect_err("EOF recovery should report a bounded mismatch");
17165
17166 let AntlrError::ParserError { message, .. } = error else {
17167 panic!("expected ParserError, got {error:?}");
17168 };
17169 insta::assert_snapshot!(message, @"mismatched input '<EOF>' expecting {'x', 2}");
17170 assert_eq!(parser.number_of_syntax_errors(), 1);
17171 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
17172 }
17173
17174 #[test]
17175 fn sync_decision_deletes_token_before_eof_at_loop_back() {
17176 let atn = star_loop_then_eof_atn();
17182 let mut parser = mini_parser(vec![
17183 TestToken::new(2).with_text("c"),
17184 TestToken::eof("parser-test", 1, 1, 1),
17185 ]);
17186 parser.rule_context_stack = vec![RuleContextFrame {
17187 rule_index: 0,
17188 invoking_state: 0,
17189 }];
17190 let children = parser
17191 .sync_decision(&atn, 5, true, false)
17192 .expect("single token before EOF recovers");
17193 assert_eq!(children.len(), 1);
17194 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
17195 assert_eq!(parser.number_of_syntax_errors(), 1);
17196 assert_eq!(
17197 parser.la(1),
17198 TOKEN_EOF,
17199 "EOF is left for the rule's EOF match"
17200 );
17201 }
17202
17203 #[test]
17204 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
17205 let atn = star_loop_then_eof_atn();
17210 let mut parser = mini_parser(vec![
17211 TestToken::new(2).with_text("c"),
17212 TestToken::new(2).with_text("c"),
17213 TestToken::eof("parser-test", 1, 2, 2),
17214 ]);
17215 parser.rule_context_stack = vec![RuleContextFrame {
17216 rule_index: 0,
17217 invoking_state: 0,
17218 }];
17219 let error = parser
17220 .sync_decision(&atn, 5, true, false)
17221 .expect_err("two tokens at the loop entry must not be deleted");
17222 match error {
17223 AntlrError::ParserError { message, .. } => {
17224 assert!(message.starts_with("mismatched input"), "got: {message}");
17225 }
17226 other => panic!("expected mismatched-input ParserError, got {other:?}"),
17227 }
17228 assert_eq!(
17229 parser.la(1),
17230 2,
17231 "nothing consumed; cursor still on first `c`"
17232 );
17233 }
17234
17235 #[test]
17236 fn sync_decision_consumes_until_eof_at_loop_back() {
17237 let atn = star_loop_then_eof_atn();
17243 let mut parser = mini_parser(vec![
17244 TestToken::new(2).with_text("c"),
17245 TestToken::new(2).with_text("c"),
17246 TestToken::eof("parser-test", 1, 2, 2),
17247 ]);
17248 parser.rule_context_stack = vec![RuleContextFrame {
17249 rule_index: 0,
17250 invoking_state: 0,
17251 }];
17252 let children = parser
17253 .sync_decision(&atn, 5, false, true)
17254 .expect("loop-back multi-token deletion recovers onto EOF");
17255 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
17256 assert!(
17257 children
17258 .iter()
17259 .all(|child| parser.node(*child).kind() == NodeKind::Error)
17260 );
17261 assert_eq!(parser.number_of_syntax_errors(), 1);
17262 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
17263 }
17264
17265 #[test]
17266 fn sync_decision_returns_before_recovery_for_nullable_exit() {
17267 let atn = nested_star_rule_atn();
17268 for (current_context_empty, loop_back) in [(true, false), (false, true)] {
17269 let mut parser = mini_parser(vec![
17270 TestToken::new(2).with_text("c"),
17271 TestToken::new(1).with_text("a"),
17272 TestToken::eof("parser-test", 1, 2, 2),
17273 ]);
17274 parser.rule_context_stack = vec![
17275 RuleContextFrame {
17276 rule_index: 0,
17277 invoking_state: 0,
17278 },
17279 RuleContextFrame {
17280 rule_index: 1,
17281 invoking_state: 1,
17282 },
17283 ];
17284
17285 let children = parser
17286 .sync_decision(&atn, 5, current_context_empty, loop_back)
17287 .expect("nullable synchronization is a no-op");
17288
17289 assert!(children.is_empty());
17290 assert_eq!(parser.la(1), 2, "the caller must receive the current token");
17291 assert_eq!(parser.number_of_syntax_errors(), 0);
17292 assert_eq!(
17293 parser
17294 .generated_sync_expected
17295 .as_ref()
17296 .expect("nullable sync preserves expected symbols")
17297 .to_btree_set(),
17298 BTreeSet::from([TOKEN_EOF, 1])
17299 );
17300 }
17301 }
17302
17303 fn predicate_after_token_atn() -> Atn {
17304 let mut atn = ParserAtnBuilder::new(2);
17305 assert_eq!(
17306 atn.add_state(AtnStateKind::RuleStart, Some(0))
17307 .expect("state")
17308 .index(),
17309 0
17310 );
17311 assert_eq!(
17312 atn.add_state(AtnStateKind::Basic, Some(0))
17313 .expect("state")
17314 .index(),
17315 1
17316 );
17317 assert_eq!(
17318 atn.add_state(AtnStateKind::Basic, Some(0))
17319 .expect("state")
17320 .index(),
17321 2
17322 );
17323 assert_eq!(
17324 atn.add_state(AtnStateKind::Basic, Some(0))
17325 .expect("state")
17326 .index(),
17327 3
17328 );
17329 assert_eq!(
17330 atn.add_state(AtnStateKind::RuleStop, Some(0))
17331 .expect("state")
17332 .index(),
17333 4
17334 );
17335 atn.set_rule_to_start_state(vec![0])
17336 .expect("rule start states");
17337 atn.set_rule_to_stop_state(vec![4])
17338 .expect("rule stop states");
17339 atn.add_transition(
17340 0,
17341 ParserTransitionSpec::Atom {
17342 target: 1,
17343 label: 1,
17344 },
17345 )
17346 .expect("transition");
17347 atn.add_transition(
17348 1,
17349 ParserTransitionSpec::Predicate {
17350 target: 2,
17351 rule_index: 0,
17352 pred_index: 0,
17353 context_dependent: false,
17354 },
17355 )
17356 .expect("transition");
17357 atn.add_transition(
17358 2,
17359 ParserTransitionSpec::Atom {
17360 target: 3,
17361 label: 2,
17362 },
17363 )
17364 .expect("transition");
17365 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
17366 .expect("transition");
17367 finish_atn(atn)
17368 }
17369
17370 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
17371 let mut atn = ParserAtnBuilder::new(1);
17372 for (state_number, kind) in [
17373 (0, AtnStateKind::RuleStart),
17374 (1, AtnStateKind::BlockStart),
17375 (2, AtnStateKind::Basic),
17376 (3, AtnStateKind::Basic),
17377 (4, AtnStateKind::Basic),
17378 (5, AtnStateKind::Basic),
17379 (6, AtnStateKind::BlockEnd),
17380 (7, AtnStateKind::RuleStop),
17381 ] {
17382 assert_eq!(
17383 atn.add_state(kind, Some(0)).expect("state").index(),
17384 state_number
17385 );
17386 }
17387 atn.set_rule_to_start_state(vec![0])
17388 .expect("rule start states");
17389 atn.set_rule_to_stop_state(vec![7])
17390 .expect("rule stop states");
17391 atn.add_decision_state(1).expect("decision state");
17392 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17393 .expect("transition");
17394 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17395 .expect("transition");
17396 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17397 .expect("transition");
17398 atn.add_transition(
17399 2,
17400 ParserTransitionSpec::Predicate {
17401 target: 4,
17402 rule_index: 0,
17403 pred_index: pred_indexes[0],
17404 context_dependent: false,
17405 },
17406 )
17407 .expect("transition");
17408 atn.add_transition(
17409 3,
17410 ParserTransitionSpec::Predicate {
17411 target: 5,
17412 rule_index: 0,
17413 pred_index: pred_indexes[1],
17414 context_dependent: false,
17415 },
17416 )
17417 .expect("transition");
17418 atn.add_transition(
17419 4,
17420 ParserTransitionSpec::Atom {
17421 target: 6,
17422 label: 1,
17423 },
17424 )
17425 .expect("transition");
17426 atn.add_transition(
17427 5,
17428 ParserTransitionSpec::Atom {
17429 target: 6,
17430 label: 1,
17431 },
17432 )
17433 .expect("transition");
17434 atn.add_transition(
17435 6,
17436 ParserTransitionSpec::Atom {
17437 target: 7,
17438 label: TOKEN_EOF,
17439 },
17440 )
17441 .expect("transition");
17442 finish_atn(atn)
17443 }
17444
17445 fn context_containment_recovery_atn() -> Atn {
17450 context_containment_test_atn(
17451 Some(6),
17452 ParserTransitionSpec::Atom {
17453 target: 7,
17454 label: TOKEN_EOF,
17455 },
17456 )
17457 }
17458
17459 fn semantic_fallback_viability_atn() -> Atn {
17461 let mut atn = ParserAtnBuilder::new(3);
17462 for (state_number, kind) in [
17463 (0, AtnStateKind::RuleStart),
17464 (1, AtnStateKind::BlockStart),
17465 (2, AtnStateKind::Basic),
17466 (3, AtnStateKind::Basic),
17467 (4, AtnStateKind::Basic),
17468 (5, AtnStateKind::Basic),
17469 (6, AtnStateKind::Basic),
17470 (7, AtnStateKind::Basic),
17471 (8, AtnStateKind::Basic),
17472 (9, AtnStateKind::BlockEnd),
17473 (10, AtnStateKind::RuleStop),
17474 ] {
17475 assert_eq!(
17476 atn.add_state(kind, Some(0)).expect("state").index(),
17477 state_number
17478 );
17479 }
17480 atn.set_rule_to_start_state(vec![0])
17481 .expect("rule start states");
17482 atn.set_rule_to_stop_state(vec![10])
17483 .expect("rule stop states");
17484 atn.set_end_state(1, 9).expect("block end state");
17485 atn.add_decision_state(1).expect("decision state");
17486 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17487 .expect("entry transition");
17488 atn.add_transition(
17489 1,
17490 ParserTransitionSpec::Atom {
17491 target: 2,
17492 label: 1,
17493 },
17494 )
17495 .expect("first alternative");
17496 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17497 .expect("second alternative");
17498 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
17499 .expect("third alternative");
17500 atn.add_transition(
17501 2,
17502 ParserTransitionSpec::Atom {
17503 target: 9,
17504 label: 2,
17505 },
17506 )
17507 .expect("first alternative suffix");
17508 for (source, target, pred_index) in [(3, 4, 0), (6, 7, 1)] {
17509 atn.add_transition(
17510 source,
17511 ParserTransitionSpec::Predicate {
17512 target,
17513 rule_index: 0,
17514 pred_index,
17515 context_dependent: false,
17516 },
17517 )
17518 .expect("predicate transition");
17519 }
17520 for (source, target, label) in [(4, 5, 1), (5, 9, 3), (7, 8, 1), (8, 9, 3)] {
17521 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
17522 .expect("predicate alternative token");
17523 }
17524 atn.add_transition(
17525 9,
17526 ParserTransitionSpec::Atom {
17527 target: 10,
17528 label: TOKEN_EOF,
17529 },
17530 )
17531 .expect("EOF transition");
17532 finish_atn(atn)
17533 }
17534
17535 fn rule_call_predicate_decision_atn() -> Atn {
17537 let mut atn = ParserAtnBuilder::new(1);
17538 for (state_number, kind, rule_index) in [
17539 (0, AtnStateKind::RuleStart, 0),
17540 (1, AtnStateKind::BlockStart, 0),
17541 (2, AtnStateKind::Basic, 0),
17542 (3, AtnStateKind::Basic, 0),
17543 (4, AtnStateKind::BlockEnd, 0),
17544 (5, AtnStateKind::RuleStop, 0),
17545 (6, AtnStateKind::RuleStart, 1),
17546 (7, AtnStateKind::Basic, 1),
17547 (8, AtnStateKind::RuleStop, 1),
17548 ] {
17549 assert_eq!(
17550 atn.add_state(kind, Some(rule_index))
17551 .expect("state")
17552 .index(),
17553 state_number
17554 );
17555 }
17556 atn.set_rule_to_start_state(vec![0, 6])
17557 .expect("rule start states");
17558 atn.set_rule_to_stop_state(vec![5, 8])
17559 .expect("rule stop states");
17560 atn.set_end_state(1, 4).expect("block end state");
17561 atn.add_decision_state(1).expect("decision state");
17562 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17563 .expect("entry transition");
17564 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17565 .expect("gated alternative entry");
17566 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17567 .expect("direct alternative entry");
17568 atn.add_transition(
17569 2,
17570 ParserTransitionSpec::Rule {
17571 target: 6,
17572 rule_index: 1,
17573 follow_state: 4,
17574 precedence: 0,
17575 },
17576 )
17577 .expect("gated alternative");
17578 atn.add_transition(
17579 3,
17580 ParserTransitionSpec::Atom {
17581 target: 4,
17582 label: 1,
17583 },
17584 )
17585 .expect("direct alternative");
17586 atn.add_transition(
17587 4,
17588 ParserTransitionSpec::Atom {
17589 target: 5,
17590 label: TOKEN_EOF,
17591 },
17592 )
17593 .expect("EOF transition");
17594 atn.add_transition(
17595 6,
17596 ParserTransitionSpec::Predicate {
17597 target: 7,
17598 rule_index: 1,
17599 pred_index: 0,
17600 context_dependent: false,
17601 },
17602 )
17603 .expect("callee predicate");
17604 atn.add_transition(
17605 7,
17606 ParserTransitionSpec::Atom {
17607 target: 8,
17608 label: 1,
17609 },
17610 )
17611 .expect("callee token");
17612 finish_atn(atn)
17613 }
17614
17615 fn predicate_gated_star_loop_atn() -> Atn {
17617 let mut atn = ParserAtnBuilder::new(2);
17618 for (state_number, kind) in [
17619 (0, AtnStateKind::RuleStart),
17620 (1, AtnStateKind::StarLoopEntry),
17621 (2, AtnStateKind::Basic),
17622 (3, AtnStateKind::Basic),
17623 (4, AtnStateKind::StarLoopBack),
17624 (5, AtnStateKind::LoopEnd),
17625 (6, AtnStateKind::RuleStop),
17626 ] {
17627 assert_eq!(
17628 atn.add_state(kind, Some(0)).expect("state").index(),
17629 state_number
17630 );
17631 }
17632 atn.set_rule_to_start_state(vec![0])
17633 .expect("rule start states");
17634 atn.set_rule_to_stop_state(vec![6])
17635 .expect("rule stop states");
17636 atn.add_decision_state(1).expect("decision state");
17637 atn.set_loop_back_state(5, 4).expect("loop back state");
17638 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17639 .expect("entry transition");
17640 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17641 .expect("loop enter");
17642 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
17643 .expect("loop exit");
17644 atn.add_transition(
17645 2,
17646 ParserTransitionSpec::Predicate {
17647 target: 3,
17648 rule_index: 0,
17649 pred_index: 0,
17650 context_dependent: false,
17651 },
17652 )
17653 .expect("loop predicate");
17654 atn.add_transition(
17655 3,
17656 ParserTransitionSpec::Atom {
17657 target: 4,
17658 label: 1,
17659 },
17660 )
17661 .expect("loop token");
17662 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
17663 .expect("loop back");
17664 atn.add_transition(
17665 5,
17666 ParserTransitionSpec::Atom {
17667 target: 6,
17668 label: TOKEN_EOF,
17669 },
17670 )
17671 .expect("EOF transition");
17672 finish_atn(atn)
17673 }
17674
17675 fn nested_nullable_context_atn() -> Atn {
17676 let mut atn = ParserAtnBuilder::new(1);
17677 for state_number in 0..=20 {
17678 let kind = match state_number {
17679 0 | 10 | 16 => AtnStateKind::RuleStart,
17680 9 | 15 | 20 => AtnStateKind::RuleStop,
17681 _ => AtnStateKind::Basic,
17682 };
17683 let rule_index = match state_number {
17684 0..=9 => 0,
17685 10..=15 => 1,
17686 _ => 2,
17687 };
17688 assert_eq!(
17689 atn.add_state(kind, Some(rule_index))
17690 .expect("state")
17691 .index(),
17692 state_number
17693 );
17694 }
17695 atn.set_rule_to_start_state(vec![0, 10, 16])
17696 .expect("rule start states");
17697 atn.set_rule_to_stop_state(vec![9, 15, 20])
17698 .expect("rule stop states");
17699 atn.add_transition(
17700 1,
17701 ParserTransitionSpec::Rule {
17702 target: 10,
17703 rule_index: 1,
17704 follow_state: 8,
17705 precedence: 0,
17706 },
17707 )
17708 .expect("transition");
17709 atn.add_transition(
17710 8,
17711 ParserTransitionSpec::Atom {
17712 target: 9,
17713 label: 1,
17714 },
17715 )
17716 .expect("transition");
17717 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17718 .expect("transition");
17719 atn.add_transition(
17720 2,
17721 ParserTransitionSpec::Rule {
17722 target: 16,
17723 rule_index: 2,
17724 follow_state: 14,
17725 precedence: 0,
17726 },
17727 )
17728 .expect("transition");
17729 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
17730 .expect("transition");
17731 finish_atn(atn)
17732 }
17733
17734 fn tail_call_context_atn() -> Atn {
17735 let mut atn = ParserAtnBuilder::new(1);
17736 for (kind, rule_index) in [
17737 (AtnStateKind::RuleStart, 0),
17738 (AtnStateKind::Basic, 0),
17739 (AtnStateKind::Basic, 0),
17740 (AtnStateKind::RuleStop, 0),
17741 (AtnStateKind::RuleStart, 1),
17742 (AtnStateKind::Basic, 1),
17743 (AtnStateKind::RuleStop, 1),
17744 (AtnStateKind::RuleStart, 2),
17745 (AtnStateKind::RuleStop, 2),
17746 ] {
17747 atn.add_state(kind, Some(rule_index)).expect("state");
17748 }
17749 atn.set_rule_to_start_state(vec![0, 4, 7])
17750 .expect("rule starts");
17751 atn.set_rule_to_stop_state(vec![3, 6, 8])
17752 .expect("rule stops");
17753 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17754 .expect("outer entry");
17755 atn.add_transition(
17756 1,
17757 ParserTransitionSpec::Rule {
17758 target: 4,
17759 rule_index: 1,
17760 follow_state: 2,
17761 precedence: 0,
17762 },
17763 )
17764 .expect("non-tail outer call");
17765 atn.add_transition(
17766 2,
17767 ParserTransitionSpec::Atom {
17768 target: 3,
17769 label: 1,
17770 },
17771 )
17772 .expect("observable outer continuation");
17773 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
17774 .expect("middle entry");
17775 atn.add_transition(
17776 5,
17777 ParserTransitionSpec::Rule {
17778 target: 7,
17779 rule_index: 2,
17780 follow_state: 6,
17781 precedence: 0,
17782 },
17783 )
17784 .expect("tail middle call");
17785 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
17786 .expect("inner body");
17787 finish_atn(atn)
17788 }
17789
17790 fn generated_match_recovery_atn() -> Atn {
17791 let mut atn = ParserAtnBuilder::new(2);
17792 assert_eq!(
17793 atn.add_state(AtnStateKind::RuleStart, Some(0))
17794 .expect("state")
17795 .index(),
17796 0
17797 );
17798 assert_eq!(
17799 atn.add_state(AtnStateKind::Basic, Some(0))
17800 .expect("state")
17801 .index(),
17802 1
17803 );
17804 assert_eq!(
17805 atn.add_state(AtnStateKind::Basic, Some(0))
17806 .expect("state")
17807 .index(),
17808 2
17809 );
17810 assert_eq!(
17811 atn.add_state(AtnStateKind::RuleStop, Some(0))
17812 .expect("state")
17813 .index(),
17814 3
17815 );
17816 assert_eq!(
17817 atn.add_state(AtnStateKind::RuleStart, Some(1))
17818 .expect("state")
17819 .index(),
17820 4
17821 );
17822 assert_eq!(
17823 atn.add_state(AtnStateKind::RuleStop, Some(1))
17824 .expect("state")
17825 .index(),
17826 5
17827 );
17828 atn.set_rule_to_start_state(vec![0, 4])
17829 .expect("rule start states");
17830 atn.set_rule_to_stop_state(vec![3, 5])
17831 .expect("rule stop states");
17832 atn.add_transition(
17833 1,
17834 ParserTransitionSpec::Rule {
17835 target: 4,
17836 rule_index: 1,
17837 follow_state: 2,
17838 precedence: 0,
17839 },
17840 )
17841 .expect("transition");
17842 atn.add_transition(
17843 2,
17844 ParserTransitionSpec::Atom {
17845 target: 3,
17846 label: TOKEN_EOF,
17847 },
17848 )
17849 .expect("transition");
17850 finish_atn(atn)
17851 }
17852
17853 fn complement_set_atn() -> Atn {
17854 let mut atn = ParserAtnBuilder::new(1);
17855 assert_eq!(
17856 atn.add_state(AtnStateKind::RuleStart, Some(0))
17857 .expect("state")
17858 .index(),
17859 0
17860 );
17861 assert_eq!(
17862 atn.add_state(AtnStateKind::RuleStop, Some(0))
17863 .expect("state")
17864 .index(),
17865 1
17866 );
17867 atn.set_rule_to_start_state(vec![0])
17868 .expect("rule start states");
17869 atn.set_rule_to_stop_state(vec![1])
17870 .expect("rule stop states");
17871 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
17872 atn.add_transition(
17873 0,
17874 ParserTransitionSpec::NotSet {
17875 target: 1,
17876 set: excluded,
17877 },
17878 )
17879 .expect("transition");
17880 finish_atn(atn)
17881 }
17882
17883 fn wildcard_then_eof_atn() -> Atn {
17886 let mut atn = ParserAtnBuilder::new(1);
17887 assert_eq!(
17888 atn.add_state(AtnStateKind::RuleStart, Some(0))
17889 .expect("state")
17890 .index(),
17891 0
17892 );
17893 assert_eq!(
17894 atn.add_state(AtnStateKind::RuleStop, Some(0))
17895 .expect("state")
17896 .index(),
17897 1
17898 );
17899 assert_eq!(
17900 atn.add_state(AtnStateKind::Basic, Some(0))
17901 .expect("state")
17902 .index(),
17903 2
17904 );
17905 atn.set_rule_to_start_state(vec![0])
17906 .expect("rule start states");
17907 atn.set_rule_to_stop_state(vec![1])
17908 .expect("rule stop states");
17909 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
17910 .expect("transition");
17911 atn.add_transition(
17912 2,
17913 ParserTransitionSpec::Atom {
17914 target: 1,
17915 label: TOKEN_EOF,
17916 },
17917 )
17918 .expect("transition");
17919 finish_atn(atn)
17920 }
17921
17922 #[test]
17923 fn parser_matches_token_and_reports_mismatch() {
17924 let source = Source {
17925 tokens: vec![
17926 TestToken::new(1).with_text("x"),
17927 TestToken::eof("parser-test", 1, 1, 1),
17928 ],
17929 index: 0,
17930 };
17931 let data = RecognizerData::new(
17932 "Mini.g4",
17933 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17934 );
17935 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17936 let matched = parser.match_token(1).expect("token 1 should match");
17937 assert_eq!(parser.node(matched).text(), "x");
17938 assert!(parser.match_token(1).is_err());
17939 }
17940
17941 #[test]
17942 fn parser_matches_token_sets() {
17943 let mut parser = mini_parser(vec![
17944 TestToken::new(1).with_text("x"),
17945 TestToken::eof("parser-test", 1, 1, 1),
17946 ]);
17947
17948 let matched = parser
17949 .match_set(&[(1, 1), (3, 4)])
17950 .expect("token set should match");
17951 assert_eq!(parser.node(matched).text(), "x");
17952 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
17953 }
17954
17955 #[test]
17956 fn generated_rule_api_tracks_state_and_precedence() {
17957 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17958
17959 let context = parser.enter_rule(7, 2);
17960 assert_eq!(context.rule_index(), 2);
17961 assert_eq!(parser.state(), 7);
17962 assert_eq!(
17963 parser.rule_context_stack,
17964 vec![RuleContextFrame {
17965 rule_index: 2,
17966 invoking_state: 7
17967 }]
17968 );
17969
17970 let recursive = parser.enter_recursion_rule(11, 3, 4);
17971 assert_eq!(recursive.rule_index(), 3);
17972 assert!(parser.precpred(4));
17973 assert!(parser.precpred(5));
17974 assert!(!parser.precpred(3));
17975
17976 let next = parser.push_new_recursion_context(13, 3);
17977 assert_eq!(next.invoking_state(), 13);
17978 parser.unroll_recursion_context();
17979 assert_eq!(parser.precedence_stack, vec![0]);
17980 assert_eq!(
17981 parser.rule_context_stack,
17982 vec![RuleContextFrame {
17983 rule_index: 2,
17984 invoking_state: 7
17985 }]
17986 );
17987
17988 parser.exit_rule();
17989 assert!(parser.rule_context_stack.is_empty());
17990 }
17991
17992 #[test]
17993 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
17994 let mut parser = mini_parser(vec![
17995 TestToken::new(1).with_text("x"),
17996 TestToken::eof("parser-test", 1, 1, 1),
17997 ]);
17998 let matched = parser.match_token(1).expect("token should match");
17999 assert_eq!(parser.node(matched).text(), "x");
18000 parser.record_generated_syntax_error();
18001 parser.set_int_member(7, 11);
18002 parser.set_build_parse_trees(false);
18003 parser.set_report_diagnostic_errors(true);
18004 parser.set_prediction_mode(PredictionMode::Sll);
18005 parser.set_bail_on_error(true);
18006 let _context = parser.enter_recursion_rule(9, 0, 4);
18007 parser.pending_invoking_states.push(5);
18008 parser.unknown_predicate_hits.push((0, 1));
18009 parser.unhandled_action_hits.push((0, 2));
18010
18011 parser.reset();
18012
18013 assert_eq!(parser.input.index(), 0);
18014 assert_eq!(parser.la(1), 1);
18015 assert_eq!(parser.state(), -1);
18016 assert_eq!(parser.number_of_syntax_errors(), 0);
18017 assert_eq!(parser.parse_tree_storage().node_count(), 0);
18018 assert!(parser.rule_context_stack.is_empty());
18019 assert!(parser.pending_invoking_states.is_empty());
18020 assert_eq!(parser.precedence_stack, [0]);
18021 assert!(parser.unknown_predicate_hits.is_empty());
18022 assert!(parser.unhandled_action_hits.is_empty());
18023 assert_eq!(parser.int_member(7), Some(11));
18024 assert!(!parser.build_parse_trees());
18025 assert!(parser.report_diagnostic_errors());
18026 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
18027 assert!(parser.bail_on_error());
18028 }
18029
18030 #[test]
18031 fn set_token_stream_replaces_input_and_resets_parser() {
18032 let mut parser = mini_parser(vec![
18033 TestToken::new(1).with_text("old"),
18034 TestToken::eof("parser-test", 1, 1, 1),
18035 ]);
18036 parser.consume();
18037 parser.record_generated_syntax_error();
18038 let replacement = CommonTokenStream::new(Source {
18039 tokens: vec![
18040 TestToken::new(2).with_text("new"),
18041 TestToken::eof("parser-test", 1, 1, 1),
18042 ],
18043 index: 0,
18044 });
18045
18046 parser.set_token_stream(replacement);
18047
18048 assert_eq!(parser.input.index(), 0);
18049 assert_eq!(parser.la(1), 2);
18050 assert_eq!(parser.input.text_all(), "new");
18051 assert_eq!(parser.number_of_syntax_errors(), 0);
18052 }
18053
18054 #[test]
18055 fn active_invocation_states_exclude_the_root_frame() {
18056 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18057
18058 let _root = parser.enter_rule(0, 0);
18059 assert!(parser.active_invocation_states().is_empty());
18060
18061 let marker = parser.push_invoking_state(6);
18062 let _child = parser.enter_rule(2, 1);
18063 parser.discard_invoking_state(marker);
18064 assert_eq!(parser.active_invocation_states(), [6]);
18065
18066 let marker = parser.push_invoking_state(13);
18067 let _grandchild = parser.enter_rule(4, 2);
18068 parser.discard_invoking_state(marker);
18069 assert_eq!(parser.active_invocation_states(), [13, 6]);
18070
18071 parser.exit_rule();
18072 parser.exit_rule();
18073 parser.exit_rule();
18074 }
18075
18076 #[test]
18077 fn parser_predicates_support_token_adjacency() {
18078 let mut parser = mini_parser(vec![
18079 TestToken::new(1).with_text("=").with_span(0, 0),
18080 TestToken::new(1).with_text(">").with_span(1, 1),
18081 TestToken::eof("parser-test", 2, 1, 2),
18082 ]);
18083 parser.consume();
18084 parser.consume();
18085
18086 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
18087
18088 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
18089
18090 let mut parser = mini_parser(vec![
18091 TestToken::new(1).with_text("=").with_span(0, 0),
18092 TestToken::new(1)
18093 .with_text(" ")
18094 .with_channel(HIDDEN_CHANNEL)
18095 .with_span(1, 1),
18096 TestToken::new(1).with_text(">").with_span(2, 2),
18097 TestToken::eof("parser-test", 3, 1, 3),
18098 ]);
18099 parser.consume();
18100 parser.consume();
18101
18102 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
18103 }
18104
18105 #[test]
18106 fn parser_predicates_support_context_child_text_checks() {
18107 let mut parser = mini_parser(vec![
18108 TestToken::new(1).with_text("var"),
18109 TestToken::eof("parser-test", 1, 1, 1),
18110 ]);
18111 let mut context = ParserRuleContext::new(1, 0);
18112 let mut child_context = ParserRuleContext::new(2, 0);
18113 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
18114 parser.tree.add_child(&mut child_context, terminal);
18115 let child = parser.rule_node(child_context);
18116 parser.tree.add_child(&mut context, child);
18117 let predicates = [(
18118 1,
18119 0,
18120 ParserPredicate::ContextChildRuleTextNotEquals {
18121 rule_index: 2,
18122 text: "var",
18123 },
18124 )];
18125
18126 assert!(
18127 !parser.parser_semantic_predicate_matches_with_context_and_local(
18128 &predicates,
18129 1,
18130 0,
18131 &context,
18132 0,
18133 )
18134 );
18135 }
18136
18137 #[test]
18138 fn context_expected_symbols_walks_nullable_parent_contexts() {
18139 let atn = nested_nullable_context_atn();
18140 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18141 parser.rule_context_stack = vec![
18142 RuleContextFrame {
18143 rule_index: 0,
18144 invoking_state: 0,
18145 },
18146 RuleContextFrame {
18147 rule_index: 1,
18148 invoking_state: 1,
18149 },
18150 RuleContextFrame {
18151 rule_index: 2,
18152 invoking_state: 2,
18153 },
18154 ];
18155
18156 let expected = parser.context_expected_symbols(&atn);
18157
18158 assert!(expected.contains(&1));
18159 assert!(expected.contains(&TOKEN_EOF));
18160 }
18161
18162 #[test]
18163 fn prediction_context_return_states_track_rule_stack_changes() {
18164 let atn = nested_nullable_context_atn();
18165 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18166 parser.rule_context_stack = vec![
18167 RuleContextFrame {
18168 rule_index: 0,
18169 invoking_state: 0,
18170 },
18171 RuleContextFrame {
18172 rule_index: 1,
18173 invoking_state: 1,
18174 },
18175 RuleContextFrame {
18176 rule_index: 2,
18177 invoking_state: 2,
18178 },
18179 ];
18180
18181 let initial_version = parser.rule_context_version();
18182 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
18183 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
18184 assert_eq!(first, second);
18185 assert_eq!(parser.rule_context_version(), initial_version);
18186
18187 parser.exit_rule();
18188 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
18189 assert_ne!(first, after_pop);
18190 assert_ne!(parser.rule_context_version(), initial_version);
18191 }
18192
18193 #[test]
18194 fn prediction_context_return_states_skip_tail_call_frames() {
18195 let atn = tail_call_context_atn();
18196 assert!(
18197 atn.state(5)
18198 .expect("tail call source")
18199 .transitions()
18200 .first()
18201 .expect("tail call")
18202 .is_tail_call()
18203 );
18204 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18205 parser.rule_context_stack = vec![
18206 RuleContextFrame {
18207 rule_index: 0,
18208 invoking_state: 0,
18209 },
18210 RuleContextFrame {
18211 rule_index: 1,
18212 invoking_state: 1,
18213 },
18214 RuleContextFrame {
18215 rule_index: 2,
18216 invoking_state: 5,
18217 },
18218 ];
18219
18220 assert_eq!(
18221 parser
18222 .prediction_context_return_states(&atn)
18223 .collect::<Vec<_>>(),
18224 [2]
18225 );
18226 }
18227
18228 #[test]
18229 fn generated_match_token_recovers_missing_token_from_context_follow() {
18230 let atn = generated_match_recovery_atn();
18231 let data = RecognizerData::new(
18232 "Mini.g4",
18233 Vocabulary::new(
18234 [None, Some("'X'"), Some("'Y'")],
18235 [None, Some("X"), Some("Y")],
18236 [None::<&str>, None, None],
18237 ),
18238 );
18239 let mut parser = BaseParser::new(
18240 CommonTokenStream::new(Source {
18241 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
18242 index: 0,
18243 }),
18244 data,
18245 );
18246 parser.rule_context_stack = vec![
18247 RuleContextFrame {
18248 rule_index: 0,
18249 invoking_state: 0,
18250 },
18251 RuleContextFrame {
18252 rule_index: 1,
18253 invoking_state: 1,
18254 },
18255 ];
18256 assert_eq!(parser.number_of_syntax_errors(), 0);
18257
18258 let node = parser
18259 .match_token_recovering(2, 5, &atn)
18260 .expect("generated match should insert missing token");
18261
18262 assert_eq!(node.children().len(), 1);
18263 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
18264 assert_eq!(
18265 node.clone()
18266 .into_child_iter()
18267 .map(|child| parser.node(child).text())
18268 .collect::<Vec<_>>(),
18269 ["<missing 'Y'>"]
18270 );
18271 assert!(!node.consumed_eof());
18274 assert_eq!(parser.la(1), TOKEN_EOF);
18275 assert_eq!(parser.number_of_syntax_errors(), 1);
18276 assert_eq!(
18277 parser.generated_parser_diagnostics,
18278 [ParserDiagnostic {
18279 line: 1,
18280 column: 3,
18281 message: "missing 'Y' at '<EOF>'".to_owned(),
18282 offending: parser.input.lt_id(1),
18283 }]
18284 );
18285 }
18286
18287 #[test]
18288 fn generated_match_token_counts_single_token_deletion_recovery() {
18289 let atn = generated_match_recovery_atn();
18290 let data = RecognizerData::new(
18291 "Mini.g4",
18292 Vocabulary::new(
18293 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
18294 [None, Some("X"), Some("Y"), Some("Z")],
18295 [None::<&str>, None, None, None],
18296 ),
18297 );
18298 let mut parser = BaseParser::new(
18299 CommonTokenStream::new(Source {
18300 tokens: vec![
18301 TestToken::new(3).with_text("z"),
18302 TestToken::new(2).with_text("y"),
18303 TestToken::eof("parser-test", 3, 1, 3),
18304 ],
18305 index: 0,
18306 }),
18307 data,
18308 );
18309
18310 let node = parser
18311 .match_token_recovering(2, 5, &atn)
18312 .expect("generated match should delete the extraneous token");
18313
18314 assert_eq!(node.children().len(), 2);
18315 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
18316 assert_eq!(parser.node(node.children()[0]).text(), "z");
18317 assert_eq!(parser.node(node.children()[1]).text(), "y");
18318 assert_eq!(
18319 node.into_child_iter()
18320 .map(|child| parser.node(child).text())
18321 .collect::<Vec<_>>(),
18322 ["z", "y"]
18323 );
18324 assert_eq!(parser.number_of_syntax_errors(), 1);
18325 }
18326
18327 #[test]
18328 fn generated_match_token_iterates_single_success_without_a_children_vec() {
18329 let atn = generated_match_recovery_atn();
18330 let data = RecognizerData::new(
18331 "Mini.g4",
18332 Vocabulary::new(
18333 [None, Some("'X'"), Some("'Y'")],
18334 [None, Some("X"), Some("Y")],
18335 [None::<&str>, None, None],
18336 ),
18337 );
18338 let mut parser = BaseParser::new(
18339 CommonTokenStream::new(Source {
18340 tokens: vec![
18341 TestToken::new(2).with_text("y"),
18342 TestToken::eof("parser-test", 1, 1, 1),
18343 ],
18344 index: 0,
18345 }),
18346 data,
18347 );
18348
18349 let node = parser
18350 .match_token_recovering(2, 5, &atn)
18351 .expect("generated match should consume the expected token");
18352
18353 assert_eq!(
18354 node.into_child_iter()
18355 .map(|child| parser.node(child).text())
18356 .collect::<Vec<_>>(),
18357 ["y"]
18358 );
18359 assert_eq!(parser.number_of_syntax_errors(), 0);
18360 }
18361
18362 #[test]
18363 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
18364 let atn = generated_match_recovery_atn();
18365 let data = RecognizerData::new(
18366 "Mini.g4",
18367 Vocabulary::new(
18368 [None, Some("'X'"), Some("'Y'")],
18369 [None, Some("X"), Some("Y")],
18370 [None::<&str>, None, None],
18371 ),
18372 );
18373 let mut parser = BaseParser::new(
18374 CommonTokenStream::new(Source {
18375 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
18376 index: 0,
18377 }),
18378 data,
18379 );
18380 parser.rule_context_stack = vec![
18381 RuleContextFrame {
18382 rule_index: 0,
18383 invoking_state: 0,
18384 },
18385 RuleContextFrame {
18386 rule_index: 1,
18387 invoking_state: 1,
18388 },
18389 ];
18390 let marker = parser.generated_diagnostics_checkpoint();
18391
18392 let _ = parser
18393 .match_token_recovering(2, 5, &atn)
18394 .expect("generated match should insert missing token");
18395 assert_eq!(parser.number_of_syntax_errors(), 1);
18396
18397 parser.restore_generated_diagnostics(marker);
18398
18399 assert_eq!(parser.number_of_syntax_errors(), 0);
18400 assert!(parser.generated_parser_diagnostics.is_empty());
18401 }
18402
18403 #[test]
18404 fn generated_prediction_diagnostics_use_adaptive_context() {
18405 let atn = two_alt_decision_atn();
18406 let data = RecognizerData::new(
18407 "Mini.g4",
18408 Vocabulary::new(
18409 [None, Some("'x'"), Some("'y'")],
18410 [None, Some("X"), Some("Y")],
18411 [None::<&str>, None, None],
18412 ),
18413 )
18414 .with_rule_names(["s"]);
18415 let mut parser = BaseParser::new(
18416 CommonTokenStream::new(Source {
18417 tokens: vec![
18418 TestToken::new(1)
18419 .with_text("x")
18420 .with_position(1, 0)
18421 .with_span(0, 0),
18422 TestToken::new(2)
18423 .with_text("y")
18424 .with_position(1, 2)
18425 .with_span(1, 1),
18426 TestToken::eof("parser-test", 2, 1, 3),
18427 ],
18428 index: 0,
18429 }),
18430 data,
18431 );
18432 parser.set_report_diagnostic_errors(true);
18433
18434 parser.record_generated_prediction_diagnostic(
18435 &atn,
18436 1,
18437 &ParserAtnPrediction {
18438 alt: 1,
18439 requires_full_context: true,
18440 has_semantic_context: false,
18441 diagnostic: Some(ParserAtnPredictionDiagnostic {
18442 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
18443 start_index: 0,
18444 sll_stop_index: 1,
18445 ll_stop_index: 0,
18446 conflicting_alts: vec![1, 2],
18447 exact: false,
18448 }),
18449 },
18450 );
18451 parser.record_generated_prediction_diagnostic(
18456 &atn,
18457 1,
18458 &ParserAtnPrediction {
18459 alt: 1,
18460 requires_full_context: true,
18461 has_semantic_context: false,
18462 diagnostic: Some(ParserAtnPredictionDiagnostic {
18463 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
18464 start_index: 0,
18465 sll_stop_index: 1,
18466 ll_stop_index: 1,
18467 conflicting_alts: vec![1, 2],
18468 exact: false,
18469 }),
18470 },
18471 );
18472
18473 insta::assert_debug_snapshot!(
18476 "generated_prediction_diagnostics_use_adaptive_context",
18477 parser.generated_parser_diagnostics
18478 );
18479 }
18480
18481 #[test]
18482 fn sll_mode_suppresses_exact_conflict_diagnostics() {
18483 let atn = two_alt_decision_atn();
18484 let mut parser = mini_parser(vec![
18485 TestToken::new(1).with_text("x"),
18486 TestToken::eof("parser-test", 1, 1, 1),
18487 ]);
18488 parser.set_prediction_mode(PredictionMode::Sll);
18489 parser.set_report_diagnostic_errors(true);
18490
18491 parser.record_generated_prediction_diagnostic(
18492 &atn,
18493 1,
18494 &ParserAtnPrediction {
18495 alt: 1,
18496 requires_full_context: false,
18497 has_semantic_context: false,
18498 diagnostic: Some(ParserAtnPredictionDiagnostic {
18499 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
18500 start_index: 0,
18501 sll_stop_index: 0,
18502 ll_stop_index: 0,
18503 conflicting_alts: vec![1, 2],
18504 exact: true,
18505 }),
18506 },
18507 );
18508
18509 assert!(parser.generated_parser_diagnostics.is_empty());
18510 }
18511
18512 #[test]
18513 fn local_exact_conflict_reports_ambiguity_without_full_context_attempt() {
18514 let atn = two_alt_decision_atn();
18515 let mut parser = mini_parser(vec![
18516 TestToken::new(1).with_text("x"),
18517 TestToken::eof("parser-test", 1, 1, 1),
18518 ]);
18519 parser.set_report_diagnostic_errors(true);
18520
18521 parser.record_generated_prediction_diagnostic(
18522 &atn,
18523 1,
18524 &ParserAtnPrediction {
18525 alt: 1,
18526 requires_full_context: false,
18527 has_semantic_context: false,
18528 diagnostic: Some(ParserAtnPredictionDiagnostic {
18529 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
18530 start_index: 0,
18531 sll_stop_index: 0,
18532 ll_stop_index: 0,
18533 conflicting_alts: vec![1, 2],
18534 exact: true,
18535 }),
18536 },
18537 );
18538
18539 insta::assert_debug_snapshot!(
18540 "local_exact_conflict_reports_ambiguity_without_full_context_attempt",
18541 parser.generated_parser_diagnostics
18542 );
18543 }
18544
18545 #[test]
18546 fn full_context_exact_conflict_reports_attempt_and_ambiguity() {
18547 let atn = two_alt_decision_atn();
18548 let mut parser = mini_parser(vec![
18549 TestToken::new(1).with_text("x"),
18550 TestToken::new(2).with_text("y"),
18551 TestToken::eof("parser-test", 2, 1, 2),
18552 ]);
18553 parser.set_report_diagnostic_errors(true);
18554
18555 parser.record_generated_prediction_diagnostic(
18556 &atn,
18557 1,
18558 &ParserAtnPrediction {
18559 alt: 1,
18560 requires_full_context: true,
18561 has_semantic_context: false,
18562 diagnostic: Some(ParserAtnPredictionDiagnostic {
18563 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
18564 start_index: 0,
18565 sll_stop_index: 0,
18566 ll_stop_index: 1,
18567 conflicting_alts: vec![1, 2],
18568 exact: true,
18569 }),
18570 },
18571 );
18572
18573 insta::assert_debug_snapshot!(
18574 "full_context_exact_conflict_reports_attempt_and_ambiguity",
18575 parser.generated_parser_diagnostics
18576 );
18577 }
18578
18579 #[test]
18580 fn generated_match_not_set_recovers_empty_complement_at_eof() {
18581 let atn = complement_set_atn();
18582 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18583 parser.rule_context_stack = vec![RuleContextFrame {
18584 rule_index: 0,
18585 invoking_state: 0,
18586 }];
18587
18588 let node = parser
18589 .match_not_token_set_recovering(
18590 atn.token_set(0).expect("excluded token set"),
18591 1,
18592 1,
18593 1,
18594 &atn,
18595 )
18596 .expect("empty complement should recover at EOF");
18597
18598 assert_eq!(node.children().len(), 1);
18599 assert!(!node.consumed_eof());
18602 assert_eq!(parser.la(1), TOKEN_EOF);
18603 assert_eq!(
18604 parser.generated_parser_diagnostics,
18605 [ParserDiagnostic {
18606 line: 1,
18607 column: 1,
18608 message: "missing {} at '<EOF>'".to_owned(),
18609 offending: parser.input.lt_id(1),
18610 }]
18611 );
18612 }
18613
18614 #[test]
18615 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
18616 let atn = wildcard_then_eof_atn();
18622 let data = RecognizerData::new(
18623 "Mini.g4",
18624 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18625 );
18626 let mut parser = BaseParser::new(
18627 CommonTokenStream::new(Source {
18628 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
18629 index: 0,
18630 }),
18631 data,
18632 );
18633 parser.rule_context_stack = vec![RuleContextFrame {
18634 rule_index: 0,
18635 invoking_state: 0,
18636 }];
18637
18638 let node = parser
18639 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
18640 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
18641
18642 assert_eq!(node.children().len(), 1);
18644 assert!(!node.consumed_eof());
18645 assert!(
18646 parser
18647 .node(node.children()[0])
18648 .text()
18649 .starts_with("<missing")
18650 );
18651 assert_eq!(parser.la(1), TOKEN_EOF);
18652 assert_eq!(
18653 parser.generated_parser_diagnostics,
18654 [ParserDiagnostic {
18655 line: 1,
18656 column: 1,
18657 message: "missing 'x' at '<EOF>'".to_owned(),
18658 offending: parser.input.lt_id(1),
18659 }]
18660 );
18661 }
18662
18663 #[test]
18664 fn generated_rule_recovery_consumes_to_parent_follow() {
18665 let atn = generated_match_recovery_atn();
18666 let data = RecognizerData::new(
18667 "Mini.g4",
18668 Vocabulary::new(
18669 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
18670 [None, Some("X"), Some("Y"), Some("Z")],
18671 [None::<&str>, None, None, None],
18672 ),
18673 );
18674 let mut parser = BaseParser::new(
18675 CommonTokenStream::new(Source {
18676 tokens: vec![
18677 TestToken::new(3).with_text("z"),
18678 TestToken::eof("parser-test", 1, 1, 1),
18679 ],
18680 index: 0,
18681 }),
18682 data,
18683 );
18684 let _parent = parser.enter_rule(0, 0);
18685 let marker = parser.push_invoking_state(1);
18686 let mut child = parser.enter_rule(4, 1);
18687 parser.discard_invoking_state(marker);
18688
18689 let offending = parser.input.lt_id(1);
18692 assert!(offending.is_some(), "the 'z' token should be buffered");
18693 parser.recover_generated_rule(
18694 &mut child,
18695 &atn,
18696 AntlrError::ParserError {
18697 line: 1,
18698 column: 0,
18699 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
18700 offending,
18701 },
18702 );
18703 let tree = parser.finish_rule(child, false);
18704
18705 assert_eq!(parser.la(1), TOKEN_EOF);
18706 assert_eq!(
18707 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
18708 "(a z)"
18709 );
18710 assert_eq!(parser.number_of_syntax_errors(), 1);
18711 assert_eq!(
18712 parser.generated_parser_diagnostics,
18713 [ParserDiagnostic {
18714 line: 1,
18715 column: 0,
18716 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
18717 offending,
18718 }]
18719 );
18720 parser.exit_rule();
18721 }
18722
18723 #[test]
18724 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
18725 let atn = nested_nullable_context_atn();
18726 let mut parser = mini_parser(vec![
18727 TestToken::new(1).with_text("x"),
18728 TestToken::eof("parser-test", 1, 1, 1),
18729 ]);
18730 parser.rule_context_stack = vec![
18731 RuleContextFrame {
18732 rule_index: 0,
18733 invoking_state: 0,
18734 },
18735 RuleContextFrame {
18736 rule_index: 1,
18737 invoking_state: 1,
18738 },
18739 RuleContextFrame {
18740 rule_index: 2,
18741 invoking_state: 2,
18742 },
18743 ];
18744 parser.set_state(20);
18745 let mut context = ParserRuleContext::new(2, 2);
18746
18747 parser.recover_generated_rule(
18748 &mut context,
18749 &atn,
18750 AntlrError::NoViableAlternative {
18751 input: "'x'".to_owned(),
18752 },
18753 );
18754 assert_eq!(parser.input.index(), 0);
18755
18756 parser.set_state(21);
18757 parser.recover_generated_rule(
18758 &mut context,
18759 &atn,
18760 AntlrError::NoViableAlternative {
18761 input: "'x'".to_owned(),
18762 },
18763 );
18764 assert_eq!(parser.input.index(), 0);
18765 assert_eq!(
18766 parser.generated_recovery_error_states,
18767 BTreeSet::from([20, 21])
18768 );
18769
18770 parser.set_state(20);
18771 parser.recover_generated_rule(
18772 &mut context,
18773 &atn,
18774 AntlrError::NoViableAlternative {
18775 input: "'x'".to_owned(),
18776 },
18777 );
18778
18779 assert_eq!(parser.input.index(), 1);
18780 assert_eq!(parser.la(1), TOKEN_EOF);
18781 assert!(context.has_matched_child());
18782 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
18783
18784 parser.match_eof().expect("EOF should match");
18785 assert_eq!(parser.generated_recovery_error_index, None);
18786 assert!(parser.generated_recovery_error_states.is_empty());
18787 }
18788
18789 #[test]
18790 fn greedy_ll1_alt_handles_nullable_loop_exit() {
18791 let mut body_symbols = TokenBitSet::default();
18792 body_symbols.insert(1);
18793 let entry = DecisionLookahead {
18794 transitions: vec![
18795 TransitionLookSet {
18796 symbols: body_symbols,
18797 nullable: false,
18798 },
18799 TransitionLookSet {
18800 symbols: TokenBitSet::default(),
18801 nullable: true,
18802 },
18803 ],
18804 };
18805
18806 assert_eq!(ll1_unique_alt(&entry, 2), None);
18807 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
18808 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
18809 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
18810 }
18811
18812 #[test]
18813 fn ordinary_repetition_builds_tree_in_input_order() {
18814 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18815 let mut parser = mini_parser(repeated_x_tokens(3));
18816 let tree = parser
18817 .parse_atn_rule(&atn, 0)
18818 .expect("ordinary repetition should parse");
18819
18820 let root = parser
18821 .node(tree)
18822 .as_rule()
18823 .expect("entry result should be a rule");
18824 let body_rules = root.child_rules(1).collect::<Vec<_>>();
18825 assert_eq!(root.text(), "xxx<EOF>");
18826 assert_eq!(body_rules.len(), 3);
18827 assert_eq!(
18828 body_rules
18829 .iter()
18830 .map(|rule| rule.start_id().expect("body start").index())
18831 .collect::<Vec<_>>(),
18832 [0, 1, 2]
18833 );
18834 assert_eq!(
18835 body_rules
18836 .iter()
18837 .map(|rule| rule.stop_id().expect("body stop").index())
18838 .collect::<Vec<_>>(),
18839 [0, 1, 2]
18840 );
18841 assert_eq!(parser.number_of_syntax_errors(), 0);
18842 }
18843 }
18844
18845 #[test]
18846 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
18847 const DEPTH: usize = 20_000;
18848
18849 std::thread::Builder::new()
18850 .name("deferred-rule-materialization".to_owned())
18851 .stack_size(256 * 1024)
18852 .spawn(|| {
18853 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
18854 let mut root = FastDeferredNodeId::EMPTY;
18855 for depth in 0..DEPTH {
18856 root = parser
18857 .recognition_arena
18858 .deferred_rule_node(FastDeferredRule {
18859 rule_index: u32::try_from(depth).expect("depth fits in u32"),
18860 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
18861 start_index: 0,
18862 stop_index: None,
18863 deferred_children: root,
18864 children: NodeSeqId::EMPTY,
18865 });
18866 }
18867
18868 let (mut children, alt_number) =
18869 parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
18870 assert_eq!(alt_number, 0);
18871 for expected_rule in (0..DEPTH).rev() {
18872 let mut nodes = parser.recognition_arena.iter(children);
18873 let node = nodes.next().expect("nested rule node");
18874 assert!(nodes.next().is_none(), "each rule has one child");
18875 let ArenaRecognizedNode::Rule {
18876 rule_index,
18877 children: nested,
18878 ..
18879 } = parser.recognition_arena.node(node)
18880 else {
18881 panic!("expected nested rule");
18882 };
18883 assert_eq!(rule_index as usize, expected_rule);
18884 children = nested;
18885 }
18886 assert!(children.is_empty());
18887 })
18888 .expect("small-stack thread should start")
18889 .join()
18890 .expect("deferred rules should materialize without recursion");
18891 }
18892
18893 #[test]
18894 fn deferred_alternatives_preserve_left_recursive_contexts() {
18895 let mut parser = mini_parser(vec![
18896 TestToken::new(1).with_text("1"),
18897 TestToken::new(2).with_text("+"),
18898 TestToken::new(1).with_text("2"),
18899 TestToken::eof("parser-test", 3, 1, 3),
18900 ]);
18901 let base = parser.arena_token_node(0, false);
18902 let operator = parser.arena_token_node(1, false);
18903 let right = parser.arena_token_node(2, false);
18904
18905 let base = parser.recognition_arena.prepend(NodeSeqId::EMPTY, base);
18906 let base = parser.recognition_arena.deferred_fragment(base);
18907 let operator = parser.recognition_arena.prepend(NodeSeqId::EMPTY, operator);
18908 let operator = parser.recognition_arena.deferred_fragment(operator);
18909 let right = parser.recognition_arena.prepend(NodeSeqId::EMPTY, right);
18910 let right = parser.recognition_arena.deferred_fragment(right);
18911 let base_alt = parser.recognition_arena.deferred_alternative(1);
18912 let boundary = parser.recognition_arena.deferred_left_recursive_boundary(0);
18913 let operator_alt = parser.recognition_arena.deferred_alternative(6);
18914
18915 let mut deferred = FastDeferredNodeId::EMPTY;
18916 for fragment in [base_alt, base, boundary, operator_alt, operator, right] {
18917 deferred = parser
18918 .recognition_arena
18919 .concat_deferred_nodes(deferred, fragment);
18920 }
18921 let (nodes, root_alt_number) =
18922 parser.materialize_fast_deferred_nodes(deferred, NodeSeqId::EMPTY);
18923 let nodes = parser
18924 .recognition_arena
18925 .fold_left_recursive_boundaries(nodes);
18926
18927 let mut root = ParserRuleContext::new(0, -1);
18928 root.set_context_alt_number(root_alt_number);
18929 let mut cursor = nodes;
18930 while let Some(link) = parser.recognition_arena.link(cursor) {
18931 let child = parser
18932 .arena_recognized_node_tree(link.head, false, true)
18933 .expect("materialized child should become a public tree");
18934 parser.tree.add_child(&mut root, child);
18935 cursor = link.tail;
18936 }
18937 let tree = parser.rule_node(root);
18938 let contexts = parser
18939 .node(tree)
18940 .descendants()
18941 .filter_map(Node::as_rule)
18942 .map(|rule| {
18943 (
18944 rule.rule_index(),
18945 rule.alt_number(),
18946 rule.context_alt_number(),
18947 rule.text(),
18948 )
18949 })
18950 .collect::<Vec<_>>();
18951
18952 insta::assert_debug_snapshot!(
18953 "deferred_alternatives_preserve_left_recursive_contexts",
18954 contexts
18955 );
18956 }
18957
18958 #[test]
18959 fn fast_recognizer_preserves_labeled_left_recursive_operator_context() {
18960 let atn = labeled_left_recursive_operator_atn();
18961 let mut parser = mini_parser(vec![
18962 TestToken::new(1).with_text("a"),
18963 TestToken::new(3).with_text("+"),
18964 TestToken::new(1).with_text("b"),
18965 TestToken::eof("parser-test", 3, 1, 3),
18966 ]);
18967
18968 let (tree, _) = parser
18969 .parse_atn_rule_with_runtime_options(
18970 &atn,
18971 0,
18972 ParserRuntimeOptions {
18973 track_context_alt_numbers: true,
18974 ..ParserRuntimeOptions::default()
18975 },
18976 )
18977 .expect("labeled left-recursive addition should parse");
18978 let contexts = parser
18979 .node(tree)
18980 .descendants()
18981 .filter_map(Node::as_rule)
18982 .map(|rule| {
18983 let operator = rule
18984 .children()
18985 .next()
18986 .and_then(Node::as_rule)
18987 .is_some_and(|child| child.rule_index() == rule.rule_index());
18988 (operator, rule.context_alt_number(), rule.text())
18989 })
18990 .collect::<Vec<_>>();
18991
18992 insta::assert_debug_snapshot!(
18993 "fast_recognizer_preserves_labeled_left_recursive_operator_context",
18994 contexts
18995 );
18996 assert!(!parser.recognition_arena.deferred_nodes.is_empty());
18997 assert_eq!(parser.number_of_syntax_errors(), 0);
18998 }
18999
19000 #[test]
19001 fn deeply_nested_rule_calls_grow_the_stack() {
19002 const DEPTH: usize = 4_096;
19003 const STACK_SIZE: usize = 256 * 1024;
19004 let atn = nested_rule_chain_atn(DEPTH);
19005 std::thread::Builder::new()
19006 .name("nested-adaptive-set-rules".to_owned())
19007 .stack_size(STACK_SIZE)
19008 .spawn(move || {
19009 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
19010 parser.set_build_parse_trees(false);
19011 parser.fast_first_set_prefilter = false;
19014 parser
19015 .parse_atn_rule(&atn, 0)
19016 .expect("nested rule chain should grow the native stack");
19017 assert_eq!(parser.input.index(), 1);
19018 })
19019 .expect("small-stack thread should start")
19020 .join()
19021 .expect("nested rule chain should not overflow its stack");
19022 }
19023
19024 #[test]
19025 fn deeply_nested_branching_rules_grow_the_stack() {
19026 const DEPTH: usize = 4_096;
19027 const STACK_SIZE: usize = 256 * 1024;
19028 let atn = nested_rule_graph_atn(DEPTH, true, false);
19029 std::thread::Builder::new()
19030 .name("nested-branching-rules".to_owned())
19031 .stack_size(STACK_SIZE)
19032 .spawn(move || {
19033 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
19034 parser.set_build_parse_trees(false);
19035 parser
19036 .parse_atn_rule(&atn, 0)
19037 .expect("branching rule chain should grow the native stack");
19038 assert_eq!(parser.input.index(), 1);
19039 })
19040 .expect("small-stack thread should start")
19041 .join()
19042 .expect("branching rule chain should not overflow its stack");
19043 }
19044
19045 #[test]
19046 fn deeply_nested_rule_follows_grow_the_stack() {
19047 const DEPTH: usize = 4_096;
19048 const STACK_SIZE: usize = 256 * 1024;
19049 let atn = nested_rule_graph_atn(DEPTH, false, true);
19050 std::thread::Builder::new()
19051 .name("nested-rule-follows".to_owned())
19052 .stack_size(STACK_SIZE)
19053 .spawn(move || {
19054 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
19055 parser.set_build_parse_trees(false);
19056 parser.fast_first_set_prefilter = false;
19057 parser
19058 .parse_atn_rule(&atn, 0)
19059 .expect("rule follow chain should grow the native stack");
19060 assert_eq!(parser.input.index(), DEPTH);
19061 })
19062 .expect("small-stack thread should start")
19063 .join()
19064 .expect("nested rule follow chain should not overflow its stack");
19065 }
19066
19067 #[test]
19068 fn deeply_nested_recovery_grows_the_stack() {
19069 const DEPTH: usize = 4_096;
19070 const STACK_SIZE: usize = 256 * 1024;
19071 let atn = nested_rule_chain_atn(DEPTH);
19072 std::thread::Builder::new()
19073 .name("nested-rule-recovery".to_owned())
19074 .stack_size(STACK_SIZE)
19075 .spawn(move || {
19076 let mut parser = mini_parser(vec![
19077 TestToken::new(2).with_text("z"),
19078 TestToken::new(1).with_text("x"),
19079 TestToken::eof("parser-test", 2, 1, 2),
19080 ]);
19081 parser.set_build_parse_trees(false);
19082 parser.fast_first_set_prefilter = false;
19083 parser
19084 .parse_atn_rule(&atn, 0)
19085 .expect("nested recovery should grow the native stack");
19086 assert_eq!(parser.input.index(), 2);
19087 assert_eq!(parser.number_of_syntax_errors(), 1);
19088 })
19089 .expect("small-stack thread should start")
19090 .join()
19091 .expect("nested rule recovery should not overflow its stack");
19092 }
19093
19094 #[test]
19095 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
19096 const REPETITIONS: usize = 64;
19097
19098 let atn = ambiguous_ordinary_star_loop_atn();
19099 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
19100 let tree = parser
19101 .parse_atn_rule(&atn, 0)
19102 .expect("ambiguous ordinary repetition should parse");
19103
19104 let root = parser
19105 .node(tree)
19106 .as_rule()
19107 .expect("entry result should be a rule");
19108 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
19109 assert_eq!(parser.input.index(), REPETITIONS);
19110 assert!(
19111 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
19112 "equivalent segmentations should keep deferred storage linear"
19113 );
19114 assert_eq!(parser.number_of_syntax_errors(), 0);
19115 }
19116
19117 #[test]
19118 fn long_ordinary_repetition_does_not_consume_native_stack() {
19119 const REPETITIONS: usize = 20_000;
19120
19121 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
19122 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
19123 parser.set_build_parse_trees(false);
19124 parser
19125 .parse_atn_rule(&atn, 0)
19126 .expect("long ordinary repetition should parse");
19127
19128 assert_eq!(parser.input.index(), REPETITIONS);
19129 assert_eq!(parser.number_of_syntax_errors(), 0);
19130 }
19131 }
19132
19133 #[test]
19134 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
19135 const REPETITIONS: usize = 2_000;
19136 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
19137
19138 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
19139 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
19140 let tree = parser
19141 .parse_atn_rule(&atn, 0)
19142 .expect("long rule repetition should parse");
19143
19144 let root = parser
19145 .node(tree)
19146 .as_rule()
19147 .expect("entry result should be a rule");
19148 assert_eq!(root.text(), expected_text);
19149 assert_eq!(root.child_rules(1).count(), REPETITIONS);
19150 let first_body = root.child_rules(1).next().expect("first body rule");
19151 let last_body = root.child_rules(1).next_back().expect("last body rule");
19152 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
19153 assert_eq!(
19154 last_body.stop_id().expect("last body stop").index(),
19155 REPETITIONS - 1
19156 );
19157
19158 let stats = parser.recognition_arena_stats();
19159 assert_eq!(
19160 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
19161 (REPETITIONS, REPETITIONS, 0)
19162 );
19163 assert_eq!(
19164 (stats.total_links, stats.live_links, stats.dead_links),
19165 (REPETITIONS, REPETITIONS, 0)
19166 );
19167 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
19168 assert_eq!(
19169 parser.recognition_arena.deferred_nodes.len(),
19170 REPETITIONS * 2 - 1
19171 );
19172 assert_eq!(parser.number_of_syntax_errors(), 0);
19173 }
19174 }
19175
19176 #[test]
19177 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
19178 let key = |state_number| FastRecognizeKey {
19179 state_number,
19180 stop_state: 10,
19181 index: state_number,
19182 rule_start_index: 0,
19183 decision_start_index: None,
19184 precedence: 0,
19185 recovery_symbols_id: 0,
19186 recovery_state: None,
19187 };
19188
19189 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
19190 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
19191 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
19192 }
19193 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
19194 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
19195
19196 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
19197 let repeated = key(1);
19198 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
19199 assert!(promote.clean_memo_enabled_for_key(&repeated));
19200 }
19201 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
19202
19203 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
19204 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
19205 }
19206 assert!(sparse.clean_memo_enabled_for_key(&repeated));
19207 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
19208 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
19209 assert!(sparse.clean_memo_enabled_for_key(&repeated));
19210 }
19211 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
19212 }
19213
19214 #[test]
19215 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
19216 assert_eq!(
19217 fast_recognize_memo_capacity(0),
19218 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
19219 );
19220 assert_eq!(
19221 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
19222 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
19223 );
19224 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
19225 assert_eq!(
19226 fast_recognize_memo_capacity(usize::MAX),
19227 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
19228 );
19229 }
19230
19231 #[test]
19232 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
19233 let mut scratch = FastRecognizeTopScratch::default();
19234 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
19235 let retained_capacity = scratch.memo.capacity();
19236 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
19237 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
19238
19239 let larger_capacity = retained_capacity + 1;
19240 scratch.prepare(larger_capacity);
19241 let grown_capacity = scratch.memo.capacity();
19242 assert!(grown_capacity >= larger_capacity);
19243 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
19244
19245 scratch.memo.insert(
19246 FastRecognizeKey {
19247 state_number: 0,
19248 stop_state: 0,
19249 index: 0,
19250 rule_start_index: 0,
19251 decision_start_index: None,
19252 precedence: 0,
19253 recovery_symbols_id: 0,
19254 recovery_state: None,
19255 },
19256 Rc::from([FastRecognizeOutcome {
19257 index: 0,
19258 consumed_eof: false,
19259 diagnostics: DiagnosticSeqId::EMPTY,
19260 deferred_nodes: FastDeferredNodeId::EMPTY,
19261 nodes: NodeSeqId::EMPTY,
19262 }]),
19263 );
19264 scratch.release_oversized_memo();
19265 assert!(scratch.memo.is_empty());
19266 assert_eq!(scratch.memo.capacity(), grown_capacity);
19267
19268 scratch
19269 .memo
19270 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
19271 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
19272
19273 scratch.release_oversized_memo();
19274 assert!(scratch.memo.is_empty());
19275 assert_eq!(scratch.memo.capacity(), 0);
19276 }
19277
19278 #[test]
19279 fn clean_empty_multi_alt_outcomes_are_memoized() {
19280 let mut atn = ParserAtnBuilder::new(2);
19281 assert_eq!(
19282 atn.add_state(AtnStateKind::RuleStart, Some(0))
19283 .expect("state")
19284 .index(),
19285 0
19286 );
19287 assert_eq!(
19288 atn.add_state(AtnStateKind::BlockStart, Some(0))
19289 .expect("state")
19290 .index(),
19291 1
19292 );
19293 assert_eq!(
19294 atn.add_state(AtnStateKind::RuleStop, Some(0))
19295 .expect("state")
19296 .index(),
19297 2
19298 );
19299 atn.set_rule_to_start_state(vec![0])
19300 .expect("rule start states");
19301 atn.set_rule_to_stop_state(vec![2])
19302 .expect("rule stop states");
19303 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
19304 .expect("transition");
19305 atn.add_transition(
19306 1,
19307 ParserTransitionSpec::Atom {
19308 target: 2,
19309 label: 1,
19310 },
19311 )
19312 .expect("transition");
19313 atn.add_transition(
19314 1,
19315 ParserTransitionSpec::Atom {
19316 target: 2,
19317 label: 2,
19318 },
19319 )
19320 .expect("transition");
19321 let atn = finish_atn(atn);
19322
19323 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
19324 parser.fast_recovery_enabled = false;
19325 let mut visiting = FxHashSet::default();
19326 let mut memo = FxHashMap::default();
19327 let mut expected = ExpectedTokens::default();
19328 let outcomes = parser.recognize_state_fast(
19329 &atn,
19330 FastRecognizeRequest {
19331 state_number: 1,
19332 stop_state: 2,
19333 index: 0,
19334 rule_start_index: 0,
19335 decision_start_index: None,
19336 precedence: 0,
19337 depth: 0,
19338 recovery_symbols: parser.empty_recovery_symbols(),
19339 recovery_state: None,
19340 },
19341 FastRecognizeScratch {
19342 predicate_context: None,
19343 visiting: &mut visiting,
19344 memo: &mut memo,
19345 expected: &mut expected,
19346 native_depth: 0,
19347 },
19348 );
19349
19350 assert!(outcomes.is_empty());
19351 assert_eq!(memo.len(), 1);
19352 assert!(memo.values().next().expect("memo entry").is_empty());
19353
19354 parser.clean_memo_mode = CleanMemoMode::Sparse;
19355 visiting.clear();
19356 memo.clear();
19357 expected = ExpectedTokens::default();
19358 let sparse_outcomes = parser.recognize_state_fast(
19359 &atn,
19360 FastRecognizeRequest {
19361 state_number: 1,
19362 stop_state: 2,
19363 index: 0,
19364 rule_start_index: 0,
19365 decision_start_index: None,
19366 precedence: 0,
19367 depth: 0,
19368 recovery_symbols: parser.empty_recovery_symbols(),
19369 recovery_state: None,
19370 },
19371 FastRecognizeScratch {
19372 predicate_context: None,
19373 visiting: &mut visiting,
19374 memo: &mut memo,
19375 expected: &mut expected,
19376 native_depth: 0,
19377 },
19378 );
19379
19380 assert!(sparse_outcomes.is_empty());
19381 assert!(memo.is_empty());
19382 }
19383
19384 #[test]
19385 fn wildcard_matches_non_eof_only() {
19386 let mut parser = mini_parser(vec![
19387 TestToken::new(1).with_text("x"),
19388 TestToken::eof("parser-test", 1, 1, 1),
19389 ]);
19390 let matched = parser.match_wildcard().expect("wildcard");
19391 assert_eq!(parser.node(matched).text(), "x");
19392 assert!(parser.match_wildcard().is_err());
19393 }
19394
19395 #[test]
19396 fn add_parse_child_records_match_even_without_tree_building() {
19397 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
19402 let token = TestToken::new(1).with_text("x");
19403
19404 parser.set_build_parse_trees(false);
19405 let mut ctx = ParserRuleContext::new(0, 0);
19406 assert!(!ctx.has_matched_child());
19407 let child = parser.terminal_tree(token.id);
19408 parser.add_parse_child(&mut ctx, child);
19409 assert_eq!(ctx.child_count(), 0);
19411 assert_eq!(parser.parse_tree_storage().node_count(), 0);
19412 assert!(ctx.has_matched_child());
19414
19415 parser.set_build_parse_trees(true);
19417 let mut ctx = ParserRuleContext::new(0, 0);
19418 let child = parser.terminal_tree(token.id);
19419 parser.add_parse_child(&mut ctx, child);
19420 assert_eq!(ctx.child_count(), 1);
19421 assert!(ctx.has_matched_child());
19422 }
19423
19424 #[test]
19425 fn disabled_tree_building_does_not_grow_flat_storage() {
19426 let mut parser = mini_parser(vec![
19427 TestToken::new(1).with_text("x"),
19428 TestToken::new(1).with_text("y"),
19429 TestToken::eof("parser-test", 2, 1, 2),
19430 ]);
19431 parser.set_build_parse_trees(false);
19432 let mut context = ParserRuleContext::new(0, -1);
19433
19434 for _ in 0..2 {
19435 let child = parser.match_token(1).expect("token should match");
19436 parser.add_parse_child(&mut context, child);
19437 }
19438 let current = parser.input.lt_id(1).expect("EOF token");
19439 let error = parser.error_tree(current);
19440 parser.add_parse_child(&mut context, error);
19441 let root = parser.rule_node(context);
19442
19443 assert_eq!(
19444 parser.parse_tree_storage().stats(),
19445 ParseTreeStats::default()
19446 );
19447 assert!(
19448 parser
19449 .parse_tree_storage()
19450 .node(parser.token_store(), root)
19451 .is_none(),
19452 "the no-tree sentinel must not resolve to stored data"
19453 );
19454 }
19455
19456 #[test]
19457 fn disabled_tree_building_skips_recognition_rule_node_storage() {
19458 let atn = ordinary_star_loop_atn();
19459 let mut parser = mini_parser(repeated_x_tokens(3));
19460 parser.set_build_parse_trees(false);
19461
19462 parser
19463 .parse_atn_rule(&atn, 0)
19464 .expect("ordinary repetition should parse without a tree");
19465
19466 assert_eq!(parser.input.index(), 3);
19467 assert!(parser.recognition_arena.nodes.is_empty());
19468 assert!(parser.recognition_arena.seq_links.is_empty());
19469 assert!(parser.recognition_arena.deferred_nodes.is_empty());
19470 assert!(parser.recognition_arena.deferred_rules.is_empty());
19471 assert!(!parser.fast_token_nodes_enabled);
19472 assert!(parser.fast_recognize_scratch.memo.is_empty());
19473 }
19474
19475 #[test]
19476 fn parser_interprets_simple_atn_rule() {
19477 let atn = token_then_eof_atn();
19478 let mut parser = mini_parser(vec![
19479 TestToken::new(1).with_text("x"),
19480 TestToken::eof("parser-test", 1, 1, 1),
19481 ]);
19482
19483 let tree = parser
19484 .parse_atn_rule(&atn, 0)
19485 .expect("artificial parser rule should parse");
19486 assert_eq!(parser.node(tree).text(), "x<EOF>");
19487 assert_eq!(parser.number_of_syntax_errors(), 0);
19488 assert_eq!(
19489 parser
19490 .node(tree)
19491 .first_rule_stop(0)
19492 .expect("rule should stop at EOF")
19493 .token_type(),
19494 TOKEN_EOF
19495 );
19496
19497 let mut parser = mini_parser(vec![
19498 TestToken::new(1).with_text("x"),
19499 TestToken::eof("parser-test", 1, 1, 1),
19500 ]);
19501 let (tree, actions) = parser
19502 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19503 .expect("runtime-option parser rule should parse");
19504 assert!(actions.is_empty());
19505 assert_eq!(
19506 parser
19507 .node(tree)
19508 .first_rule_stop(0)
19509 .expect("rule should stop at EOF")
19510 .token_type(),
19511 TOKEN_EOF
19512 );
19513 }
19514
19515 #[test]
19516 fn runtime_options_default_ignores_noop_action_transitions() {
19517 let atn = noop_action_then_token_then_eof_atn();
19518 let mut parser = mini_parser(vec![
19519 TestToken::new(1).with_text("x"),
19520 TestToken::eof("parser-test", 1, 1, 1),
19521 ]);
19522
19523 let (tree, actions) = parser
19524 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19525 .expect("no-op parser action should not force action replay");
19526
19527 assert_eq!(parser.node(tree).text(), "x<EOF>");
19528 assert!(
19529 actions.is_empty(),
19530 "action_index=None transitions are ANTLR metadata, not replay actions"
19531 );
19532 assert_eq!(parser.number_of_syntax_errors(), 0);
19533 }
19534
19535 #[test]
19536 fn parser_exposes_buffered_token_stream_after_parse() {
19537 let atn = token_then_eof_atn();
19538 let mut parser = mini_parser(vec![
19539 TestToken::new(1).with_text("x"),
19540 TestToken::eof("parser-test", 1, 1, 1),
19541 ]);
19542
19543 let tree = parser
19544 .parse_atn_rule(&atn, 0)
19545 .expect("artificial parser rule should parse");
19546 assert_eq!(parser.node(tree).text(), "x<EOF>");
19547
19548 let stream = parser.token_stream();
19549 let source_index_after_parse = stream.token_source().index;
19550 let buffered = stream.tokens().collect::<Vec<_>>();
19551 assert_eq!(buffered.len(), 2);
19552 assert_eq!(buffered[0].text(), Some("x"));
19553 assert_eq!(buffered[0].token_id().index(), 0);
19554 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
19555 assert_eq!(stream.token_source().index, source_index_after_parse);
19556 drop(buffered);
19557
19558 let stream = parser.into_token_stream();
19559 assert_eq!(stream.token_source().index, source_index_after_parse);
19560 assert_eq!(
19561 stream.tokens().next().expect("first token").text(),
19562 Some("x")
19563 );
19564 assert_eq!(
19565 stream.tokens().nth(1).expect("EOF token").token_type(),
19566 TOKEN_EOF
19567 );
19568 }
19569
19570 #[test]
19571 fn parsed_file_exposes_all_buffered_tokens() {
19572 let atn = token_then_eof_atn();
19573 let mut parser = mini_parser(vec![
19574 TestToken::new(99)
19575 .with_text(" comment")
19576 .with_channel(HIDDEN_CHANNEL),
19577 TestToken::new(1).with_text("x"),
19578 TestToken::eof("parser-test", 9, 1, 9),
19579 ]);
19580
19581 let tree = parser
19582 .parse_atn_rule(&atn, 0)
19583 .expect("artificial parser rule should parse");
19584 let parsed = parser.into_parsed_file(tree);
19585
19586 insta::assert_debug_snapshot!(
19589 "parsed_file_exposes_all_buffered_tokens",
19590 parsed
19591 .tokens()
19592 .iter()
19593 .map(|token| (token.token_type(), token.channel(), token.text()))
19594 .collect::<Vec<_>>()
19595 );
19596 assert_eq!(parsed.tokens().into_iter().count(), 3);
19597 }
19598
19599 #[test]
19600 fn parser_syntax_error_count_tracks_interpreted_recovery() {
19601 let atn = token_then_eof_atn();
19602 let mut parser = mini_parser(vec![
19603 TestToken::new(1).with_text("x"),
19604 TestToken::new(2).with_text("y"),
19605 TestToken::eof("parser-test", 2, 1, 2),
19606 ]);
19607
19608 let tree = parser
19609 .parse_atn_rule(&atn, 0)
19610 .expect("invalid token should recover into an error node");
19611
19612 assert_eq!(parser.number_of_syntax_errors(), 1);
19613 assert_eq!(
19614 parser
19615 .node(tree)
19616 .first_error_token()
19617 .expect("recovery should embed an error token")
19618 .text(),
19619 Some("y")
19620 );
19621 }
19622
19623 #[test]
19624 fn failed_interpreted_parse_notifies_error_listener() {
19625 let atn = token_then_eof_atn();
19626 let mut parser = mini_parser(vec![
19627 TestToken::new(2)
19628 .with_text("y")
19629 .with_span(0, 0)
19630 .with_byte_span(0, 1)
19631 .with_position(3, 5),
19632 TestToken::eof("parser-test", 1, 1, 1),
19633 ]);
19634 parser.remove_error_listeners();
19635 let diagnostics = Arc::new(Mutex::new(Vec::new()));
19636 parser.add_error_listener(RecordingErrorListener {
19637 diagnostics: Arc::clone(&diagnostics),
19638 });
19639
19640 let error = parser
19641 .parse_atn_rule(&atn, 0)
19642 .expect_err("start-rule mismatch should remain a parser error");
19643
19644 assert_eq!(parser.number_of_syntax_errors(), 1);
19645 assert!(matches!(&error, AntlrError::ParserError { .. }));
19646 insta::assert_debug_snapshot!(
19647 "failed_interpreted_parse_notifies_error_listener",
19648 *diagnostics.lock().expect("recorded diagnostics lock")
19649 );
19650 }
19651
19652 #[test]
19653 fn adaptive_direct_rule_uses_simulator_decision() {
19654 let atn = two_alt_decision_atn();
19655 let mut simulator = ParserAtnSimulator::new(&atn);
19656 let mut parser = mini_parser(vec![
19657 TestToken::new(2).with_text("y"),
19658 TestToken::eof("parser-test", 1, 1, 1),
19659 ]);
19660
19661 let tree = parser
19662 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
19663 .expect("direct adaptive rule should parse");
19664
19665 assert_eq!(parser.node(tree).text(), "y");
19666 assert_eq!(parser.input.index(), 1);
19667 }
19668
19669 #[test]
19670 fn adaptive_direct_rule_restores_input_on_fallback() {
19671 let atn = predicate_after_token_atn();
19672 let mut simulator = ParserAtnSimulator::new(&atn);
19673 let mut parser = mini_parser(vec![
19674 TestToken::new(1).with_text("x"),
19675 TestToken::new(2).with_text("y"),
19676 TestToken::eof("parser-test", 2, 1, 2),
19677 ]);
19678
19679 let tree = parser
19680 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
19681 .expect("fallback recognizer should parse");
19682
19683 assert_eq!(parser.node(tree).text(), "xy");
19684 assert_eq!(parser.input.index(), 2);
19685 let stats = parser.parse_tree_storage().stats();
19686 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
19687 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
19688 assert_eq!(stats.scratch_links, 0);
19689 }
19690
19691 #[test]
19692 fn unknown_predicate_policy_defaults_to_assume_true() {
19693 let atn = predicate_after_token_atn();
19694 let mut parser = mini_parser(vec![
19695 TestToken::new(1).with_text("x"),
19696 TestToken::new(2).with_text("y"),
19697 TestToken::eof("parser-test", 2, 1, 2),
19698 ]);
19699
19700 let (tree, _) = parser
19701 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19702 .expect("unknown predicate should pass under the default policy");
19703
19704 assert_eq!(parser.node(tree).text(), "xy");
19705 assert_eq!(parser.number_of_syntax_errors(), 0);
19706 }
19707
19708 #[test]
19709 fn private_context_alt_tracking_keeps_fast_predicate_recognition() {
19710 let atn = predicate_gated_same_lookahead_atn([0, 1]);
19711 let mut parser = mini_parser(vec![
19712 TestToken::new(1).with_text("x"),
19713 TestToken::eof("parser-test", 1, 1, 1),
19714 ]);
19715
19716 let (tree, _) = parser
19717 .parse_atn_rule_with_runtime_options(
19718 &atn,
19719 0,
19720 ParserRuntimeOptions {
19721 predicates: &[
19722 (0, 0, ParserPredicate::False),
19723 (0, 1, ParserPredicate::True),
19724 ],
19725 track_context_alt_numbers: true,
19726 ..ParserRuntimeOptions::default()
19727 },
19728 )
19729 .expect("the second predicate-gated alternative should match");
19730
19731 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19732 insta::assert_debug_snapshot!(
19733 "private_context_alt_tracking_keeps_fast_predicate_recognition",
19734 (root.alt_number(), root.context_alt_number(), root.text())
19735 );
19736 assert_eq!(parser.number_of_syntax_errors(), 0);
19737 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
19738 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
19739 }
19740
19741 #[test]
19742 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
19743 let atn = token_then_eof_atn();
19747 let mut parser = mini_parser(vec![
19748 TestToken::new(1).with_text("x"),
19749 TestToken::eof("parser-test", 1, 1, 1),
19750 ]);
19751
19752 parser.unknown_predicate_hits.push((7, 3));
19754
19755 parser
19757 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19758 .expect("child rule parses");
19759
19760 let error = parser
19762 .take_unknown_semantic_error()
19763 .expect("parent's recorded coordinate must survive the nested interpreted parse");
19764 let AntlrError::Unsupported(message) = error else {
19765 panic!("expected AntlrError::Unsupported, got {error:?}");
19766 };
19767 assert!(message.contains("pred_index=3"), "message: {message}");
19768 }
19769
19770 #[test]
19771 fn nested_committed_parse_preserves_prior_unhandled_action_hits() {
19772 let atn = token_then_eof_atn();
19773 let mut parser = mini_parser(vec![
19774 TestToken::new(1).with_text("x"),
19775 TestToken::eof("parser-test", 1, 1, 1),
19776 ]);
19777 parser.unhandled_action_hits.push((7, 42));
19778
19779 parser
19780 .parse_atn_rule_with_runtime_options(
19781 &atn,
19782 0,
19783 ParserRuntimeOptions {
19784 action_indices: &[(usize::MAX, 0)],
19785 ..ParserRuntimeOptions::default()
19786 },
19787 )
19788 .expect("a child with no action miss must not observe its parent's miss");
19789
19790 let error = parser
19791 .take_unknown_semantic_error()
19792 .expect("the parent's action miss must survive the nested committed parse");
19793 let AntlrError::Unsupported(message) = error else {
19794 panic!("expected AntlrError::Unsupported, got {error:?}");
19795 };
19796 assert!(
19797 message.contains("rule_index=7") && message.contains("state=42"),
19798 "message: {message}"
19799 );
19800 }
19801
19802 #[test]
19803 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
19804 let atn = predicate_after_token_atn();
19805 let mut parser = mini_parser(vec![
19806 TestToken::new(1).with_text("x"),
19807 TestToken::new(2).with_text("y"),
19808 TestToken::eof("parser-test", 2, 1, 2),
19809 ]);
19810
19811 let result = parser.parse_atn_rule_with_runtime_options(
19812 &atn,
19813 0,
19814 ParserRuntimeOptions {
19815 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
19816 ..ParserRuntimeOptions::default()
19817 },
19818 );
19819
19820 assert!(
19821 result.is_err(),
19822 "the only path is predicate-guarded, so assume-false must fail the parse"
19823 );
19824 }
19825
19826 #[test]
19827 fn predicate_failure_message_keeps_semantic_recovery_path() {
19828 let atn = predicate_after_token_atn();
19829 let mut parser = mini_parser(vec![
19830 TestToken::new(1).with_text("x"),
19831 TestToken::new(2).with_text("y"),
19832 TestToken::eof("parser-test", 2, 1, 2),
19833 ]);
19834
19835 let (tree, _) = parser
19836 .parse_atn_rule_with_runtime_options(
19837 &atn,
19838 0,
19839 ParserRuntimeOptions {
19840 predicates: &[(
19841 0,
19842 0,
19843 ParserPredicate::FalseWithMessage {
19844 message: "predicate rejected input",
19845 },
19846 )],
19847 ..ParserRuntimeOptions::default()
19848 },
19849 )
19850 .expect("failure-message predicates recover through the semantic interpreter");
19851
19852 assert_eq!(parser.node(tree).text(), "xy");
19853 assert_eq!(parser.number_of_syntax_errors(), 1);
19854 assert!(
19855 parser.fast_predicate_cache.is_empty(),
19856 "failure-message predicates need the semantic interpreter's recovery outcome"
19857 );
19858 }
19859
19860 #[test]
19861 fn unknown_predicate_policy_error_names_the_coordinate() {
19862 let atn = predicate_after_token_atn();
19863 let mut parser = mini_parser(vec![
19864 TestToken::new(1).with_text("x"),
19865 TestToken::new(2).with_text("y"),
19866 TestToken::eof("parser-test", 2, 1, 2),
19867 ]);
19868
19869 let error = parser
19870 .parse_atn_rule_with_runtime_options(
19871 &atn,
19872 0,
19873 ParserRuntimeOptions {
19874 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19875 ..ParserRuntimeOptions::default()
19876 },
19877 )
19878 .expect_err("evaluating an unknown predicate under Error policy must fail");
19879
19880 let AntlrError::Unsupported(message) = error else {
19881 panic!("expected AntlrError::Unsupported, got {error:?}");
19882 };
19883 assert!(
19884 message.contains("unsupported semantic predicate"),
19885 "message should name the failure class: {message}"
19886 );
19887 assert!(
19888 message.contains("pred_index=0"),
19889 "message should carry the coordinate: {message}"
19890 );
19891 }
19892
19893 #[test]
19894 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
19895 let atn = predicate_after_token_atn();
19901 let mut parser = mini_parser(vec![
19902 TestToken::new(1).with_text("x"),
19903 TestToken::new(2).with_text("y"),
19904 TestToken::eof("parser-test", 2, 1, 2),
19905 ]);
19906
19907 parser
19908 .parse_atn_rule_with_runtime_options(
19909 &atn,
19910 0,
19911 ParserRuntimeOptions {
19912 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19913 ..ParserRuntimeOptions::default()
19914 },
19915 )
19916 .expect_err("first parse fails loud under the Error policy");
19917
19918 parser.reset_unknown_semantic_hits();
19923 assert!(
19924 parser.take_unknown_semantic_error().is_none(),
19925 "reset must drop stale unknown-predicate coordinates before a reused parse"
19926 );
19927 }
19928
19929 #[derive(Debug, Default)]
19930 struct RecordingHooks {
19931 predicates: Vec<(usize, usize, usize, Option<String>)>,
19932 actions: Vec<(usize, String, Option<String>)>,
19933 action_trees: Vec<Option<String>>,
19934 }
19935
19936 impl SemanticHooks for RecordingHooks {
19937 fn sempred<S>(
19938 &mut self,
19939 ctx: &mut ParserSemCtx<'_, S>,
19940 rule_index: usize,
19941 pred_index: usize,
19942 ) -> Option<bool>
19943 where
19944 S: TokenSource,
19945 {
19946 self.predicates.push((
19947 ctx.input_index(),
19948 rule_index,
19949 pred_index,
19950 ctx.token_text(1)
19951 .and_then(|token| token.text().map(str::to_owned)),
19952 ));
19953 Some(true)
19954 }
19955
19956 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19957 where
19958 S: TokenSource,
19959 {
19960 self.actions.push((
19961 action.source_state(),
19962 ctx.action_text(),
19963 ctx.rule_name().map(str::to_owned),
19964 ));
19965 self.action_trees.push(ctx.tree().map(Node::text));
19966 true
19967 }
19968 }
19969
19970 #[derive(Debug, Default)]
19971 struct StatefulActionHooks {
19972 entered: bool,
19973 events: Vec<String>,
19974 }
19975
19976 impl SemanticHooks for StatefulActionHooks {
19977 fn sempred<S>(
19978 &mut self,
19979 _ctx: &mut ParserSemCtx<'_, S>,
19980 _rule_index: usize,
19981 _pred_index: usize,
19982 ) -> Option<bool>
19983 where
19984 S: TokenSource,
19985 {
19986 self.events.push(format!("predicate:{}", self.entered));
19987 Some(self.entered)
19988 }
19989
19990 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19991 where
19992 S: TokenSource,
19993 {
19994 self.events.push(format!(
19995 "action:{}",
19996 action
19997 .action_index()
19998 .map_or_else(|| "legacy".to_owned(), |index| index.to_string())
19999 ));
20000 self.entered = true;
20001 true
20002 }
20003 }
20004
20005 #[derive(Debug, Default)]
20006 struct InitOrderingHooks {
20007 initialized: bool,
20008 events: Vec<String>,
20009 }
20010
20011 impl SemanticHooks for InitOrderingHooks {
20012 fn sempred<S>(
20013 &mut self,
20014 _ctx: &mut ParserSemCtx<'_, S>,
20015 _rule_index: usize,
20016 _pred_index: usize,
20017 ) -> Option<bool>
20018 where
20019 S: TokenSource,
20020 {
20021 self.events.push(format!("predicate:{}", self.initialized));
20022 Some(self.initialized)
20023 }
20024
20025 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
20026 where
20027 S: TokenSource,
20028 {
20029 if action.is_rule_init() {
20030 self.initialized = true;
20031 self.events.push("init".to_owned());
20032 } else {
20033 self.events.push(format!(
20034 "action:{}:initialized={}",
20035 action
20036 .action_index()
20037 .map_or_else(|| "legacy".to_owned(), |index| index.to_string()),
20038 self.initialized
20039 ));
20040 }
20041 true
20042 }
20043 }
20044
20045 #[derive(Debug, Default)]
20046 struct ActionContextHooks {
20047 actions: Vec<(usize, Option<i64>, Option<usize>)>,
20048 }
20049
20050 impl SemanticHooks for ActionContextHooks {
20051 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
20052 where
20053 S: TokenSource,
20054 {
20055 self.actions.push((
20056 action.action_index().unwrap_or(usize::MAX),
20057 ctx.local_int_arg(),
20058 action.stop_index(),
20059 ));
20060 true
20061 }
20062 }
20063
20064 #[derive(Debug, Default)]
20065 struct DecliningActionHooks {
20066 actions: Vec<usize>,
20067 }
20068
20069 impl SemanticHooks for DecliningActionHooks {
20070 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
20071 where
20072 S: TokenSource,
20073 {
20074 self.actions.push(action.source_state());
20075 false
20076 }
20077 }
20078
20079 #[derive(Debug, Default)]
20080 struct ForcedSecondAlternativeHooks {
20081 decisions: Vec<(usize, usize, usize)>,
20082 }
20083
20084 impl SemanticHooks for ForcedSecondAlternativeHooks {
20085 fn observes_parser_decisions(&self) -> bool {
20086 true
20087 }
20088
20089 fn parser_decision_override(
20090 &mut self,
20091 decision: usize,
20092 input_index: usize,
20093 alternative_count: usize,
20094 ) -> Option<usize> {
20095 self.decisions
20096 .push((decision, input_index, alternative_count));
20097 Some(2)
20098 }
20099 }
20100
20101 #[derive(Debug, Default)]
20102 struct ContainmentRecoveryHooks {
20103 decisions: Vec<(usize, usize, usize)>,
20104 }
20105
20106 impl SemanticHooks for ContainmentRecoveryHooks {
20107 fn observes_parser_decisions(&self) -> bool {
20108 true
20109 }
20110
20111 fn parser_decision_override(
20112 &mut self,
20113 decision: usize,
20114 input_index: usize,
20115 alternative_count: usize,
20116 ) -> Option<usize> {
20117 self.decisions
20118 .push((decision, input_index, alternative_count));
20119 (decision == 1).then_some(1)
20120 }
20121 }
20122
20123 struct RecordingParseListener {
20124 events: Arc<Mutex<Vec<String>>>,
20125 }
20126
20127 impl ParseListener for RecordingParseListener {
20128 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
20129 self.events
20130 .lock()
20131 .expect("parse-listener event lock")
20132 .push(format!("enter:{}", event.rule_index));
20133 Ok(())
20134 }
20135
20136 fn exit_every_rule(&mut self, rule_index: usize) {
20137 self.events
20138 .lock()
20139 .expect("parse-listener event lock")
20140 .push(format!("exit:{rule_index}"));
20141 }
20142 }
20143
20144 #[derive(Debug, Default)]
20145 struct RejectingPredicateHooks {
20146 predicates: Vec<(usize, usize, usize, Option<String>)>,
20147 }
20148
20149 impl SemanticHooks for RejectingPredicateHooks {
20150 fn sempred<S>(
20151 &mut self,
20152 ctx: &mut ParserSemCtx<'_, S>,
20153 rule_index: usize,
20154 pred_index: usize,
20155 ) -> Option<bool>
20156 where
20157 S: TokenSource,
20158 {
20159 self.predicates.push((
20160 ctx.input_index(),
20161 rule_index,
20162 pred_index,
20163 ctx.token_text(1)
20164 .and_then(|token| token.text().map(str::to_owned)),
20165 ));
20166 Some(false)
20167 }
20168 }
20169
20170 #[test]
20171 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
20172 let atn = predicate_gated_same_lookahead_atn([0, 0]);
20173 let mut parser = mini_parser_with_hooks(
20174 vec![
20175 TestToken::new(1).with_text("x"),
20176 TestToken::eof("parser-test", 1, 1, 1),
20177 ],
20178 RecordingHooks::default(),
20179 );
20180
20181 let (tree, _) = parser
20182 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
20183 .expect("both alternatives share one replay-safe predicate result");
20184
20185 assert_eq!(parser.node(tree).text(), "x<EOF>");
20186 assert_eq!(
20187 parser.semantic_hooks.predicates,
20188 vec![(0, 0, 0, Some("x".to_owned()))]
20189 );
20190 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
20191 }
20192
20193 #[test]
20194 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
20195 let atn = predicate_after_token_atn();
20196 let mut parser = mini_parser_with_hooks(
20197 vec![
20198 TestToken::new(1).with_text("x"),
20199 TestToken::new(2).with_text("y"),
20200 TestToken::eof("parser-test", 2, 1, 2),
20201 ],
20202 RecordingHooks::default(),
20203 );
20204
20205 let (tree, _) = parser
20206 .parse_atn_rule_with_runtime_options(
20207 &atn,
20208 0,
20209 ParserRuntimeOptions {
20210 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20211 ..ParserRuntimeOptions::default()
20212 },
20213 )
20214 .expect("hook supplies the missing predicate result");
20215
20216 assert_eq!(parser.node(tree).text(), "xy");
20217 assert_eq!(
20218 parser.semantic_hooks.predicates,
20219 vec![(1, 0, 0, Some("y".to_owned()))]
20220 );
20221 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
20222 }
20223
20224 #[test]
20225 fn runtime_options_default_preserves_semantic_hook_predicates() {
20226 let atn = predicate_after_token_atn();
20227 let mut parser = mini_parser_with_hooks(
20228 vec![
20229 TestToken::new(1).with_text("x"),
20230 TestToken::new(2).with_text("y"),
20231 TestToken::eof("parser-test", 2, 1, 2),
20232 ],
20233 RejectingPredicateHooks::default(),
20234 );
20235
20236 let result =
20237 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
20238
20239 assert!(
20240 result.is_err(),
20241 "default runtime options must not bypass semantic hooks for predicate ATNs"
20242 );
20243 assert_eq!(
20244 parser.semantic_hooks.predicates,
20245 vec![(1, 0, 0, Some("y".to_owned()))]
20246 );
20247 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
20248 }
20249
20250 #[test]
20251 fn committed_action_runs_before_later_predicate() {
20252 let atn = committed_action_then_predicate_atn();
20253 let mut parser = mini_parser_with_hooks(
20254 vec![
20255 TestToken::new(1).with_text("x"),
20256 TestToken::eof("parser-test", 1, 1, 1),
20257 ],
20258 StatefulActionHooks::default(),
20259 );
20260
20261 let (tree, deferred_actions) = parser
20262 .parse_atn_rule_with_runtime_options(
20263 &atn,
20264 0,
20265 ParserRuntimeOptions {
20266 action_indices: &[(0, 7)],
20267 ..ParserRuntimeOptions::default()
20268 },
20269 )
20270 .expect("the predicate should observe the preceding committed action");
20271
20272 assert_eq!(parser.node(tree).text(), "x<EOF>");
20273 assert!(deferred_actions.is_empty());
20274 assert_eq!(parser.semantic_hooks.events, ["action:7", "predicate:true"]);
20275 }
20276
20277 #[test]
20278 fn committed_action_hook_observes_parameterized_rule_argument() {
20279 let atn = parameterized_child_action_eof_atn();
20280 let rule_args = [ParserRuleArg {
20281 source_state: 0,
20282 rule_index: 1,
20283 value: 42,
20284 inherit_local: false,
20285 }];
20286 let mut parser = mini_parser_with_hooks(
20287 vec![TestToken::eof("parser-test", 0, 1, 0)],
20288 ActionContextHooks::default(),
20289 );
20290
20291 parser
20292 .parse_atn_rule_with_runtime_options(
20293 &atn,
20294 0,
20295 ParserRuntimeOptions {
20296 action_indices: &[(1, 20), (4, 10)],
20297 rule_args: &rule_args,
20298 ..ParserRuntimeOptions::default()
20299 },
20300 )
20301 .expect("the parameterized child should parse");
20302
20303 assert_eq!(
20304 parser.semantic_hooks.actions[0],
20305 (10, Some(42), None),
20306 "the child action should observe its invocation argument"
20307 );
20308 }
20309
20310 #[test]
20311 fn committed_parent_propagates_child_eof_consumption() {
20312 let atn = parameterized_child_action_eof_atn();
20313 let mut parser = mini_parser_with_hooks(
20314 vec![TestToken::eof("parser-test", 0, 1, 0)],
20315 ActionContextHooks::default(),
20316 );
20317
20318 let (tree, _) = parser
20319 .parse_atn_rule_with_runtime_options(
20320 &atn,
20321 0,
20322 ParserRuntimeOptions {
20323 action_indices: &[(1, 20), (4, 10)],
20324 ..ParserRuntimeOptions::default()
20325 },
20326 )
20327 .expect("the parent should retain its child's EOF boundary");
20328
20329 assert_eq!(
20330 parser.semantic_hooks.actions[1],
20331 (20, None, Some(0)),
20332 "the parent action should stop at EOF"
20333 );
20334 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20335 assert_eq!(root.stop().map(|token| token.token_type()), Some(TOKEN_EOF));
20336 let child = root
20337 .child_rules(1)
20338 .next()
20339 .expect("the parent should contain the child rule");
20340 assert_eq!(
20341 child.stop().map(|token| token.token_type()),
20342 Some(TOKEN_EOF)
20343 );
20344 }
20345
20346 #[test]
20347 fn committed_walker_does_not_run_action_in_losing_alternative() {
20348 let atn = losing_alternative_action_atn();
20349 let mut parser = mini_parser_with_hooks(
20350 vec![
20351 TestToken::new(2).with_text("y"),
20352 TestToken::eof("parser-test", 1, 1, 1),
20353 ],
20354 StatefulActionHooks::default(),
20355 );
20356
20357 let (tree, deferred_actions) = parser
20358 .parse_atn_rule_with_runtime_options(
20359 &atn,
20360 0,
20361 ParserRuntimeOptions {
20362 action_indices: &[(2, 0)],
20363 ..ParserRuntimeOptions::default()
20364 },
20365 )
20366 .expect("the token-led second alternative should be selected");
20367
20368 assert_eq!(parser.node(tree).text(), "y");
20369 assert!(deferred_actions.is_empty());
20370 assert!(parser.semantic_hooks.events.is_empty());
20371 }
20372
20373 #[test]
20374 fn committed_walker_honors_decision_overrides() {
20375 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20376 let predicates = [(0, 0, ParserPredicate::True), (0, 1, ParserPredicate::True)];
20377 let mut parser = mini_parser_with_hooks(
20378 vec![
20379 TestToken::new(1).with_text("x"),
20380 TestToken::eof("parser-test", 1, 1, 1),
20381 ],
20382 ForcedSecondAlternativeHooks::default(),
20383 );
20384
20385 let (tree, deferred_actions) = parser
20386 .parse_atn_rule_with_runtime_options(
20387 &atn,
20388 0,
20389 ParserRuntimeOptions {
20390 action_indices: &[(usize::MAX, 0)],
20391 track_alt_numbers: true,
20392 predicates: &predicates,
20393 ..ParserRuntimeOptions::default()
20394 },
20395 )
20396 .expect("the forced second alternative should parse");
20397
20398 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20399 assert_eq!(root.alt_number(), 2);
20400 assert_eq!(root.text(), "x<EOF>");
20401 assert!(deferred_actions.is_empty());
20402 assert_eq!(parser.semantic_hooks.decisions, [(0, 0, 2)]);
20403 assert_eq!(parser.number_of_syntax_errors(), 0);
20404 }
20405
20406 #[test]
20407 fn committed_walker_sll_mode_does_not_report_full_context_diagnostics() {
20408 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20409 let predicates = [(0, 0, ParserPredicate::True), (0, 1, ParserPredicate::True)];
20410 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20411 let mut parser = mini_parser(vec![
20412 TestToken::new(1).with_text("x"),
20413 TestToken::eof("parser-test", 1, 1, 1),
20414 ]);
20415 parser.set_prediction_mode(PredictionMode::Sll);
20416 parser.set_report_diagnostic_errors(true);
20417 parser.remove_error_listeners();
20418 parser.add_error_listener(RecordingErrorListener {
20419 diagnostics: Arc::clone(&diagnostics),
20420 });
20421
20422 let (tree, deferred_actions) = parser
20423 .parse_atn_rule_with_runtime_options(
20424 &atn,
20425 0,
20426 ParserRuntimeOptions {
20427 action_indices: &[(usize::MAX, 0)],
20428 predicates: &predicates,
20429 ..ParserRuntimeOptions::default()
20430 },
20431 )
20432 .expect("SLL prediction should select the first viable alternative");
20433
20434 assert_eq!(parser.node(tree).text(), "x<EOF>");
20435 assert!(deferred_actions.is_empty());
20436 assert_eq!(parser.number_of_syntax_errors(), 0);
20437 assert!(
20438 diagnostics
20439 .lock()
20440 .expect("recorded diagnostics lock")
20441 .is_empty(),
20442 "SLL mode must not retry with full context or report LL diagnostics"
20443 );
20444 }
20445
20446 #[test]
20447 fn committed_sll_containment_conflict_enables_token_deletion_recovery() {
20448 let atn = context_containment_recovery_atn();
20449 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20450 let mut parser = mini_parser_with_hooks(
20451 vec![
20452 TestToken::new(1).with_text("a"),
20453 TestToken::new(2).with_text("b"),
20454 TestToken::new(5).with_text("x"),
20455 TestToken::new(3).with_text("c"),
20456 TestToken::eof("parser-test", 4, 1, 4),
20457 ],
20458 ContainmentRecoveryHooks::default(),
20459 );
20460 parser.set_prediction_mode(PredictionMode::Sll);
20461 parser.remove_error_listeners();
20462 parser.add_error_listener(RecordingErrorListener {
20463 diagnostics: Arc::clone(&diagnostics),
20464 });
20465
20466 let (tree, deferred_actions) = parser
20467 .parse_atn_rule_with_runtime_options(
20468 &atn,
20469 0,
20470 ParserRuntimeOptions {
20471 action_indices: &[(usize::MAX, 0)],
20472 ..ParserRuntimeOptions::default()
20473 },
20474 )
20475 .expect("the selected alternative should recover by deleting token x");
20476
20477 assert!(deferred_actions.is_empty());
20478 assert_eq!(parser.node(tree).text(), "abxc<EOF>");
20479 assert_eq!(parser.number_of_syntax_errors(), 1);
20480 assert_eq!(parser.semantic_hooks.decisions, [(0, 0, 2), (1, 0, 2)]);
20481 insta::assert_debug_snapshot!(
20482 "committed_sll_containment_conflict_enables_token_deletion_recovery",
20483 diagnostics
20484 .lock()
20485 .expect("recorded diagnostics lock")
20486 .as_slice()
20487 );
20488 }
20489
20490 #[test]
20491 fn committed_walker_filters_diagnostics_after_semantic_selection() {
20492 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20493 let predicates = [
20494 (0, 0, ParserPredicate::False),
20495 (0, 1, ParserPredicate::True),
20496 ];
20497 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20498 let mut parser = mini_parser(vec![
20499 TestToken::new(1).with_text("x"),
20500 TestToken::eof("parser-test", 1, 1, 1),
20501 ]);
20502 parser.set_prediction_mode(PredictionMode::LlExactAmbigDetection);
20503 parser.set_report_diagnostic_errors(true);
20504 parser.remove_error_listeners();
20505 parser.add_error_listener(RecordingErrorListener {
20506 diagnostics: Arc::clone(&diagnostics),
20507 });
20508
20509 let (tree, _) = parser
20510 .parse_atn_rule_with_runtime_options(
20511 &atn,
20512 0,
20513 ParserRuntimeOptions {
20514 action_indices: &[(usize::MAX, 0)],
20515 track_alt_numbers: true,
20516 predicates: &predicates,
20517 ..ParserRuntimeOptions::default()
20518 },
20519 )
20520 .expect("the true predicate should make the second alternative unique");
20521
20522 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20523 assert_eq!(root.alt_number(), 2);
20524 assert!(
20525 diagnostics
20526 .lock()
20527 .expect("recorded diagnostics lock")
20528 .is_empty(),
20529 "predicate filtering made the decision unambiguous"
20530 );
20531 }
20532
20533 #[test]
20534 fn committed_walker_skips_diagnostic_only_predicates_when_reporting_is_disabled() {
20535 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20536 let mut parser = mini_parser_with_hooks(
20537 vec![
20538 TestToken::new(1).with_text("x"),
20539 TestToken::eof("parser-test", 1, 1, 1),
20540 ],
20541 RecordingHooks::default(),
20542 );
20543 parser.set_prediction_mode(PredictionMode::LlExactAmbigDetection);
20544
20545 let (tree, _) = parser
20546 .parse_atn_rule_with_runtime_options(
20547 &atn,
20548 0,
20549 ParserRuntimeOptions {
20550 action_indices: &[(usize::MAX, 0)],
20551 track_alt_numbers: true,
20552 ..ParserRuntimeOptions::default()
20553 },
20554 )
20555 .expect("the first predicate-bearing alternative should parse");
20556
20557 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20558 assert_eq!(root.alt_number(), 1);
20559 assert_eq!(
20560 parser.semantic_hooks.predicates,
20561 [
20562 (0, 0, 0, Some("x".to_owned())),
20563 (0, 0, 0, Some("x".to_owned())),
20564 ],
20565 "diagnostic-only alternatives must not invoke semantic hooks"
20566 );
20567 }
20568
20569 #[test]
20570 fn committed_walker_falls_back_only_to_simulator_viable_alternatives() {
20571 let atn = semantic_fallback_viability_atn();
20572 let predicates = [
20573 (0, 0, ParserPredicate::False),
20574 (0, 1, ParserPredicate::True),
20575 ];
20576 let mut parser = mini_parser(vec![
20577 TestToken::new(1).with_text("a"),
20578 TestToken::new(3).with_text("c"),
20579 TestToken::eof("parser-test", 2, 1, 2),
20580 ]);
20581
20582 let (tree, deferred_actions) = parser
20583 .parse_atn_rule_with_runtime_options(
20584 &atn,
20585 0,
20586 ParserRuntimeOptions {
20587 action_indices: &[(usize::MAX, 0)],
20588 track_alt_numbers: true,
20589 predicates: &predicates,
20590 ..ParserRuntimeOptions::default()
20591 },
20592 )
20593 .expect("the true A C alternative should survive semantic fallback");
20594
20595 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20596 assert_eq!(root.alt_number(), 3);
20597 assert_eq!(root.text(), "ac<EOF>");
20598 assert!(deferred_actions.is_empty());
20599 assert_eq!(parser.number_of_syntax_errors(), 0);
20600 }
20601
20602 #[test]
20603 fn committed_walker_evaluates_predicates_reached_through_rule_calls() {
20604 let atn = rule_call_predicate_decision_atn();
20605 let predicates = [(1, 0, ParserPredicate::False)];
20606 let mut parser = mini_parser(vec![
20607 TestToken::new(1).with_text("a"),
20608 TestToken::eof("parser-test", 1, 1, 1),
20609 ]);
20610
20611 let (tree, deferred_actions) = parser
20612 .parse_atn_rule_with_runtime_options(
20613 &atn,
20614 0,
20615 ParserRuntimeOptions {
20616 action_indices: &[(usize::MAX, 0)],
20617 track_alt_numbers: true,
20618 predicates: &predicates,
20619 ..ParserRuntimeOptions::default()
20620 },
20621 )
20622 .expect("the direct caller alternative should survive the false callee predicate");
20623
20624 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20625 assert_eq!(root.alt_number(), 2);
20626 assert_eq!(root.text(), "a<EOF>");
20627 assert_eq!(root.child_rules(1).count(), 0);
20628 assert!(deferred_actions.is_empty());
20629 assert_eq!(parser.number_of_syntax_errors(), 0);
20630 }
20631
20632 #[test]
20633 fn committed_walker_uses_callee_argument_for_prediction_predicates() {
20634 let atn = rule_call_predicate_decision_atn();
20635 let predicates = [(1, 0, ParserPredicate::LocalIntEquals { value: 1 })];
20636 let rule_args = [ParserRuleArg {
20637 source_state: 2,
20638 rule_index: 1,
20639 value: 2,
20640 inherit_local: false,
20641 }];
20642 let mut parser = mini_parser(vec![
20643 TestToken::new(1).with_text("a"),
20644 TestToken::eof("parser-test", 1, 1, 1),
20645 ]);
20646
20647 let (tree, _) = parser
20648 .parse_atn_rule_with_runtime_options(
20649 &atn,
20650 0,
20651 ParserRuntimeOptions {
20652 action_indices: &[(usize::MAX, 0)],
20653 track_alt_numbers: true,
20654 predicates: &predicates,
20655 rule_args: &rule_args,
20656 ..ParserRuntimeOptions::default()
20657 },
20658 )
20659 .expect("the direct alternative should survive the false callee predicate");
20660
20661 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20662 assert_eq!(root.alt_number(), 2);
20663 assert_eq!(root.child_rules(1).count(), 0);
20664 assert_eq!(parser.number_of_syntax_errors(), 0);
20665 }
20666
20667 #[test]
20668 fn committed_predicate_star_loop_uses_single_token_deletion() {
20669 let atn = predicate_gated_star_loop_atn();
20670 let predicates = [(0, 0, ParserPredicate::True)];
20671 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20672 let mut parser = mini_parser(vec![
20673 TestToken::new(2).with_text("x"),
20674 TestToken::new(1).with_text("a"),
20675 TestToken::eof("parser-test", 2, 1, 2),
20676 ]);
20677 parser.remove_error_listeners();
20678 parser.add_error_listener(RecordingErrorListener {
20679 diagnostics: Arc::clone(&diagnostics),
20680 });
20681
20682 let (tree, deferred_actions) = parser
20683 .parse_atn_rule_with_runtime_options(
20684 &atn,
20685 0,
20686 ParserRuntimeOptions {
20687 action_indices: &[(usize::MAX, 0)],
20688 predicates: &predicates,
20689 ..ParserRuntimeOptions::default()
20690 },
20691 )
20692 .expect("the loop decision should delete the extraneous token and continue");
20693
20694 assert_eq!(parser.node(tree).text(), "xa<EOF>");
20695 assert!(deferred_actions.is_empty());
20696 assert_eq!(parser.number_of_syntax_errors(), 1);
20697 insta::assert_debug_snapshot!(
20698 "committed_predicate_star_loop_uses_single_token_deletion",
20699 *diagnostics.lock().expect("recorded diagnostics lock")
20700 );
20701 }
20702
20703 #[test]
20704 fn committed_walker_applies_legacy_and_semir_actions_before_indexed_hooks() {
20705 let atn = committed_action_then_predicate_atn();
20706 let member_actions = [ParserMemberAction {
20707 source_state: 0,
20708 member: 0,
20709 delta: 2,
20710 }];
20711 let return_actions = [ParserReturnAction {
20712 source_state: 0,
20713 rule_index: 0,
20714 name: "legacy",
20715 value: 3,
20716 }];
20717 let predicates = [(
20718 0,
20719 0,
20720 ParserPredicate::MemberEquals {
20721 member: 0,
20722 value: 7,
20723 equals: true,
20724 },
20725 )];
20726 let mut ir = SemIr::new();
20727 let semantic_member = ParserMemberAction {
20728 source_state: 0,
20729 member: 0,
20730 delta: 5,
20731 }
20732 .lower_into_semir(&mut ir);
20733 let semantic_return = ParserReturnAction {
20734 source_state: 0,
20735 rule_index: 0,
20736 name: "semantic",
20737 value: 11,
20738 }
20739 .lower_into_semir(&mut ir);
20740 let semantics = ParserSemantics {
20741 ir,
20742 predicates: Vec::new(),
20743 actions: vec![semantic_member, semantic_return],
20744 };
20745 let mut parser = mini_parser_with_hooks(
20746 vec![
20747 TestToken::new(1).with_text("x"),
20748 TestToken::eof("parser-test", 1, 1, 1),
20749 ],
20750 StatefulActionHooks::default(),
20751 );
20752
20753 let (tree, deferred_actions) = parser
20754 .parse_atn_rule_with_runtime_options(
20755 &atn,
20756 0,
20757 ParserRuntimeOptions {
20758 action_indices: &[(0, 7)],
20759 predicates: &predicates,
20760 semantics: Some(&semantics),
20761 member_actions: &member_actions,
20762 return_actions: &return_actions,
20763 ..ParserRuntimeOptions::default()
20764 },
20765 )
20766 .expect("the predicate should observe both committed member actions");
20767
20768 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20769 assert_eq!(root.text(), "x<EOF>");
20770 assert_eq!(root.int_return("legacy"), Some(3));
20771 assert_eq!(root.int_return("semantic"), Some(11));
20772 assert_eq!(parser.int_member(0), Some(7));
20773 assert!(deferred_actions.is_empty());
20774 assert_eq!(parser.semantic_hooks.events, ["action:7"]);
20775 assert_eq!(parser.number_of_syntax_errors(), 0);
20776 }
20777
20778 #[test]
20779 fn committed_walker_runs_action_once_per_star_loop_iteration() {
20780 let atn = committed_action_star_loop_atn();
20781 let mut parser = mini_parser_with_hooks(
20782 vec![
20783 TestToken::new(1).with_text("a"),
20784 TestToken::new(1).with_text("b"),
20785 TestToken::eof("parser-test", 2, 1, 2),
20786 ],
20787 StatefulActionHooks::default(),
20788 );
20789
20790 let (tree, deferred_actions) = parser
20791 .parse_atn_rule_with_runtime_options(
20792 &atn,
20793 0,
20794 ParserRuntimeOptions {
20795 action_indices: &[(2, 3)],
20796 ..ParserRuntimeOptions::default()
20797 },
20798 )
20799 .expect("the committed star loop should parse");
20800
20801 assert_eq!(parser.node(tree).text(), "ab<EOF>");
20802 assert!(deferred_actions.is_empty());
20803 assert_eq!(parser.semantic_hooks.events, ["action:3", "action:3"]);
20804 }
20805
20806 #[test]
20807 fn committed_walker_has_no_total_step_cap() {
20808 const TOKEN_COUNT: usize = RECOGNITION_DEPTH_LIMIT + 1;
20809 let atn = committed_action_star_loop_atn();
20810 let mut parser = mini_parser(repeated_x_tokens(TOKEN_COUNT));
20811 parser.set_build_parse_trees(false);
20812
20813 parser
20814 .parse_atn_rule_with_runtime_options(
20815 &atn,
20816 0,
20817 ParserRuntimeOptions {
20818 action_indices: &[(usize::MAX, 0)],
20819 ..ParserRuntimeOptions::default()
20820 },
20821 )
20822 .expect("valid committed loops must not have a total-work cap");
20823
20824 assert_eq!(parser.input.index(), TOKEN_COUNT);
20825 assert_eq!(parser.number_of_syntax_errors(), 0);
20826 }
20827
20828 #[test]
20829 fn committed_walker_rejects_non_consuming_cycles() {
20830 let atn = committed_non_consuming_cycle_atn();
20831 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
20832 parser.set_bail_on_error(true);
20833
20834 let error = parser
20835 .parse_atn_rule_with_runtime_options(
20836 &atn,
20837 0,
20838 ParserRuntimeOptions {
20839 action_indices: &[(usize::MAX, 0)],
20840 ..ParserRuntimeOptions::default()
20841 },
20842 )
20843 .expect_err("a non-consuming cycle must not spin forever");
20844
20845 assert!(
20846 error.to_string().contains("non-consuming ATN cycle"),
20847 "unexpected error: {error}"
20848 );
20849 }
20850
20851 #[test]
20852 fn deeply_nested_committed_rule_calls_grow_the_stack() {
20853 const DEPTH: usize = 4_096;
20854 const STACK_SIZE: usize = 256 * 1024;
20855 let atn = nested_rule_chain_atn(DEPTH);
20856 std::thread::Builder::new()
20857 .name("nested-committed-rules".to_owned())
20858 .stack_size(STACK_SIZE)
20859 .spawn(move || {
20860 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
20861 parser.set_build_parse_trees(false);
20862 parser
20863 .parse_atn_rule_with_runtime_options(
20864 &atn,
20865 0,
20866 ParserRuntimeOptions {
20867 action_indices: &[(usize::MAX, 0)],
20868 ..ParserRuntimeOptions::default()
20869 },
20870 )
20871 .expect("nested committed rules should grow the native stack");
20872 assert_eq!(parser.input.index(), 1);
20873 })
20874 .expect("small-stack thread should start")
20875 .join()
20876 .expect("nested committed rules should not overflow their stack");
20877 }
20878
20879 #[test]
20880 fn committed_walker_runs_action_once_per_left_recursive_operator() {
20881 let atn = committed_action_left_recursive_atn();
20882 let mut parser = mini_parser_with_hooks(
20883 vec![
20884 TestToken::new(1).with_text("a"),
20885 TestToken::new(3).with_text("+"),
20886 TestToken::new(1).with_text("b"),
20887 TestToken::new(3).with_text("+"),
20888 TestToken::new(1).with_text("c"),
20889 TestToken::eof("parser-test", 5, 1, 5),
20890 ],
20891 StatefulActionHooks::default(),
20892 );
20893
20894 let (tree, deferred_actions) = parser
20895 .parse_atn_rule_with_runtime_options(
20896 &atn,
20897 0,
20898 ParserRuntimeOptions {
20899 action_indices: &[(6, 11)],
20900 ..ParserRuntimeOptions::default()
20901 },
20902 )
20903 .expect("the committed left-recursive rule should parse");
20904
20905 assert_eq!(parser.node(tree).text(), "a+b+c");
20906 assert!(deferred_actions.is_empty());
20907 assert_eq!(parser.semantic_hooks.events, ["action:11", "action:11"]);
20908 }
20909
20910 #[test]
20911 fn committed_left_recursive_depth_cap_keeps_listener_events_balanced() {
20912 let atn = committed_action_left_recursive_atn();
20913 let events = Arc::new(Mutex::new(Vec::new()));
20914 let mut parser = mini_parser(vec![
20915 TestToken::new(1).with_text("a"),
20916 TestToken::new(3).with_text("+"),
20917 TestToken::new(1).with_text("b"),
20918 TestToken::eof("parser-test", 3, 1, 3),
20919 ]);
20920 parser.set_max_rule_depth(Some(1));
20921 parser.add_parse_listener(RecordingParseListener {
20922 events: Arc::clone(&events),
20923 });
20924
20925 let error = parser
20926 .parse_atn_rule_with_runtime_options(
20927 &atn,
20928 0,
20929 ParserRuntimeOptions {
20930 action_indices: &[(6, 11)],
20931 ..ParserRuntimeOptions::default()
20932 },
20933 )
20934 .expect_err("the left-recursive expansion should exceed the depth cap");
20935
20936 insta::assert_debug_snapshot!(
20937 "committed_left_recursive_depth_cap_keeps_listener_events_balanced",
20938 (
20939 error.to_string(),
20940 events.lock().expect("parse-listener event lock").as_slice(),
20941 )
20942 );
20943 }
20944
20945 #[test]
20946 fn committed_walker_preserves_nested_rule_listener_events() {
20947 let atn = ordinary_star_loop_atn();
20948 let events = Arc::new(Mutex::new(Vec::new()));
20949 let mut parser = mini_parser(vec![
20950 TestToken::new(1).with_text("a"),
20951 TestToken::new(1).with_text("b"),
20952 TestToken::eof("parser-test", 2, 1, 2),
20953 ]);
20954 parser.add_parse_listener(RecordingParseListener {
20955 events: Arc::clone(&events),
20956 });
20957
20958 let (tree, _) = parser
20959 .parse_atn_rule_with_runtime_options(
20960 &atn,
20961 0,
20962 ParserRuntimeOptions {
20963 action_indices: &[(usize::MAX, 0)],
20964 ..ParserRuntimeOptions::default()
20965 },
20966 )
20967 .expect("the committed nested-rule path should parse");
20968
20969 assert_eq!(parser.node(tree).text(), "ab<EOF>");
20970 assert_eq!(
20971 *events.lock().expect("parse-listener event lock"),
20972 [
20973 "enter:0", "enter:1", "exit:1", "enter:1", "exit:1", "exit:0",
20974 ]
20975 );
20976 }
20977
20978 #[test]
20979 fn committed_walker_enforces_rule_depth_cap() {
20980 let atn = ordinary_star_loop_atn();
20981 let mut parser = mini_parser(vec![
20982 TestToken::new(1).with_text("a"),
20983 TestToken::eof("parser-test", 1, 1, 1),
20984 ]);
20985 parser.set_max_rule_depth(Some(1));
20986
20987 let error = parser
20988 .parse_atn_rule_with_runtime_options(
20989 &atn,
20990 0,
20991 ParserRuntimeOptions {
20992 action_indices: &[(usize::MAX, 0)],
20993 ..ParserRuntimeOptions::default()
20994 },
20995 )
20996 .expect_err("the nested rule should exceed the committed-path cap");
20997
20998 assert!(
20999 error
21000 .to_string()
21001 .contains("rule nesting depth limit of 1 exceeded"),
21002 "unexpected error: {error}"
21003 );
21004 }
21005
21006 #[test]
21007 fn committed_abort_precedes_and_clears_unhandled_action_error() {
21008 let atn = action_then_nested_rule_atn();
21009 let mut parser = mini_parser_with_hooks(
21010 vec![TestToken::eof("parser-test", 0, 1, 0)],
21011 DecliningActionHooks::default(),
21012 );
21013 parser.set_max_rule_depth(Some(1));
21014
21015 let error = parser
21016 .parse_atn_rule_with_runtime_options(
21017 &atn,
21018 0,
21019 ParserRuntimeOptions {
21020 action_indices: &[(0, 7)],
21021 unknown_predicate_policy: UnknownSemanticPolicy::Error,
21022 ..ParserRuntimeOptions::default()
21023 },
21024 )
21025 .expect_err("the recovered child abort must outrank the earlier action miss");
21026
21027 assert_eq!(parser.semantic_hooks.actions, [0]);
21028 assert!(
21029 error
21030 .to_string()
21031 .contains("rule nesting depth limit of 1 exceeded"),
21032 "unexpected error: {error}"
21033 );
21034 assert!(
21035 parser.take_parse_abort().is_none(),
21036 "the returned abort must not remain sticky"
21037 );
21038 assert!(
21039 parser.take_unknown_semantic_error().is_none(),
21040 "the masked action miss must not poison parser reuse"
21041 );
21042 }
21043
21044 #[test]
21045 fn top_level_committed_semantic_error_does_not_poison_reuse() {
21046 let atn = committed_action_then_predicate_atn();
21047 let predicates = [(0, 0, ParserPredicate::True)];
21048 let mut parser = mini_parser_with_hooks(
21049 vec![
21050 TestToken::new(1).with_text("x"),
21051 TestToken::eof("parser-test", 1, 1, 1),
21052 ],
21053 DecliningActionHooks::default(),
21054 );
21055
21056 let error = parser
21057 .parse_atn_rule_with_runtime_options(
21058 &atn,
21059 0,
21060 ParserRuntimeOptions {
21061 action_indices: &[(0, 7)],
21062 predicates: &predicates,
21063 unknown_predicate_policy: UnknownSemanticPolicy::Error,
21064 ..ParserRuntimeOptions::default()
21065 },
21066 )
21067 .expect_err("the declined committed action must fail loud");
21068 assert!(
21069 error.to_string().contains("unhandled semantic action"),
21070 "unexpected error: {error}"
21071 );
21072
21073 parser.input.seek(0);
21074 let (tree, _) = parser
21075 .parse_atn_rule_with_runtime_options(
21076 &atn,
21077 0,
21078 ParserRuntimeOptions {
21079 predicates: &predicates,
21080 ..ParserRuntimeOptions::default()
21081 },
21082 )
21083 .expect("a clean interpreted reuse must not observe the prior action miss");
21084
21085 assert_eq!(parser.node(tree).text(), "x<EOF>");
21086 assert!(
21087 parser.take_unknown_semantic_error().is_none(),
21088 "the returned top-level semantic error must drain its recorded hit"
21089 );
21090 }
21091
21092 #[test]
21093 fn committed_walker_runs_handled_rule_init_before_indexed_action() {
21094 let atn = committed_action_then_predicate_atn();
21095 let mut parser = mini_parser_with_hooks(
21096 vec![
21097 TestToken::new(1).with_text("x"),
21098 TestToken::eof("parser-test", 1, 1, 1),
21099 ],
21100 InitOrderingHooks::default(),
21101 );
21102
21103 let (_, deferred_actions) = parser
21104 .parse_atn_rule_with_runtime_options(
21105 &atn,
21106 0,
21107 ParserRuntimeOptions {
21108 init_action_rules: &[0],
21109 action_indices: &[(0, 7)],
21110 ..ParserRuntimeOptions::default()
21111 },
21112 )
21113 .expect("the named action should observe rule-init state");
21114
21115 assert!(deferred_actions.is_empty());
21116 assert_eq!(
21117 parser.semantic_hooks.events,
21118 ["init", "action:7:initialized=true", "predicate:true",]
21119 );
21120 }
21121
21122 #[test]
21123 fn committed_walker_defers_unhandled_rule_init_for_legacy_replay() {
21124 let atn = token_then_eof_atn();
21125 let mut parser = mini_parser(vec![
21126 TestToken::new(1).with_text("x"),
21127 TestToken::eof("parser-test", 1, 1, 1),
21128 ]);
21129
21130 let (_, deferred_actions) = parser
21131 .parse_atn_rule_with_runtime_options(
21132 &atn,
21133 0,
21134 ParserRuntimeOptions {
21135 init_action_rules: &[0],
21136 action_indices: &[(usize::MAX, 0)],
21137 unknown_predicate_policy: UnknownSemanticPolicy::Error,
21138 ..ParserRuntimeOptions::default()
21139 },
21140 )
21141 .expect("a declined init should remain available for legacy replay");
21142
21143 assert_eq!(
21144 deferred_actions,
21145 [ParserAction::new_rule_init(0, 0, Some(0))]
21146 );
21147 }
21148
21149 #[test]
21150 fn committed_walker_dispatches_recovery_diagnostics() {
21151 let atn = noop_action_then_token_then_eof_atn();
21152 let diagnostics = Arc::new(Mutex::new(Vec::new()));
21153 let mut parser = mini_parser_with_hooks(
21154 vec![
21155 TestToken::new(1).with_text("x"),
21156 TestToken::new(2).with_text("y"),
21157 TestToken::eof("parser-test", 2, 1, 2),
21158 ],
21159 StatefulActionHooks::default(),
21160 );
21161 parser.remove_error_listeners();
21162 parser.add_error_listener(RecordingErrorListener {
21163 diagnostics: Arc::clone(&diagnostics),
21164 });
21165
21166 let (tree, _) = parser
21167 .parse_atn_rule_with_runtime_options(
21168 &atn,
21169 0,
21170 ParserRuntimeOptions {
21171 action_indices: &[(0, 5)],
21172 ..ParserRuntimeOptions::default()
21173 },
21174 )
21175 .expect("the committed rule should recover");
21176
21177 assert_eq!(parser.node(tree).text(), "xy<EOF>");
21178 assert_eq!(parser.number_of_syntax_errors(), 1);
21179 insta::assert_debug_snapshot!(
21180 "committed_walker_dispatches_recovery_diagnostics",
21181 *diagnostics.lock().expect("recorded diagnostics lock")
21182 );
21183 }
21184
21185 #[test]
21186 fn committed_bail_error_notifies_error_listener() {
21187 let atn = noop_action_then_token_then_eof_atn();
21188 let diagnostics = Arc::new(Mutex::new(Vec::new()));
21189 let mut parser = mini_parser(vec![
21190 TestToken::new(2)
21191 .with_text("y")
21192 .with_span(0, 0)
21193 .with_byte_span(0, 1)
21194 .with_position(3, 5),
21195 TestToken::eof("parser-test", 1, 1, 1),
21196 ]);
21197 parser.set_bail_on_error(true);
21198 parser.remove_error_listeners();
21199 parser.add_error_listener(RecordingErrorListener {
21200 diagnostics: Arc::clone(&diagnostics),
21201 });
21202
21203 let error = parser
21204 .parse_atn_rule_with_runtime_options(
21205 &atn,
21206 0,
21207 ParserRuntimeOptions {
21208 action_indices: &[(0, 5)],
21209 ..ParserRuntimeOptions::default()
21210 },
21211 )
21212 .expect_err("bail mode must return the committed token mismatch");
21213 let diagnostics = diagnostics
21214 .lock()
21215 .expect("recorded diagnostics lock")
21216 .clone();
21217
21218 insta::assert_debug_snapshot!(
21219 "committed_bail_error_notifies_error_listener",
21220 (error, diagnostics)
21221 );
21222 }
21223
21224 #[test]
21225 fn semantic_hook_handles_committed_parser_action() {
21226 let atn = token_then_eof_atn();
21227 let mut parser = mini_parser_with_hooks(
21228 vec![
21229 TestToken::new(1).with_text("x"),
21230 TestToken::eof("parser-test", 1, 1, 1),
21231 ],
21232 RecordingHooks::default(),
21233 );
21234 let (tree, _) = parser
21235 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
21236 .expect("rule parses before action hook is tested");
21237
21238 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
21239 assert_eq!(
21240 parser.semantic_hooks.actions,
21241 vec![(42, "x".to_owned(), Some("s".to_owned()))]
21242 );
21243 assert_eq!(
21244 parser.semantic_hooks.action_trees,
21245 [Some("x<EOF>".to_owned())]
21246 );
21247 }
21248
21249 #[test]
21250 fn unhandled_committed_action_fails_loud_under_error_policy() {
21251 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21255 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
21256 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
21257
21258 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
21260
21261 let error = parser
21262 .take_unknown_semantic_error()
21263 .expect("an unhandled committed action under Error policy must fail loud");
21264 let AntlrError::Unsupported(message) = error else {
21265 panic!("expected AntlrError::Unsupported, got {error:?}");
21266 };
21267 assert!(
21268 message.contains("unhandled semantic action") && message.contains("state=42"),
21269 "message should name the dropped action coordinate: {message}"
21270 );
21271
21272 let mut lenient =
21274 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21275 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
21276 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
21277 assert!(lenient.take_unknown_semantic_error().is_none());
21278 }
21279
21280 #[test]
21281 fn translated_predicate_is_unaffected_by_error_policy() {
21282 let atn = predicate_after_token_atn();
21283 let mut parser = mini_parser(vec![
21284 TestToken::new(1).with_text("x"),
21285 TestToken::new(2).with_text("y"),
21286 TestToken::eof("parser-test", 2, 1, 2),
21287 ]);
21288
21289 let (tree, _) = parser
21290 .parse_atn_rule_with_runtime_options(
21291 &atn,
21292 0,
21293 ParserRuntimeOptions {
21294 predicates: &[(0, 0, ParserPredicate::True)],
21295 unknown_predicate_policy: UnknownSemanticPolicy::Error,
21296 ..ParserRuntimeOptions::default()
21297 },
21298 )
21299 .expect("a predicate covered by the table is not an unknown coordinate");
21300
21301 assert_eq!(parser.node(tree).text(), "xy");
21302 }
21303
21304 #[test]
21309 fn parser_speculative_replay_threads_stack_member_state() {
21310 let mut ir = SemIr::new();
21311 let one = ir.expr(PExpr::Int(1));
21312 let push = ir.stmt(AStmt::PushMember(0, one));
21313 let pop = ir.stmt(AStmt::PopMember(0));
21314 let semantics = ParserSemantics {
21315 ir,
21316 predicates: Vec::new(),
21317 actions: vec![
21318 ParserSemanticAction {
21319 source_state: 1,
21320 rule_index: usize::MAX,
21321 stmt: push,
21322 speculative: true,
21323 },
21324 ParserSemanticAction {
21325 source_state: 2,
21326 rule_index: usize::MAX,
21327 stmt: pop,
21328 speculative: true,
21329 },
21330 ],
21331 };
21332
21333 let pushed = member_values_after_action(1, &[], Some(&semantics), &MemberEnv::new());
21335 assert_eq!(pushed.stack_top(0), Some(1));
21336 assert_eq!(pushed.stack_len(0), 1);
21337
21338 assert_eq!(MemberEnv::new().stack_len(0), 0);
21341
21342 let popped = member_values_after_action(2, &[], Some(&semantics), &pushed);
21345 assert_eq!(popped.stack_top(0), None);
21346 assert_eq!(popped, MemberEnv::new(), "emptied stack must canonicalize");
21347
21348 let underflowed = member_values_after_action(2, &[], Some(&semantics), &MemberEnv::new());
21350 assert_eq!(underflowed, MemberEnv::new());
21351 }
21352
21353 fn hook_predicate_semantics() -> ParserSemantics {
21358 let mut ir = SemIr::new();
21359 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
21360 ParserSemantics {
21361 ir,
21362 predicates: vec![ParserSemanticPredicate {
21363 rule_index: 0,
21364 pred_index: 0,
21365 expr,
21366 failure_message: None,
21367 }],
21368 actions: Vec::new(),
21369 }
21370 }
21371
21372 #[derive(Debug, Default)]
21373 struct DecliningHooks;
21374
21375 impl SemanticHooks for DecliningHooks {}
21376
21377 #[test]
21378 fn semir_hook_none_falls_through_to_assume_true() {
21379 let atn = predicate_after_token_atn();
21380 let semantics = hook_predicate_semantics();
21381 let mut parser = mini_parser_with_hooks(
21382 vec![
21383 TestToken::new(1).with_text("x"),
21384 TestToken::new(2).with_text("y"),
21385 TestToken::eof("parser-test", 2, 1, 2),
21386 ],
21387 DecliningHooks,
21388 );
21389
21390 let (tree, _) = parser
21391 .parse_atn_rule_with_runtime_options(
21392 &atn,
21393 0,
21394 ParserRuntimeOptions {
21395 semantics: Some(&semantics),
21396 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
21397 ..ParserRuntimeOptions::default()
21398 },
21399 )
21400 .expect("a declined SemIR hook must pass under assume-true");
21401
21402 assert_eq!(parser.node(tree).text(), "xy");
21403 }
21404
21405 #[test]
21406 fn semir_hook_none_falls_through_to_assume_false() {
21407 let atn = predicate_after_token_atn();
21408 let semantics = hook_predicate_semantics();
21409 let mut parser = mini_parser_with_hooks(
21410 vec![
21411 TestToken::new(1).with_text("x"),
21412 TestToken::new(2).with_text("y"),
21413 TestToken::eof("parser-test", 2, 1, 2),
21414 ],
21415 DecliningHooks,
21416 );
21417
21418 let result = parser.parse_atn_rule_with_runtime_options(
21419 &atn,
21420 0,
21421 ParserRuntimeOptions {
21422 semantics: Some(&semantics),
21423 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
21424 ..ParserRuntimeOptions::default()
21425 },
21426 );
21427
21428 assert!(
21429 result.is_err(),
21430 "a declined SemIR hook must fail the only guarded path under assume-false"
21431 );
21432 }
21433
21434 #[test]
21435 fn semir_hook_none_records_coordinate_under_error_policy() {
21436 let atn = predicate_after_token_atn();
21437 let semantics = hook_predicate_semantics();
21438 let mut parser = mini_parser_with_hooks(
21439 vec![
21440 TestToken::new(1).with_text("x"),
21441 TestToken::new(2).with_text("y"),
21442 TestToken::eof("parser-test", 2, 1, 2),
21443 ],
21444 DecliningHooks,
21445 );
21446
21447 let error = parser
21448 .parse_atn_rule_with_runtime_options(
21449 &atn,
21450 0,
21451 ParserRuntimeOptions {
21452 semantics: Some(&semantics),
21453 unknown_predicate_policy: UnknownSemanticPolicy::Error,
21454 ..ParserRuntimeOptions::default()
21455 },
21456 )
21457 .expect_err("a declined SemIR hook under Error policy must fail the parse");
21458
21459 let AntlrError::Unsupported(message) = error else {
21460 panic!("expected AntlrError::Unsupported, got {error:?}");
21461 };
21462 assert!(
21463 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
21464 "message should name the unresolved coordinate: {message}"
21465 );
21466 }
21467
21468 #[test]
21469 fn generated_direct_predicate_honors_installed_policy() {
21470 let semantics = hook_predicate_semantics();
21476 let context = ParserRuleContext::new(0, -1);
21477
21478 let mut assume_true =
21479 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21480 assert!(
21481 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
21482 &semantics, 0, 0, &context, 0
21483 ),
21484 "default AssumeTrue accepts a declined hook"
21485 );
21486 assert!(assume_true.take_unknown_semantic_error().is_none());
21487
21488 let mut error_policy =
21489 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21490 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
21491 assert!(
21492 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
21493 &semantics, 0, 0, &context, 0
21494 ),
21495 "Error policy rejects a declined hook on the generated-direct path"
21496 );
21497 let error = error_policy
21498 .take_unknown_semantic_error()
21499 .expect("Error policy records the unresolved coordinate for the generated path");
21500 let AntlrError::Unsupported(message) = error else {
21501 panic!("expected AntlrError::Unsupported, got {error:?}");
21502 };
21503 assert!(message.contains("pred_index=0"), "message: {message}");
21504 }
21505
21506 #[test]
21507 fn parser_rule_start_skips_leading_hidden_tokens() {
21508 let atn = token_then_eof_atn();
21509 let mut parser = mini_parser(vec![
21510 TestToken::new(99)
21511 .with_text(" ")
21512 .with_channel(HIDDEN_CHANNEL),
21513 TestToken::new(1).with_text("x"),
21514 TestToken::eof("parser-test", 2, 1, 2),
21515 ]);
21516
21517 let tree = parser
21518 .parse_atn_rule(&atn, 0)
21519 .expect("artificial parser rule should parse");
21520 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
21521 panic!("rule node should be present");
21522 };
21523 assert_eq!(
21524 rule.start()
21525 .expect("rule should have a start token")
21526 .token_type(),
21527 1
21528 );
21529 }
21530
21531 #[test]
21532 fn parser_action_after_eof_stops_at_eof_token() {
21533 let atn = eof_then_action_atn();
21534 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
21535
21536 let (_, actions) = parser
21537 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
21538 .expect("EOF action rule should parse");
21539
21540 assert_eq!(actions.len(), 1);
21541 assert_eq!(actions[0].stop_index(), Some(0));
21542 assert_eq!(
21543 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
21544 ""
21545 );
21546 }
21547
21548 #[test]
21549 fn after_action_stop_uses_rule_context_stop_not_cursor() {
21550 let mut id = TestToken::new(1).with_text("x");
21555 id.set_token_index(0);
21556 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
21557 eof.set_token_index(1);
21558 let mut parser = mini_parser(vec![id.clone(), eof]);
21559 parser.consume();
21561 assert_eq!(parser.la(1), TOKEN_EOF);
21562
21563 let mut ctx = ParserRuleContext::new(0, 0);
21566 parser.set_context_stop(
21567 &mut ctx,
21568 parser.token_id_at(0).expect("ID token should be buffered"),
21569 );
21570 let tree = parser.rule_node(ctx);
21571
21572 let current_index = parser.input.index();
21573 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
21575 assert_eq!(
21577 parser.after_action_stop_index_for_tree(tree, current_index),
21578 Some(0)
21579 );
21580 }
21581
21582 #[test]
21583 fn after_action_start_uses_rule_context_start_not_cursor() {
21584 let mut parser = mini_parser(vec![
21589 TestToken::new(9)
21590 .with_text(" ")
21591 .with_channel(HIDDEN_CHANNEL),
21592 TestToken::new(9)
21593 .with_text(" ")
21594 .with_channel(HIDDEN_CHANNEL),
21595 TestToken::new(1).with_text("x"),
21596 TestToken::eof("parser-test", 3, 1, 3),
21597 ]);
21598
21599 let mut ctx = ParserRuleContext::new(0, 0);
21600 parser.set_context_start(
21601 &mut ctx,
21602 parser.token_id_at(2).expect("ID token should be buffered"),
21603 );
21604 let tree = parser.rule_node(ctx);
21605
21606 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
21609
21610 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
21612 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
21613 }
21614
21615 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
21616 FastRecognizeOutcome {
21617 index,
21618 consumed_eof,
21619 diagnostics: DiagnosticSeqId::EMPTY,
21620 deferred_nodes: FastDeferredNodeId::EMPTY,
21621 nodes: NodeSeqId(marker),
21622 }
21623 }
21624
21625 #[test]
21626 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
21627 let mut outcomes = vec![
21628 clean_fast_outcome(4, false, 0),
21629 clean_fast_outcome(2, false, 1),
21630 clean_fast_outcome(4, false, 2),
21631 clean_fast_outcome(4, true, 3),
21632 clean_fast_outcome(2, false, 4),
21633 ];
21634 let mut scratch = FastOutcomeDedupScratch::default();
21635
21636 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21637
21638 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
21639 assert_eq!(
21640 outcomes
21641 .iter()
21642 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
21643 .collect::<Vec<_>>(),
21644 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
21645 );
21646 assert!(scratch.dense_words.is_empty());
21647 assert!(scratch.sparse_keys.is_empty());
21648 }
21649
21650 #[test]
21651 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
21652 let mut scratch = FastOutcomeDedupScratch::default();
21653 let mut outcomes = (100..109)
21654 .flat_map(|index| {
21655 [
21656 clean_fast_outcome(
21657 index,
21658 false,
21659 u32::try_from(index).expect("test index fits in u32"),
21660 ),
21661 clean_fast_outcome(index, false, u32::MAX),
21662 ]
21663 })
21664 .collect();
21665
21666 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21667
21668 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
21669 assert_eq!(outcomes.len(), 9);
21670 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
21671 let dense_capacity = scratch.dense_words.capacity();
21672
21673 let mut reused = (1_000..1_009)
21674 .map(|index| {
21675 clean_fast_outcome(
21676 index,
21677 false,
21678 u32::try_from(index).expect("test index fits in u32"),
21679 )
21680 })
21681 .collect();
21682 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
21683
21684 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
21685 assert_eq!(reused.len(), 9);
21686 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
21687 }
21688
21689 #[test]
21690 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
21691 let mut scratch = FastOutcomeDedupScratch::default();
21692 let sparse_indexes = [
21693 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
21694 ];
21695 let mut outcomes = sparse_indexes
21696 .into_iter()
21697 .chain([400_000])
21698 .enumerate()
21699 .map(|(marker, index)| {
21700 clean_fast_outcome(
21701 index,
21702 false,
21703 u32::try_from(marker).expect("test marker fits in u32"),
21704 )
21705 })
21706 .collect();
21707
21708 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21709
21710 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21711 assert_eq!(outcomes.len(), sparse_indexes.len());
21712 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
21713 let sparse_capacity = scratch.sparse_keys.capacity();
21714
21715 let mut reused = sparse_indexes
21716 .into_iter()
21717 .map(|index| {
21718 clean_fast_outcome(
21719 index,
21720 false,
21721 u32::try_from(index).expect("test index fits in u32"),
21722 )
21723 })
21724 .collect();
21725 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
21726
21727 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21728 assert_eq!(reused.len(), sparse_indexes.len());
21729 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
21730 }
21731
21732 #[test]
21733 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
21734 let mut scratch = FastOutcomeDedupScratch::default();
21735 scratch
21736 .sparse_keys
21737 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
21738 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
21739 let mut outcomes = (0..9)
21740 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
21741 .collect();
21742
21743 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21744
21745 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21746 assert!(scratch.sparse_keys.is_empty());
21747 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
21748 }
21749
21750 #[test]
21751 fn fast_outcome_selection_respects_sll_tie_order() {
21752 let mut arena = RecognitionArena::default();
21753 let first = FastRecognizeOutcome {
21754 index: 1,
21755 consumed_eof: false,
21756 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21757 line: 1,
21758 column: 0,
21759 message: "mismatched input 'x'".to_owned(),
21760 offending: None,
21761 }]),
21762 deferred_nodes: FastDeferredNodeId::EMPTY,
21763 nodes: NodeSeqId::EMPTY,
21764 };
21765 let second = FastRecognizeOutcome {
21766 index: first.index,
21767 consumed_eof: first.consumed_eof,
21768 diagnostics: DiagnosticSeqId::EMPTY,
21769 deferred_nodes: FastDeferredNodeId::EMPTY,
21770 nodes: NodeSeqId::EMPTY,
21771 };
21772
21773 let selected = select_best_fast_outcome(
21774 [first, second].into_iter(),
21775 PredictionMode::Sll,
21776 None,
21777 |_| panic!("caller-follow token probe should not run"),
21778 &arena,
21779 )
21780 .expect("one outcome should be selected");
21781 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
21782 let eof_second = FastRecognizeOutcome {
21783 index: second.index,
21784 consumed_eof: true,
21785 diagnostics: DiagnosticSeqId::EMPTY,
21786 deferred_nodes: FastDeferredNodeId::EMPTY,
21787 nodes: NodeSeqId::EMPTY,
21788 };
21789 let selected = select_best_fast_outcome(
21790 [first, eof_second].into_iter(),
21791 PredictionMode::Sll,
21792 None,
21793 |_| panic!("caller-follow token probe should not run"),
21794 &arena,
21795 )
21796 .expect("one outcome should be selected");
21797 assert!(!selected.consumed_eof);
21798 let selected = select_best_fast_outcome(
21799 [first, second].into_iter(),
21800 PredictionMode::Ll,
21801 None,
21802 |_| panic!("caller-follow token probe should not run"),
21803 &arena,
21804 )
21805 .expect("one outcome should be selected");
21806 assert!(selected.diagnostics.is_empty());
21807 }
21808
21809 #[test]
21810 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
21811 let mut arena = RecognitionArena::default();
21812 let first = FastRecognizeOutcome {
21813 index: 3,
21814 consumed_eof: false,
21815 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21816 line: 1,
21817 column: 0,
21818 message: "mismatched input 'x' expecting 'a'".to_owned(),
21819 offending: None,
21820 }]),
21821 deferred_nodes: FastDeferredNodeId::EMPTY,
21822 nodes: NodeSeqId::EMPTY,
21823 };
21824 let same_rank = FastRecognizeOutcome {
21825 index: first.index,
21826 consumed_eof: first.consumed_eof,
21827 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21828 line: 1,
21829 column: 0,
21830 message: "mismatched input 'x' expecting 'b'".to_owned(),
21831 offending: None,
21832 }]),
21833 deferred_nodes: FastDeferredNodeId::EMPTY,
21834 nodes: NodeSeqId::EMPTY,
21835 };
21836 let better_rank = FastRecognizeOutcome {
21837 index: first.index,
21838 consumed_eof: first.consumed_eof,
21839 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21840 line: 1,
21841 column: 0,
21842 message: "missing 'a' at 'x'".to_owned(),
21843 offending: None,
21844 }]),
21845 deferred_nodes: FastDeferredNodeId::EMPTY,
21846 nodes: NodeSeqId::EMPTY,
21847 };
21848 let mut outcomes = vec![first, same_rank, better_rank];
21849
21850 dedupe_fast_outcomes(&mut outcomes, &arena);
21851
21852 assert_eq!(outcomes.len(), 2);
21853 assert_eq!(
21854 arena
21855 .diagnostics(outcomes[0].diagnostics)
21856 .next()
21857 .expect("first diagnostic")
21858 .message,
21859 "mismatched input 'x' expecting 'a'"
21860 );
21861 assert_eq!(
21862 arena
21863 .diagnostics(outcomes[1].diagnostics)
21864 .next()
21865 .expect("second diagnostic")
21866 .message,
21867 "missing 'a' at 'x'"
21868 );
21869 }
21870
21871 #[test]
21872 fn fast_outcome_selection_prefers_generated_caller_follow() {
21873 let arena = RecognitionArena::default();
21874 let earlier = FastRecognizeOutcome {
21875 index: 7,
21876 consumed_eof: false,
21877 diagnostics: DiagnosticSeqId::EMPTY,
21878 deferred_nodes: FastDeferredNodeId::EMPTY,
21879 nodes: NodeSeqId::EMPTY,
21880 };
21881 let later = FastRecognizeOutcome {
21882 index: 8,
21883 consumed_eof: false,
21884 diagnostics: DiagnosticSeqId::EMPTY,
21885 deferred_nodes: FastDeferredNodeId::EMPTY,
21886 nodes: NodeSeqId::EMPTY,
21887 };
21888 let mut follow = TokenBitSet::default();
21889 follow.insert(5);
21890
21891 let selected = select_best_fast_outcome(
21892 [later, earlier].into_iter(),
21893 PredictionMode::Ll,
21894 Some(&follow),
21895 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
21896 &arena,
21897 )
21898 .expect("one outcome should be selected");
21899 assert_eq!(selected.index, 7);
21900
21901 let selected = select_best_fast_outcome(
21902 [later, earlier].into_iter(),
21903 PredictionMode::Ll,
21904 Some(&follow),
21905 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
21906 &arena,
21907 )
21908 .expect("one outcome should be selected");
21909 assert_eq!(selected.index, 8);
21910
21911 let indented_next_statement = FastRecognizeOutcome {
21912 index: 9,
21913 consumed_eof: false,
21914 diagnostics: DiagnosticSeqId::EMPTY,
21915 deferred_nodes: FastDeferredNodeId::EMPTY,
21916 nodes: NodeSeqId::EMPTY,
21917 };
21918 let selected = select_best_fast_outcome(
21919 [indented_next_statement, earlier].into_iter(),
21920 PredictionMode::Ll,
21921 Some(&follow),
21922 |index| {
21923 let is_boundary = index == 7;
21924 let is_boundary_gap = matches!(index, 7 | 8);
21925 (
21926 if index == 7 { 5 } else { TOKEN_EOF },
21927 is_boundary,
21928 is_boundary_gap,
21929 )
21930 },
21931 &arena,
21932 )
21933 .expect("one outcome should be selected");
21934 assert_eq!(selected.index, 7);
21935
21936 let continuation = FastRecognizeOutcome {
21937 index: 10,
21938 consumed_eof: false,
21939 diagnostics: DiagnosticSeqId::EMPTY,
21940 deferred_nodes: FastDeferredNodeId::EMPTY,
21941 nodes: NodeSeqId::EMPTY,
21942 };
21943 let selected = select_best_fast_outcome(
21944 [continuation, earlier].into_iter(),
21945 PredictionMode::Ll,
21946 Some(&follow),
21947 |index| {
21948 let is_boundary = matches!(index, 7 | 9);
21949 (
21950 if index == 7 { 5 } else { TOKEN_EOF },
21951 is_boundary,
21952 is_boundary,
21953 )
21954 },
21955 &arena,
21956 )
21957 .expect("one outcome should be selected");
21958 assert_eq!(selected.index, 10);
21959
21960 let selected = select_best_fast_outcome(
21961 [earlier, later].into_iter(),
21962 PredictionMode::Sll,
21963 Some(&follow),
21964 |_| panic!("caller-follow token probe should not run in SLL mode"),
21965 &arena,
21966 )
21967 .expect("one outcome should be selected");
21968 assert_eq!(selected.index, 8);
21969 }
21970
21971 #[test]
21972 fn caller_follow_boundary_text_requires_separator_shape() {
21973 assert!(is_caller_follow_boundary_text(";"));
21974 assert!(is_caller_follow_boundary_text("\n"));
21975 assert!(is_caller_follow_boundary_text("\r\n "));
21976 assert!(is_caller_follow_boundary_text(";\n"));
21977 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
21978 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
21979 assert!(!is_caller_follow_boundary_text("identifier"));
21980 assert!(is_caller_follow_boundary_gap_text(" \t "));
21981 assert!(is_caller_follow_boundary_gap_text("\n "));
21982 assert!(is_caller_follow_boundary_gap_text(";\t"));
21983 assert!(!is_caller_follow_boundary_gap_text(
21984 "\"\"\"line1\nline2\"\"\""
21985 ));
21986 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
21987 }
21988
21989 #[test]
21990 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
21991 let mut parser = mini_parser(vec![
21992 TestToken::new(5).with_text("\n"),
21993 TestToken::new(6)
21994 .with_text("// comment\n")
21995 .with_channel(HIDDEN_CHANNEL),
21996 TestToken::new(1).with_text("x"),
21997 TestToken::eof("parser-test", 1, 2, 0),
21998 ]);
21999
22000 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
22001 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
22002 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
22003 }
22004
22005 #[test]
22006 fn caller_follow_token_info_uses_stream_visible_channel() {
22007 let source = Source {
22008 tokens: vec![
22009 TestToken::new(5).with_text("\n").with_channel(2),
22010 TestToken::new(1).with_text("x").with_channel(2),
22011 TestToken::new(6)
22012 .with_text("// comment\n")
22013 .with_channel(HIDDEN_CHANNEL),
22014 TestToken::eof("parser-test", 1, 2, 0),
22015 ],
22016 index: 0,
22017 };
22018 let data = RecognizerData::new(
22019 "Mini.g4",
22020 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
22021 );
22022 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
22023
22024 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
22025 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
22026 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
22027 }
22028
22029 #[test]
22030 fn reset_per_parse_caches_clears_state_expected_token_cache() {
22031 let atn = token_then_eof_atn();
22032 let mut parser = mini_parser(Vec::new());
22033
22034 let _ = parser.cached_state_expected_token_set(&atn, 0);
22035 assert!(!parser.state_expected_token_cache.is_empty());
22036
22037 parser.reset_per_parse_caches();
22038 assert!(parser.state_expected_token_cache.is_empty());
22039 }
22040
22041 #[test]
22042 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
22043 let cyclic = epsilon_cycle_atn();
22044 let acyclic = token_then_eof_atn();
22045 let mut parser = mini_parser(Vec::new());
22046
22047 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
22048 assert_eq!(
22049 parser.empty_cycle_cache_atn,
22050 Some(SharedAtnCacheKey::for_atn(&cyclic))
22051 );
22052 assert_eq!(parser.empty_cycle_cache[1], Some(true));
22053
22054 parser.reset_per_parse_caches();
22055 assert_eq!(parser.empty_cycle_cache[1], Some(true));
22056 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
22057
22058 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
22059 assert_eq!(
22060 parser.empty_cycle_cache_atn,
22061 Some(SharedAtnCacheKey::for_atn(&acyclic))
22062 );
22063 assert_eq!(parser.empty_cycle_cache[1], Some(false));
22064 }
22065
22066 #[test]
22067 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
22068 let source = Source {
22069 tokens: vec![
22070 TestToken::new(1).with_text("x"),
22071 TestToken::eof("parser-test", 1, 1, 1),
22072 ],
22073 index: 0,
22074 };
22075 let data = RecognizerData::new(
22076 "Mini.g4",
22077 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
22078 );
22079 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
22080 let expected = ExpectedTokens {
22081 index: Some(0),
22082 symbols: BTreeSet::new(),
22083 no_viable: None,
22084 };
22085
22086 let (_, message) = parser.expected_error_message(0, 0, &expected);
22087
22088 assert_eq!(message, "mismatched input 'x'");
22089 }
22090
22091 #[test]
22092 fn eof_rule_stop_index_points_at_eof_token() {
22093 let source = Source {
22094 tokens: vec![
22095 TestToken::new(1).with_text("x"),
22096 TestToken::eof("parser-test", 1, 1, 1),
22097 ],
22098 index: 0,
22099 };
22100 let data = RecognizerData::new(
22101 "Mini.g4",
22102 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
22103 );
22104 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
22105
22106 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
22107 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
22108 }
22109
22110 #[test]
22111 fn generated_parser_action_uses_current_rule_stop_boundary() {
22112 let mut parser = mini_parser(vec![
22113 TestToken::new(1).with_text("x"),
22114 TestToken::eof("parser-test", 1, 1, 1),
22115 ]);
22116
22117 parser.match_token(1).expect("token should match");
22118 let action = parser.parser_action_at_current(7, 0, 0, false);
22119 assert_eq!(action.source_state(), 7);
22120 assert_eq!(action.rule_index(), 0);
22121 assert_eq!(action.start_index(), 0);
22122 assert_eq!(action.stop_index(), Some(0));
22123
22124 parser.match_eof().expect("EOF should match");
22125 let action = parser.parser_action_at_current(8, 0, 0, true);
22126 assert_eq!(action.stop_index(), Some(1));
22127 }
22128
22129 #[test]
22130 fn folds_left_recursive_boundary_into_rule_node() {
22131 let mut arena = RecognitionArena::default();
22132 let first = arena.push_node(ArenaRecognizedNode::Token {
22133 token: TokenId::try_from(0).expect("test token ID"),
22134 });
22135 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
22136 rule_index: 1,
22137 alt_number: 3,
22138 });
22139 let second = arena.push_node(ArenaRecognizedNode::Token {
22140 token: TokenId::try_from(1).expect("test token ID"),
22141 });
22142 let mut nodes = NodeSeqId::EMPTY;
22143 for node in [first, boundary, second].into_iter().rev() {
22144 nodes = arena.prepend(nodes, node);
22145 }
22146
22147 let folded = arena.fold_left_recursive_boundaries(nodes);
22148 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
22149
22150 assert_eq!(folded_nodes.len(), 2);
22151 let ArenaRecognizedNode::Rule {
22152 rule_index,
22153 invoking_state,
22154 alt_number,
22155 start_index,
22156 stop_index,
22157 children,
22158 ..
22159 } = arena.node(folded_nodes[0])
22160 else {
22161 panic!("first folded node should be a rule");
22162 };
22163 insta::assert_debug_snapshot!(
22167 "folds_left_recursive_boundary_into_rule_node",
22168 (
22169 rule_index,
22170 invoking_state,
22171 alt_number,
22172 start_index,
22173 stop_index
22174 )
22175 );
22176 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
22177 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
22178
22179 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
22180 assert_eq!(
22181 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
22182 (4, 3, 1)
22183 );
22184 assert_eq!(
22185 (stats.total_links, stats.live_links, stats.dead_links),
22186 (9, 3, 6)
22187 );
22188 }
22189
22190 #[test]
22191 fn recognition_arena_reports_live_dead_and_retained_capacity() {
22192 let mut arena = RecognitionArena::default();
22193 let token = arena.push_node(ArenaRecognizedNode::Token {
22194 token: TokenId::try_from(0).expect("test token ID"),
22195 });
22196 let extra = arena.push_extra(RecognitionExtra::MissingToken {
22197 token_type: 2,
22198 at_index: 1,
22199 text: "<missing X>".to_owned(),
22200 });
22201 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
22202 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
22203 token: TokenId::try_from(1).expect("test token ID"),
22204 });
22205 let mut live = NodeSeqId::EMPTY;
22206 live = arena.prepend(live, missing);
22207 live = arena.prepend(live, token);
22208 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
22209 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
22210 line: 1,
22211 column: 0,
22212 message: "missing X".to_owned(),
22213 offending: None,
22214 }]);
22215 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
22216 line: 1,
22217 column: 1,
22218 message: "discarded".to_owned(),
22219 offending: None,
22220 }]);
22221 let deferred_children = arena.deferred_fragment(live);
22222 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
22223 rule_index: 0,
22224 invoking_state: -1,
22225 start_index: 0,
22226 stop_index: Some(1),
22227 deferred_children,
22228 children: NodeSeqId::EMPTY,
22229 });
22230
22231 let stats = arena.stats(live, live_diagnostics);
22232
22233 assert_eq!(
22234 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
22235 (3, 2, 1)
22236 );
22237 assert_eq!(
22238 (stats.total_links, stats.live_links, stats.dead_links),
22239 (5, 3, 2)
22240 );
22241 assert_eq!(
22242 (stats.total_extras, stats.live_extras, stats.dead_extras),
22243 (3, 2, 1)
22244 );
22245 assert!(size_of::<SeqLink>() <= 8);
22246 assert!(size_of::<DiagnosticLink>() <= 8);
22247 assert!(size_of::<FastDeferredNode>() <= 12);
22248 assert!(size_of::<FastDeferredRule>() <= 28);
22249 assert!(size_of::<FastRecognizeOutcome>() <= 24);
22250 let capacities = (
22251 stats.node_capacity,
22252 stats.link_capacity,
22253 stats.extra_capacity,
22254 );
22255 let deferred_capacities = (
22256 arena.deferred_nodes.capacity(),
22257 arena.deferred_rules.capacity(),
22258 );
22259
22260 arena.reset();
22261 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
22262 assert_eq!(
22263 (reset.total_nodes, reset.total_links, reset.total_extras),
22264 (0, 0, 0)
22265 );
22266 assert_eq!(
22267 (
22268 reset.node_capacity,
22269 reset.link_capacity,
22270 reset.extra_capacity,
22271 ),
22272 capacities
22273 );
22274 assert!(arena.deferred_nodes.is_empty());
22275 assert!(arena.deferred_rules.is_empty());
22276 assert_eq!(
22277 (
22278 arena.deferred_nodes.capacity(),
22279 arena.deferred_rules.capacity(),
22280 ),
22281 deferred_capacities
22282 );
22283 }
22284
22285 #[test]
22286 fn parser_computes_recognition_arena_stats_on_demand() {
22287 let mut parser = mini_parser(Vec::new());
22288 let live = parser
22289 .recognition_arena
22290 .push_node(ArenaRecognizedNode::Token {
22291 token: TokenId::try_from(0).expect("test token ID"),
22292 });
22293 let discarded = parser
22294 .recognition_arena
22295 .push_node(ArenaRecognizedNode::ErrorToken {
22296 token: TokenId::try_from(1).expect("test token ID"),
22297 });
22298 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
22299 let _discarded_root = parser
22300 .recognition_arena
22301 .prepend(NodeSeqId::EMPTY, discarded);
22302 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
22303
22304 let stats = parser.recognition_arena_stats();
22305
22306 assert_eq!(
22307 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
22308 (2, 1, 1)
22309 );
22310 assert_eq!(
22311 (stats.total_links, stats.live_links, stats.dead_links),
22312 (2, 1, 1)
22313 );
22314 }
22315
22316 #[test]
22317 fn recognition_arena_drops_capacity_above_retention_limit() {
22318 let mut storage = Vec::<u8>::with_capacity(4);
22319 storage.extend([1, 2, 3]);
22320
22321 reset_arena_vec(&mut storage, 3);
22322
22323 assert!(storage.is_empty());
22324 assert_eq!(storage.capacity(), 0);
22325 }
22326
22327 #[test]
22328 fn recognition_arena_concatenates_diagnostics_in_source_order() {
22329 let mut arena = RecognitionArena::default();
22330 let prefix = arena.diagnostic_sequence([
22331 ParserDiagnostic {
22332 line: 1,
22333 column: 0,
22334 message: "first".to_owned(),
22335 offending: None,
22336 },
22337 ParserDiagnostic {
22338 line: 1,
22339 column: 1,
22340 message: "second".to_owned(),
22341 offending: None,
22342 },
22343 ]);
22344 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
22345 line: 1,
22346 column: 2,
22347 message: "third".to_owned(),
22348 offending: None,
22349 }]);
22350 let extras_before = arena.extras.len();
22351
22352 let combined = arena.concat_diagnostics(prefix, suffix);
22353 let messages = arena
22354 .diagnostics(combined)
22355 .map(|diagnostic| diagnostic.message.as_str())
22356 .collect::<Vec<_>>();
22357
22358 assert_eq!(messages, ["first", "second", "third"]);
22359 assert_eq!(arena.extras.len(), extras_before);
22360 }
22361
22362 #[test]
22363 fn outcome_ties_keep_later_non_recursive_alternative() {
22364 let arena = RecognitionArena::default();
22365 let first = RecognizeOutcome {
22366 index: 1,
22367 consumed_eof: false,
22368 alt_number: 0,
22369 member_values: MemberEnv::new(),
22370 return_values: BTreeMap::new(),
22371 diagnostics: DiagnosticSeqId::EMPTY,
22372 decisions: Vec::new(),
22373 actions: vec![ParserAction::new(1, 0, 0, None)],
22374 nodes: NodeSeqId::EMPTY,
22375 };
22376 let second = RecognizeOutcome {
22377 actions: vec![ParserAction::new(2, 0, 0, None)],
22378 ..first.clone()
22379 };
22380
22381 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22382 .expect("one outcome should be selected");
22383 assert_eq!(selected.actions[0].source_state(), 2);
22384 }
22385
22386 #[test]
22387 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
22388 let arena = RecognitionArena::default();
22389 let first = RecognizeOutcome {
22390 index: 1,
22391 consumed_eof: false,
22392 alt_number: 0,
22393 member_values: MemberEnv::new(),
22394 return_values: BTreeMap::new(),
22395 diagnostics: DiagnosticSeqId::EMPTY,
22396 decisions: Vec::new(),
22397 actions: vec![ParserAction::new(1, 0, 0, None)],
22398 nodes: NodeSeqId::EMPTY,
22399 };
22400 let second = RecognizeOutcome {
22401 actions: vec![
22402 ParserAction::new(2, 0, 0, None),
22403 ParserAction::new(3, 0, 0, None),
22404 ],
22405 ..first.clone()
22406 };
22407
22408 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
22409 .expect("one outcome should be selected");
22410 assert_eq!(selected.actions.len(), 2);
22411 }
22412
22413 #[test]
22414 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
22415 let arena = RecognitionArena::default();
22416 let first = RecognizeOutcome {
22417 index: 7,
22418 consumed_eof: false,
22419 alt_number: 0,
22420 member_values: MemberEnv::new(),
22421 return_values: BTreeMap::new(),
22422 diagnostics: DiagnosticSeqId::EMPTY,
22423 decisions: vec![1, 0],
22424 actions: vec![
22425 ParserAction::new(23, 2, 2, Some(4)),
22426 ParserAction::new(23, 2, 0, Some(6)),
22427 ],
22428 nodes: NodeSeqId::EMPTY,
22429 };
22430 let second = RecognizeOutcome {
22431 decisions: vec![0, 1],
22432 actions: vec![
22433 ParserAction::new(23, 2, 2, Some(6)),
22434 ParserAction::new(23, 2, 0, Some(6)),
22435 ],
22436 ..first.clone()
22437 };
22438
22439 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22440 .expect("one outcome should be selected");
22441 assert_eq!(selected.actions[0].stop_index(), Some(6));
22442 }
22443
22444 #[test]
22445 fn outcome_ties_keep_first_recursive_tree_shape() {
22446 let mut arena = RecognitionArena::default();
22447 let token = arena.push_node(ArenaRecognizedNode::Token {
22448 token: TokenId::try_from(0).expect("test token ID"),
22449 });
22450 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
22451 let inner = arena.push_node(ArenaRecognizedNode::Rule {
22452 rule_index: 1,
22453 invoking_state: -1,
22454 alt_number: 0,
22455 start_index: 0,
22456 stop_index: Some(0),
22457 return_values: None,
22458 children: token_children,
22459 });
22460 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
22461 let outer = arena.push_node(ArenaRecognizedNode::Rule {
22462 rule_index: 1,
22463 invoking_state: -1,
22464 alt_number: 0,
22465 start_index: 0,
22466 stop_index: Some(0),
22467 return_values: None,
22468 children: inner_children,
22469 });
22470 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
22471 let first = RecognizeOutcome {
22472 index: 1,
22473 consumed_eof: false,
22474 alt_number: 0,
22475 member_values: MemberEnv::new(),
22476 return_values: BTreeMap::new(),
22477 diagnostics: DiagnosticSeqId::EMPTY,
22478 decisions: Vec::new(),
22479 actions: vec![ParserAction::new(1, 0, 0, None)],
22480 nodes: recursive_nodes,
22481 };
22482 let second = RecognizeOutcome {
22483 index: 1,
22484 consumed_eof: false,
22485 alt_number: 0,
22486 member_values: MemberEnv::new(),
22487 return_values: BTreeMap::new(),
22488 diagnostics: DiagnosticSeqId::EMPTY,
22489 decisions: Vec::new(),
22490 actions: vec![ParserAction::new(2, 0, 0, None)],
22491 nodes: recursive_nodes,
22492 };
22493
22494 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22495 .expect("one outcome should be selected");
22496 assert_eq!(selected.actions[0].source_state(), 1);
22497 }
22498
22499 #[test]
22500 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
22501 let mut arena = RecognitionArena::default();
22502 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
22503 line: 1,
22504 column: 3,
22505 message: "missing 'Y' at '<EOF>'".to_owned(),
22506 offending: None,
22507 }]);
22508 let first_alt = RecognizeOutcome {
22509 index: 2,
22510 consumed_eof: true,
22511 alt_number: 0,
22512 member_values: MemberEnv::new(),
22513 return_values: BTreeMap::new(),
22514 diagnostics: recovered_diagnostics,
22515 decisions: vec![0],
22516 actions: vec![ParserAction::new(1, 0, 0, None)],
22517 nodes: NodeSeqId::EMPTY,
22518 };
22519 let second_alt = RecognizeOutcome {
22520 diagnostics: DiagnosticSeqId::EMPTY,
22521 decisions: vec![1],
22522 actions: vec![ParserAction::new(2, 0, 0, None)],
22523 ..first_alt.clone()
22524 };
22525
22526 let selected = select_best_outcome(
22527 [second_alt, first_alt].into_iter(),
22528 PredictionMode::Sll,
22529 &arena,
22530 )
22531 .expect("one outcome should be selected");
22532 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
22533 assert_eq!(selected.decisions, [0]);
22534 }
22535}