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 let Some(diagnostic) = &prediction.diagnostic else {
5655 return;
5656 };
5657 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5658 return;
5659 }
5660 let Some(decision) = atn
5661 .decision_to_state()
5662 .iter()
5663 .position(|candidate| candidate == state_number)
5664 else {
5665 return;
5666 };
5667 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5668 return;
5669 };
5670 let rule_name = self
5671 .rule_names()
5672 .get(rule_index)
5673 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5674 let attempt_input = display_input_text(
5675 &self
5676 .input
5677 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5678 );
5679 let result_input = display_input_text(
5680 &self
5681 .input
5682 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5683 );
5684 let alts = diagnostic
5685 .conflicting_alts
5686 .iter()
5687 .map(usize::to_string)
5688 .collect::<Vec<_>>()
5689 .join(", ");
5690 let key = (
5691 decision,
5692 diagnostic.start_index,
5693 format!(
5694 "{:?}:{alts}:{attempt_input}:{result_input}",
5695 diagnostic.kind
5696 ),
5697 );
5698 if !self.reported_prediction_diagnostics.insert(key) {
5699 return;
5700 }
5701 let attempt_diagnostic = diagnostic_for_token(
5702 self.token_at(diagnostic.sll_stop_index),
5703 format!(
5704 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5705 ),
5706 );
5707 self.generated_parser_diagnostics.push(attempt_diagnostic);
5708 let message = match diagnostic.kind {
5709 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5710 if !diagnostic.exact {
5715 return;
5716 }
5717 format!(
5718 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5719 )
5720 }
5721 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5722 format!(
5723 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5724 )
5725 }
5726 };
5727 let result_diagnostic =
5728 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5729 self.generated_parser_diagnostics.push(result_diagnostic);
5730 }
5731
5732 pub fn la(&self, offset: isize) -> i32 {
5733 self.input.la_token(offset)
5734 }
5735
5736 pub fn consume(&mut self) {
5737 IntStream::consume(&mut self.input);
5738 }
5739
5740 pub fn set_int_member(&mut self, member: usize, value: i64) {
5742 self.int_members.set_scalar(member, value);
5743 }
5744
5745 pub fn int_member(&self, member: usize) -> Option<i64> {
5747 self.int_members.scalar(member)
5748 }
5749
5750 pub fn push_stack_member(&mut self, member: usize, value: i64) {
5752 self.int_members.push_stack(member, value);
5753 }
5754
5755 pub fn pop_stack_member(&mut self, member: usize) -> Option<i64> {
5758 self.int_members.pop_stack(member)
5759 }
5760
5761 #[must_use]
5764 pub fn stack_member_top(&self, member: usize) -> Option<i64> {
5765 self.int_members.stack_top(member)
5766 }
5767
5768 #[must_use]
5770 pub fn stack_member_len(&self, member: usize) -> usize {
5771 self.int_members.stack_len(member)
5772 }
5773
5774 pub fn set_initial_members(&mut self, initial: impl IntoIterator<Item = (usize, i64)>) {
5781 self.int_members = MemberEnv::with_initial_scalars(initial);
5782 }
5783
5784 #[must_use]
5790 pub fn int_members_checkpoint(&self) -> MemberEnv {
5791 self.int_members.clone()
5792 }
5793
5794 pub fn restore_int_members(&mut self, members: MemberEnv) {
5796 self.int_members = members;
5797 }
5798
5799 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5801 self.int_members.add_scalar(member, delta)
5802 }
5803
5804 fn token_type_for_id(&self, id: TokenId) -> i32 {
5805 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5806 }
5807
5808 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5809 if self.build_parse_trees {
5810 self.tree.terminal(id)
5811 } else {
5812 NodeId::placeholder()
5813 }
5814 }
5815
5816 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5817 if self.build_parse_trees {
5818 self.tree.error(id)
5819 } else {
5820 NodeId::placeholder()
5821 }
5822 }
5823
5824 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5825 context.set_start_id(id);
5826 }
5827
5828 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5829 context.set_stop_id(id);
5830 }
5831
5832 fn insert_synthetic_token(
5833 &mut self,
5834 token_type: i32,
5835 text: String,
5836 line: usize,
5837 column: usize,
5838 ) -> Result<TokenId, AntlrError> {
5839 self.input
5840 .insert(
5841 TokenSpec::explicit(token_type, text)
5842 .with_span(usize::MAX, usize::MAX)
5843 .with_position(line, column),
5844 )
5845 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5846 }
5847
5848 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5855 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5856 line: 0,
5857 column: 0,
5858 message: "missing current token".to_owned(),
5859 offending: None,
5860 })?;
5861 let current_type = self.token_type_for_id(current);
5862 if current_type == token_type {
5863 self.reset_generated_recovery_state();
5864 self.consume();
5865 Ok(self.terminal_tree(current))
5866 } else {
5867 Err(AntlrError::MismatchedInput {
5868 expected: self.vocabulary().display_name(token_type),
5869 found: self.vocabulary().display_name(current_type),
5870 })
5871 }
5872 }
5873
5874 pub fn match_token_recovering(
5878 &mut self,
5879 token_type: i32,
5880 follow_state: usize,
5881 atn: &Atn,
5882 ) -> Result<GeneratedMatch, AntlrError> {
5883 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5884 line: 0,
5885 column: 0,
5886 message: "missing current token".to_owned(),
5887 offending: None,
5888 })?;
5889 let current_type = self.token_type_for_id(current);
5890 if current_type == token_type {
5891 self.generated_sync_expected = None;
5892 self.reset_generated_recovery_state();
5893 let consumed_eof = current_type == TOKEN_EOF;
5894 self.consume();
5895 return Ok(GeneratedMatch {
5896 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5897 consumed_eof,
5898 });
5899 }
5900 let mut expected_symbols = BTreeSet::new();
5901 expected_symbols.insert(token_type);
5902 self.recover_generated_match(
5903 current,
5904 GeneratedExpectedSymbols::Tree(&expected_symbols),
5905 follow_state,
5906 atn,
5907 |symbol| symbol == token_type,
5908 )
5909 }
5910
5911 pub fn match_set_recovering(
5912 &mut self,
5913 intervals: &[(i32, i32)],
5914 follow_state: usize,
5915 atn: &Atn,
5916 ) -> Result<GeneratedMatch, AntlrError> {
5917 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5918 line: 0,
5919 column: 0,
5920 message: "missing current token".to_owned(),
5921 offending: None,
5922 })?;
5923 let current_type = self.token_type_for_id(current);
5924 if interval_set_contains(intervals, current_type) {
5925 self.generated_sync_expected = None;
5926 self.reset_generated_recovery_state();
5927 let consumed_eof = current_type == TOKEN_EOF;
5928 self.consume();
5929 return Ok(GeneratedMatch {
5930 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5931 consumed_eof,
5932 });
5933 }
5934 let expected_symbols = interval_symbols(intervals);
5935 self.recover_generated_match(
5936 current,
5937 GeneratedExpectedSymbols::Tree(&expected_symbols),
5938 follow_state,
5939 atn,
5940 |symbol| interval_set_contains(intervals, symbol),
5941 )
5942 }
5943
5944 pub fn match_token_set_recovering(
5945 &mut self,
5946 set: ParserIntervalSet<'_>,
5947 follow_state: usize,
5948 atn: &Atn,
5949 ) -> Result<GeneratedMatch, AntlrError> {
5950 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5951 line: 0,
5952 column: 0,
5953 message: "missing current token".to_owned(),
5954 offending: None,
5955 })?;
5956 let current_type = self.token_type_for_id(current);
5957 if set.contains(current_type) {
5958 self.generated_sync_expected = None;
5959 self.reset_generated_recovery_state();
5960 let consumed_eof = current_type == TOKEN_EOF;
5961 self.consume();
5962 return Ok(GeneratedMatch {
5963 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5964 consumed_eof,
5965 });
5966 }
5967 self.recover_generated_match(
5968 current,
5969 GeneratedExpectedSymbols::TokenSet(set),
5970 follow_state,
5971 atn,
5972 |symbol| set.contains(symbol),
5973 )
5974 }
5975
5976 pub fn match_not_set_recovering(
5977 &mut self,
5978 intervals: &[(i32, i32)],
5979 min_vocabulary: i32,
5980 max_vocabulary: i32,
5981 follow_state: usize,
5982 atn: &Atn,
5983 ) -> Result<GeneratedMatch, AntlrError> {
5984 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5985 line: 0,
5986 column: 0,
5987 message: "missing current token".to_owned(),
5988 offending: None,
5989 })?;
5990 let current_type = self.token_type_for_id(current);
5991 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5992 && !interval_set_contains(intervals, current_type)
5993 {
5994 self.generated_sync_expected = None;
5995 self.reset_generated_recovery_state();
5996 let consumed_eof = current_type == TOKEN_EOF;
5997 self.consume();
5998 return Ok(GeneratedMatch {
5999 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
6000 consumed_eof,
6001 });
6002 }
6003 let expected_symbols =
6004 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
6005 self.recover_generated_match(
6006 current,
6007 GeneratedExpectedSymbols::Tree(&expected_symbols),
6008 follow_state,
6009 atn,
6010 |symbol| {
6011 (min_vocabulary..=max_vocabulary).contains(&symbol)
6012 && !interval_set_contains(intervals, symbol)
6013 },
6014 )
6015 }
6016
6017 pub fn match_not_token_set_recovering(
6018 &mut self,
6019 set: ParserIntervalSet<'_>,
6020 min_vocabulary: i32,
6021 max_vocabulary: i32,
6022 follow_state: usize,
6023 atn: &Atn,
6024 ) -> Result<GeneratedMatch, AntlrError> {
6025 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6026 line: 0,
6027 column: 0,
6028 message: "missing current token".to_owned(),
6029 offending: None,
6030 })?;
6031 let current_type = self.token_type_for_id(current);
6032 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
6033 {
6034 self.generated_sync_expected = None;
6035 self.reset_generated_recovery_state();
6036 let consumed_eof = current_type == TOKEN_EOF;
6037 self.consume();
6038 return Ok(GeneratedMatch {
6039 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
6040 consumed_eof,
6041 });
6042 }
6043 self.recover_generated_match(
6044 current,
6045 GeneratedExpectedSymbols::TokenSetComplement {
6046 set,
6047 min_vocabulary,
6048 max_vocabulary,
6049 },
6050 follow_state,
6051 atn,
6052 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
6053 )
6054 }
6055
6056 fn recover_generated_match(
6057 &mut self,
6058 current: TokenId,
6059 expected_symbols: GeneratedExpectedSymbols<'_>,
6060 follow_state: usize,
6061 atn: &Atn,
6062 matches: impl Fn(i32) -> bool,
6063 ) -> Result<GeneratedMatch, AntlrError> {
6064 let expected_display = expected_symbols.display(self.vocabulary());
6065 let (current_type, current_line, current_column, current_display) = {
6066 let token = self
6067 .input
6068 .token_view(current)
6069 .expect("current token ID should be valid");
6070 (
6071 token.token_type(),
6072 token.line(),
6073 token.column(),
6074 token_input_display(&token),
6075 )
6076 };
6077 if self.bail_on_error {
6078 return Err(AntlrError::ParserError {
6079 line: current_line,
6080 column: current_column,
6081 message: format!("mismatched input {current_display} expecting {expected_display}"),
6082 offending: Some(current),
6083 });
6084 }
6085 if current_type != TOKEN_EOF
6086 && let Some(next) = self.input.lt_id(2)
6087 && matches(self.token_type_for_id(next))
6088 {
6089 let message =
6090 format!("extraneous input {current_display} expecting {expected_display}");
6091 self.push_generated_parser_diagnostic(ParserDiagnostic {
6092 line: current_line,
6093 column: current_column,
6094 message,
6095 offending: Some(current),
6096 });
6097 self.record_syntax_errors(1);
6098 self.generated_sync_expected = None;
6099 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
6102 self.consume();
6103 self.consume();
6104 self.reset_generated_recovery_state();
6105 return Ok(GeneratedMatch {
6106 children: GeneratedMatchChildren::Many(vec![
6107 self.error_tree(current),
6108 self.terminal_tree(next),
6109 ]),
6110 consumed_eof,
6111 });
6112 }
6113 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
6114 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
6123 && self
6124 .cached_state_expected_symbols(atn, follow_state)
6125 .contains(&TOKEN_EOF);
6126 if follow_symbols.contains(¤t_type)
6127 && (current_type != TOKEN_EOF
6128 || self.rule_context_stack.len() > 1
6129 || expected_symbols.is_empty()
6130 || follow_explicitly_expects_eof)
6131 {
6132 let message = format!("missing {expected_display} at {current_display}");
6133 self.push_generated_parser_diagnostic(ParserDiagnostic {
6134 line: current_line,
6135 column: current_column,
6136 message,
6137 offending: Some(current),
6138 });
6139 self.record_syntax_errors(1);
6140 self.generated_sync_expected = None;
6141 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
6142 let missing_display = expected_symbol_display(token_type, self.vocabulary());
6143 let token = self.insert_synthetic_token(
6144 token_type,
6145 format!("<missing {missing_display}>"),
6146 current_line,
6147 current_column,
6148 )?;
6149 return Ok(GeneratedMatch {
6154 children: GeneratedMatchChildren::One(self.error_tree(token)),
6155 consumed_eof: false,
6156 });
6157 }
6158 let mismatch_expected_display = self
6159 .generated_sync_expected
6160 .take()
6161 .map_or(expected_display, |symbols| {
6162 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
6163 });
6164 Err(AntlrError::ParserError {
6165 line: current_line,
6166 column: current_column,
6167 message: format!(
6168 "mismatched input {current_display} expecting {mismatch_expected_display}"
6169 ),
6170 offending: Some(current),
6171 })
6172 }
6173
6174 fn generated_recovery_follow_symbols(
6175 &mut self,
6176 atn: &Atn,
6177 follow_state: usize,
6178 ) -> BTreeSet<i32> {
6179 let mut follow = self
6180 .cached_state_expected_symbols(atn, follow_state)
6181 .as_ref()
6182 .clone();
6183 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
6184 follow.extend(self.context_expected_symbols(atn));
6185 }
6186 follow
6187 }
6188
6189 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
6190 self.match_token(TOKEN_EOF)
6191 }
6192
6193 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
6194 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
6195 }
6196
6197 pub fn match_not_set(
6198 &mut self,
6199 intervals: &[(i32, i32)],
6200 min_vocabulary: i32,
6201 max_vocabulary: i32,
6202 ) -> Result<ParseTree, AntlrError> {
6203 self.match_interval_condition(intervals, |symbol| {
6204 (min_vocabulary..=max_vocabulary).contains(&symbol)
6205 && !interval_set_contains(intervals, symbol)
6206 })
6207 }
6208
6209 fn match_interval_condition(
6210 &mut self,
6211 intervals: &[(i32, i32)],
6212 matches: impl FnOnce(i32) -> bool,
6213 ) -> Result<ParseTree, AntlrError> {
6214 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6215 line: 0,
6216 column: 0,
6217 message: "missing current token".to_owned(),
6218 offending: None,
6219 })?;
6220 let current_type = self.token_type_for_id(current);
6221 if matches(current_type) {
6222 self.reset_generated_recovery_state();
6223 self.consume();
6224 Ok(self.terminal_tree(current))
6225 } else {
6226 Err(AntlrError::MismatchedInput {
6227 expected: self.interval_display(intervals),
6228 found: self.vocabulary().display_name(current_type),
6229 })
6230 }
6231 }
6232
6233 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
6234 let values = intervals
6235 .iter()
6236 .map(|(start, stop)| {
6237 if start == stop {
6238 self.vocabulary().display_name(*start)
6239 } else {
6240 format!(
6241 "{}..{}",
6242 self.vocabulary().display_name(*start),
6243 self.vocabulary().display_name(*stop)
6244 )
6245 }
6246 })
6247 .collect::<Vec<_>>()
6248 .join(", ");
6249 format!("{{{values}}}")
6250 }
6251
6252 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
6253 if self.build_parse_trees {
6254 self.tree.finish_rule(context)
6255 } else {
6256 NodeId::placeholder()
6257 }
6258 }
6259
6260 #[must_use]
6269 pub const fn generated_rule_stack_check_due(&self) -> bool {
6270 self.rule_context_stack
6271 .len()
6272 .is_multiple_of(GENERATED_RULE_STACK_CHECK_INTERVAL)
6273 }
6274
6275 #[inline]
6293 pub fn rule_depth_cap_violation(&mut self) -> Option<AntlrError> {
6294 let max = self.max_rule_depth?;
6295 if self.rule_depth_error.is_none()
6298 && self.rule_context_stack.len() + self.recursion_expansions < max
6299 {
6300 return None;
6301 }
6302 Some(self.rule_depth_cap_violation_cold(max))
6303 }
6304
6305 #[cold]
6306 fn rule_depth_cap_violation_cold(&mut self, max: usize) -> AntlrError {
6307 if let Some(error) = &self.rule_depth_error {
6308 return error.clone();
6309 }
6310 let current = self.input.lt(1);
6311 let (line, column) = current
6312 .as_ref()
6313 .map_or((0, 0), |token| (token.line(), token.column()));
6314 let error = AntlrError::ParserError {
6315 line,
6316 column,
6317 message: format!("rule nesting depth limit of {max} exceeded"),
6318 offending: current.as_ref().map(Token::token_id),
6319 };
6320 self.rule_depth_error = Some(error.clone());
6321 error
6322 }
6323
6324 pub const fn take_rule_depth_error(&mut self) -> Option<AntlrError> {
6331 self.rule_depth_error.take()
6332 }
6333
6334 #[must_use]
6341 pub const fn has_rule_depth_cap(&self) -> bool {
6342 self.max_rule_depth.is_some()
6343 }
6344
6345 pub fn add_parse_listener<L>(&mut self, listener: L)
6349 where
6350 L: ParseListener + 'static,
6351 {
6352 self.parse_listeners
6353 .push(ParseListenerSlot(Box::new(listener)));
6354 }
6355
6356 pub fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
6363 self.parse_listener_abort = None;
6364 self.parse_listeners.drain(..).map(|slot| slot.0).collect()
6365 }
6366
6367 #[must_use]
6373 pub const fn has_parse_listeners(&self) -> bool {
6374 !self.parse_listeners.is_empty()
6375 }
6376
6377 #[doc(hidden)]
6382 #[must_use]
6383 pub fn observes_parser_decisions(&self) -> bool {
6384 self.semantic_hooks.observes_parser_decisions()
6385 }
6386
6387 pub fn parse_listener_enter_rule(&mut self, rule_index: usize) -> Option<AntlrError> {
6398 if self.parse_listeners.is_empty() {
6399 return None;
6400 }
6401 self.parse_listener_enter_rule_dispatch(rule_index)
6402 }
6403
6404 fn parse_listener_enter_rule_dispatch(&mut self, rule_index: usize) -> Option<AntlrError> {
6405 if let Some(error) = &self.parse_listener_abort {
6406 return Some(error.clone());
6407 }
6408 let event = EnterRuleEvent {
6409 rule_index,
6410 current: self.input.lt(1),
6411 };
6412 let mut listeners = std::mem::take(&mut self.parse_listeners);
6416 let mut abort = None;
6417 for slot in &mut listeners {
6418 if let Err(error) = slot.0.enter_every_rule(&event) {
6419 abort = Some(error);
6420 break;
6421 }
6422 }
6423 self.parse_listeners = listeners;
6424 if let Some(error) = abort {
6425 self.parse_listener_abort = Some(error.clone());
6426 return Some(error);
6427 }
6428 None
6429 }
6430
6431 pub fn parse_listener_exit_rule(&mut self, rule_index: usize) {
6438 if self.parse_listeners.is_empty() {
6439 return;
6440 }
6441 for slot in self.parse_listeners.iter_mut().rev() {
6444 slot.0.exit_every_rule(rule_index);
6445 }
6446 }
6447
6448 pub const fn take_parse_listener_abort(&mut self) -> Option<AntlrError> {
6455 self.parse_listener_abort.take()
6456 }
6457
6458 pub fn take_parse_abort(&mut self) -> Option<AntlrError> {
6467 if let Some(error) = self.rule_depth_error.take() {
6468 self.parse_listener_abort = None;
6469 return Some(error);
6470 }
6471 self.parse_listener_abort.take()
6472 }
6473
6474 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
6477 self.set_state(state);
6478 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
6479 self.rule_context_stack.push(RuleContextFrame {
6480 rule_index,
6481 invoking_state,
6482 });
6483 self.advance_rule_context_version();
6484 let start_index = self.current_visible_index();
6485 let mut context = ParserRuleContext::new(rule_index, invoking_state);
6486 if let Some(token) = self.token_id_at(start_index) {
6487 self.set_context_start(&mut context, token);
6488 }
6489 context
6490 }
6491
6492 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
6499 let marker = self.pending_invoking_states.len();
6500 self.pending_invoking_states.push(invoking_state);
6501 marker
6502 }
6503
6504 pub fn discard_invoking_state(&mut self, marker: usize) {
6506 self.pending_invoking_states.truncate(marker);
6507 }
6508
6509 pub fn exit_rule(&mut self) {
6511 self.rule_context_stack.pop();
6512 self.advance_rule_context_version();
6513 }
6514
6515 pub fn prediction_context_return_states<'a>(
6518 &'a self,
6519 atn: &'a Atn,
6520 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
6521 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
6522 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
6523 return None;
6524 };
6525 let Some(Transition::Rule { follow_state, .. }) = atn
6526 .state(state_number)
6527 .and_then(|state| state.transitions().first())
6528 .map(ParserTransition::data)
6529 else {
6530 return None;
6531 };
6532 Some(follow_state)
6533 })
6534 }
6535
6536 pub const fn rule_context_version(&self) -> usize {
6541 self.rule_context_version
6542 }
6543
6544 const fn advance_rule_context_version(&mut self) {
6545 self.rule_context_version = self.rule_context_version.wrapping_add(1);
6546 }
6547
6548 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
6553 if self.build_parse_trees {
6554 self.tree.add_child(context, child);
6555 } else {
6556 context.note_matched_child();
6557 }
6558 }
6559
6560 #[inline]
6566 pub fn sync_into(
6567 &mut self,
6568 atn: &Atn,
6569 state_number: usize,
6570 context: &mut ParserRuleContext,
6571 loop_back: bool,
6572 sync_error: &mut Option<AntlrError>,
6573 ) -> Result<(), AntlrError> {
6574 let current_context_empty = !context.has_matched_child();
6575 match self.sync_decision(atn, state_number, current_context_empty, loop_back) {
6576 Ok(children) => {
6577 for child in children {
6578 self.add_parse_child(context, child);
6579 }
6580 Ok(())
6581 }
6582 Err(error) => {
6583 *sync_error = Some(error.clone());
6584 Err(error)
6585 }
6586 }
6587 }
6588
6589 #[inline]
6593 pub fn match_token_into(
6594 &mut self,
6595 token_type: i32,
6596 follow_state: usize,
6597 atn: &Atn,
6598 context: &mut ParserRuleContext,
6599 consumed_eof: &mut bool,
6600 ) -> Result<(), AntlrError> {
6601 let m = self.match_token_recovering(token_type, follow_state, atn)?;
6602 *consumed_eof |= m.consumed_eof();
6603 for child in m.into_child_iter() {
6604 self.add_parse_child(context, child);
6605 }
6606 Ok(())
6607 }
6608
6609 #[inline]
6612 pub fn match_token_set_into(
6613 &mut self,
6614 token_set: ParserIntervalSet<'_>,
6615 follow_state: usize,
6616 atn: &Atn,
6617 context: &mut ParserRuleContext,
6618 consumed_eof: &mut bool,
6619 ) -> Result<(), AntlrError> {
6620 let m = self.match_token_set_recovering(token_set, follow_state, atn)?;
6621 *consumed_eof |= m.consumed_eof();
6622 for child in m.into_child_iter() {
6623 self.add_parse_child(context, child);
6624 }
6625 Ok(())
6626 }
6627
6628 #[inline]
6631 pub fn match_set_into(
6632 &mut self,
6633 intervals: &[(i32, i32)],
6634 follow_state: usize,
6635 atn: &Atn,
6636 context: &mut ParserRuleContext,
6637 consumed_eof: &mut bool,
6638 ) -> Result<(), AntlrError> {
6639 let m = self.match_set_recovering(intervals, follow_state, atn)?;
6640 *consumed_eof |= m.consumed_eof();
6641 for child in m.into_child_iter() {
6642 self.add_parse_child(context, child);
6643 }
6644 Ok(())
6645 }
6646
6647 #[allow(clippy::too_many_arguments)]
6650 #[inline]
6651 pub fn match_not_token_set_into(
6652 &mut self,
6653 token_set: ParserIntervalSet<'_>,
6654 min_vocabulary: i32,
6655 max_vocabulary: i32,
6656 follow_state: usize,
6657 atn: &Atn,
6658 context: &mut ParserRuleContext,
6659 consumed_eof: &mut bool,
6660 ) -> Result<(), AntlrError> {
6661 let m = self.match_not_token_set_recovering(
6662 token_set,
6663 min_vocabulary,
6664 max_vocabulary,
6665 follow_state,
6666 atn,
6667 )?;
6668 *consumed_eof |= m.consumed_eof();
6669 for child in m.into_child_iter() {
6670 self.add_parse_child(context, child);
6671 }
6672 Ok(())
6673 }
6674
6675 #[allow(clippy::too_many_arguments)]
6678 #[inline]
6679 pub fn match_not_set_into(
6680 &mut self,
6681 intervals: &[(i32, i32)],
6682 min_vocabulary: i32,
6683 max_vocabulary: i32,
6684 follow_state: usize,
6685 atn: &Atn,
6686 context: &mut ParserRuleContext,
6687 consumed_eof: &mut bool,
6688 ) -> Result<(), AntlrError> {
6689 let m = self.match_not_set_recovering(
6690 intervals,
6691 min_vocabulary,
6692 max_vocabulary,
6693 follow_state,
6694 atn,
6695 )?;
6696 *consumed_eof |= m.consumed_eof();
6697 for child in m.into_child_iter() {
6698 self.add_parse_child(context, child);
6699 }
6700 Ok(())
6701 }
6702
6703 fn release_tree_scratch_if_idle(&mut self) {
6704 if self.rule_context_stack.is_empty() {
6705 self.tree.release_scratch();
6706 }
6707 }
6708
6709 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
6711 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6712 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6713 self.set_context_stop(&mut context, token);
6714 }
6715 let node = self.rule_node(context);
6716 self.exit_rule();
6717 self.release_tree_scratch_if_idle();
6718 node
6719 }
6720
6721 pub fn recover_generated_rule(
6728 &mut self,
6729 context: &mut ParserRuleContext,
6730 atn: &Atn,
6731 error: AntlrError,
6732 ) {
6733 let diagnostic = self.generated_rule_error_diagnostic(error);
6734 self.push_generated_parser_diagnostic(diagnostic);
6735 self.generated_sync_expected = None;
6736 let error_index = self.input.index();
6737 let error_state = self.data.state();
6738 if self.generated_recovery_error_index == Some(error_index)
6743 && self.generated_recovery_error_states.contains(&error_state)
6744 && self.la(1) != TOKEN_EOF
6745 && let Some(token) = self.input.lt_id(1)
6746 {
6747 self.consume();
6748 let child = self.error_tree(token);
6749 self.add_parse_child(context, child);
6750 }
6751 let recovery_index = self.input.index();
6752 if self.generated_recovery_error_index != Some(recovery_index) {
6753 self.generated_recovery_error_index = Some(recovery_index);
6754 self.generated_recovery_error_states.clear();
6755 }
6756 self.generated_recovery_error_states.insert(error_state);
6757 let recovery_symbols = self.context_expected_symbols(atn);
6758 loop {
6759 let symbol = self.la(1);
6760 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
6761 break;
6762 }
6763 let Some(token) = self.input.lt_id(1) else {
6764 break;
6765 };
6766 self.consume();
6767 let child = self.error_tree(token);
6768 self.add_parse_child(context, child);
6769 }
6770 self.record_syntax_errors(1);
6771 }
6772
6773 fn reset_generated_recovery_state(&mut self) {
6774 if self.generated_recovery_error_index.is_some() {
6775 self.generated_recovery_error_index = None;
6776 self.generated_recovery_error_states.clear();
6777 }
6778 }
6779
6780 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
6781 if self
6782 .generated_parser_diagnostics
6783 .iter()
6784 .any(|existing| existing == &diagnostic)
6785 {
6786 return;
6787 }
6788 self.generated_parser_diagnostics.push(diagnostic);
6789 }
6790
6791 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
6792 match error {
6793 AntlrError::ParserError {
6797 line,
6798 column,
6799 message,
6800 offending,
6801 } => ParserDiagnostic {
6802 line,
6803 column,
6804 message,
6805 offending,
6806 },
6807 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
6808 self.input.lt(1),
6809 format!("mismatched input {found} expecting {expected}"),
6810 ),
6811 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
6812 self.input.lt(1),
6813 format!("no viable alternative at input {input}"),
6814 ),
6815 AntlrError::LexerError {
6816 line,
6817 column,
6818 message,
6819 } => ParserDiagnostic {
6820 line,
6821 column,
6822 message,
6823 offending: None,
6824 },
6825 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
6826 }
6827 }
6828
6829 pub fn finish_recursion_rule(
6831 &mut self,
6832 mut context: ParserRuleContext,
6833 consumed_eof: bool,
6834 ) -> ParseTree {
6835 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6836 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6837 self.set_context_stop(&mut context, token);
6838 }
6839 let node = self.rule_node(context);
6840 self.unroll_recursion_context();
6841 self.release_tree_scratch_if_idle();
6842 node
6843 }
6844
6845 pub fn enter_recursion_rule(
6847 &mut self,
6848 state: isize,
6849 rule_index: usize,
6850 precedence: i32,
6851 ) -> ParserRuleContext {
6852 self.precedence_stack.push(precedence);
6853 self.recursion_expansion_marks
6854 .push(self.recursion_expansions);
6855 self.enter_rule(state, rule_index)
6856 }
6857
6858 pub fn push_new_recursion_context(
6860 &mut self,
6861 state: isize,
6862 rule_index: usize,
6863 ) -> ParserRuleContext {
6864 self.set_state(state);
6865 self.recursion_expansions += 1;
6868 ParserRuleContext::new(rule_index, state)
6869 }
6870
6871 pub fn push_new_recursion_context_with_previous(
6874 &mut self,
6875 state: isize,
6876 rule_index: usize,
6877 current: &mut ParserRuleContext,
6878 ) {
6879 self.set_state(state);
6880 self.recursion_expansions += 1;
6886 if let Some(stop) = self
6887 .rule_stop_token_index(self.input.index(), false)
6888 .and_then(|index| self.token_id_at(index))
6889 {
6890 self.set_context_stop(current, stop);
6891 }
6892 let invoking_state = current.invoking_state();
6893 let start = current.start_id();
6894 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
6895 if start.is_some() {
6896 replacement.set_start_from_context(current);
6897 }
6898 let previous = std::mem::replace(current, replacement);
6899 if self.build_parse_trees {
6900 let previous = self.rule_node(previous);
6901 self.tree.add_child(current, previous);
6902 }
6903 }
6904
6905 pub fn unroll_recursion_context(&mut self) {
6907 if self.precedence_stack.len() > 1 {
6908 self.precedence_stack.pop();
6909 }
6910 if let Some(mark) = self.recursion_expansion_marks.pop() {
6916 self.recursion_expansions = mark;
6917 }
6918 self.exit_rule();
6919 }
6920
6921 pub fn left_recursive_loop_enter_prediction(
6935 &mut self,
6936 atn: &Atn,
6937 state_number: usize,
6938 precedence: i32,
6939 ) -> Option<bool> {
6940 let symbol = self.la(1);
6941 if symbol == TOKEN_EOF {
6942 return Some(false);
6943 }
6944 let operator_lookahead =
6945 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
6946 let can_single = operator_lookahead.single_token.contains(symbol);
6947 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
6948 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
6949 if !can_single && !can_multi && !can_predicate {
6950 return Some(false);
6951 }
6952 if can_predicate && !can_single {
6953 return None;
6954 }
6955 if !can_single && can_multi && precedence > 0 {
6959 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
6960 if baseline.single_token.contains(symbol) {
6961 return None;
6962 }
6963 }
6964 let atn_key = SharedAtnCacheKey::for_atn(atn);
6965 let cached_overlap = self
6966 .left_recursive_caller_overlap_cache
6967 .iter()
6968 .flatten()
6969 .find(|entry| {
6970 entry.atn_key == atn_key
6971 && entry.state_number == state_number
6972 && entry.symbol == symbol
6973 && entry.context_version == self.rule_context_version
6974 })
6975 .map(|entry| entry.overlaps);
6976 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
6977 let overlaps = caller_context_can_match_symbol_before_state(
6978 atn,
6979 self.prediction_context_return_states(atn),
6980 state_number,
6981 symbol,
6982 );
6983 if let Some(slot) = self
6984 .left_recursive_caller_overlap_cache
6985 .iter_mut()
6986 .find(|slot| slot.is_none())
6987 {
6988 *slot = Some(LeftRecursiveCallerOverlap {
6989 atn_key,
6990 state_number,
6991 symbol,
6992 context_version: self.rule_context_version,
6993 overlaps,
6994 });
6995 }
6996 overlaps
6997 });
6998 if caller_overlaps {
6999 return None;
7000 }
7001 Some(true)
7002 }
7003
7004 fn cached_left_recursive_operator_lookahead(
7005 atn: &Atn,
7006 state_number: usize,
7007 precedence: i32,
7008 ) -> Rc<LeftRecursiveOperatorLookahead> {
7009 with_shared_atn_caches(atn, |cache| {
7010 let key = (state_number, precedence);
7011 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
7012 return Rc::clone(cached);
7013 }
7014 let lookahead = Rc::new(left_recursive_operator_lookahead(
7015 atn,
7016 state_number,
7017 precedence,
7018 ));
7019 cache
7020 .left_recursive_operator_lookahead
7021 .insert(key, Rc::clone(&lookahead));
7022 lookahead
7023 })
7024 }
7025
7026 pub fn left_recursive_loop_enter_matches(
7029 &mut self,
7030 atn: &Atn,
7031 state_number: usize,
7032 precedence: i32,
7033 ) -> bool {
7034 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
7035 }
7036
7037 pub fn precpred(&self, precedence: i32) -> bool {
7039 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
7040 }
7041
7042 pub fn parser_semantic_predicate_matches(
7045 &mut self,
7046 predicates: &[(usize, usize, ParserPredicate)],
7047 rule_index: usize,
7048 pred_index: usize,
7049 ) -> bool {
7050 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
7051 }
7052
7053 pub fn parser_semantic_predicate_matches_with_local(
7056 &mut self,
7057 predicates: &[(usize, usize, ParserPredicate)],
7058 rule_index: usize,
7059 pred_index: usize,
7060 local_int_arg: i32,
7061 ) -> bool {
7062 self.parser_semantic_predicate_matches_inner(
7063 predicates,
7064 rule_index,
7065 pred_index,
7066 Some((rule_index, i64::from(local_int_arg))),
7067 )
7068 }
7069
7070 fn parser_semantic_predicate_matches_inner(
7071 &mut self,
7072 predicates: &[(usize, usize, ParserPredicate)],
7073 rule_index: usize,
7074 pred_index: usize,
7075 local_int_arg: Option<(usize, i64)>,
7076 ) -> bool {
7077 let index = self.input.index();
7078 let member_values = self.int_members.clone();
7079 self.parser_predicate_matches(PredicateEval {
7080 index,
7081 rule_index,
7082 pred_index,
7083 predicates,
7084 semantics: None,
7085 context: None,
7086 local_int_arg,
7087 member_values: &member_values,
7088 })
7089 }
7090
7091 pub fn parser_semantic_predicate_matches_with_context_and_local(
7094 &mut self,
7095 predicates: &[(usize, usize, ParserPredicate)],
7096 rule_index: usize,
7097 pred_index: usize,
7098 context: &ParserRuleContext,
7099 local_int_arg: i32,
7100 ) -> bool {
7101 let index = self.input.index();
7102 let member_values = self.int_members.clone();
7103 self.parser_predicate_matches(PredicateEval {
7104 index,
7105 rule_index,
7106 pred_index,
7107 predicates,
7108 semantics: None,
7109 context: Some(context),
7110 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
7111 member_values: &member_values,
7112 })
7113 }
7114
7115 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
7118 &mut self,
7119 semantics: &ParserSemantics,
7120 rule_index: usize,
7121 pred_index: usize,
7122 context: &ParserRuleContext,
7123 local_int_arg: i32,
7124 ) -> bool {
7125 let index = self.input.index();
7126 let member_values = self.int_members.clone();
7127 self.parser_predicate_matches(PredicateEval {
7128 index,
7129 rule_index,
7130 pred_index,
7131 predicates: &[],
7132 semantics: Some(semantics),
7133 context: Some(context),
7134 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
7135 member_values: &member_values,
7136 })
7137 }
7138
7139 pub fn parser_semantic_predicate_failure_message(
7142 &self,
7143 rule_index: usize,
7144 pred_index: usize,
7145 predicates: &[(usize, usize, ParserPredicate)],
7146 ) -> Option<&'static str> {
7147 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
7148 }
7149
7150 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
7152 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
7153 line: 0,
7154 column: 0,
7155 message: "missing current token".to_owned(),
7156 offending: None,
7157 })?;
7158 if self.token_type_for_id(current) == TOKEN_EOF {
7159 return Err(AntlrError::MismatchedInput {
7160 expected: "wildcard".to_owned(),
7161 found: self.vocabulary().display_name(TOKEN_EOF),
7162 });
7163 }
7164 self.reset_generated_recovery_state();
7165 self.consume();
7166 Ok(self.terminal_tree(current))
7167 }
7168
7169 #[allow(clippy::unnecessary_wraps)]
7173 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
7174 self.set_state(state);
7175 Ok(())
7176 }
7177
7178 pub fn sync_decision(
7186 &mut self,
7187 atn: &Atn,
7188 state_number: usize,
7189 _current_context_empty: bool,
7190 loop_back: bool,
7191 ) -> Result<Vec<ParseTree>, AntlrError> {
7192 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
7193 self.generated_sync_expected = None;
7194 let Some(state) = atn.state(state_number) else {
7195 return Ok(Vec::new());
7196 };
7197 let Some(rule_index) = state.rule_index() else {
7198 return Ok(Vec::new());
7199 };
7200 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
7201 return Ok(Vec::new());
7202 };
7203 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
7204 let symbol = self.la(1);
7205 let mut has_expected_symbols = false;
7206 let mut nullable = false;
7207 let mut explicit_eof_expected = false;
7215 for transition in &entry.transitions {
7216 if transition.symbols.contains(symbol) {
7217 return Ok(Vec::new());
7218 }
7219 has_expected_symbols |= !transition.symbols.is_empty();
7220 nullable |= transition.nullable;
7221 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
7222 }
7223 if nullable {
7230 if self.context_expected_contains(atn, symbol) {
7234 return Ok(Vec::new());
7235 }
7236 let mut expected = self.context_expected_token_set(atn);
7237 for transition in &entry.transitions {
7238 expected.extend_from(&transition.symbols);
7239 }
7240 self.generated_sync_expected = Some(expected);
7241 return Ok(Vec::new());
7242 }
7243 if !has_expected_symbols {
7244 return Ok(Vec::new());
7245 }
7246 let mut expected = TokenBitSet::default();
7247 for transition in &entry.transitions {
7248 expected.extend_from(&transition.symbols);
7249 }
7250 let loop_sync = loop_back;
7267 if symbol != TOKEN_EOF {
7268 let mut cursor = self.input.index();
7269 let mut skipped = Vec::new();
7270 loop {
7271 let current = self.token_type_at(cursor);
7272 if current == TOKEN_EOF {
7273 break;
7274 }
7275 skipped.push(cursor);
7276 let next = self.consume_index(cursor, current);
7277 if next == cursor {
7278 break;
7279 }
7280 let next_symbol = self.token_type_at(next);
7281 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
7289 explicit_eof_expected
7290 } else {
7291 expected.contains(next_symbol)
7292 };
7293 if next_is_expected_stop {
7294 let current_token = self.input.lt(1);
7295 let expected_symbols = expected.to_btree_set();
7296 let message = format!(
7297 "extraneous input {} expecting {}",
7298 current_token
7299 .as_ref()
7300 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7301 self.expected_symbols_display(&expected_symbols)
7302 );
7303 self.push_generated_parser_diagnostic(diagnostic_for_token(
7304 current_token,
7305 message,
7306 ));
7307 self.record_syntax_errors(1);
7308 let mut children = Vec::with_capacity(skipped.len());
7309 for index in skipped {
7310 if let Some(token) = self.token_id_at(index) {
7311 self.consume();
7312 children.push(self.error_tree(token));
7313 }
7314 }
7315 if !loop_sync {
7316 self.reset_generated_recovery_state();
7317 }
7318 return Ok(children);
7319 }
7320 if !loop_sync {
7324 break;
7325 }
7326 cursor = next;
7327 }
7328 }
7329 let current = self.input.lt(1);
7330 let expected_symbols = expected.to_btree_set();
7331 Err(AntlrError::ParserError {
7332 line: current.as_ref().map(Token::line).unwrap_or_default(),
7333 column: current.as_ref().map(Token::column).unwrap_or_default(),
7334 message: format!(
7335 "mismatched input {} expecting {}",
7336 current
7337 .as_ref()
7338 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7339 self.expected_symbols_display(&expected_symbols)
7340 ),
7341 offending: current.as_ref().map(Token::token_id),
7342 })
7343 }
7344
7345 pub fn ll1_decision_prediction(
7352 &mut self,
7353 atn: &Atn,
7354 state_number: usize,
7355 ) -> Option<ParserAtnPrediction> {
7356 let state = atn.state(state_number)?;
7357 if state.precedence_rule_decision() {
7358 return None;
7359 }
7360 let rule_stop = state
7361 .rule_index()
7362 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
7363 let symbol = self.la(1);
7364 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
7365 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
7366 alt: alt + 1,
7367 requires_full_context: false,
7368 has_semantic_context: false,
7369 diagnostic: None,
7370 })
7371 }
7372
7373 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
7374 let mut expected = BTreeSet::new();
7375 for index in (1..self.rule_context_stack.len()).rev() {
7376 let invoking_state = self.rule_context_stack[index].invoking_state;
7377 let Ok(state_number) = usize::try_from(invoking_state) else {
7378 continue;
7379 };
7380 let Some(Transition::Rule { follow_state, .. }) = atn
7381 .state(state_number)
7382 .and_then(|state| state.transitions().first())
7383 .map(ParserTransition::data)
7384 else {
7385 continue;
7386 };
7387 let return_state = follow_state;
7388 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
7389 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
7390 return expected;
7391 }
7392 }
7393 expected.insert(TOKEN_EOF);
7394 expected
7395 }
7396
7397 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
7398 let mut expected = TokenBitSet::default();
7399 for index in (1..self.rule_context_stack.len()).rev() {
7400 let invoking_state = self.rule_context_stack[index].invoking_state;
7401 let Ok(state_number) = usize::try_from(invoking_state) else {
7402 continue;
7403 };
7404 let Some(Transition::Rule { follow_state, .. }) = atn
7405 .state(state_number)
7406 .and_then(|state| state.transitions().first())
7407 .map(ParserTransition::data)
7408 else {
7409 continue;
7410 };
7411 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
7412 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7413 return expected;
7414 }
7415 }
7416 expected.insert(TOKEN_EOF);
7417 expected
7418 }
7419
7420 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
7427 for index in (1..self.rule_context_stack.len()).rev() {
7428 let invoking_state = self.rule_context_stack[index].invoking_state;
7429 let Ok(state_number) = usize::try_from(invoking_state) else {
7430 continue;
7431 };
7432 let Some(Transition::Rule { follow_state, .. }) = atn
7433 .state(state_number)
7434 .and_then(|state| state.transitions().first())
7435 .map(ParserTransition::data)
7436 else {
7437 continue;
7438 };
7439 if self
7440 .cached_state_expected_token_set(atn, follow_state)
7441 .contains(symbol)
7442 {
7443 return true;
7444 }
7445 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7446 return false;
7447 }
7448 }
7449 symbol == TOKEN_EOF
7450 }
7451
7452 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
7454 let error_index = self.input.index();
7455 self.no_viable_alternative_error_at(start_index, error_index)
7456 }
7457
7458 pub fn no_viable_alternative_error_at(
7463 &self,
7464 start_index: usize,
7465 error_index: usize,
7466 ) -> AntlrError {
7467 let diagnostic = self.no_viable_alternative(start_index, error_index);
7468 AntlrError::ParserError {
7469 line: diagnostic.line,
7470 column: diagnostic.column,
7471 message: diagnostic.message,
7472 offending: diagnostic.offending,
7473 }
7474 }
7475
7476 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
7478 let current = self.input.lt(1);
7479 AntlrError::ParserError {
7480 line: current.as_ref().map(Token::line).unwrap_or_default(),
7481 column: current.as_ref().map(Token::column).unwrap_or_default(),
7482 message: format!("rule failed predicate: {}", message.into()),
7483 offending: current.as_ref().map(Token::token_id),
7484 }
7485 }
7486
7487 pub fn failed_predicate_option_error(
7490 &self,
7491 rule_index: usize,
7492 message: impl Into<String>,
7493 ) -> AntlrError {
7494 let current = self.input.lt(1);
7495 let rule_name = self
7496 .rule_names()
7497 .get(rule_index)
7498 .map_or_else(|| rule_index.to_string(), Clone::clone);
7499 AntlrError::ParserError {
7500 line: current.as_ref().map(Token::line).unwrap_or_default(),
7501 column: current.as_ref().map(Token::column).unwrap_or_default(),
7502 message: format!("rule {rule_name} {}", message.into()),
7503 offending: current.as_ref().map(Token::token_id),
7504 }
7505 }
7506
7507 pub fn parser_action_at_current(
7509 &mut self,
7510 source_state: usize,
7511 rule_index: usize,
7512 start_index: usize,
7513 consumed_eof: bool,
7514 ) -> ParserAction {
7515 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7516 ParserAction::new(source_state, rule_index, start_index, stop_index)
7517 }
7518
7519 pub fn parser_action_at_current_indexed(
7521 &mut self,
7522 source_state: usize,
7523 rule_index: usize,
7524 action_index: usize,
7525 start_index: usize,
7526 consumed_eof: bool,
7527 ) -> ParserAction {
7528 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7529 ParserAction::new_indexed(
7530 source_state,
7531 rule_index,
7532 action_index,
7533 start_index,
7534 stop_index,
7535 )
7536 }
7537
7538 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
7543 self.parser_action_hook_inner(action, None, Some(tree), None, true)
7544 }
7545
7546 pub fn parser_action_hook_with_context(
7551 &mut self,
7552 action: ParserAction,
7553 context: &ParserRuleContext,
7554 ) -> bool {
7555 self.parser_action_hook_inner(action, Some(context), None, None, true)
7556 }
7557
7558 pub fn parser_action_hook_with_context_and_local(
7564 &mut self,
7565 action: ParserAction,
7566 context: &ParserRuleContext,
7567 local_int_arg: i32,
7568 ) -> bool {
7569 self.parser_action_hook_inner(
7570 action,
7571 Some(context),
7572 None,
7573 Some((action.rule_index(), i64::from(local_int_arg))),
7574 true,
7575 )
7576 }
7577
7578 fn parser_rule_init_hook_with_context(
7583 &mut self,
7584 action: ParserAction,
7585 context: &ParserRuleContext,
7586 local_int_arg: Option<(usize, i64)>,
7587 ) -> bool {
7588 debug_assert!(action.is_rule_init());
7589 self.parser_action_hook_inner(action, Some(context), None, local_int_arg, false)
7590 }
7591
7592 fn parser_action_hook_inner(
7593 &mut self,
7594 action: ParserAction,
7595 context: Option<&ParserRuleContext>,
7596 tree: Option<ParseTree>,
7597 local_int_arg: Option<(usize, i64)>,
7598 record_unhandled: bool,
7599 ) -> bool {
7600 let rule_index = action.rule_index();
7601 let rule_name = self.rule_names().get(rule_index).cloned();
7602 let input = &mut self.input;
7603 let semantic_hooks = &mut self.semantic_hooks;
7604 let member_values = &self.int_members;
7605 let mut ctx = ParserSemCtx {
7606 input,
7607 tree_storage: &self.tree,
7608 rule_index,
7609 coordinate_index: action.action_index().unwrap_or(usize::MAX),
7610 rule_name,
7611 context,
7612 tree,
7613 local_int_arg,
7614 member_values,
7615 action: Some(action),
7616 };
7617 let handled = semantic_hooks.action(&mut ctx, action);
7618 if record_unhandled
7624 && !handled
7625 && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error)
7626 {
7627 let coordinate = (rule_index, action.source_state());
7628 if !self.unhandled_action_hits.contains(&coordinate) {
7629 self.unhandled_action_hits.push(coordinate);
7630 }
7631 }
7632 handled
7633 }
7634
7635 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
7640 &mut self,
7641 atn: &'atn Atn,
7642 simulator: &mut ParserAtnSimulator<'atn>,
7643 rule_index: usize,
7644 ) -> Result<ParseTree, AntlrError> {
7645 let start_index = self.current_visible_index();
7646 self.clear_prediction_diagnostics();
7647 self.reset_per_parse_caches();
7648 self.reset_recognition_arena();
7649 let tree_checkpoint = self.tree.checkpoint();
7650 let mut decision_by_state = vec![None; atn.states().len()];
7651 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
7652 if let Some(slot) = decision_by_state.get_mut(state_number) {
7653 *slot = Some(decision);
7654 }
7655 }
7656
7657 let result = DirectAdaptiveParser {
7658 parser: self,
7659 atn,
7660 simulator,
7661 decision_by_state,
7662 steps: 0,
7663 }
7664 .parse_rule(rule_index, -1, 0);
7665
7666 match result {
7667 Ok(tree) => {
7668 self.report_token_source_errors();
7669 self.release_tree_scratch_if_idle();
7670 Ok(tree)
7671 }
7672 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
7673 let _ = reason;
7674 self.tree.rollback(tree_checkpoint);
7675 self.input.seek(start_index);
7676 self.parse_atn_rule(atn, rule_index)
7677 }
7678 }
7679 }
7680
7681 pub fn parse_atn_rule(
7691 &mut self,
7692 atn: &Atn,
7693 rule_index: usize,
7694 ) -> Result<ParseTree, AntlrError> {
7695 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
7696 }
7697
7698 pub fn parse_atn_rule_with_precedence(
7701 &mut self,
7702 atn: &Atn,
7703 rule_index: usize,
7704 precedence: i32,
7705 ) -> Result<ParseTree, AntlrError> {
7706 self.parse_atn_rule_with_precedence_inner(
7707 atn,
7708 rule_index,
7709 precedence,
7710 None,
7711 AltNumberTracking::default(),
7712 )
7713 }
7714
7715 fn parse_atn_rule_with_precedence_inner(
7716 &mut self,
7717 atn: &Atn,
7718 rule_index: usize,
7719 precedence: i32,
7720 predicate_context: Option<FastPredicateContext<'_>>,
7721 alt_tracking: AltNumberTracking,
7722 ) -> Result<ParseTree, AntlrError> {
7723 let report_unrecovered_error = self.is_top_level_entry();
7724 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7725 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7726 })?;
7727 let stop_state = atn
7728 .rule_to_stop_state()
7729 .get(rule_index)
7730 .filter(|state| *state != usize::MAX)
7731 .ok_or_else(|| {
7732 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7733 })?;
7734
7735 let start_index = self.current_visible_index();
7736 self.clear_prediction_diagnostics();
7737 self.reset_per_parse_caches();
7738 self.reset_recognition_arena();
7739 let caller_follow_state = self.pending_invoking_follow_state(atn);
7740 self.fast_recovery_enabled = false;
7741 self.fast_token_nodes_enabled = false;
7742 self.fast_track_alt_numbers = alt_tracking.any();
7743 let top_request = FastRecognizeTopRequest {
7744 start_state,
7745 stop_state,
7746 start_index,
7747 precedence,
7748 caller_follow_state,
7749 };
7750 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
7751 self.fast_token_nodes_enabled = self.build_parse_trees;
7752 let needs_tree_retry = matches!(
7753 &first_pass,
7754 Ok((outcome, _, _))
7755 if self.build_parse_trees
7756 && self
7757 .recognition_arena
7758 .sequence_has_left_recursive_boundary(outcome.nodes)
7759 );
7760 let needs_retry = match &first_pass {
7761 Err(_) => true,
7774 Ok((outcome, _, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
7775 };
7776 let (outcome, _expected, alt_number) = if needs_retry {
7777 self.fast_first_set_prefilter = false;
7778 self.fast_recovery_enabled = false;
7779 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7780 let clean_selected = if needs_tree_retry {
7781 match clean_retry {
7782 ok @ Ok(_) => ok,
7783 Err(_) => first_pass,
7784 }
7785 } else {
7786 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
7787 };
7788 let selected = if clean_selected.is_err()
7789 || matches!(&clean_selected, Ok((outcome, _, _)) if !outcome.diagnostics.is_empty())
7790 {
7791 self.fast_recovery_enabled = true;
7792 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7793 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
7794 } else {
7795 clean_selected
7796 };
7797 self.fast_first_set_prefilter = true;
7798 self.fast_recovery_enabled = true;
7799 selected.map_err(|expected| {
7800 if predicate_context.is_some()
7801 && let Some(error) = self.unknown_semantic_error()
7802 {
7803 self.report_token_source_errors();
7804 return error;
7805 }
7806 let error = self.recognition_error(rule_index, start_index, &expected);
7807 self.record_syntax_errors(1);
7808 self.report_token_source_errors();
7809 if report_unrecovered_error {
7810 self.report_unrecovered_parser_error(&error);
7811 }
7812 error
7813 })?
7814 } else {
7815 first_pass.expect("first_pass is Ok in the no-retry branch")
7816 };
7817 if predicate_context.is_some()
7818 && let Some(error) = self.unknown_semantic_error()
7819 {
7820 self.report_token_source_errors();
7821 return Err(error);
7822 }
7823 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7824 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7825 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7826 self.report_token_source_errors();
7827 let mut context = ParserRuleContext::with_child_capacity(
7828 rule_index,
7829 self.state(),
7830 if self.build_parse_trees {
7831 self.recognition_arena.sequence_len(outcome.nodes)
7832 } else {
7833 0
7834 },
7835 );
7836 if alt_tracking.public {
7837 context.set_alt_number(alt_number.max(1));
7838 }
7839 if alt_tracking.context {
7840 context.set_context_alt_number(alt_number);
7841 }
7842 if let Some(token) = self.token_id_at(start_index) {
7843 self.set_context_start(&mut context, token);
7844 }
7845 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
7846 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
7847 self.set_context_stop(&mut context, token);
7848 }
7849 let live_root = if self.build_parse_trees {
7850 self.recognition_arena
7851 .fold_left_recursive_boundaries(outcome.nodes)
7852 } else {
7853 outcome.nodes
7854 };
7855 if self.build_parse_trees {
7856 if self
7857 .recognition_arena
7858 .sequence_has_explicit_token(live_root)
7859 {
7860 let mut cursor = live_root;
7861 while let Some(link) = self.recognition_arena.link(cursor) {
7862 let child = self.arena_recognized_node_tree(
7863 link.head,
7864 alt_tracking.public,
7865 alt_tracking.context,
7866 )?;
7867 self.tree.add_child(&mut context, child);
7868 cursor = link.tail;
7869 }
7870 } else {
7871 self.add_arena_implicit_token_children(
7872 &mut context,
7873 start_index,
7874 stop_index,
7875 live_root,
7876 alt_tracking,
7877 )?;
7878 }
7879 }
7880 self.finish_recognition_arena(live_root, outcome.diagnostics);
7881 self.input.seek(outcome.index);
7882
7883 let tree = self.rule_node(context);
7884 self.release_tree_scratch_if_idle();
7885 Ok(tree)
7886 }
7887
7888 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
7889 let invoking_state = self.pending_invoking_states.last().copied()?;
7890 let state_number = usize::try_from(invoking_state).ok()?;
7891 match atn.state(state_number)?.transitions().first()?.data() {
7892 Transition::Rule { follow_state, .. } => Some(follow_state),
7893 _ => None,
7894 }
7895 }
7896
7897 #[cfg(test)]
7898 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
7899 caller_follow_token_info_for_stream(&mut self.input, index)
7900 }
7901
7902 fn fast_recognize_top(
7907 &mut self,
7908 atn: &Atn,
7909 request: FastRecognizeTopRequest,
7910 predicate_context: Option<FastPredicateContext<'_>>,
7911 ) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
7912 let FastRecognizeTopRequest {
7913 start_state,
7914 stop_state,
7915 start_index,
7916 precedence,
7917 caller_follow_state,
7918 } = request;
7919 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
7928 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
7929 recognize_scratch.prepare(memo_capacity);
7930 let mut expected = ExpectedTokens::default();
7931 let empty_recovery = self.empty_recovery_symbols();
7932 let outcomes = self.recognize_state_fast(
7933 atn,
7934 FastRecognizeRequest {
7935 state_number: start_state,
7936 stop_state,
7937 index: start_index,
7938 rule_start_index: start_index,
7939 decision_start_index: None,
7940 precedence,
7941 depth: 0,
7942 recovery_symbols: empty_recovery,
7943 recovery_state: None,
7944 },
7945 FastRecognizeScratch {
7946 predicate_context,
7947 visiting: &mut recognize_scratch.visiting,
7948 memo: &mut recognize_scratch.memo,
7949 expected: &mut expected,
7950 native_depth: 0,
7951 },
7952 );
7953 recognize_scratch.release_oversized_memo();
7954 self.fast_recognize_scratch = recognize_scratch;
7955 #[cfg(feature = "perf-counters")]
7956 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
7957 perf_counters::dump();
7958 perf_counters::reset();
7959 }
7960 let caller_follow =
7961 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
7962 let selected = {
7963 let arena = &self.recognition_arena;
7964 let input = &mut self.input;
7965 select_best_fast_outcome(
7966 outcomes.into_iter(),
7967 self.prediction_mode,
7968 caller_follow.as_deref(),
7969 |index| caller_follow_token_info_for_stream(input, index),
7970 arena,
7971 )
7972 };
7973 match selected {
7974 Some(mut outcome) => {
7975 let alt_number = if self.build_parse_trees || self.fast_track_alt_numbers {
7976 self.materialize_fast_outcome_nodes(&mut outcome)
7977 } else {
7978 0
7979 };
7980 Ok((outcome, expected, alt_number))
7981 }
7982 None => Err(expected),
7983 }
7984 }
7985
7986 fn arena_recognized_node_tree(
7988 &mut self,
7989 node_id: RecognizedNodeId,
7990 track_alt_numbers: bool,
7991 track_context_alt_numbers: bool,
7992 ) -> Result<ParseTree, AntlrError> {
7993 let node = self.recognition_arena.node(node_id);
7994 match node {
7995 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
7996 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
7997 ArenaRecognizedNode::MissingToken { extra } => {
7998 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
7999 RecognitionExtra::MissingToken {
8000 token_type,
8001 at_index,
8002 text,
8003 } => (*token_type, *at_index as usize, text.clone()),
8004 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
8005 unreachable!("missing-token node must reference missing-token extra")
8006 }
8007 };
8008 let (line, column) = self
8009 .token_at(at_index)
8010 .map_or((0, 0), |token| (token.line(), token.column()));
8011 let token = self.insert_synthetic_token(token_type, text, line, column)?;
8012 Ok(self.error_tree(token))
8013 }
8014 ArenaRecognizedNode::Rule {
8015 rule_index,
8016 invoking_state,
8017 alt_number,
8018 start_index,
8019 stop_index,
8020 return_values,
8021 children,
8022 } => {
8023 let mut context = ParserRuleContext::with_child_capacity(
8024 rule_index as usize,
8025 invoking_state as isize,
8026 self.recognition_arena.sequence_len(children),
8027 );
8028 if track_alt_numbers {
8029 context.set_alt_number((alt_number as usize).max(1));
8030 }
8031 if track_context_alt_numbers {
8032 context.set_context_alt_number(alt_number as usize);
8033 }
8034 if let Some(extra) = return_values {
8035 let RecognitionExtra::ReturnValues(values) =
8036 self.recognition_arena.extra(extra)
8037 else {
8038 unreachable!("rule node must reference return-values extra");
8039 };
8040 for (name, value) in values {
8041 context.set_int_return(name.clone(), *value);
8042 }
8043 }
8044 if let Some(token) = self.token_id_at(start_index as usize) {
8045 self.set_context_start(&mut context, token);
8046 }
8047 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
8048 self.set_context_stop(&mut context, token);
8049 }
8050 let mut cursor = self
8051 .recognition_arena
8052 .fold_left_recursive_boundaries(children);
8053 while let Some(link) = self.recognition_arena.link(cursor) {
8054 let child = self.arena_recognized_node_tree(
8055 link.head,
8056 track_alt_numbers,
8057 track_context_alt_numbers,
8058 )?;
8059 self.tree.add_child(&mut context, child);
8060 cursor = link.tail;
8061 }
8062 Ok(self.rule_node(context))
8063 }
8064 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
8065 Err(AntlrError::Unsupported(format!(
8066 "unfolded left-recursive boundary for rule {rule_index}"
8067 )))
8068 }
8069 }
8070 }
8071
8072 fn arena_recognized_node_tree_with_implicit_tokens(
8073 &mut self,
8074 node_id: RecognizedNodeId,
8075 alt_tracking: AltNumberTracking,
8076 ) -> Result<ParseTree, AntlrError> {
8077 let node = self.recognition_arena.node(node_id);
8078 match node {
8079 ArenaRecognizedNode::Rule {
8080 rule_index,
8081 invoking_state,
8082 alt_number,
8083 start_index,
8084 stop_index,
8085 children,
8086 ..
8087 } => {
8088 let mut context = ParserRuleContext::with_child_capacity(
8089 rule_index as usize,
8090 invoking_state as isize,
8091 self.recognition_arena.sequence_len(children),
8092 );
8093 if alt_tracking.public {
8094 context.set_alt_number((alt_number as usize).max(1));
8095 }
8096 if alt_tracking.context {
8097 context.set_context_alt_number(alt_number as usize);
8098 }
8099 if let Some(token) = self.token_id_at(start_index as usize) {
8100 self.set_context_start(&mut context, token);
8101 }
8102 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
8103 self.set_context_stop(&mut context, token);
8104 }
8105 let children = self
8106 .recognition_arena
8107 .fold_left_recursive_boundaries(children);
8108 self.add_arena_implicit_token_children(
8109 &mut context,
8110 start_index as usize,
8111 stop_index.map(|index| index as usize),
8112 children,
8113 alt_tracking,
8114 )?;
8115 Ok(self.rule_node(context))
8116 }
8117 _ => {
8118 self.arena_recognized_node_tree(node_id, alt_tracking.public, alt_tracking.context)
8119 }
8120 }
8121 }
8122
8123 fn add_arena_implicit_token_children(
8124 &mut self,
8125 context: &mut ParserRuleContext,
8126 start_index: usize,
8127 stop_index: Option<usize>,
8128 mut children: NodeSeqId,
8129 alt_tracking: AltNumberTracking,
8130 ) -> Result<(), AntlrError> {
8131 let mut cursor = Some(start_index);
8132 while let Some(link) = self.recognition_arena.link(children) {
8133 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
8134 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
8135 let child =
8136 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
8137 self.tree.add_child(context, child);
8138 if let Some(child_stop) = child_stop {
8139 let next = self.next_visible_after_token(child_stop);
8140 cursor = match (cursor, next) {
8141 (None, _) | (_, None) => None,
8142 (Some(current), Some(next)) => Some(current.max(next)),
8143 };
8144 }
8145 } else {
8146 let child =
8147 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
8148 self.tree.add_child(context, child);
8149 }
8150 children = link.tail;
8151 }
8152 if let Some(stop) = stop_index {
8153 self.add_visible_terminals_through(context, cursor, stop)?;
8154 }
8155 Ok(())
8156 }
8157
8158 fn add_visible_terminals_before(
8159 &mut self,
8160 context: &mut ParserRuleContext,
8161 cursor: &mut Option<usize>,
8162 before: usize,
8163 ) -> Result<(), AntlrError> {
8164 let Some(stop) = before.checked_sub(1) else {
8165 return Ok(());
8166 };
8167 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
8168 *cursor = next;
8169 Ok(())
8170 }
8171
8172 fn add_visible_terminals_through(
8173 &mut self,
8174 context: &mut ParserRuleContext,
8175 mut cursor: Option<usize>,
8176 stop: usize,
8177 ) -> Result<Option<usize>, AntlrError> {
8178 while let Some(index) = cursor {
8179 if index > stop {
8180 return Ok(Some(index));
8181 }
8182 let token = self
8183 .input
8184 .get_id(index)
8185 .ok_or_else(|| AntlrError::ParserError {
8186 line: 0,
8187 column: 0,
8188 message: format!("missing token at index {index}"),
8189 offending: None,
8190 })?;
8191 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
8192 let child = self.terminal_tree(token);
8193 self.tree.add_child(context, child);
8194 if is_eof {
8195 return Ok(None);
8196 }
8197 cursor = self.next_visible_after_token(index);
8198 }
8199 Ok(None)
8200 }
8201
8202 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
8203 let next = self.input.next_visible_after(index);
8204 (next != index).then_some(next)
8205 }
8206
8207 pub fn parse_atn_rule_with_actions(
8214 &mut self,
8215 atn: &Atn,
8216 rule_index: usize,
8217 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8218 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
8219 }
8220
8221 pub fn parse_atn_rule_with_action_inits(
8229 &mut self,
8230 atn: &Atn,
8231 rule_index: usize,
8232 init_action_rules: &[usize],
8233 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8234 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
8235 }
8236
8237 pub fn parse_atn_rule_with_action_options(
8243 &mut self,
8244 atn: &Atn,
8245 rule_index: usize,
8246 init_action_rules: &[usize],
8247 track_alt_numbers: bool,
8248 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8249 self.parse_atn_rule_with_runtime_options(
8250 atn,
8251 rule_index,
8252 ParserRuntimeOptions {
8253 init_action_rules,
8254 track_alt_numbers,
8255 ..ParserRuntimeOptions::default()
8256 },
8257 )
8258 }
8259
8260 pub fn parse_atn_rule_with_runtime_options(
8267 &mut self,
8268 atn: &Atn,
8269 rule_index: usize,
8270 options: ParserRuntimeOptions<'_>,
8271 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8272 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
8273 }
8274
8275 fn parse_atn_rule_committed_with_runtime_options(
8276 &mut self,
8277 atn: &Atn,
8278 rule_index: usize,
8279 precedence: i32,
8280 options: ParserRuntimeOptions<'_>,
8281 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8282 let top_level_entry = self.is_top_level_entry();
8283 self.unknown_predicate_policy = options.unknown_predicate_policy;
8284 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8285 let prior_unhandled_action_hits = std::mem::take(&mut self.unhandled_action_hits);
8286 self.clear_prediction_diagnostics();
8287 self.reset_per_parse_caches();
8288 self.reset_recognition_arena();
8289
8290 let mut decision_by_state = vec![None; atn.states().len()];
8291 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
8292 if let Some(slot) = decision_by_state.get_mut(state_number) {
8293 *slot = Some(decision);
8294 }
8295 }
8296 let mut action_index_by_state = FxHashMap::default();
8297 for &(state, index) in options.action_indices {
8298 action_index_by_state.entry(state).or_insert(index);
8299 }
8300 let mut simulator = ParserAtnSimulator::new(atn);
8301 simulator.set_track_prediction_rule_calls(!options.rule_args.is_empty());
8302 let (result, deferred_actions) = {
8303 let mut committed = CommittedAtnParser {
8304 parser: self,
8305 atn,
8306 simulator,
8307 options,
8308 decision_by_state,
8309 action_index_by_state,
8310 deferred_actions: Vec::new(),
8311 };
8312 let result = committed.parse_rule(rule_index, precedence, None, None);
8313 (result, committed.deferred_actions)
8314 };
8315
8316 if top_level_entry {
8317 self.report_generated_parser_diagnostics();
8318 }
8319 let semantic_error = self.unknown_semantic_error();
8320 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8321 self.restore_prior_unhandled_action_hits(prior_unhandled_action_hits);
8322 if top_level_entry && let Some(error) = self.take_parse_abort() {
8323 self.reset_unknown_semantic_hits();
8324 return Err(error);
8325 }
8326 if let Some(error) = semantic_error {
8327 if top_level_entry {
8328 self.reset_unknown_semantic_hits();
8329 }
8330 return Err(error);
8331 }
8332 let result = result.map(|outcome| (outcome.tree, deferred_actions));
8333 if top_level_entry && let Err(error) = &result {
8334 self.report_unrecovered_parser_error(error);
8335 }
8336 result
8337 }
8338
8339 pub fn parse_atn_rule_with_runtime_options_and_precedence(
8342 &mut self,
8343 atn: &Atn,
8344 rule_index: usize,
8345 precedence: i32,
8346 options: ParserRuntimeOptions<'_>,
8347 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8348 if !options.action_indices.is_empty() {
8349 return self.parse_atn_rule_committed_with_runtime_options(
8350 atn, rule_index, precedence, options,
8351 );
8352 }
8353 let report_unrecovered_error = self.is_top_level_entry();
8354 let ParserRuntimeOptions {
8355 init_action_rules,
8356 track_alt_numbers,
8357 track_context_alt_numbers,
8358 predicates,
8359 semantics,
8360 rule_args,
8361 member_actions,
8362 return_actions,
8363 unknown_predicate_policy,
8364 ..
8365 } = options;
8366 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
8367 if init_action_rules.is_empty()
8368 && !capture_alt_numbers
8369 && predicates.is_empty()
8370 && semantics.is_none()
8371 && rule_args.is_empty()
8372 && member_actions.is_empty()
8373 && return_actions.is_empty()
8374 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
8375 && !atn_has_observable_action_transitions(atn)
8376 && !self.semantic_hooks.observes_parser_decisions()
8377 && (!self.semantic_hooks.observes_parser_predicates()
8378 || !atn_has_predicate_transitions(atn))
8379 {
8380 return self
8381 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
8382 .map(|tree| (tree, Vec::new()));
8383 }
8384 if !self.semantic_hooks.observes_parser_decisions()
8385 && can_use_fast_predicate_recognizer(atn, &options)
8386 {
8387 self.unknown_predicate_policy = unknown_predicate_policy;
8388 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8389 let member_values = self.int_members.clone();
8390 let result = self
8391 .parse_atn_rule_with_precedence_inner(
8392 atn,
8393 rule_index,
8394 precedence,
8395 Some(FastPredicateContext {
8396 predicates,
8397 semantics,
8398 member_values: &member_values,
8399 }),
8400 AltNumberTracking {
8401 public: track_alt_numbers,
8402 context: track_context_alt_numbers,
8403 },
8404 )
8405 .map(|tree| (tree, Vec::new()));
8406 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
8407 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8408 }
8409 return result;
8410 }
8411 self.unknown_predicate_policy = unknown_predicate_policy;
8412 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8419 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
8420 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
8421 })?;
8422 let stop_state = atn
8423 .rule_to_stop_state()
8424 .get(rule_index)
8425 .filter(|state| *state != usize::MAX)
8426 .ok_or_else(|| {
8427 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
8428 })?;
8429
8430 let start_index = self.current_visible_index();
8431 self.clear_prediction_diagnostics();
8432 self.reset_per_parse_caches();
8433 self.reset_recognition_arena();
8434 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
8435 let invoking_state = self.pending_invoking_states.pop();
8436 let local_int_arg = invoking_state
8437 .and_then(|state| usize::try_from(state).ok())
8438 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
8439 let mut visiting = BTreeSet::new();
8440 let mut memo = BTreeMap::new();
8441 let mut expected = ExpectedTokens::default();
8442 let member_values = self.int_members.clone();
8443 let return_values = BTreeMap::new();
8444 let outcomes = self.recognize_state(
8445 atn,
8446 RecognizeRequest {
8447 state_number: start_state,
8448 stop_state,
8449 index: start_index,
8450 rule_start_index: start_index,
8451 decision_start_index: None,
8452 init_action_rules: &init_action_rules,
8453 predicates,
8454 semantics,
8455 rule_args,
8456 member_actions,
8457 return_actions,
8458 local_int_arg,
8459 member_values,
8460 return_values,
8461 rule_alt_number: 0,
8462 track_alt_numbers: capture_alt_numbers,
8463 consumed_eof: false,
8464 committed_decision: false,
8465 precedence,
8466 depth: 0,
8467 recovery_symbols: BTreeSet::new(),
8468 recovery_state: None,
8469 },
8470 &mut visiting,
8471 &mut memo,
8472 &mut expected,
8473 );
8474 if let Some(error) = self.unknown_semantic_error() {
8475 self.report_token_source_errors();
8476 return Err(error);
8483 }
8484 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8487 let Some(outcome) = select_best_outcome(
8488 outcomes.into_iter(),
8489 self.prediction_mode,
8490 &self.recognition_arena,
8491 ) else {
8492 let error = self.recognition_error(rule_index, start_index, &expected);
8493 self.record_syntax_errors(1);
8494 self.report_token_source_errors();
8495 if report_unrecovered_error {
8496 self.report_unrecovered_parser_error(&error);
8497 }
8498 return Err(error);
8499 };
8500
8501 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
8502 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
8503 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
8504 self.report_token_source_errors();
8505 let mut actions = outcome.actions;
8506 if init_action_rules.contains(&rule_index) {
8507 actions.insert(
8508 0,
8509 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
8510 );
8511 }
8512 let mut context =
8513 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
8514 if track_alt_numbers {
8515 context.set_alt_number(outcome.alt_number.max(1));
8516 }
8517 if track_context_alt_numbers {
8518 context.set_context_alt_number(outcome.alt_number);
8519 }
8520 for (name, value) in outcome.return_values {
8521 context.set_int_return(name, value);
8522 }
8523 if let Some(token) = self.token_id_at(start_index) {
8524 self.set_context_start(&mut context, token);
8525 }
8526 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
8527 self.set_context_stop(&mut context, token);
8528 }
8529 let live_root = if self.build_parse_trees {
8530 self.recognition_arena
8531 .fold_left_recursive_boundaries(outcome.nodes)
8532 } else {
8533 outcome.nodes
8534 };
8535 if self.build_parse_trees {
8536 let mut nodes = live_root;
8537 while let Some(link) = self.recognition_arena.link(nodes) {
8538 let child = self.arena_recognized_node_tree(
8539 link.head,
8540 track_alt_numbers,
8541 track_context_alt_numbers,
8542 )?;
8543 self.tree.add_child(&mut context, child);
8544 nodes = link.tail;
8545 }
8546 }
8547 self.finish_recognition_arena(live_root, outcome.diagnostics);
8548 self.input.seek(outcome.index);
8549
8550 let tree = self.rule_node(context);
8551 self.release_tree_scratch_if_idle();
8552 Ok((tree, actions))
8553 }
8554
8555 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
8562 let mut context = ParserRuleContext::new(rule_index, self.state());
8563 while self.la(1) != TOKEN_EOF {
8564 let token_type = self.la(1);
8565 let child = self.match_token(token_type)?;
8566 if self.build_parse_trees {
8567 self.tree.add_child(&mut context, child);
8568 }
8569 }
8570 if self.build_parse_trees {
8571 let child = self.match_eof()?;
8572 self.tree.add_child(&mut context, child);
8573 }
8574 let tree = self.rule_node(context);
8575 self.release_tree_scratch_if_idle();
8576 Ok(tree)
8577 }
8578
8579 fn recognition_error(
8582 &mut self,
8583 rule_index: usize,
8584 start_index: usize,
8585 expected: &ExpectedTokens,
8586 ) -> AntlrError {
8587 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
8588 self.input.seek(index);
8589 let current = self.input.lt(1);
8590 let line = current.as_ref().map(Token::line).unwrap_or_default();
8591 let column = current.as_ref().map(Token::column).unwrap_or_default();
8592 AntlrError::ParserError {
8593 line,
8594 column,
8595 message,
8596 offending: current.as_ref().map(Token::token_id),
8597 }
8598 }
8599
8600 fn expected_error_message(
8602 &mut self,
8603 rule_index: usize,
8604 start_index: usize,
8605 expected: &ExpectedTokens,
8606 ) -> (usize, String) {
8607 let index = expected
8608 .index
8609 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
8610 .unwrap_or_else(|| self.input.index());
8611 self.input.seek(index);
8612 let current = self.input.lt(1);
8613 let message = if expected
8614 .no_viable
8615 .as_ref()
8616 .is_some_and(|no_viable| no_viable.error_index == index)
8617 {
8618 let start = expected
8619 .no_viable
8620 .as_ref()
8621 .map_or(start_index, |no_viable| no_viable.start_index);
8622 let text = display_input_text(&self.input.text(start, index));
8623 format!("no viable alternative at input '{text}'")
8624 } else if expected.symbols.is_empty() {
8625 if expected.index.is_some() {
8626 let found = current
8627 .as_ref()
8628 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
8629 if current
8630 .as_ref()
8631 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8632 {
8633 format!(
8634 "missing {} at {found}",
8635 self.expected_symbols_display(&expected.symbols)
8636 )
8637 } else {
8638 format!("mismatched input {found}")
8639 }
8640 } else {
8641 format!("no viable alternative while parsing rule {rule_index}")
8642 }
8643 } else {
8644 format!(
8645 "mismatched input {} expecting {}",
8646 current
8647 .as_ref()
8648 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8649 self.expected_symbols_display(&expected.symbols)
8650 )
8651 };
8652 (index, message)
8653 }
8654
8655 fn child_rule_failure_recovery(
8658 &mut self,
8659 rule_index: usize,
8660 start_index: usize,
8661 sync_symbols: &BTreeSet<i32>,
8662 member_values: MemberEnv,
8663 expected: &ExpectedTokens,
8664 ) -> Option<RecognizeOutcome> {
8665 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8666 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8667 let mut next_index = error_index;
8668 loop {
8669 let symbol = self.token_type_at(next_index);
8670 if sync_symbols.contains(&symbol) {
8671 if next_index == error_index {
8672 return None;
8673 }
8674 break;
8675 }
8676 if symbol == TOKEN_EOF {
8677 break;
8678 }
8679 let after = self.consume_index(next_index, symbol);
8680 if after == next_index {
8681 break;
8682 }
8683 next_index = after;
8684 }
8685 let mut nodes = NodeSeqId::EMPTY;
8686 let error = self.arena_token_node(error_index, true);
8687 self.arena_prepend(&mut nodes, error);
8688 let diagnostics = self
8689 .recognition_arena
8690 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8691 Some(RecognizeOutcome {
8692 index: next_index,
8693 consumed_eof: false,
8694 alt_number: 0,
8695 member_values,
8696 return_values: BTreeMap::new(),
8697 diagnostics,
8698 decisions: Vec::new(),
8699 actions: Vec::new(),
8700 nodes,
8701 })
8702 }
8703
8704 fn child_rule_failure_recovery_outcomes(
8707 &mut self,
8708 request: ChildRuleFailureRecovery<'_>,
8709 ) -> Vec<RecognizeOutcome> {
8710 let sync_symbols =
8711 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
8712 self.child_rule_failure_recovery(
8713 request.rule_index,
8714 request.start_index,
8715 &sync_symbols,
8716 request.member_values,
8717 request.expected,
8718 )
8719 .into_iter()
8720 .collect()
8721 }
8722
8723 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
8725 expected_symbols_display(symbols, self.vocabulary())
8726 }
8727
8728 fn single_token_deletion(
8731 &mut self,
8732 transition: ParserTransition<'_>,
8733 index: usize,
8734 max_token_type: i32,
8735 expected_symbols: &BTreeSet<i32>,
8736 ) -> Option<(ParserDiagnostic, usize, i32)> {
8737 let current_symbol = self.token_type_at(index);
8738 if current_symbol == TOKEN_EOF {
8739 return None;
8740 }
8741 let next_index = self.consume_index(index, current_symbol);
8742 if next_index == index {
8743 return None;
8744 }
8745 let next_symbol = self.token_type_at(next_index);
8746 if !transition.matches(next_symbol, 1, max_token_type) {
8747 return None;
8748 }
8749 let transition_expected = transition_expected_symbols(transition, max_token_type);
8750 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8751 &transition_expected
8752 } else {
8753 expected_symbols
8754 });
8755 let current = self.token_at(index);
8756 let message = format!(
8757 "extraneous input {} expecting {expected_display}",
8758 current
8759 .as_ref()
8760 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8761 );
8762 Some((
8763 diagnostic_for_token(current, message),
8764 next_index,
8765 next_symbol,
8766 ))
8767 }
8768
8769 fn current_token_deletion(
8772 &mut self,
8773 index: usize,
8774 expected_symbols: &BTreeSet<i32>,
8775 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
8776 if expected_symbols.is_empty() {
8777 return None;
8778 }
8779 let current_symbol = self.token_type_at(index);
8780 if current_symbol == TOKEN_EOF {
8781 return None;
8782 }
8783 let current = self.token_at(index);
8784 let message = format!(
8785 "extraneous input {} expecting {}",
8786 current
8787 .as_ref()
8788 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8789 self.expected_symbols_display(expected_symbols)
8790 );
8791 let diagnostic = diagnostic_for_token(current, message);
8792 let mut skipped = Vec::new();
8793 let mut cursor = index;
8794 loop {
8795 let symbol = self.token_type_at(cursor);
8796 if symbol == TOKEN_EOF {
8797 return None;
8798 }
8799 skipped.push(cursor);
8800 let next_index = self.consume_index(cursor, symbol);
8801 if next_index == cursor {
8802 return None;
8803 }
8804 let next_symbol = self.token_type_at(next_index);
8805 if expected_symbols.contains(&next_symbol) {
8806 return Some((diagnostic, next_index, skipped));
8807 }
8808 cursor = next_index;
8809 }
8810 }
8811
8812 fn single_token_insertion(
8816 &mut self,
8817 transition: ParserTransition<'_>,
8818 index: usize,
8819 max_token_type: i32,
8820 expected_symbols: &BTreeSet<i32>,
8821 follow_symbols: &BTreeSet<i32>,
8822 ) -> Option<(ParserDiagnostic, i32, String)> {
8823 let current_symbol = self.token_type_at(index);
8824 if !follow_symbols.contains(¤t_symbol) {
8825 return None;
8826 }
8827 let transition_expected = transition_expected_symbols(transition, max_token_type);
8828 let token_type = transition_expected.iter().next().copied()?;
8829 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8830 &transition_expected
8831 } else {
8832 expected_symbols
8833 });
8834 let mut token_symbols = BTreeSet::new();
8835 token_symbols.insert(token_type);
8836 let missing_token_display = self.expected_symbols_display(&token_symbols);
8837 let current = self.token_at(index);
8838 let message = format!(
8839 "missing {expected_display} at {}",
8840 current
8841 .as_ref()
8842 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8843 );
8844 let text = format!("<missing {missing_token_display}>");
8845 Some((
8846 diagnostic_for_token(current.as_ref(), message),
8847 token_type,
8848 text,
8849 ))
8850 }
8851
8852 fn fast_single_token_deletion_recovery(
8856 &mut self,
8857 recovery: FastRecoveryRequest<'_, '_>,
8858 predicate_context: Option<FastPredicateContext<'_>>,
8859 ) -> Vec<FastRecognizeOutcome> {
8860 let FastRecoveryRequest {
8861 atn,
8862 transition,
8863 expected_symbols,
8864 target,
8865 request,
8866 visiting,
8867 memo,
8868 expected,
8869 } = recovery;
8870 let FastRecognizeRequest {
8871 stop_state,
8872 index,
8873 rule_start_index,
8874 decision_start_index,
8875 precedence,
8876 depth,
8877 ..
8878 } = request;
8879 let Some((diagnostic, next_index, next_symbol)) =
8880 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8881 else {
8882 return Vec::new();
8883 };
8884 let after_next = self.consume_index(next_index, next_symbol);
8885 let empty_recovery = self.empty_recovery_symbols();
8886 self.recognize_state_fast(
8887 atn,
8888 FastRecognizeRequest {
8889 state_number: target,
8890 stop_state,
8891 index: after_next,
8892 rule_start_index,
8893 decision_start_index,
8894 precedence,
8895 depth: depth + 1,
8896 recovery_symbols: empty_recovery,
8897 recovery_state: None,
8898 },
8899 FastRecognizeScratch {
8900 predicate_context,
8901 visiting,
8902 memo,
8903 expected,
8904 native_depth: 0,
8905 },
8906 )
8907 .into_iter()
8908 .map(|mut outcome| {
8909 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
8910 outcome.diagnostics = self
8911 .recognition_arena
8912 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8913 if self.fast_token_nodes_enabled {
8914 let token = self.arena_token_node(next_index, false);
8915 self.defer_fast_outcome_node(&mut outcome, token);
8916 let error = self.arena_token_node(index, true);
8917 self.defer_fast_outcome_node(&mut outcome, error);
8918 }
8919 outcome
8920 })
8921 .collect()
8922 }
8923
8924 fn fast_single_token_insertion_recovery(
8928 &mut self,
8929 recovery: FastRecoveryRequest<'_, '_>,
8930 predicate_context: Option<FastPredicateContext<'_>>,
8931 ) -> Vec<FastRecognizeOutcome> {
8932 let FastRecoveryRequest {
8933 atn,
8934 transition,
8935 expected_symbols,
8936 target,
8937 request,
8938 visiting,
8939 memo,
8940 expected,
8941 } = recovery;
8942 let FastRecognizeRequest {
8943 stop_state,
8944 index,
8945 rule_start_index,
8946 decision_start_index,
8947 precedence,
8948 depth,
8949 ..
8950 } = request;
8951 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
8952 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
8953 transition,
8954 index,
8955 atn.max_token_type(),
8956 &expected_symbols,
8957 &follow_symbols,
8958 ) else {
8959 return Vec::new();
8960 };
8961 let empty_recovery = self.empty_recovery_symbols();
8962 self.recognize_state_fast(
8963 atn,
8964 FastRecognizeRequest {
8965 state_number: target,
8966 stop_state,
8967 index,
8968 rule_start_index,
8969 decision_start_index,
8970 precedence,
8971 depth: depth + 1,
8972 recovery_symbols: empty_recovery,
8973 recovery_state: None,
8974 },
8975 FastRecognizeScratch {
8976 predicate_context,
8977 visiting,
8978 memo,
8979 expected,
8980 native_depth: 0,
8981 },
8982 )
8983 .into_iter()
8984 .map(|mut outcome| {
8985 outcome.diagnostics = self
8986 .recognition_arena
8987 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8988 let missing = self.arena_missing_token_node(token_type, index, text.clone());
8989 self.defer_fast_outcome_node(&mut outcome, missing);
8990 outcome
8991 })
8992 .collect()
8993 }
8994
8995 fn fast_current_token_deletion_recovery(
8998 &mut self,
8999 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
9000 predicate_context: Option<FastPredicateContext<'_>>,
9001 ) -> Vec<FastRecognizeOutcome> {
9002 let FastCurrentTokenDeletionRequest {
9003 atn,
9004 expected_symbols,
9005 mut request,
9006 visiting,
9007 memo,
9008 expected,
9009 } = recovery;
9010 if request.index == request.rule_start_index {
9011 return Vec::new();
9012 }
9013 let Some((diagnostic, next_index, skipped)) =
9014 self.current_token_deletion(request.index, &expected_symbols)
9015 else {
9016 return Vec::new();
9017 };
9018 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9019 request.index = next_index;
9020 request.depth += 1;
9021 request.recovery_state = None;
9022 self.recognize_state_fast(
9023 atn,
9024 request,
9025 FastRecognizeScratch {
9026 predicate_context,
9027 visiting,
9028 memo,
9029 expected,
9030 native_depth: 0,
9031 },
9032 )
9033 .into_iter()
9034 .map(|mut outcome| {
9035 outcome.diagnostics = self
9036 .recognition_arena
9037 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9038 for index in skipped.iter().rev() {
9039 let error = self.arena_token_node(*index, true);
9040 self.defer_fast_outcome_node(&mut outcome, error);
9041 }
9042 outcome
9043 })
9044 .collect()
9045 }
9046
9047 fn fast_child_rule_failure_recovery(
9050 &mut self,
9051 rule_index: usize,
9052 start_index: usize,
9053 sync_symbols: &BTreeSet<i32>,
9054 expected: &ExpectedTokens,
9055 ) -> Option<FastRecognizeOutcome> {
9056 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
9057 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
9058 let mut next_index = error_index;
9059 loop {
9060 let symbol = self.token_type_at(next_index);
9061 if sync_symbols.contains(&symbol) {
9062 if next_index == error_index {
9063 return None;
9064 }
9065 break;
9066 }
9067 if symbol == TOKEN_EOF {
9068 break;
9069 }
9070 let after = self.consume_index(next_index, symbol);
9071 if after == next_index {
9072 break;
9073 }
9074 next_index = after;
9075 }
9076 let diagnostics = self
9077 .recognition_arena
9078 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
9079 let mut nodes = NodeSeqId::EMPTY;
9080 if self.fast_token_nodes_enabled {
9081 let error = self.arena_token_node(error_index, true);
9082 self.arena_prepend(&mut nodes, error);
9083 }
9084 Some(FastRecognizeOutcome {
9085 index: next_index,
9086 consumed_eof: false,
9087 diagnostics,
9088 deferred_nodes: FastDeferredNodeId::EMPTY,
9089 nodes,
9090 })
9091 }
9092
9093 fn fast_child_rule_failure_recovery_outcomes(
9096 &mut self,
9097 request: FastChildRuleFailureRecoveryRequest<'_>,
9098 ) -> Vec<FastRecognizeOutcome> {
9099 let FastChildRuleFailureRecoveryRequest {
9100 atn,
9101 rule_index,
9102 start_index,
9103 follow_state,
9104 stop_state,
9105 expected,
9106 } = request;
9107 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
9108 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
9109 .into_iter()
9110 .collect()
9111 }
9112
9113 fn defer_fast_outcome_node(
9114 &mut self,
9115 outcome: &mut FastRecognizeOutcome,
9116 node: RecognizedNodeId,
9117 ) {
9118 if outcome.deferred_nodes.is_empty() {
9119 self.arena_prepend(&mut outcome.nodes, node);
9120 return;
9121 }
9122 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
9123 let fragment = self.recognition_arena.deferred_fragment(fragment);
9124 outcome.deferred_nodes = self
9125 .recognition_arena
9126 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
9127 }
9128
9129 fn defer_fast_outcome_alternative(
9130 &mut self,
9131 outcome: &mut FastRecognizeOutcome,
9132 alt_number: usize,
9133 ) {
9134 let alternative = self.recognition_arena.deferred_alternative(alt_number);
9135 outcome.deferred_nodes = self
9136 .recognition_arena
9137 .concat_deferred_nodes(alternative, outcome.deferred_nodes);
9138 }
9139
9140 fn defer_fast_outcome_boundary(
9141 &mut self,
9142 outcome: &mut FastRecognizeOutcome,
9143 rule_index: usize,
9144 ) {
9145 let boundary = self
9146 .recognition_arena
9147 .deferred_left_recursive_boundary(rule_index);
9148 outcome.deferred_nodes = self
9149 .recognition_arena
9150 .concat_deferred_nodes(boundary, outcome.deferred_nodes);
9151 }
9152
9153 fn materialize_fast_deferred_nodes(
9154 &mut self,
9155 root: FastDeferredNodeId,
9156 initial_suffix: NodeSeqId,
9157 ) -> (NodeSeqId, usize) {
9158 if root.is_empty() {
9159 return (initial_suffix, 0);
9160 }
9161
9162 enum Frame {
9163 Visit(FastDeferredNodeId),
9164 ContinuePrefix(FastDeferredNodeId),
9165 FinishRule {
9166 rule: FastDeferredRule,
9167 parent_suffix: NodeSeqId,
9168 parent_alt_number: u32,
9169 parent_pending_boundary: Option<RecognizedNodeId>,
9170 },
9171 }
9172
9173 let mut result = initial_suffix;
9174 let mut alt_number = 0;
9178 let mut pending_boundary = None;
9179 let mut pending = Vec::with_capacity(16);
9180 pending.push(Frame::Visit(root));
9181 let mut fragment_nodes = Vec::new();
9182 while let Some(frame) = pending.pop() {
9183 match frame {
9184 Frame::Visit(deferred) => {
9185 if deferred.is_empty() {
9186 continue;
9187 }
9188
9189 match self.recognition_arena.deferred_node(deferred) {
9190 FastDeferredNode::Fragment(sequence) => {
9191 fragment_nodes.clear();
9192 fragment_nodes.extend(self.recognition_arena.iter(sequence));
9193 while let Some(node) = fragment_nodes.pop() {
9194 self.arena_prepend(&mut result, node);
9195 }
9196 }
9197 FastDeferredNode::Rule(rule) => {
9198 let rule = self.recognition_arena.deferred_rule(rule);
9199 let parent_suffix = result;
9200 let parent_alt_number = alt_number;
9201 let parent_pending_boundary = pending_boundary;
9202 result = rule.children;
9203 alt_number = 0;
9204 pending_boundary = None;
9205 pending.push(Frame::FinishRule {
9206 rule,
9207 parent_suffix,
9208 parent_alt_number,
9209 parent_pending_boundary,
9210 });
9211 pending.push(Frame::Visit(rule.deferred_children));
9212 }
9213 FastDeferredNode::Alternative(selected) => {
9214 if let Some(boundary) = pending_boundary {
9215 self.recognition_arena
9216 .set_boundary_alt_number(boundary, selected);
9217 } else {
9218 alt_number = selected;
9219 }
9220 }
9221 FastDeferredNode::LeftRecursiveBoundary { rule_index } => {
9222 let boundary = self.arena_boundary_node(rule_index as usize, 0);
9223 self.arena_prepend(&mut result, boundary);
9224 pending_boundary = Some(boundary);
9225 }
9226 FastDeferredNode::Concat {
9227 prefix,
9228 suffix: deferred_suffix,
9229 } => {
9230 pending.push(Frame::ContinuePrefix(prefix));
9231 pending.push(Frame::Visit(deferred_suffix));
9232 }
9233 }
9234 }
9235 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
9236 Frame::FinishRule {
9237 rule,
9238 parent_suffix,
9239 parent_alt_number,
9240 parent_pending_boundary,
9241 } => {
9242 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
9243 rule_index: rule.rule_index,
9244 invoking_state: rule.invoking_state,
9245 alt_number,
9246 start_index: rule.start_index,
9247 stop_index: rule.stop_index,
9248 return_values: None,
9249 children: result,
9250 });
9251 result = parent_suffix;
9252 self.arena_prepend(&mut result, node);
9253 alt_number = parent_alt_number;
9254 pending_boundary = parent_pending_boundary;
9255 }
9256 }
9257 }
9258 (result, alt_number as usize)
9259 }
9260
9261 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) -> usize {
9262 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
9263 let (nodes, alt_number) =
9264 self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
9265 outcome.nodes = nodes;
9266 alt_number
9267 }
9268
9269 fn recognize_repetition_fast(
9272 &mut self,
9273 atn: &Atn,
9274 request: &FastRecognizeRequest,
9275 shape: FastRepetitionShape,
9276 scratch: FastRecognizeScratch<'_, '_>,
9277 ) -> Vec<FastRecognizeOutcome> {
9278 let FastRecognizeScratch {
9279 predicate_context,
9280 visiting,
9281 memo,
9282 expected,
9283 native_depth,
9284 } = scratch;
9285 let lookahead = if self.fast_first_set_prefilter {
9286 atn.state(request.state_number).and_then(|state| {
9287 state
9288 .rule_index()
9289 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9290 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
9291 })
9292 } else {
9293 None
9294 };
9295 let (enter_alt_number, exit_alt_number) = if self.fast_track_alt_numbers {
9296 let state = atn
9297 .state(request.state_number)
9298 .expect("repetition request state must exist");
9299 (
9300 next_alt_number(state, 2, shape.enter_transition_index, 0, true),
9301 next_alt_number(state, 2, shape.exit_transition_index, 0, true),
9302 )
9303 } else {
9304 (0, 0)
9305 };
9306 let mut work = Vec::with_capacity(2);
9307 push_fast_repetition_work(
9308 &mut work,
9309 shape,
9310 FastRepetitionPath {
9311 index: request.index,
9312 deferred_nodes: FastDeferredNodeId::EMPTY,
9313 diagnostics: DiagnosticSeqId::EMPTY,
9314 consumed_eof: false,
9315 },
9316 lookahead.as_deref(),
9317 self.token_type_at(request.index),
9318 );
9319 let mut coordinates = FastRepetitionCoordinates::new(request.index);
9320 let mut outcomes = Vec::new();
9321 while let Some(item) = work.pop() {
9322 match item {
9323 FastRepetitionWork::Enter(path) => {
9324 if !coordinates.insert_entered(path) {
9325 continue;
9326 }
9327 let path_nodes = if enter_alt_number == 0 {
9328 path.deferred_nodes
9329 } else {
9330 let alternative = self
9331 .recognition_arena
9332 .deferred_alternative(enter_alt_number);
9333 self.recognition_arena
9334 .concat_deferred_nodes(path.deferred_nodes, alternative)
9335 };
9336 let body_outcomes = self.recognize_state_fast(
9337 atn,
9338 FastRecognizeRequest {
9339 state_number: shape.enter_target,
9340 stop_state: shape.body_stop_state,
9341 index: path.index,
9342 rule_start_index: request.rule_start_index,
9343 decision_start_index: request.decision_start_index,
9344 precedence: request.precedence,
9345 depth: request.depth.saturating_add(1),
9346 recovery_symbols: Rc::clone(&request.recovery_symbols),
9347 recovery_state: request.recovery_state,
9348 },
9349 FastRecognizeScratch {
9350 predicate_context,
9351 visiting: &mut *visiting,
9352 memo: &mut *memo,
9353 expected: &mut *expected,
9354 native_depth: native_depth + 1,
9355 },
9356 );
9357 for body in body_outcomes.into_iter().rev() {
9358 if body.index <= path.index {
9362 continue;
9363 }
9364 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
9365 let body_nodes = self
9366 .recognition_arena
9367 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
9368 let deferred_nodes = self
9369 .recognition_arena
9370 .concat_deferred_nodes(path_nodes, body_nodes);
9371 let next_path = FastRepetitionPath {
9372 index: body.index,
9373 deferred_nodes,
9374 diagnostics: self
9375 .recognition_arena
9376 .concat_diagnostics(path.diagnostics, body.diagnostics),
9377 consumed_eof: path.consumed_eof || body.consumed_eof,
9378 };
9379 let symbol = self.token_type_at(next_path.index);
9380 push_fast_repetition_work(
9381 &mut work,
9382 shape,
9383 next_path,
9384 lookahead.as_deref(),
9385 symbol,
9386 );
9387 }
9388 }
9389 FastRepetitionWork::Exit(path) => {
9390 if !coordinates.insert_exited(path) {
9391 continue;
9392 }
9393 let path_nodes = if exit_alt_number == 0 {
9394 path.deferred_nodes
9395 } else {
9396 let alternative =
9397 self.recognition_arena.deferred_alternative(exit_alt_number);
9398 self.recognition_arena
9399 .concat_deferred_nodes(path.deferred_nodes, alternative)
9400 };
9401 let suffixes = self.recognize_state_fast(
9402 atn,
9403 FastRecognizeRequest {
9404 state_number: shape.exit_target,
9405 stop_state: request.stop_state,
9406 index: path.index,
9407 rule_start_index: request.rule_start_index,
9408 decision_start_index: request.decision_start_index,
9409 precedence: request.precedence,
9410 depth: request.depth.saturating_add(1),
9411 recovery_symbols: Rc::clone(&request.recovery_symbols),
9412 recovery_state: request.recovery_state,
9413 },
9414 FastRecognizeScratch {
9415 predicate_context,
9416 visiting: &mut *visiting,
9417 memo: &mut *memo,
9418 expected: &mut *expected,
9419 native_depth: native_depth + 1,
9420 },
9421 );
9422 for mut outcome in suffixes {
9423 outcome.deferred_nodes = self
9424 .recognition_arena
9425 .concat_deferred_nodes(path_nodes, outcome.deferred_nodes);
9426 outcome.diagnostics = self
9427 .recognition_arena
9428 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
9429 outcome.consumed_eof |= path.consumed_eof;
9430 outcomes.push(outcome);
9431 }
9432 }
9433 }
9434 }
9435 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9436 outcomes
9437 }
9438
9439 fn recognize_state_fast(
9442 &mut self,
9443 atn: &Atn,
9444 request: FastRecognizeRequest,
9445 scratch: FastRecognizeScratch<'_, '_>,
9446 ) -> Vec<FastRecognizeOutcome> {
9447 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
9448 return self.recognize_state_fast_inner(atn, request, scratch);
9449 }
9450 self.recognize_state_fast_checked(atn, request, scratch)
9451 }
9452
9453 #[inline(never)]
9454 fn recognize_state_fast_checked(
9455 &mut self,
9456 atn: &Atn,
9457 request: FastRecognizeRequest,
9458 mut scratch: FastRecognizeScratch<'_, '_>,
9459 ) -> Vec<FastRecognizeOutcome> {
9460 scratch.native_depth = 1;
9461 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
9462 self.recognize_state_fast_inner(atn, request, scratch)
9463 })
9464 }
9465
9466 #[allow(clippy::too_many_lines)]
9467 fn recognize_state_fast_inner(
9468 &mut self,
9469 atn: &Atn,
9470 request: FastRecognizeRequest,
9471 scratch: FastRecognizeScratch<'_, '_>,
9472 ) -> Vec<FastRecognizeOutcome> {
9473 #[cfg(feature = "perf-counters")]
9474 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
9475 let FastRecognizeScratch {
9476 predicate_context,
9477 visiting,
9478 memo,
9479 expected,
9480 native_depth,
9481 } = scratch;
9482 let FastRecognizeRequest {
9483 mut state_number,
9484 stop_state,
9485 mut index,
9486 rule_start_index,
9487 decision_start_index,
9488 precedence,
9489 mut depth,
9490 recovery_symbols,
9491 recovery_state,
9492 } = request;
9493 let max_token_type = atn.max_token_type();
9494 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
9513 let mut inline_consumed_eof = false;
9514 loop {
9515 if depth > RECOGNITION_DEPTH_LIMIT {
9516 return Vec::new();
9517 }
9518 if state_number == stop_state {
9519 let mut nodes = NodeSeqId::EMPTY;
9520 if self.fast_token_nodes_enabled {
9521 for token_index in inline_consumed_tokens.iter().rev() {
9522 let token = self.arena_token_node(*token_index, false);
9523 self.arena_prepend(&mut nodes, token);
9524 }
9525 }
9526 return vec![FastRecognizeOutcome {
9527 index,
9528 consumed_eof: inline_consumed_eof,
9529 diagnostics: DiagnosticSeqId::EMPTY,
9530 deferred_nodes: FastDeferredNodeId::EMPTY,
9531 nodes,
9532 }];
9533 }
9534 let Some(state) = atn.state(state_number) else {
9535 return Vec::new();
9536 };
9537 let transitions = state.transitions();
9538 if transitions.len() == 1 && !state.precedence_rule_decision() {
9539 let transition = transitions
9540 .first()
9541 .expect("single transition checked above");
9542 let transition_kind = transition.kind();
9543 let target = transition.target();
9544 match transition_kind {
9545 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
9546 if left_recursive_boundary(atn, state, target).is_none() =>
9547 {
9548 #[cfg(feature = "perf-counters")]
9549 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9550 state_number = target;
9551 depth += 1;
9552 continue;
9553 }
9554 ParserTransitionKind::Predicate
9555 if left_recursive_boundary(atn, state, target).is_none() =>
9556 {
9557 #[cfg(feature = "perf-counters")]
9558 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9559 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
9560 {
9561 record_predicate_no_viable(expected, decision_start_index, index);
9562 return Vec::new();
9563 }
9564 state_number = target;
9565 depth += 1;
9566 continue;
9567 }
9568 ParserTransitionKind::Precedence
9569 if packed_i32(transition.arg0()) >= precedence
9570 && left_recursive_boundary(atn, state, target).is_none() =>
9571 {
9572 #[cfg(feature = "perf-counters")]
9573 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9574 state_number = target;
9575 depth += 1;
9576 continue;
9577 }
9578 ParserTransitionKind::Atom
9588 | ParserTransitionKind::Range
9589 | ParserTransitionKind::Set
9590 | ParserTransitionKind::NotSet
9591 | ParserTransitionKind::Wildcard
9592 if !self.fast_recovery_enabled =>
9593 {
9594 let symbol = self.token_type_at(index);
9595 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9596 #[cfg(feature = "perf-counters")]
9597 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9598 if self.fast_token_nodes_enabled {
9599 inline_consumed_tokens.push(index);
9600 }
9601 inline_consumed_eof |= symbol == TOKEN_EOF;
9602 index = self.consume_index(index, symbol);
9603 state_number = target;
9604 depth += 1;
9605 continue;
9606 }
9607 }
9610 _ => {}
9611 }
9612 }
9613 break;
9614 }
9615 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
9619 let Some(state) = atn.state(state_number) else {
9620 return Vec::new();
9621 };
9622 let transitions = state.transitions();
9623 let transition_count = transitions.len();
9624 if !self.fast_recovery_enabled
9625 && let Some(shape) = fast_repetition_shape(atn, state)
9626 {
9627 let mut outcomes = self.recognize_repetition_fast(
9628 atn,
9629 &FastRecognizeRequest {
9630 state_number,
9631 stop_state,
9632 index,
9633 rule_start_index,
9634 decision_start_index,
9635 precedence,
9636 depth,
9637 recovery_symbols: Rc::clone(&recovery_symbols),
9638 recovery_state,
9639 },
9640 shape,
9641 FastRecognizeScratch {
9642 predicate_context,
9643 visiting: &mut *visiting,
9644 memo: &mut *memo,
9645 expected: &mut *expected,
9646 native_depth: native_depth + 1,
9647 },
9648 );
9649 if inline_pending {
9650 for outcome in &mut outcomes {
9651 outcome.consumed_eof |= inline_consumed_eof;
9652 if self.fast_token_nodes_enabled {
9653 for token_index in inline_consumed_tokens.iter().rev() {
9654 let token = self.arena_token_node(*token_index, false);
9655 self.defer_fast_outcome_node(outcome, token);
9656 }
9657 }
9658 }
9659 }
9660 return outcomes;
9661 }
9662 let key = if self.fast_recovery_enabled {
9672 FastRecognizeKey {
9673 state_number,
9674 stop_state,
9675 index,
9676 rule_start_index,
9677 decision_start_index,
9678 precedence,
9679 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
9680 recovery_state,
9681 }
9682 } else {
9683 FastRecognizeKey {
9684 state_number,
9685 stop_state,
9686 index,
9687 rule_start_index: 0,
9688 decision_start_index: None,
9689 precedence,
9690 recovery_symbols_id: 0,
9691 recovery_state: None,
9692 }
9693 };
9694 let memo_lookup_enabled = self.fast_recovery_enabled
9699 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
9700 if memo_lookup_enabled {
9701 if let Some(outcomes) = memo.get(&key) {
9702 #[cfg(feature = "perf-counters")]
9703 {
9704 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
9705 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
9706 }
9707 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
9711 let inline_eof = inline_consumed_eof;
9712 let inline_tokens = &inline_consumed_tokens;
9713 return outcomes
9714 .iter()
9715 .copied()
9716 .map(|mut outcome| {
9717 if inline_eof {
9718 outcome.consumed_eof = true;
9719 }
9720 if self.fast_token_nodes_enabled {
9721 for token_index in inline_tokens.iter().rev() {
9722 let token = self.arena_token_node(*token_index, false);
9723 self.defer_fast_outcome_node(&mut outcome, token);
9724 }
9725 }
9726 outcome
9727 })
9728 .collect();
9729 }
9730 return outcomes.to_vec();
9731 }
9732 #[cfg(feature = "perf-counters")]
9733 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
9734 }
9735
9736 let needs_cycle_guard = if self.fast_recovery_enabled {
9741 transitions.iter().any(ParserTransition::is_epsilon)
9742 } else {
9743 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
9744 };
9745 #[cfg(feature = "perf-counters")]
9746 if needs_cycle_guard {
9747 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
9748 } else {
9749 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
9750 match state
9751 .transitions()
9752 .first()
9753 .expect("single-transition path requires one transition")
9754 .data()
9755 {
9756 Transition::Rule { .. } => {
9757 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
9758 }
9759 Transition::Atom { .. }
9760 | Transition::Range { .. }
9761 | Transition::Set { .. }
9762 | Transition::NotSet { .. }
9763 | Transition::Wildcard { .. } => {
9764 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
9765 }
9766 _ => {
9767 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
9768 }
9769 }
9770 }
9771 let has_inserted_cycle_guard = if needs_cycle_guard {
9772 if !visiting.insert(key.clone()) {
9773 #[cfg(feature = "perf-counters")]
9774 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
9775 return Vec::new();
9776 }
9777 true
9778 } else {
9779 false
9780 };
9781 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9782 Some(index)
9783 } else {
9784 decision_start_index
9785 };
9786 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
9787 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
9788 } else {
9789 (Rc::clone(&recovery_symbols), recovery_state)
9790 };
9791
9792 let lookahead_filter = if transition_count > 1
9811 && self.fast_first_set_prefilter
9812 && !state.precedence_rule_decision()
9813 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
9814 {
9815 state
9816 .rule_index()
9817 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9818 .map(|rule_stop| {
9819 let symbol = self.token_type_at(index);
9820 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
9821 (symbol, entry)
9822 })
9823 } else {
9824 None
9825 };
9826 let ll1_only_alt: Option<usize> = if transition_count > 1
9835 && let Some((symbol, entry)) = lookahead_filter.as_ref()
9836 {
9837 let key = (state.state_number(), *symbol);
9838 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
9839 cached
9840 } else {
9841 let result = ll1_unique_alt(entry, *symbol);
9842 self.ll1_decision_cache.insert(key, result);
9843 result
9844 }
9845 } else {
9846 None
9847 };
9848 let lookahead_filter = lookahead_filter.as_ref();
9849 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
9855 for (transition_index, transition) in transitions.iter().enumerate() {
9856 if let Some(alt) = ll1_only_alt {
9857 if alt != transition_index {
9859 continue;
9860 }
9861 }
9862 let transition_kind = transition.kind();
9863 if ll1_only_alt.is_none()
9864 && should_skip_via_lookahead(
9865 transition_kind,
9866 transition_index,
9867 lookahead_filter,
9868 index,
9869 self.fast_recovery_enabled,
9870 expected,
9871 )
9872 {
9873 continue;
9874 }
9875 let target = transition.target();
9876 let outcomes_before_transition = outcomes.len();
9877 let left_recursive_boundary = match transition_kind {
9878 ParserTransitionKind::Epsilon
9879 | ParserTransitionKind::Action
9880 | ParserTransitionKind::Predicate
9881 | ParserTransitionKind::Precedence => left_recursive_boundary(atn, state, target),
9882 ParserTransitionKind::Atom
9883 | ParserTransitionKind::Range
9884 | ParserTransitionKind::Set
9885 | ParserTransitionKind::NotSet
9886 | ParserTransitionKind::Wildcard
9887 | ParserTransitionKind::Rule => None,
9888 };
9889 match transition_kind {
9890 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
9891 #[cfg(feature = "perf-counters")]
9892 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9893 outcomes.extend(self.recognize_state_fast(
9894 atn,
9895 FastRecognizeRequest {
9896 state_number: target,
9897 stop_state,
9898 index,
9899 rule_start_index,
9900 decision_start_index: next_decision_start_index,
9901 precedence,
9902 depth: depth + 1,
9903 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9904 recovery_state: epsilon_recovery_state,
9905 },
9906 FastRecognizeScratch {
9907 predicate_context,
9908 visiting,
9909 memo,
9910 expected,
9911 native_depth: native_depth + 1,
9912 },
9913 ));
9914 }
9915 ParserTransitionKind::Predicate => {
9916 #[cfg(feature = "perf-counters")]
9917 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9918 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
9919 outcomes.extend(self.recognize_state_fast(
9920 atn,
9921 FastRecognizeRequest {
9922 state_number: target,
9923 stop_state,
9924 index,
9925 rule_start_index,
9926 decision_start_index: next_decision_start_index,
9927 precedence,
9928 depth: depth + 1,
9929 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9930 recovery_state: epsilon_recovery_state,
9931 },
9932 FastRecognizeScratch {
9933 predicate_context,
9934 visiting,
9935 memo,
9936 expected,
9937 native_depth: native_depth + 1,
9938 },
9939 ));
9940 } else {
9941 record_predicate_no_viable(expected, next_decision_start_index, index);
9942 }
9943 }
9944 ParserTransitionKind::Precedence => {
9945 let transition_precedence = packed_i32(transition.arg0());
9946 if transition_precedence >= precedence {
9947 outcomes.extend(self.recognize_state_fast(
9948 atn,
9949 FastRecognizeRequest {
9950 state_number: target,
9951 stop_state,
9952 index,
9953 rule_start_index,
9954 decision_start_index: next_decision_start_index,
9955 precedence,
9956 depth: depth + 1,
9957 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9958 recovery_state: epsilon_recovery_state,
9959 },
9960 FastRecognizeScratch {
9961 predicate_context,
9962 visiting,
9963 memo,
9964 expected,
9965 native_depth: native_depth + 1,
9966 },
9967 ));
9968 }
9969 }
9970 ParserTransitionKind::Rule => {
9971 let rule_index = transition.arg0() as usize;
9972 let follow_state = transition.arg1() as usize;
9973 let rule_precedence = packed_i32(transition.arg2());
9974 #[cfg(feature = "perf-counters")]
9975 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
9976 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
9977 continue;
9978 };
9979 let symbol = self.token_type_at(index);
9991 if self.fast_first_set_prefilter {
9992 let first = self.cached_rule_first_set(atn, target, child_stop);
10005 if should_skip_rule_via_first_set(
10006 &first,
10007 symbol,
10008 self.fast_recovery_enabled,
10009 index,
10010 expected,
10011 ) {
10012 continue;
10013 }
10014 }
10015 let expected_before_child =
10016 self.fast_recovery_enabled.then(|| expected.clone());
10017 let mut children = self.recognize_state_fast(
10018 atn,
10019 FastRecognizeRequest {
10020 state_number: target,
10021 stop_state: child_stop,
10022 index,
10023 rule_start_index: index,
10024 decision_start_index: None,
10025 precedence: rule_precedence,
10026 depth: depth + 1,
10027 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
10028 recovery_state: epsilon_recovery_state,
10029 },
10030 FastRecognizeScratch {
10031 predicate_context,
10032 visiting,
10033 memo,
10034 expected,
10035 native_depth: native_depth + 1,
10036 },
10037 );
10038 if children.is_empty() && self.fast_recovery_enabled {
10039 children = self.fast_child_rule_failure_recovery_outcomes(
10040 FastChildRuleFailureRecoveryRequest {
10041 atn,
10042 rule_index,
10043 start_index: index,
10044 follow_state,
10045 stop_state,
10046 expected,
10047 },
10048 );
10049 }
10050 if let Some(expected_before_child) = expected_before_child {
10051 if children
10052 .iter()
10053 .any(|child| child.diagnostics.is_empty() && child.index > index)
10054 {
10055 *expected = expected_before_child;
10056 }
10057 }
10058 for child in children {
10059 let child_index = child.index;
10060 let child_consumed_eof = child.consumed_eof;
10061 let child_diagnostics = child.diagnostics;
10062 let empty_recovery = self.empty_recovery_symbols();
10063 let follow_outcomes = self.recognize_state_fast(
10064 atn,
10065 FastRecognizeRequest {
10066 state_number: follow_state,
10067 stop_state,
10068 index: child_index,
10069 rule_start_index,
10070 decision_start_index: next_decision_start_index,
10071 precedence,
10072 depth: depth + 1,
10073 recovery_symbols: empty_recovery,
10074 recovery_state: None,
10075 },
10076 FastRecognizeScratch {
10077 predicate_context,
10078 visiting,
10079 memo,
10080 expected,
10081 native_depth: native_depth + 1,
10082 },
10083 );
10084 if follow_outcomes.is_empty() {
10085 continue;
10086 }
10087 let child_stop_index =
10088 self.rule_stop_token_index(child_index, child_consumed_eof);
10089 let child_node = self.build_parse_trees.then(|| {
10090 self.recognition_arena.deferred_rule_node(FastDeferredRule {
10091 rule_index: u32::try_from(rule_index)
10092 .expect("rule index fits in u32"),
10093 invoking_state: i32::try_from(invoking_state_number(state_number))
10094 .expect("invoking state fits in i32"),
10095 start_index: u32::try_from(index)
10096 .expect("rule start index fits in u32"),
10097 stop_index: child_stop_index.map(|stop_index| {
10098 u32::try_from(stop_index).expect("rule stop index fits in u32")
10099 }),
10100 deferred_children: child.deferred_nodes,
10101 children: child.nodes,
10102 })
10103 });
10104 let child_diags_empty = child_diagnostics.is_empty();
10105 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
10106 outcome.consumed_eof |= child_consumed_eof;
10107 if !child_diags_empty {
10110 outcome.diagnostics = self
10111 .recognition_arena
10112 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
10113 }
10114 if let Some(child_node) = child_node {
10115 outcome.deferred_nodes = self
10116 .recognition_arena
10117 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
10118 }
10119 outcome
10120 }));
10121 }
10122 }
10123 ParserTransitionKind::Atom
10124 | ParserTransitionKind::Range
10125 | ParserTransitionKind::Set
10126 | ParserTransitionKind::NotSet
10127 | ParserTransitionKind::Wildcard => {
10128 #[cfg(feature = "perf-counters")]
10129 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
10130 let symbol = self.token_type_at(index);
10131 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
10132 let next_index = self.consume_index(index, symbol);
10133 let empty_recovery = self.empty_recovery_symbols();
10134 outcomes.extend(
10135 self.recognize_state_fast(
10136 atn,
10137 FastRecognizeRequest {
10138 state_number: target,
10139 stop_state,
10140 index: next_index,
10141 rule_start_index,
10142 decision_start_index: next_decision_start_index,
10143 precedence,
10144 depth: depth + 1,
10145 recovery_symbols: empty_recovery,
10146 recovery_state: None,
10147 },
10148 FastRecognizeScratch {
10149 predicate_context,
10150 visiting,
10151 memo,
10152 expected,
10153 native_depth: native_depth + 1,
10154 },
10155 )
10156 .into_iter()
10157 .map(|mut outcome| {
10158 outcome.consumed_eof |= symbol == TOKEN_EOF;
10159 if self.fast_token_nodes_enabled {
10160 let token = self.arena_token_node(index, false);
10161 self.defer_fast_outcome_node(&mut outcome, token);
10162 }
10163 outcome
10164 }),
10165 );
10166 } else {
10167 if !self.fast_recovery_enabled {
10168 continue;
10176 }
10177 let expected_symbols = fast_recovery_expected_symbols(
10178 self,
10179 atn,
10180 state.state_number(),
10181 &recovery_symbols,
10182 );
10183 if expected_symbols.contains(&symbol) {
10184 continue;
10185 }
10186 {
10187 expected.record_transition(index, transition, max_token_type);
10188 record_no_viable_if_ambiguous(
10189 expected,
10190 next_decision_start_index,
10191 index,
10192 );
10193 outcomes.extend(self.fast_single_token_deletion_recovery(
10194 FastRecoveryRequest {
10195 atn,
10196 transition,
10197 expected_symbols: Rc::clone(&expected_symbols),
10198 target,
10199 request: FastRecognizeRequest {
10200 state_number,
10201 stop_state,
10202 index,
10203 rule_start_index,
10204 decision_start_index,
10205 precedence,
10206 depth,
10207 recovery_symbols: Rc::clone(&recovery_symbols),
10208 recovery_state,
10209 },
10210 visiting,
10211 memo,
10212 expected,
10213 },
10214 predicate_context,
10215 ));
10216 if !state_is_left_recursive_rule(atn, state) {
10217 outcomes.extend(self.fast_single_token_insertion_recovery(
10218 FastRecoveryRequest {
10219 atn,
10220 transition,
10221 expected_symbols: Rc::clone(&expected_symbols),
10222 target,
10223 request: FastRecognizeRequest {
10224 state_number,
10225 stop_state,
10226 index,
10227 rule_start_index,
10228 decision_start_index,
10229 precedence,
10230 depth,
10231 recovery_symbols: Rc::clone(&recovery_symbols),
10232 recovery_state,
10233 },
10234 visiting,
10235 memo,
10236 expected,
10237 },
10238 predicate_context,
10239 ));
10240 }
10241 outcomes.extend(self.fast_current_token_deletion_recovery(
10242 FastCurrentTokenDeletionRequest {
10243 atn,
10244 expected_symbols,
10245 request: FastRecognizeRequest {
10246 state_number,
10247 stop_state,
10248 index,
10249 rule_start_index,
10250 decision_start_index,
10251 precedence,
10252 depth,
10253 recovery_symbols: Rc::clone(&recovery_symbols),
10254 recovery_state,
10255 },
10256 visiting,
10257 memo,
10258 expected,
10259 },
10260 predicate_context,
10261 ));
10262 }
10263 }
10264 }
10265 }
10266 let alt_number = next_alt_number(
10267 state,
10268 transition_count,
10269 transition_index,
10270 0,
10271 self.fast_track_alt_numbers,
10272 );
10273 if alt_number != 0 || left_recursive_boundary.is_some() {
10274 for outcome in &mut outcomes[outcomes_before_transition..] {
10275 if alt_number != 0 {
10276 self.defer_fast_outcome_alternative(outcome, alt_number);
10277 }
10278 if let Some(rule_index) = left_recursive_boundary {
10279 self.defer_fast_outcome_boundary(outcome, rule_index);
10280 }
10281 }
10282 }
10283 }
10284
10285 if has_inserted_cycle_guard {
10286 visiting.remove(&key);
10287 }
10288 if matches!(
10289 self.prediction_mode,
10290 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
10291 ) && self.fast_recovery_enabled
10292 {
10293 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
10297 }
10298 if self.fast_recovery_enabled {
10299 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
10300 } else {
10301 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
10302 }
10303 let should_memoize = self.fast_recovery_enabled
10313 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
10314 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
10318 if inline_consumed_eof {
10319 outcome.consumed_eof = true;
10320 }
10321 if !inline_consumed_tokens.is_empty() {
10322 for token_index in inline_consumed_tokens.iter().rev() {
10323 let token = self.arena_token_node(*token_index, false);
10324 self.defer_fast_outcome_node(&mut outcome, token);
10325 }
10326 }
10327 outcome
10328 };
10329 if should_memoize {
10330 #[cfg(feature = "perf-counters")]
10331 {
10332 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
10333 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
10334 match outcomes.len() {
10335 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
10336 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
10337 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
10338 }
10339 }
10340 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
10345 memo.insert(key, Rc::clone(&stored));
10346 if inline_pending {
10347 return stored
10348 .iter()
10349 .copied()
10350 .map(&mut apply_inline_pending)
10351 .collect();
10352 }
10353 return stored.to_vec();
10354 }
10355 #[cfg(feature = "perf-counters")]
10356 match outcomes.len() {
10357 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
10358 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
10359 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
10360 }
10361 if inline_pending {
10362 return outcomes.into_iter().map(apply_inline_pending).collect();
10363 }
10364 outcomes
10365 }
10366
10367 fn single_token_deletion_recovery(
10370 &mut self,
10371 recovery: RecoveryRequest<'_, '_>,
10372 ) -> Vec<RecognizeOutcome> {
10373 let RecoveryRequest {
10374 atn,
10375 transition,
10376 expected_symbols,
10377 target,
10378 request,
10379 visiting,
10380 memo,
10381 expected,
10382 } = recovery;
10383 let RecognizeRequest {
10384 stop_state,
10385 index,
10386 rule_start_index,
10387 decision_start_index,
10388 init_action_rules,
10389 predicates,
10390 semantics,
10391 rule_args,
10392 member_actions,
10393 return_actions,
10394 local_int_arg,
10395 member_values,
10396 return_values,
10397 rule_alt_number,
10398 track_alt_numbers,
10399 consumed_eof,
10400 precedence,
10401 depth,
10402 ..
10403 } = request;
10404 let Some((diagnostic, next_index, next_symbol)) =
10405 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
10406 else {
10407 return Vec::new();
10408 };
10409 let after_next = self.consume_index(next_index, next_symbol);
10410 self.recognize_state(
10411 atn,
10412 RecognizeRequest {
10413 state_number: target,
10414 stop_state,
10415 index: after_next,
10416 rule_start_index,
10417 decision_start_index,
10418 init_action_rules,
10419 predicates,
10420 semantics,
10421 rule_args,
10422 member_actions,
10423 return_actions,
10424 local_int_arg,
10425 member_values,
10426 return_values,
10427 rule_alt_number,
10428 track_alt_numbers,
10429 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
10430 committed_decision: false,
10431 precedence,
10432 depth: depth + 1,
10433 recovery_symbols: BTreeSet::new(),
10434 recovery_state: None,
10435 },
10436 visiting,
10437 memo,
10438 expected,
10439 )
10440 .into_iter()
10441 .map(|mut outcome| {
10442 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
10443 outcome.diagnostics = self
10444 .recognition_arena
10445 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10446 let token = self.arena_token_node(next_index, false);
10447 self.arena_prepend(&mut outcome.nodes, token);
10448 let error = self.arena_token_node(index, true);
10449 self.arena_prepend(&mut outcome.nodes, error);
10450 outcome
10451 })
10452 .collect()
10453 }
10454
10455 fn current_token_deletion_recovery(
10458 &mut self,
10459 recovery: CurrentTokenDeletionRequest<'_, '_>,
10460 ) -> Vec<RecognizeOutcome> {
10461 let CurrentTokenDeletionRequest {
10462 atn,
10463 expected_symbols,
10464 mut request,
10465 visiting,
10466 memo,
10467 expected,
10468 } = recovery;
10469 let error_index = request.index;
10470 if error_index == request.rule_start_index {
10471 return Vec::new();
10472 }
10473 let Some((diagnostic, next_index, skipped)) =
10474 self.current_token_deletion(error_index, &expected_symbols)
10475 else {
10476 return Vec::new();
10477 };
10478 request.state_number = request.recovery_state.unwrap_or(request.state_number);
10479 request.index = next_index;
10480 request.committed_decision = false;
10481 request.depth += 1;
10482 request.recovery_state = None;
10483 self.recognize_state(atn, request, visiting, memo, expected)
10484 .into_iter()
10485 .map(|mut outcome| {
10486 outcome.diagnostics = self
10487 .recognition_arena
10488 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10489 for index in skipped.iter().rev() {
10490 let error = self.arena_token_node(*index, true);
10491 self.arena_prepend(&mut outcome.nodes, error);
10492 }
10493 outcome
10494 })
10495 .collect()
10496 }
10497
10498 fn consuming_failure_fallback(
10501 &mut self,
10502 fallback: ConsumingFailureFallback<'_>,
10503 visiting: &mut BTreeSet<RecognizeKey>,
10504 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10505 expected: &mut ExpectedTokens,
10506 ) -> Vec<RecognizeOutcome> {
10507 if fallback.expected_symbols.is_empty() {
10508 return Vec::new();
10509 }
10510 if fallback.symbol == TOKEN_EOF {
10511 return self.eof_consuming_failure_fallback(fallback, expected);
10512 }
10513 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
10514 }
10515
10516 fn non_eof_consuming_failure_fallback(
10519 &mut self,
10520 fallback: ConsumingFailureFallback<'_>,
10521 visiting: &mut BTreeSet<RecognizeKey>,
10522 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10523 expected: &mut ExpectedTokens,
10524 ) -> Vec<RecognizeOutcome> {
10525 let ConsumingFailureFallback {
10526 atn,
10527 target,
10528 request,
10529 symbol,
10530 expected_symbols,
10531 decision_start_index,
10532 decision,
10533 } = fallback;
10534 let error_index = request.index;
10535 let diagnostic =
10536 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
10537 let next_index = self.consume_index(error_index, symbol);
10538 self.recognize_state(
10539 atn,
10540 RecognizeRequest {
10541 state_number: target,
10542 stop_state: request.stop_state,
10543 index: next_index,
10544 rule_start_index: request.rule_start_index,
10545 decision_start_index,
10546 init_action_rules: request.init_action_rules,
10547 predicates: request.predicates,
10548 semantics: request.semantics,
10549 rule_args: request.rule_args,
10550 member_actions: request.member_actions,
10551 return_actions: request.return_actions,
10552 local_int_arg: request.local_int_arg,
10553 member_values: request.member_values,
10554 return_values: request.return_values,
10555 rule_alt_number: request.rule_alt_number,
10556 track_alt_numbers: request.track_alt_numbers,
10557 consumed_eof: request.consumed_eof,
10558 committed_decision: false,
10559 precedence: request.precedence,
10560 depth: request.depth + 1,
10561 recovery_symbols: BTreeSet::new(),
10562 recovery_state: None,
10563 },
10564 visiting,
10565 memo,
10566 expected,
10567 )
10568 .into_iter()
10569 .map(|mut outcome| {
10570 prepend_decision(&mut outcome, decision);
10571 outcome.diagnostics = self
10572 .recognition_arena
10573 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10574 let error = self.arena_token_node(error_index, true);
10575 self.arena_prepend(&mut outcome.nodes, error);
10576 outcome
10577 })
10578 .collect()
10579 }
10580
10581 fn eof_consuming_failure_fallback(
10584 &mut self,
10585 fallback: ConsumingFailureFallback<'_>,
10586 expected: &ExpectedTokens,
10587 ) -> Vec<RecognizeOutcome> {
10588 let request = fallback.request;
10589 if request.index == request.rule_start_index {
10590 return Vec::new();
10591 }
10592 let diagnostic =
10593 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
10594 let diagnostics = self
10595 .recognition_arena
10596 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10597 vec![RecognizeOutcome {
10598 index: request.index,
10599 consumed_eof: request.consumed_eof,
10600 alt_number: request.rule_alt_number,
10601 member_values: request.member_values,
10602 return_values: request.return_values,
10603 diagnostics,
10604 decisions: Vec::new(),
10605 actions: Vec::new(),
10606 nodes: NodeSeqId::EMPTY,
10607 }]
10608 }
10609
10610 fn single_token_insertion_recovery(
10613 &mut self,
10614 recovery: RecoveryRequest<'_, '_>,
10615 ) -> Vec<RecognizeOutcome> {
10616 let RecoveryRequest {
10617 atn,
10618 transition,
10619 expected_symbols,
10620 target,
10621 request,
10622 visiting,
10623 memo,
10624 expected,
10625 } = recovery;
10626 let RecognizeRequest {
10627 stop_state,
10628 index,
10629 rule_start_index,
10630 decision_start_index,
10631 init_action_rules,
10632 predicates,
10633 semantics,
10634 rule_args,
10635 member_actions,
10636 return_actions,
10637 local_int_arg,
10638 member_values,
10639 return_values,
10640 rule_alt_number,
10641 track_alt_numbers,
10642 consumed_eof,
10643 precedence,
10644 depth,
10645 ..
10646 } = request;
10647 let follow_symbols = state_expected_symbols(atn, transition.target());
10648 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
10649 transition,
10650 index,
10651 atn.max_token_type(),
10652 &expected_symbols,
10653 &follow_symbols,
10654 ) else {
10655 return Vec::new();
10656 };
10657 self.recognize_state(
10658 atn,
10659 RecognizeRequest {
10660 state_number: target,
10661 stop_state,
10662 index,
10663 rule_start_index,
10664 decision_start_index,
10665 init_action_rules,
10666 predicates,
10667 semantics,
10668 rule_args,
10669 member_actions,
10670 return_actions,
10671 local_int_arg,
10672 member_values,
10673 return_values,
10674 rule_alt_number,
10675 track_alt_numbers,
10676 consumed_eof,
10677 committed_decision: false,
10678 precedence,
10679 depth: depth + 1,
10680 recovery_symbols: BTreeSet::new(),
10681 recovery_state: None,
10682 },
10683 visiting,
10684 memo,
10685 expected,
10686 )
10687 .into_iter()
10688 .map(|mut outcome| {
10689 outcome.diagnostics = self
10690 .recognition_arena
10691 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10692 let missing = self.arena_missing_token_node(token_type, index, text.clone());
10693 self.arena_prepend(&mut outcome.nodes, missing);
10694 outcome
10695 })
10696 .collect()
10697 }
10698
10699 #[allow(clippy::too_many_lines)]
10702 fn recognize_state(
10703 &mut self,
10704 atn: &Atn,
10705 request: RecognizeRequest<'_>,
10706 visiting: &mut BTreeSet<RecognizeKey>,
10707 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10708 expected: &mut ExpectedTokens,
10709 ) -> Vec<RecognizeOutcome> {
10710 let request_template = request.clone();
10711 let RecognizeRequest {
10712 state_number,
10713 stop_state,
10714 index,
10715 rule_start_index,
10716 decision_start_index,
10717 init_action_rules,
10718 predicates,
10719 semantics,
10720 rule_args,
10721 member_actions,
10722 return_actions,
10723 local_int_arg,
10724 member_values,
10725 return_values,
10726 rule_alt_number,
10727 track_alt_numbers,
10728 consumed_eof,
10729 committed_decision,
10730 precedence,
10731 depth,
10732 recovery_symbols,
10733 recovery_state,
10734 } = request;
10735 if depth > RECOGNITION_DEPTH_LIMIT {
10736 return Vec::new();
10737 }
10738 if state_number == stop_state {
10739 return stop_outcome(
10740 index,
10741 consumed_eof,
10742 rule_alt_number,
10743 member_values,
10744 return_values,
10745 );
10746 }
10747 let key = RecognizeKey {
10748 state_number,
10749 stop_state,
10750 index,
10751 rule_start_index,
10752 decision_start_index,
10753 local_int_arg,
10754 member_values: member_values.clone(),
10755 return_values: return_values.clone(),
10756 rule_alt_number,
10757 track_alt_numbers,
10758 consumed_eof,
10759 committed_decision,
10760 precedence,
10761 recovery_symbols: recovery_symbols.clone(),
10762 recovery_state,
10763 };
10764 if let Some(outcomes) = memo.get(&key) {
10765 return outcomes.clone();
10766 }
10767
10768 let visit_key = key.clone();
10769 if !visiting.insert(visit_key.clone()) {
10770 return Vec::new();
10771 }
10772
10773 let Some(state) = atn.state(state_number) else {
10774 visiting.remove(&visit_key);
10775 return Vec::new();
10776 };
10777 let decision_override_generation = self.decision_override_generation;
10778 let transitions = state.transitions();
10779 let transition_count = transitions.len();
10780 let overridden_transition = if transition_count > 1
10781 && self.semantic_hooks.observes_parser_decisions()
10782 {
10783 atn.decision_to_state()
10784 .iter()
10785 .position(|candidate| candidate == state_number)
10786 .and_then(|decision| {
10787 self.semantic_hooks
10788 .parser_decision_override(decision, index, transition_count)
10789 })
10790 .and_then(|alternative| alternative.checked_sub(1))
10791 .filter(|alternative| *alternative < transition_count)
10792 } else {
10793 None
10794 };
10795 if overridden_transition.is_some() {
10796 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
10797 }
10798 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
10799 Some(index)
10800 } else {
10801 decision_start_index
10802 };
10803 let (epsilon_recovery_symbols, epsilon_recovery_state) =
10804 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
10805 let mut outcomes = Vec::new();
10806 for (transition_index, transition) in transitions.iter().enumerate() {
10807 if overridden_transition.is_some_and(|forced| forced != transition_index) {
10808 continue;
10809 }
10810 let transition_committed =
10811 committed_decision || overridden_transition == Some(transition_index);
10812 let mut transition_request = request_template.clone();
10813 transition_request.committed_decision = transition_committed;
10814 let decision =
10815 transition_decision(atn, state, transition_count, transition_index, predicates);
10816 let next_alt_number = next_alt_number(
10817 state,
10818 transition_count,
10819 transition_index,
10820 rule_alt_number,
10821 track_alt_numbers,
10822 );
10823 let transition_data = transition.data();
10824 match &transition_data {
10825 Transition::Epsilon { target } | Transition::Action { target, .. } => {
10826 let (action_rule_index, action_index) = match &transition_data {
10827 Transition::Action {
10828 rule_index,
10829 action_index,
10830 ..
10831 } => (Some(*rule_index), *action_index),
10832 _ => (None, None),
10833 };
10834 outcomes.extend(self.recognize_epsilon_or_action_step(
10835 atn,
10836 &transition_request,
10837 EpsilonActionStep {
10838 source_state: state_number,
10839 target: *target,
10840 action_rule_index,
10841 action_index,
10842 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
10843 decision,
10844 decision_start_index: next_decision_start_index,
10845 alt_number: next_alt_number,
10846 recovery_symbols: epsilon_recovery_symbols.clone(),
10847 recovery_state: epsilon_recovery_state,
10848 },
10849 RecognizeScratch {
10850 visiting,
10851 memo,
10852 expected,
10853 },
10854 ));
10855 }
10856 Transition::Predicate {
10857 target,
10858 rule_index,
10859 pred_index,
10860 ..
10861 } => {
10862 let predicate = PredicateEval {
10863 index,
10864 rule_index: *rule_index,
10865 pred_index: *pred_index,
10866 predicates,
10867 semantics,
10868 context: None,
10869 local_int_arg,
10870 member_values: &member_values,
10871 };
10872 if self.parser_predicate_matches(predicate) {
10873 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
10874 outcomes.extend(
10875 self.recognize_state(
10876 atn,
10877 RecognizeRequest {
10878 state_number: *target,
10879 stop_state,
10880 index,
10881 rule_start_index,
10882 decision_start_index: next_decision_start_index,
10883 init_action_rules,
10884 predicates,
10885 semantics,
10886 rule_args,
10887 member_actions,
10888 return_actions,
10889 local_int_arg,
10890 member_values: member_values.clone(),
10891 return_values: return_values.clone(),
10892 rule_alt_number: next_alt_number,
10893 track_alt_numbers,
10894 consumed_eof,
10895 committed_decision: transition_committed,
10896 precedence,
10897 depth: depth + 1,
10898 recovery_symbols: epsilon_recovery_symbols.clone(),
10899 recovery_state: epsilon_recovery_state,
10900 },
10901 visiting,
10902 memo,
10903 expected,
10904 )
10905 .into_iter()
10906 .map(|mut outcome| {
10907 prepend_decision(&mut outcome, decision);
10908 if let Some(rule_index) = left_recursive_boundary {
10909 let boundary =
10910 self.arena_boundary_node(rule_index, next_alt_number);
10911 self.arena_prepend(&mut outcome.nodes, boundary);
10912 }
10913 outcome
10914 }),
10915 );
10916 } else if let Some(message) = semantics
10917 .and_then(|semantics| {
10918 self.parser_semantic_ir_predicate_failure_message(
10919 *rule_index,
10920 *pred_index,
10921 semantics,
10922 )
10923 })
10924 .or_else(|| {
10925 self.parser_predicate_failure_message(
10926 *rule_index,
10927 *pred_index,
10928 predicates,
10929 )
10930 })
10931 {
10932 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
10933 rule_index: *rule_index,
10934 index,
10935 message,
10936 member_values: member_values.clone(),
10937 return_values: return_values.clone(),
10938 rule_alt_number,
10939 }));
10940 } else {
10941 record_predicate_no_viable(expected, next_decision_start_index, index);
10942 }
10943 }
10944 Transition::Precedence {
10945 target,
10946 precedence: transition_precedence,
10947 } => {
10948 if *transition_precedence >= precedence {
10949 outcomes.extend(
10950 self.recognize_state(
10951 atn,
10952 RecognizeRequest {
10953 state_number: *target,
10954 stop_state,
10955 index,
10956 rule_start_index,
10957 decision_start_index: next_decision_start_index,
10958 init_action_rules,
10959 predicates,
10960 semantics,
10961 rule_args,
10962 member_actions,
10963 return_actions,
10964 local_int_arg,
10965 member_values: member_values.clone(),
10966 return_values: return_values.clone(),
10967 rule_alt_number: next_alt_number,
10968 track_alt_numbers,
10969 consumed_eof,
10970 committed_decision: transition_committed,
10971 precedence,
10972 depth: depth + 1,
10973 recovery_symbols: epsilon_recovery_symbols.clone(),
10974 recovery_state: epsilon_recovery_state,
10975 },
10976 visiting,
10977 memo,
10978 expected,
10979 )
10980 .into_iter()
10981 .map(|mut outcome| {
10982 prepend_decision(&mut outcome, decision);
10983 outcome
10984 }),
10985 );
10986 }
10987 }
10988 Transition::Rule {
10989 target,
10990 rule_index,
10991 follow_state,
10992 precedence: rule_precedence,
10993 ..
10994 } => {
10995 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
10996 continue;
10997 };
10998 let child_local_int_arg =
10999 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
11000 let expected_before_child = expected.clone();
11001 let children = self.recognize_state(
11002 atn,
11003 RecognizeRequest {
11004 state_number: *target,
11005 stop_state: child_stop,
11006 index,
11007 rule_start_index: index,
11008 decision_start_index: None,
11009 init_action_rules,
11010 predicates,
11011 semantics,
11012 rule_args,
11013 member_actions,
11014 return_actions,
11015 local_int_arg: child_local_int_arg,
11016 member_values: member_values.clone(),
11017 return_values: BTreeMap::new(),
11018 rule_alt_number: 0,
11019 track_alt_numbers,
11020 consumed_eof: false,
11021 committed_decision: transition_committed,
11022 precedence: *rule_precedence,
11023 depth: depth + 1,
11024 recovery_symbols: epsilon_recovery_symbols.clone(),
11025 recovery_state: epsilon_recovery_state,
11026 },
11027 visiting,
11028 memo,
11029 expected,
11030 );
11031 let children = if children.is_empty() {
11032 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
11033 atn,
11034 rule_index: *rule_index,
11035 start_index: index,
11036 follow_state: *follow_state,
11037 stop_state,
11038 member_values: member_values.clone(),
11039 expected,
11040 })
11041 } else {
11042 children
11043 };
11044 let preserve_child_expected =
11045 self.child_expected_reaches_clean_eof(&children, expected);
11046 restore_expected(
11047 &children,
11048 index,
11049 expected,
11050 expected_before_child,
11051 preserve_child_expected,
11052 );
11053 for child in children {
11054 let child_stop_index =
11055 self.rule_stop_token_index(child.index, child.consumed_eof);
11056 let child_nodes = self
11057 .recognition_arena
11058 .fold_left_recursive_boundaries(child.nodes);
11059 let child_node = self.arena_rule_node(ArenaRuleSpec {
11060 rule_index: *rule_index,
11061 invoking_state: invoking_state_number(state_number),
11062 alt_number: child.alt_number,
11063 start_index: index,
11064 stop_index: child_stop_index,
11065 return_values: child.return_values.clone(),
11066 children: child_nodes,
11067 });
11068 outcomes.extend(
11069 self.recognize_state(
11070 atn,
11071 RecognizeRequest {
11072 state_number: *follow_state,
11073 stop_state,
11074 index: child.index,
11075 rule_start_index,
11076 decision_start_index: next_decision_start_index,
11077 init_action_rules,
11078 predicates,
11079 semantics,
11080 rule_args,
11081 member_actions,
11082 return_actions,
11083 local_int_arg,
11084 member_values: child.member_values.clone(),
11085 return_values: return_values.clone(),
11086 rule_alt_number,
11087 track_alt_numbers,
11088 consumed_eof: consumed_eof || child.consumed_eof,
11089 committed_decision: transition_committed
11090 && child.index == index,
11091 precedence,
11092 depth: depth + 1,
11093 recovery_symbols: BTreeSet::new(),
11094 recovery_state: None,
11095 },
11096 visiting,
11097 memo,
11098 expected,
11099 )
11100 .into_iter()
11101 .map(|mut outcome| {
11102 outcome.consumed_eof |= child.consumed_eof;
11103 outcome.diagnostics = self
11104 .recognition_arena
11105 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
11106 let mut decisions = child.decisions.clone();
11107 decisions.append(&mut outcome.decisions);
11108 outcome.decisions = decisions;
11109 prepend_decision(&mut outcome, decision);
11110 let mut actions = child.actions.clone();
11111 if init_action_rules.contains(rule_index) {
11112 actions.insert(
11113 0,
11114 ParserAction::new_rule_init(
11115 *rule_index,
11116 index,
11117 Some(*follow_state),
11118 ),
11119 );
11120 }
11121 actions.append(&mut outcome.actions);
11122 outcome.actions = actions;
11123 self.arena_prepend(&mut outcome.nodes, child_node);
11124 outcome
11125 }),
11126 );
11127 }
11128 }
11129 Transition::Atom { target, .. }
11130 | Transition::Range { target, .. }
11131 | Transition::Set { target, .. }
11132 | Transition::NotSet { target, .. }
11133 | Transition::Wildcard { target, .. } => {
11134 let symbol = self.token_type_at(index);
11135 if transition_data.matches(symbol, 1, atn.max_token_type()) {
11136 let next_index = self.consume_index(index, symbol);
11137 outcomes.extend(
11138 self.recognize_state(
11139 atn,
11140 RecognizeRequest {
11141 state_number: *target,
11142 stop_state,
11143 index: next_index,
11144 rule_start_index,
11145 decision_start_index: next_decision_start_index,
11146 init_action_rules,
11147 predicates,
11148 semantics,
11149 rule_args,
11150 member_actions,
11151 return_actions,
11152 local_int_arg,
11153 member_values: member_values.clone(),
11154 return_values: return_values.clone(),
11155 rule_alt_number: next_alt_number,
11156 track_alt_numbers,
11157 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
11158 committed_decision: false,
11159 precedence,
11160 depth: depth + 1,
11161 recovery_symbols: BTreeSet::new(),
11162 recovery_state: None,
11163 },
11164 visiting,
11165 memo,
11166 expected,
11167 )
11168 .into_iter()
11169 .map(|mut outcome| {
11170 prepend_decision(&mut outcome, decision);
11171 outcome.consumed_eof |= symbol == TOKEN_EOF;
11172 let token = self.arena_token_node(index, false);
11173 self.arena_prepend(&mut outcome.nodes, token);
11174 outcome
11175 }),
11176 );
11177 } else {
11178 let expected_symbols =
11179 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
11180 if expected_symbols.contains(&symbol) && !transition_committed {
11181 continue;
11182 }
11183 expected.record_transition(index, transition, atn.max_token_type());
11184 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
11185 let before_recovery = outcomes.len();
11186 let recovery_request = transition_request.clone();
11187 if transition_committed {
11188 outcomes.extend(self.consuming_failure_fallback(
11189 ConsumingFailureFallback {
11190 atn,
11191 target: *target,
11192 request: recovery_request,
11193 symbol,
11194 expected_symbols,
11195 decision_start_index: next_decision_start_index,
11196 decision,
11197 },
11198 visiting,
11199 memo,
11200 expected,
11201 ));
11202 break;
11203 }
11204 outcomes.extend(
11205 self.single_token_deletion_recovery(RecoveryRequest {
11206 atn,
11207 transition,
11208 expected_symbols: expected_symbols.clone(),
11209 target: *target,
11210 request: recovery_request.clone(),
11211 visiting,
11212 memo,
11213 expected,
11214 })
11215 .into_iter()
11216 .map(|mut outcome| {
11217 prepend_decision(&mut outcome, decision);
11218 outcome
11219 }),
11220 );
11221 if !state_is_left_recursive_rule(atn, state) {
11222 outcomes.extend(
11223 self.single_token_insertion_recovery(RecoveryRequest {
11224 atn,
11225 transition,
11226 expected_symbols: expected_symbols.clone(),
11227 target: *target,
11228 request: recovery_request.clone(),
11229 visiting,
11230 memo,
11231 expected,
11232 })
11233 .into_iter()
11234 .map(|mut outcome| {
11235 prepend_decision(&mut outcome, decision);
11236 outcome
11237 }),
11238 );
11239 }
11240 outcomes.extend(self.current_token_deletion_recovery(
11241 CurrentTokenDeletionRequest {
11242 atn,
11243 expected_symbols: expected_symbols.clone(),
11244 request: recovery_request.clone(),
11245 visiting,
11246 memo,
11247 expected,
11248 },
11249 ));
11250 if outcomes.len() == before_recovery {
11251 outcomes.extend(self.consuming_failure_fallback(
11252 ConsumingFailureFallback {
11253 atn,
11254 target: *target,
11255 request: recovery_request,
11256 symbol,
11257 expected_symbols,
11258 decision_start_index: next_decision_start_index,
11259 decision,
11260 },
11261 visiting,
11262 memo,
11263 expected,
11264 ));
11265 }
11266 }
11267 }
11268 }
11269 if self.decision_override_generation != decision_override_generation {
11270 break;
11271 }
11272 }
11273
11274 visiting.remove(&visit_key);
11275 self.record_prediction_diagnostics(atn, state, index, &outcomes);
11276 if matches!(
11277 self.prediction_mode,
11278 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11279 ) {
11280 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
11281 }
11282 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
11283 memo.insert(key, outcomes.clone());
11284 outcomes
11285 }
11286
11287 fn recognize_epsilon_or_action_step(
11290 &mut self,
11291 atn: &Atn,
11292 request: &RecognizeRequest<'_>,
11293 step: EpsilonActionStep,
11294 scratch: RecognizeScratch<'_>,
11295 ) -> Vec<RecognizeOutcome> {
11296 let RecognizeScratch {
11297 visiting,
11298 memo,
11299 expected,
11300 } = scratch;
11301 let action = step.action_rule_index.map(|rule_index| {
11302 let stop_index = self.rule_stop_token_index(request.index, request.consumed_eof);
11303 step.action_index.map_or_else(
11304 || {
11305 ParserAction::new(
11306 step.source_state,
11307 rule_index,
11308 request.rule_start_index,
11309 stop_index,
11310 )
11311 },
11312 |action_index| {
11313 ParserAction::new_indexed(
11314 step.source_state,
11315 rule_index,
11316 action_index,
11317 request.rule_start_index,
11318 stop_index,
11319 )
11320 },
11321 )
11322 });
11323 let next_member_values = if action.is_some() {
11324 member_values_after_action(
11325 step.source_state,
11326 request.member_actions,
11327 request.semantics,
11328 &request.member_values,
11329 )
11330 } else {
11331 request.member_values.clone()
11332 };
11333 let next_return_values = action.map_or_else(
11334 || request.return_values.clone(),
11335 |action| {
11336 return_values_after_action(
11337 step.source_state,
11338 action.rule_index(),
11339 request.return_actions,
11340 request.semantics,
11341 &request.return_values,
11342 )
11343 },
11344 );
11345
11346 self.recognize_state(
11347 atn,
11348 RecognizeRequest {
11349 state_number: step.target,
11350 stop_state: request.stop_state,
11351 index: request.index,
11352 rule_start_index: request.rule_start_index,
11353 decision_start_index: step.decision_start_index,
11354 init_action_rules: request.init_action_rules,
11355 predicates: request.predicates,
11356 semantics: request.semantics,
11357 rule_args: request.rule_args,
11358 member_actions: request.member_actions,
11359 return_actions: request.return_actions,
11360 local_int_arg: request.local_int_arg,
11361 member_values: next_member_values,
11362 return_values: next_return_values,
11363 rule_alt_number: if step.left_recursive_boundary.is_some() {
11364 0
11365 } else {
11366 step.alt_number
11367 },
11368 track_alt_numbers: request.track_alt_numbers,
11369 consumed_eof: request.consumed_eof,
11370 committed_decision: request.committed_decision,
11371 precedence: request.precedence,
11372 depth: request.depth + 1,
11373 recovery_symbols: step.recovery_symbols,
11374 recovery_state: step.recovery_state,
11375 },
11376 visiting,
11377 memo,
11378 expected,
11379 )
11380 .into_iter()
11381 .map(|mut outcome| {
11382 prepend_decision(&mut outcome, step.decision);
11383 if let Some(rule_index) = step.left_recursive_boundary {
11384 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
11385 self.arena_prepend(&mut outcome.nodes, boundary);
11386 }
11387 if let Some(action) = action {
11388 outcome.actions.insert(0, action);
11389 }
11390 outcome
11391 })
11392 .collect()
11393 }
11394
11395 fn token_type_at(&mut self, index: usize) -> i32 {
11400 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
11401 self.input.fill();
11402 }
11403 self.input.token_type_at_index(index)
11404 }
11405
11406 fn cached_state_expected_symbols(
11418 &mut self,
11419 atn: &Atn,
11420 state_number: usize,
11421 ) -> Rc<BTreeSet<i32>> {
11422 if let Some(cached) = self.state_expected_cache.get(&state_number) {
11423 return Rc::clone(cached);
11424 }
11425 let symbols = state_expected_symbols(atn, state_number);
11426 let entry = self.intern_recovery_symbols(symbols);
11427 self.state_expected_cache
11428 .insert(state_number, Rc::clone(&entry));
11429 entry
11430 }
11431
11432 fn cached_state_expected_token_set(
11433 &mut self,
11434 atn: &Atn,
11435 state_number: usize,
11436 ) -> Rc<TokenBitSet> {
11437 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
11438 return Rc::clone(cached);
11439 }
11440 let symbols = with_shared_atn_caches(atn, |cache| {
11444 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
11445 return Rc::clone(cached);
11446 }
11447 let symbols = Rc::new(state_expected_token_set(atn, state_number));
11448 cache
11449 .state_expected_tokens
11450 .insert(state_number, Rc::clone(&symbols));
11451 symbols
11452 });
11453 self.state_expected_token_cache
11454 .insert(state_number, Rc::clone(&symbols));
11455 symbols
11456 }
11457
11458 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
11459 if self.rule_stop_reach_cache.len() <= state_number {
11460 self.rule_stop_reach_cache
11461 .resize_with(atn.states().len().max(state_number + 1), || None);
11462 }
11463 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
11464 return reaches;
11465 }
11466 let reaches = with_shared_atn_caches(atn, |cache| {
11467 *cache
11468 .rule_stop_reach
11469 .entry(state_number)
11470 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
11471 });
11472 self.rule_stop_reach_cache[state_number] = Some(reaches);
11473 reaches
11474 }
11475
11476 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
11479 Rc::clone(&self.empty_recovery_symbols)
11480 }
11481
11482 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
11491 if set.is_empty() {
11492 return Rc::clone(&self.empty_recovery_symbols);
11493 }
11494 let candidate = Rc::new(set);
11495 match self.recovery_symbols_intern.get(&candidate) {
11496 Some(existing) => Rc::clone(existing),
11497 None => {
11498 self.recovery_symbols_intern
11499 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
11500 candidate
11501 }
11502 }
11503 }
11504
11505 fn cached_decision_lookahead(
11510 &mut self,
11511 atn: &Atn,
11512 state: AtnState<'_>,
11513 rule_stop_state: usize,
11514 ) -> Rc<DecisionLookahead> {
11515 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
11522 return Rc::clone(cached);
11523 }
11524 let entry = with_shared_atn_caches(atn, |cache| {
11525 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
11526 return Rc::clone(cached);
11527 }
11528 let mut entry = DecisionLookahead {
11529 transitions: Vec::with_capacity(state.transitions().len()),
11530 };
11531 for transition in &state.transitions() {
11532 entry.transitions.push(transition_first_set(
11533 atn,
11534 transition,
11535 rule_stop_state,
11536 &mut cache.first_set,
11537 ));
11538 }
11539 let entry = Rc::new(entry);
11540 cache
11541 .decision_lookahead
11542 .insert(state.state_number(), Rc::clone(&entry));
11543 entry
11544 });
11545 self.decision_lookahead_cache
11546 .insert(state.state_number(), Rc::clone(&entry));
11547 entry
11548 }
11549
11550 fn cached_rule_first_set(
11551 &mut self,
11552 atn: &Atn,
11553 target: usize,
11554 child_stop: usize,
11555 ) -> Rc<FirstSet> {
11556 if self.rule_first_set_cache.len() <= target {
11557 self.rule_first_set_cache
11558 .resize_with(atn.states().len().max(target + 1), || None);
11559 }
11560 if let Some(cached) = self
11561 .rule_first_set_cache
11562 .get(target)
11563 .and_then(Option::as_ref)
11564 {
11565 return Rc::clone(cached);
11566 }
11567 let first = with_shared_first_set_cache(atn, |cache| {
11568 rule_first_set(atn, target, child_stop, cache)
11569 });
11570 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
11571 first
11572 }
11573
11574 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
11575 let atn_key = SharedAtnCacheKey::for_atn(atn);
11576 if self.empty_cycle_cache_atn != Some(atn_key) {
11577 self.empty_cycle_cache.clear();
11578 self.empty_cycle_cache_atn = Some(atn_key);
11579 }
11580 if self.empty_cycle_cache.len() <= state_number {
11581 self.empty_cycle_cache
11582 .resize_with(atn.state_count().max(state_number + 1), || None);
11583 }
11584 if let Some(cached) = self.empty_cycle_cache[state_number] {
11585 return cached;
11586 }
11587 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
11588 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
11589 self.empty_cycle_cache[state_number] = Some(result);
11590 result
11591 }
11592
11593 fn empty_path_reaches_state(
11594 &mut self,
11595 atn: &Atn,
11596 state_number: usize,
11597 target_state: usize,
11598 visited: &mut FxHashSet<usize>,
11599 ) -> bool {
11600 enum Work {
11601 Visit(usize),
11602 RuleFollow {
11603 target: usize,
11604 rule_index: usize,
11605 follow_state: usize,
11606 },
11607 }
11608
11609 let mut work = vec![Work::Visit(state_number)];
11610 while let Some(item) = work.pop() {
11611 match item {
11612 Work::Visit(state_number) => {
11613 if !visited.insert(state_number) {
11614 continue;
11615 }
11616 let Some(state) = atn.state(state_number) else {
11617 continue;
11618 };
11619 let transitions = state.transitions();
11620 for transition_index in (0..transitions.len()).rev() {
11621 let transition = transitions
11622 .get(transition_index)
11623 .expect("in-bounds parser transition");
11624 let kind = transition.kind();
11625 let target = transition.target();
11626 match kind {
11627 ParserTransitionKind::Atom
11628 | ParserTransitionKind::Range
11629 | ParserTransitionKind::Set
11630 | ParserTransitionKind::NotSet
11631 | ParserTransitionKind::Wildcard => {}
11632 ParserTransitionKind::Rule => {
11633 if target == target_state {
11634 return true;
11635 }
11636 work.push(Work::RuleFollow {
11637 target,
11638 rule_index: transition.arg0() as usize,
11639 follow_state: transition.arg1() as usize,
11640 });
11641 work.push(Work::Visit(target));
11642 }
11643 ParserTransitionKind::Epsilon
11644 | ParserTransitionKind::Predicate
11645 | ParserTransitionKind::Action
11646 | ParserTransitionKind::Precedence => {
11647 if target == target_state {
11648 return true;
11649 }
11650 work.push(Work::Visit(target));
11651 }
11652 }
11653 }
11654 }
11655 Work::RuleFollow {
11656 target,
11657 rule_index,
11658 follow_state,
11659 } => {
11660 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
11661 continue;
11662 };
11663 if self.cached_rule_first_set(atn, target, child_stop).nullable {
11664 if follow_state == target_state {
11665 return true;
11666 }
11667 work.push(Work::Visit(follow_state));
11668 }
11669 }
11670 }
11671 }
11672 false
11673 }
11674
11675 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
11678 match self.clean_memo_mode {
11679 CleanMemoMode::Promote => true,
11680 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
11681 CleanMemoMode::Sparse => {
11682 self.clean_memo_sparse_samples += 1;
11683 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
11684 return false;
11685 }
11686 self.clean_memo_sparse_samples = 0;
11687 self.clean_memo_mode = CleanMemoMode::Probe;
11688 self.clean_memo_probe_samples = 0;
11689 self.clean_memo_probe_repeats = 0;
11690 self.clean_memo_probe_seen.clear();
11691 self.observe_clean_memo_probe(key)
11692 }
11693 }
11694 }
11695
11696 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
11697 self.clean_memo_probe_samples += 1;
11698 if !self.clean_memo_probe_seen.insert(key.clone()) {
11699 self.clean_memo_probe_repeats += 1;
11700 }
11701 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
11702 self.clean_memo_mode = CleanMemoMode::Promote;
11703 self.clean_memo_probe_seen.clear();
11704 return true;
11705 }
11706 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
11707 self.clean_memo_mode = CleanMemoMode::Sparse;
11708 self.clean_memo_sparse_samples = 0;
11709 self.clean_memo_probe_seen.clear();
11710 return false;
11711 }
11712 true
11713 }
11714
11715 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
11717 self.input.get(index)
11718 }
11719
11720 fn token_id_at(&self, index: usize) -> Option<TokenId> {
11722 self.input.get_id(index)
11723 }
11724
11725 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
11726 let token = self
11727 .token_id_at(index)
11728 .expect("recognized token index must exist in the token store");
11729 let node = if error {
11730 ArenaRecognizedNode::ErrorToken { token }
11731 } else {
11732 ArenaRecognizedNode::Token { token }
11733 };
11734 self.recognition_arena.push_node(node)
11735 }
11736
11737 fn arena_missing_token_node(
11738 &mut self,
11739 token_type: i32,
11740 at_index: usize,
11741 text: String,
11742 ) -> RecognizedNodeId {
11743 let extra = self
11744 .recognition_arena
11745 .push_extra(RecognitionExtra::MissingToken {
11746 token_type,
11747 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
11748 text,
11749 });
11750 self.recognition_arena
11751 .push_node(ArenaRecognizedNode::MissingToken { extra })
11752 }
11753
11754 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
11755 let ArenaRuleSpec {
11756 rule_index,
11757 invoking_state,
11758 alt_number,
11759 start_index,
11760 stop_index,
11761 return_values,
11762 children,
11763 } = spec;
11764 let return_values = (!return_values.is_empty()).then(|| {
11765 self.recognition_arena
11766 .push_extra(RecognitionExtra::ReturnValues(return_values))
11767 });
11768 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
11769 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11770 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
11771 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11772 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
11773 stop_index: stop_index
11774 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
11775 return_values,
11776 children,
11777 })
11778 }
11779
11780 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
11781 self.recognition_arena
11782 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
11783 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11784 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11785 })
11786 }
11787
11788 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
11789 *sequence = self.recognition_arena.prepend(*sequence, node);
11790 }
11791
11792 #[allow(clippy::missing_const_for_fn)]
11795 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
11796 self.last_recognition_arena_root = root;
11797 self.last_recognition_arena_diagnostics = diagnostics;
11798 #[cfg(feature = "perf-counters")]
11799 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
11800 let stats = self.recognition_arena_stats();
11801 #[allow(clippy::print_stderr)]
11802 {
11803 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
11804 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
11805 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
11806 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
11807 eprintln!("perf recognition_links_total={}", stats.total_links);
11808 eprintln!("perf recognition_links_live={}", stats.live_links);
11809 eprintln!("perf recognition_links_dead={}", stats.dead_links);
11810 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
11811 eprintln!("perf recognition_extras_total={}", stats.total_extras);
11812 eprintln!("perf recognition_extras_live={}", stats.live_extras);
11813 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
11814 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
11815 }
11816 }
11817 }
11818
11819 fn reset_recognition_arena(&mut self) {
11820 self.recognition_arena.reset();
11821 self.last_recognition_arena_root = NodeSeqId::EMPTY;
11822 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
11823 }
11824
11825 fn current_visible_index(&mut self) -> usize {
11828 let index = self.input.index();
11829 self.input.seek(index);
11830 self.input.index()
11831 }
11832
11833 fn child_expected_reaches_clean_eof(
11836 &mut self,
11837 children: &[RecognizeOutcome],
11838 expected: &ExpectedTokens,
11839 ) -> bool {
11840 let Some(index) = expected.index else {
11841 return false;
11842 };
11843 self.token_type_at(index) == TOKEN_EOF
11844 && children
11845 .iter()
11846 .any(|child| child.diagnostics.is_empty() && child.index == index)
11847 }
11848
11849 fn previous_token_index(&self, index: usize) -> Option<usize> {
11856 self.input.previous_visible_token_index(index)
11857 }
11858
11859 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
11864 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
11865 Some(index)
11866 } else {
11867 self.previous_token_index(index)
11868 }
11869 }
11870
11871 #[must_use]
11888 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
11889 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
11890 self.rule_stop_token_index(current_index, consumed_eof)
11891 }
11892
11893 #[must_use]
11902 pub fn after_action_stop_index_for_tree(
11903 &mut self,
11904 tree: ParseTree,
11905 current_index: usize,
11906 ) -> Option<usize> {
11907 if let Some(stop) = self
11908 .node(tree)
11909 .as_rule()
11910 .and_then(crate::tree::RuleNodeView::stop_id)
11911 {
11912 return Some(stop.index());
11913 }
11914 self.after_action_stop_index(current_index)
11915 }
11916
11917 #[must_use]
11927 pub fn after_action_start_index_for_tree(
11928 &self,
11929 tree: ParseTree,
11930 fallback_index: usize,
11931 ) -> usize {
11932 if let Some(start) = self
11933 .node(tree)
11934 .as_rule()
11935 .and_then(crate::tree::RuleNodeView::start_id)
11936 {
11937 return start.index();
11938 }
11939 fallback_index
11940 }
11941
11942 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
11947 self.rule_stop_token_index(index, consumed_eof)
11948 .and_then(|token_index| self.token_id_at(token_index))
11949 }
11950
11951 fn predicate_failure_recovery(
11958 &mut self,
11959 request: PredicateFailureRecovery<'_>,
11960 ) -> RecognizeOutcome {
11961 let PredicateFailureRecovery {
11962 rule_index,
11963 index,
11964 message,
11965 member_values,
11966 return_values,
11967 rule_alt_number,
11968 } = request;
11969 let rule_name = self
11970 .rule_names()
11971 .get(rule_index)
11972 .map_or_else(|| rule_index.to_string(), Clone::clone);
11973 let diagnostic = diagnostic_for_token(
11974 self.token_at(index).as_ref(),
11975 format!("rule {rule_name} {message}"),
11976 );
11977 let mut reversed_nodes = NodeSeqId::EMPTY;
11978 let mut next_index = index;
11979 loop {
11980 let symbol = self.token_type_at(next_index);
11981 if symbol == TOKEN_EOF {
11982 break;
11983 }
11984 let error = self.arena_token_node(next_index, true);
11985 self.arena_prepend(&mut reversed_nodes, error);
11986 let after = self.consume_index(next_index, symbol);
11987 if after == next_index {
11988 break;
11989 }
11990 next_index = after;
11991 }
11992 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
11993 let diagnostics = self
11994 .recognition_arena
11995 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
11996 RecognizeOutcome {
11997 index: next_index,
11998 consumed_eof: false,
11999 alt_number: rule_alt_number,
12000 member_values,
12001 return_values,
12002 diagnostics,
12003 decisions: Vec::new(),
12004 actions: Vec::new(),
12005 nodes,
12006 }
12007 }
12008
12009 fn parser_semantic_hook_result(
12012 &mut self,
12013 request: ParserSemanticHookRequest<'_>,
12014 ) -> Option<bool> {
12015 let ParserSemanticHookRequest {
12016 index,
12017 rule_index,
12018 pred_index,
12019 context,
12020 local_int_arg,
12021 member_values,
12022 } = request;
12023 let rule_name = self.rule_names().get(rule_index).cloned();
12024 self.input.seek(index);
12025 let input = &mut self.input;
12026 let semantic_hooks = &mut self.semantic_hooks;
12027 let mut ctx = ParserSemCtx {
12028 input,
12029 tree_storage: &self.tree,
12030 rule_index,
12031 coordinate_index: pred_index,
12032 rule_name,
12033 context,
12034 tree: None,
12035 local_int_arg,
12036 member_values,
12037 action: None,
12038 };
12039 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
12040 }
12041
12042 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
12047 if prior.is_empty() {
12048 return;
12049 }
12050 let mut merged = prior;
12051 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
12052 if !merged.contains(&coordinate) {
12053 merged.push(coordinate);
12054 }
12055 }
12056 self.unknown_predicate_hits = merged;
12057 }
12058
12059 fn restore_prior_unhandled_action_hits(&mut self, prior: Vec<(usize, usize)>) {
12062 if prior.is_empty() {
12063 return;
12064 }
12065 let mut merged = prior;
12066 for coordinate in std::mem::take(&mut self.unhandled_action_hits) {
12067 if !merged.contains(&coordinate) {
12068 merged.push(coordinate);
12069 }
12070 }
12071 self.unhandled_action_hits = merged;
12072 }
12073
12074 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
12083 apply_unknown_predicate_policy(
12084 self.unknown_predicate_policy,
12085 rule_index,
12086 pred_index,
12087 &mut self.unknown_predicate_hits,
12088 )
12089 }
12090
12091 fn unknown_semantic_error(&self) -> Option<AntlrError> {
12094 use std::fmt::Write as _;
12095 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
12096 return None;
12097 }
12098 let mut message = String::new();
12099 for (rule_index, pred_index) in &self.unknown_predicate_hits {
12100 if !message.is_empty() {
12101 message.push_str("; ");
12102 }
12103 let _ = match self.rule_names().get(*rule_index) {
12104 Some(rule_name) => write!(
12105 message,
12106 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
12107 ),
12108 None => write!(
12109 message,
12110 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
12111 ),
12112 };
12113 }
12114 for (rule_index, source_state) in &self.unhandled_action_hits {
12115 if !message.is_empty() {
12116 message.push_str("; ");
12117 }
12118 let _ = match self.rule_names().get(*rule_index) {
12119 Some(rule_name) => write!(
12120 message,
12121 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
12122 ),
12123 None => write!(
12124 message,
12125 "unhandled semantic action: rule_index={rule_index} state={source_state}"
12126 ),
12127 };
12128 }
12129 Some(AntlrError::Unsupported(message))
12130 }
12131
12132 fn parser_semir_predicate_matches(
12140 &mut self,
12141 semantics: &ParserSemantics,
12142 predicate: &ParserSemanticPredicate,
12143 request: ParserSemanticHookRequest<'_>,
12144 ) -> bool {
12145 self.input.seek(request.index);
12146 let rule_name = self
12147 .data
12148 .rule_names()
12149 .get(request.rule_index)
12150 .map(String::as_str);
12151 let unknown_predicate_policy = self.unknown_predicate_policy;
12152 let mut ctx = ParserSemIrCtx {
12153 input: &mut self.input,
12154 tree_storage: &self.tree,
12155 semantic_hooks: &mut self.semantic_hooks,
12156 rule_index: request.rule_index,
12157 coordinate_index: request.pred_index,
12158 rule_name,
12159 context: request.context,
12160 local_int_arg: request.local_int_arg,
12161 member_values: request.member_values,
12162 invoked_predicates: &mut self.invoked_predicates,
12163 unknown_predicate_policy,
12164 unknown_predicate_hits: &mut self.unknown_predicate_hits,
12165 };
12166 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
12167 }
12168
12169 fn fast_parser_predicate_matches(
12170 &mut self,
12171 context: Option<FastPredicateContext<'_>>,
12172 transition: ParserTransition<'_>,
12173 index: usize,
12174 ) -> bool {
12175 let Some(context) = context else {
12176 return true;
12177 };
12178 let rule_index = transition.arg0() as usize;
12179 let pred_index = transition.arg1() as usize;
12180 let key = (index, rule_index, pred_index);
12181 if let Some(result) = self.fast_predicate_cache.get(&key) {
12182 return *result;
12183 }
12184 let result = self.parser_predicate_matches(PredicateEval {
12185 index,
12186 rule_index,
12187 pred_index,
12188 predicates: context.predicates,
12189 semantics: context.semantics,
12190 context: None,
12191 local_int_arg: None,
12192 member_values: context.member_values,
12193 });
12194 self.fast_predicate_cache.insert(key, result);
12195 result
12196 }
12197
12198 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
12199 let PredicateEval {
12200 index,
12201 rule_index,
12202 pred_index,
12203 predicates,
12204 semantics,
12205 context,
12206 local_int_arg,
12207 member_values,
12208 } = eval;
12209 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
12210 semantics
12211 .predicates
12212 .iter()
12213 .find(|predicate| {
12214 predicate.rule_index == rule_index && predicate.pred_index == pred_index
12215 })
12216 .map(|predicate| (semantics, predicate))
12217 }) {
12218 return self.parser_semir_predicate_matches(
12219 semantics,
12220 predicate,
12221 ParserSemanticHookRequest {
12222 index,
12223 rule_index,
12224 pred_index,
12225 context,
12226 local_int_arg,
12227 member_values,
12228 },
12229 );
12230 }
12231 let Some((_, _, predicate)) = predicates
12232 .iter()
12233 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
12234 else {
12235 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
12236 index,
12237 rule_index,
12238 pred_index,
12239 context,
12240 local_int_arg,
12241 member_values,
12242 }) {
12243 return result;
12244 }
12245 return self.unknown_predicate_result(rule_index, pred_index);
12246 };
12247 self.input.seek(index);
12248 match predicate {
12249 ParserPredicate::True => true,
12250 ParserPredicate::False => false,
12251 ParserPredicate::FalseWithMessage { .. } => false,
12252 ParserPredicate::Invoke { value } => {
12253 let key = (rule_index, pred_index);
12254 if !self.invoked_predicates.contains(&key) {
12255 self.invoked_predicates.push(key);
12256 use std::io::Write as _;
12257 let mut stdout = std::io::stdout().lock();
12258 let _ = writeln!(stdout, "eval={value}");
12259 }
12260 *value
12261 }
12262 ParserPredicate::LookaheadTextEquals { offset, text } => self
12263 .input
12264 .lt(*offset)
12265 .is_some_and(|token| Token::text(&token) == Some(*text)),
12266 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
12267 self.la(*offset) != *token_type
12268 }
12269 ParserPredicate::TokenPairAdjacent => {
12270 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
12271 return false;
12272 };
12273 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
12274 return false;
12275 };
12276 first + 1 == second
12277 }
12278 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
12279 .and_then(|context| {
12280 context
12281 .child_rules(&self.tree, self.input.token_store(), *rule_index)
12282 .next()
12283 .map(crate::tree::RuleNodeView::text)
12284 })
12285 .is_none_or(|actual| actual != *text),
12286 ParserPredicate::LocalIntEquals { value } => {
12287 local_int_arg.is_none_or(|(_, actual)| actual == *value)
12288 }
12289 ParserPredicate::LocalIntLessOrEqual { value } => {
12290 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
12291 }
12292 ParserPredicate::MemberModuloEquals {
12293 member,
12294 modulus,
12295 value,
12296 equals,
12297 } => {
12298 if *modulus == 0 {
12299 return false;
12300 }
12301 let actual = member_values.scalar(*member).unwrap_or_default() % *modulus;
12302 (actual == *value) == *equals
12303 }
12304 ParserPredicate::MemberEquals {
12305 member,
12306 value,
12307 equals,
12308 } => {
12309 let actual = member_values.scalar(*member).unwrap_or_default();
12310 (actual == *value) == *equals
12311 }
12312 }
12313 }
12314
12315 fn parser_predicate_failure_message(
12317 &self,
12318 rule_index: usize,
12319 pred_index: usize,
12320 predicates: &[(usize, usize, ParserPredicate)],
12321 ) -> Option<&'static str> {
12322 predicates
12323 .iter()
12324 .find_map(|(rule, pred, predicate)| match predicate {
12325 ParserPredicate::FalseWithMessage { message }
12326 if *rule == rule_index && *pred == pred_index =>
12327 {
12328 Some(*message)
12329 }
12330 _ => None,
12331 })
12332 }
12333
12334 pub fn parser_semantic_ir_predicate_failure_message(
12337 &self,
12338 rule_index: usize,
12339 pred_index: usize,
12340 semantics: &ParserSemantics,
12341 ) -> Option<&'static str> {
12342 semantics
12343 .predicates
12344 .iter()
12345 .find(|predicate| {
12346 predicate.rule_index == rule_index && predicate.pred_index == pred_index
12347 })
12348 .and_then(|predicate| predicate.failure_message)
12349 }
12350
12351 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
12360 if symbol == TOKEN_EOF {
12361 return index;
12362 }
12363 self.input.next_visible_after(index)
12364 }
12365
12366 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
12369 let text = display_input_text(&self.input.text(start_index, error_index));
12370 diagnostic_for_token(
12371 self.token_at(error_index).as_ref(),
12372 format!("no viable alternative at input '{text}'"),
12373 )
12374 }
12375
12376 fn recovery_failure_diagnostic(
12379 &self,
12380 index: usize,
12381 decision_start_index: Option<usize>,
12382 expected_symbols: &BTreeSet<i32>,
12383 ) -> ParserDiagnostic {
12384 if expected_symbols.len() > 1 {
12385 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
12386 return self.no_viable_alternative(decision_start, index);
12387 }
12388 }
12389 diagnostic_for_token(
12390 self.token_at(index).as_ref(),
12391 format!(
12392 "mismatched input {} expecting {}",
12393 self.token_at(index)
12394 .as_ref()
12395 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
12396 self.expected_symbols_display(expected_symbols)
12397 ),
12398 )
12399 }
12400
12401 fn eof_rule_recovery_diagnostic(
12404 &self,
12405 index: usize,
12406 expected_symbols: &BTreeSet<i32>,
12407 expected: &ExpectedTokens,
12408 ) -> ParserDiagnostic {
12409 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
12410 &expected.symbols
12411 } else {
12412 expected_symbols
12413 };
12414 diagnostic_for_token(
12415 self.token_at(index).as_ref(),
12416 format!(
12417 "mismatched input {} expecting {}",
12418 self.token_at(index)
12419 .as_ref()
12420 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
12421 self.expected_symbols_display(symbols)
12422 ),
12423 )
12424 }
12425
12426 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
12432 let Some(stop) = stop else {
12433 return String::new();
12434 };
12435 let stop = if self
12436 .token_at(stop)
12437 .is_some_and(|token| token.token_type() == TOKEN_EOF)
12438 {
12439 let Some(previous) = self.previous_token_index(stop) else {
12440 return String::new();
12441 };
12442 previous
12443 } else {
12444 stop
12445 };
12446 self.input.text(start, stop)
12447 }
12448
12449 fn clear_prediction_diagnostics(&mut self) {
12452 self.prediction_diagnostics.clear();
12453 self.reported_prediction_diagnostics.clear();
12454 }
12455
12456 fn reset_per_parse_caches(&mut self) {
12480 self.rule_first_set_cache.clear();
12481 self.decision_lookahead_cache.clear();
12482 self.ll1_decision_cache.clear();
12483 self.fast_predicate_cache.clear();
12484 self.rule_stop_reach_cache.clear();
12485 self.clean_memo_mode = CleanMemoMode::Probe;
12486 self.clean_memo_probe_seen.clear();
12487 self.clean_memo_probe_samples = 0;
12488 self.clean_memo_probe_repeats = 0;
12489 self.clean_memo_sparse_samples = 0;
12490 self.recovery_symbols_intern.clear();
12491 self.state_expected_cache.clear();
12492 self.state_expected_token_cache.clear();
12493 }
12494
12495 fn record_prediction_diagnostics(
12498 &mut self,
12499 atn: &Atn,
12500 state: AtnState<'_>,
12501 start_index: usize,
12502 outcomes: &[RecognizeOutcome],
12503 ) {
12504 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
12505 return;
12506 }
12507 let Some(decision) = atn
12508 .decision_to_state()
12509 .iter()
12510 .position(|state_number| state_number == state.state_number())
12511 else {
12512 return;
12513 };
12514 let Some(rule_index) = state.rule_index() else {
12515 return;
12516 };
12517 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
12518 for outcome in outcomes
12519 .iter()
12520 .filter(|outcome| outcome.diagnostics.is_empty())
12521 {
12522 let Some(alt) = outcome.decisions.first() else {
12523 continue;
12524 };
12525 alts_by_end
12526 .entry(outcome.index)
12527 .or_default()
12528 .insert(alt + 1);
12529 }
12530 let Some((&end_index, ambig_alts)) = alts_by_end
12531 .iter()
12532 .filter(|(_, alts)| alts.len() > 1)
12533 .max_by_key(|(end, _)| *end)
12534 else {
12535 return;
12536 };
12537 let rule_name = self
12538 .rule_names()
12539 .get(rule_index)
12540 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
12541 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
12542 let input = display_input_text(&self.input.text(start_index, stop_index));
12543 let alts = ambig_alts
12544 .iter()
12545 .map(usize::to_string)
12546 .collect::<Vec<_>>()
12547 .join(", ");
12548 let key = (decision, start_index, format!("{alts}:{input}"));
12549 if !self.reported_prediction_diagnostics.insert(key) {
12550 return;
12551 }
12552 let start_diagnostic = diagnostic_for_token(
12553 self.token_at(start_index),
12554 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
12555 );
12556 let stop_diagnostic = diagnostic_for_token(
12557 self.token_at(stop_index),
12558 format!(
12559 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
12560 ),
12561 );
12562 self.prediction_diagnostics.push(start_diagnostic);
12563 self.prediction_diagnostics.push(stop_diagnostic);
12564 }
12565
12566 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
12568 expected_symbols_display(
12569 &state_expected_symbols(atn, state_number),
12570 self.vocabulary(),
12571 )
12572 }
12573
12574 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
12579 let state = usize::try_from(self.data().state()).unwrap_or(0);
12580 ExpectedTokenSet {
12581 symbols: state_expected_symbols(atn, state),
12582 }
12583 }
12584
12585 pub const fn set_bail_on_error(&mut self, bail: bool) {
12588 self.bail_on_error = bail;
12589 }
12590
12591 #[must_use]
12593 pub const fn bail_on_error(&self) -> bool {
12594 self.bail_on_error
12595 }
12596
12597 pub fn rule_invocation_stack(&self) -> Vec<String> {
12600 self.rule_context_stack
12601 .iter()
12602 .rev()
12603 .map(|frame| {
12604 self.data()
12605 .rule_names()
12606 .get(frame.rule_index)
12607 .cloned()
12608 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
12609 })
12610 .collect()
12611 }
12612
12613 pub fn active_invocation_states(&self) -> Vec<isize> {
12617 self.rule_context_stack
12618 .iter()
12619 .skip(1)
12620 .rev()
12621 .map(|frame| frame.invoking_state)
12622 .collect()
12623 }
12624
12625 pub fn token_display_at(&self, index: usize) -> Option<String> {
12627 self.token_at(index).map(|token| format!("{token}"))
12628 }
12629}
12630
12631impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
12632where
12633 S: TokenSource,
12634 H: SemanticHooks,
12635{
12636 fn parse_rule(
12637 &mut self,
12638 rule_index: usize,
12639 invoking_state: isize,
12640 precedence: i32,
12641 ) -> DirectAdaptiveParseResult<ParseTree> {
12642 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
12643 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
12644 )?;
12645 let stop_state = self
12646 .atn
12647 .rule_to_stop_state()
12648 .get(rule_index)
12649 .filter(|state| *state != usize::MAX)
12650 .ok_or(DirectAdaptiveParseControl::Fallback(
12651 DirectAdaptiveFallback::MissingAtn,
12652 ))?;
12653 let start_index = self.parser.current_visible_index();
12654 let mut context = ParserRuleContext::new(rule_index, invoking_state);
12655 if let Some(token) = self.parser.token_id_at(start_index) {
12656 self.parser.set_context_start(&mut context, token);
12657 }
12658 let mut state_number = start_state;
12659 let mut consumed_eof = false;
12660 while state_number != stop_state {
12661 self.step()?;
12662 let (transition, boundary) = self.next_transition(state_number, precedence)?;
12663 if boundary.is_some() {
12664 return Err(DirectAdaptiveParseControl::Fallback(
12665 DirectAdaptiveFallback::LeftRecursiveBoundary,
12666 ));
12667 }
12668 match transition.data() {
12669 Transition::Epsilon { target } => {
12670 state_number = target;
12671 }
12672 Transition::Precedence {
12673 target,
12674 precedence: transition_precedence,
12675 } => {
12676 if transition_precedence < precedence {
12677 return Err(DirectAdaptiveParseControl::Fallback(
12678 DirectAdaptiveFallback::Precedence,
12679 ));
12680 }
12681 state_number = target;
12682 }
12683 Transition::Rule {
12684 rule_index,
12685 follow_state,
12686 precedence: rule_precedence,
12687 ..
12688 } => {
12689 let child = self.parse_rule(
12690 rule_index,
12691 invoking_state_number(state_number),
12692 rule_precedence,
12693 )?;
12694 if self.parser.build_parse_trees {
12695 self.parser.tree.add_child(&mut context, child);
12696 }
12697 state_number = follow_state;
12698 }
12699 Transition::Atom { .. }
12700 | Transition::Range { .. }
12701 | Transition::Set { .. }
12702 | Transition::NotSet { .. }
12703 | Transition::Wildcard { .. } => {
12704 let (matched_eof, child) = self.consume_transition(transition)?;
12705 consumed_eof |= matched_eof;
12706 if let Some(child) = child {
12707 self.parser.tree.add_child(&mut context, child);
12708 }
12709 state_number = transition.target();
12710 }
12711 Transition::Predicate { .. } => {
12712 return Err(DirectAdaptiveParseControl::Fallback(
12713 DirectAdaptiveFallback::Predicate,
12714 ));
12715 }
12716 Transition::Action { .. } => {
12717 return Err(DirectAdaptiveParseControl::Fallback(
12718 DirectAdaptiveFallback::Action,
12719 ));
12720 }
12721 }
12722 }
12723
12724 let stop_index = self
12725 .parser
12726 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
12727 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
12728 self.parser.set_context_stop(&mut context, token);
12729 }
12730 Ok(self.parser.rule_node(context))
12731 }
12732
12733 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
12734 self.steps += 1;
12735 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
12736 return Err(DirectAdaptiveParseControl::Fallback(
12737 DirectAdaptiveFallback::StepLimit,
12738 ));
12739 }
12740 Ok(())
12741 }
12742
12743 fn next_transition(
12744 &mut self,
12745 state_number: usize,
12746 precedence: i32,
12747 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
12748 let state = self
12749 .atn
12750 .state(state_number)
12751 .ok_or(DirectAdaptiveParseControl::Fallback(
12752 DirectAdaptiveFallback::MissingAtn,
12753 ))?;
12754 if state.is_rule_stop() {
12755 return Err(DirectAdaptiveParseControl::Fallback(
12756 DirectAdaptiveFallback::RuleStop,
12757 ));
12758 }
12759 let transition_index =
12760 self.transition_index(state_number, state.transitions().len(), precedence)?;
12761 let transition = state.transitions().get(transition_index).ok_or(
12762 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
12763 )?;
12764 let boundary = match &transition.data() {
12765 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
12766 left_recursive_boundary(self.atn, state, *target)
12767 }
12768 _ => None,
12769 };
12770 Ok((transition, boundary))
12771 }
12772
12773 fn transition_index(
12774 &mut self,
12775 state_number: usize,
12776 transition_count: usize,
12777 precedence: i32,
12778 ) -> DirectAdaptiveParseResult<usize> {
12779 match transition_count {
12780 0 => Err(DirectAdaptiveParseControl::Fallback(
12781 DirectAdaptiveFallback::NoTransition,
12782 )),
12783 1 => Ok(0),
12784 _ => {
12785 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
12786 return Ok(alt);
12787 }
12788 let decision = self
12789 .decision_by_state
12790 .get(state_number)
12791 .and_then(|decision| *decision)
12792 .ok_or(DirectAdaptiveParseControl::Fallback(
12793 DirectAdaptiveFallback::UnknownDecision,
12794 ))?;
12795 let prediction = self
12796 .simulator
12797 .adaptive_predict_stream_info_with_precedence(
12798 decision,
12799 direct_precedence(precedence),
12800 &mut self.parser.input,
12801 )
12802 .map_err(|_| {
12803 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
12804 })?;
12805 if prediction.has_semantic_context {
12806 return Err(DirectAdaptiveParseControl::Fallback(
12807 DirectAdaptiveFallback::SemanticContext,
12808 ));
12809 }
12810 prediction
12811 .alt
12812 .checked_sub(1)
12813 .filter(|index| *index < transition_count)
12814 .ok_or(DirectAdaptiveParseControl::Fallback(
12815 DirectAdaptiveFallback::InvalidAlt,
12816 ))
12817 }
12818 }
12819 }
12820
12821 fn ll1_transition_index(
12822 &mut self,
12823 state_number: usize,
12824 transition_count: usize,
12825 ) -> DirectAdaptiveParseResult<Option<usize>> {
12826 let state = self
12827 .atn
12828 .state(state_number)
12829 .ok_or(DirectAdaptiveParseControl::Fallback(
12830 DirectAdaptiveFallback::MissingAtn,
12831 ))?;
12832 if state.precedence_rule_decision() {
12833 return Ok(None);
12834 }
12835 let Some(rule_stop) = state
12836 .rule_index()
12837 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
12838 else {
12839 return Ok(None);
12840 };
12841 let symbol = self.parser.input.la_token(1);
12842 let entry = self
12843 .parser
12844 .cached_decision_lookahead(self.atn, state, rule_stop);
12845 Ok(
12846 ll1_greedy_alt(&entry, symbol, state.non_greedy())
12847 .filter(|alt| *alt < transition_count),
12848 )
12849 }
12850
12851 fn consume_transition(
12852 &mut self,
12853 transition: ParserTransition<'_>,
12854 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
12855 let symbol = self.parser.input.la_token(1);
12856 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
12857 return Err(DirectAdaptiveParseControl::Fallback(
12858 DirectAdaptiveFallback::TokenMismatch,
12859 ));
12860 }
12861 let token = self
12862 .parser
12863 .input
12864 .lt_id(1)
12865 .ok_or(DirectAdaptiveParseControl::Fallback(
12866 DirectAdaptiveFallback::TokenMismatch,
12867 ))?;
12868 let matched_eof = symbol == TOKEN_EOF;
12869 if !matched_eof {
12870 self.parser.consume();
12871 }
12872 let child = self
12873 .parser
12874 .build_parse_trees
12875 .then(|| self.parser.terminal_tree(token));
12876 Ok((matched_eof, child))
12877 }
12878}
12879
12880impl<S, H> CommittedAtnParser<'_, '_, '_, S, H>
12881where
12882 S: TokenSource,
12883 H: SemanticHooks,
12884{
12885 fn parse_rule(
12886 &mut self,
12887 rule_index: usize,
12888 precedence: i32,
12889 inherited_local_int_arg: Option<(usize, i64)>,
12890 init_expected_state: Option<usize>,
12891 ) -> Result<CommittedRuleOutcome, AntlrError> {
12892 let start_state = self
12893 .atn
12894 .rule_to_start_state()
12895 .get(rule_index)
12896 .ok_or_else(|| {
12897 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
12898 })?;
12899 let stop_state = self
12900 .atn
12901 .rule_to_stop_state()
12902 .get(rule_index)
12903 .filter(|state| *state != usize::MAX)
12904 .ok_or_else(|| {
12905 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
12906 })?;
12907 let left_recursive = self
12908 .atn
12909 .state(start_state)
12910 .is_some_and(AtnState::left_recursive_rule);
12911 if let Some(error) = self.parser.rule_depth_cap_violation() {
12912 return Err(error);
12913 }
12914 if let Some(error) = self.parser.parse_listener_enter_rule(rule_index) {
12915 return Err(error);
12916 }
12917 let mut context = if left_recursive {
12918 self.parser.enter_recursion_rule(
12919 invoking_state_number(start_state),
12920 rule_index,
12921 precedence,
12922 )
12923 } else {
12924 self.parser
12925 .enter_rule(invoking_state_number(start_state), rule_index)
12926 };
12927 let rule_start_index = self.parser.current_visible_index();
12928 let local_int_arg =
12929 usize::try_from(context.invoking_state())
12930 .ok()
12931 .and_then(|source_state| {
12932 rule_local_int_arg(
12933 self.options.rule_args,
12934 source_state,
12935 rule_index,
12936 inherited_local_int_arg,
12937 )
12938 });
12939 if self.options.init_action_rules.contains(&rule_index) {
12940 let action = ParserAction::new_rule_init(
12941 rule_index,
12942 rule_start_index,
12943 init_expected_state.or(Some(start_state)),
12944 );
12945 if !self
12946 .parser
12947 .parser_rule_init_hook_with_context(action, &context, local_int_arg)
12948 {
12949 self.deferred_actions.push(action);
12950 }
12951 }
12952 let mut consumed_eof = false;
12953 let result = self.walk_rule(
12954 rule_index,
12955 start_state,
12956 stop_state,
12957 precedence,
12958 rule_start_index,
12959 local_int_arg,
12960 left_recursive,
12961 &mut context,
12962 &mut consumed_eof,
12963 );
12964
12965 let result = match result {
12966 Ok(()) => Ok(if left_recursive {
12967 self.parser.finish_recursion_rule(context, consumed_eof)
12968 } else {
12969 self.parser.finish_rule(context, consumed_eof)
12970 }),
12971 Err(error) if self.parser.bail_on_error() => {
12972 if left_recursive {
12973 self.parser.unroll_recursion_context();
12974 } else {
12975 self.parser.exit_rule();
12976 }
12977 Err(error)
12978 }
12979 Err(error) => {
12980 self.parser
12981 .recover_generated_rule(&mut context, self.atn, error);
12982 Ok(if left_recursive {
12983 self.parser.finish_recursion_rule(context, consumed_eof)
12984 } else {
12985 self.parser.finish_rule(context, consumed_eof)
12986 })
12987 }
12988 };
12989 self.parser.parse_listener_exit_rule(rule_index);
12990 result.map(|tree| CommittedRuleOutcome { tree, consumed_eof })
12991 }
12992
12993 #[allow(clippy::too_many_arguments)]
12994 fn walk_rule(
12995 &mut self,
12996 rule_index: usize,
12997 mut state_number: usize,
12998 stop_state: usize,
12999 precedence: i32,
13000 rule_start_index: usize,
13001 local_int_arg: Option<(usize, i64)>,
13002 left_recursive: bool,
13003 context: &mut ParserRuleContext,
13004 consumed_eof: &mut bool,
13005 ) -> Result<(), AntlrError> {
13006 let mut entered_loops = BTreeSet::new();
13007 let mut visited_coordinates = FxHashSet::default();
13008 let mut guarded_input_index = self.parser.input.index();
13009 while state_number != stop_state {
13010 let input_index = self.parser.input.index();
13011 if input_index != guarded_input_index {
13012 visited_coordinates.clear();
13013 guarded_input_index = input_index;
13014 }
13015 if !visited_coordinates.insert((state_number, input_index)) {
13016 return Err(AntlrError::Unsupported(format!(
13017 "committed parser encountered a non-consuming ATN cycle at state \
13018 {state_number}"
13019 )));
13020 }
13021 let state = self.atn.state(state_number).ok_or_else(|| {
13022 AntlrError::Unsupported(format!("missing parser ATN state {state_number}"))
13023 })?;
13024 if state.is_rule_stop() {
13025 return Err(AntlrError::Unsupported(format!(
13026 "rule {rule_index} reached unexpected stop state {state_number}"
13027 )));
13028 }
13029 let transition_index = {
13030 let mut decision_context = CommittedDecisionContext {
13031 precedence,
13032 local_int_arg,
13033 context,
13034 entered_loops: &mut entered_loops,
13035 };
13036 self.transition_index(state, &mut decision_context)?
13037 };
13038 let transition = state.transitions().get(transition_index).ok_or_else(|| {
13039 AntlrError::Unsupported(format!(
13040 "missing transition {transition_index} from parser ATN state {state_number}"
13041 ))
13042 })?;
13043
13044 let next_alt = next_alt_number(
13045 state,
13046 state.transitions().len(),
13047 transition_index,
13048 context.alt_number(),
13049 self.options.track_alt_numbers,
13050 );
13051 if self.options.track_alt_numbers && context.alt_number() == 0 && next_alt != 0 {
13052 context.set_alt_number(next_alt);
13053 }
13054 let next_context_alt = next_alt_number(
13055 state,
13056 state.transitions().len(),
13057 transition_index,
13058 context.context_alt_number(),
13059 self.options.track_context_alt_numbers,
13060 );
13061 if self.options.track_context_alt_numbers
13062 && context.context_alt_number() == 0
13063 && next_context_alt != 0
13064 {
13065 context.set_context_alt_number(next_context_alt);
13066 }
13067
13068 if left_recursive
13069 && left_recursive_boundary(self.atn, state, transition.target()).is_some()
13070 {
13071 if let Some(error) = self.parser.rule_depth_cap_violation() {
13072 return Err(error);
13073 }
13074 self.parser.parse_listener_exit_rule(rule_index);
13075 self.parser.push_new_recursion_context_with_previous(
13076 invoking_state_number(
13077 self.atn
13078 .rule_to_start_state()
13079 .get(rule_index)
13080 .unwrap_or(state_number),
13081 ),
13082 rule_index,
13083 context,
13084 );
13085 if let Some(error) = self.parser.parse_listener_enter_rule(rule_index) {
13086 return Err(error);
13087 }
13088 }
13089 state_number = self.apply_transition(
13090 state_number,
13091 transition,
13092 precedence,
13093 rule_start_index,
13094 local_int_arg,
13095 context,
13096 consumed_eof,
13097 )?;
13098 }
13099 Ok(())
13100 }
13101
13102 fn transition_index(
13103 &mut self,
13104 state: AtnState<'_>,
13105 decision_context: &mut CommittedDecisionContext<'_>,
13106 ) -> Result<usize, AntlrError> {
13107 let transition_count = state.transitions().len();
13108 if transition_count == 1 {
13109 return Ok(0);
13110 }
13111 let Some(decision) = self
13112 .decision_by_state
13113 .get(state.state_number())
13114 .copied()
13115 .flatten()
13116 else {
13117 return Err(AntlrError::Unsupported(format!(
13118 "parser ATN state {} has {transition_count} transitions but is not a decision",
13119 state.state_number()
13120 )));
13121 };
13122
13123 let decision_start = self.parser.input.index();
13124 let overridden_transition = if self.parser.semantic_hooks.observes_parser_decisions() {
13125 self.parser
13126 .semantic_hooks
13127 .parser_decision_override(decision, decision_start, transition_count)
13128 .and_then(|alternative| alternative.checked_sub(1))
13129 .filter(|alternative| *alternative < transition_count)
13130 } else {
13131 None
13132 };
13133 if let Some(selected) = overridden_transition {
13134 self.update_loop_selection(state, selected, decision_context);
13135 return Ok(selected);
13136 }
13137
13138 if !state.precedence_rule_decision() {
13139 let loop_back = match state.kind() {
13140 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack => true,
13141 AtnStateKind::StarLoopEntry => decision_context
13142 .entered_loops
13143 .contains(&state.state_number()),
13144 _ => false,
13145 };
13146 let children = self.parser.sync_decision(
13147 self.atn,
13148 state.state_number(),
13149 !decision_context.context.has_matched_child(),
13150 loop_back,
13151 )?;
13152 for child in children {
13153 self.parser.add_parse_child(decision_context.context, child);
13154 }
13155 }
13156
13157 let prediction_precedence = if state.precedence_rule_decision() {
13158 usize::try_from(decision_context.precedence.max(0)).unwrap_or_default()
13159 } else {
13160 0
13161 };
13162 let prediction_context = {
13163 let return_states = self
13164 .parser
13165 .prediction_context_return_states(self.atn)
13166 .collect::<Vec<_>>();
13167 self.simulator
13168 .intern_prediction_context(self.parser.rule_context_version(), return_states)
13169 };
13170 self.simulator.set_exact_ambig_detection(
13171 self.parser.prediction_mode() == PredictionMode::LlExactAmbigDetection,
13172 );
13173 let prediction_mode = self.parser.prediction_mode();
13174 let prediction = match self.simulator.adaptive_predict_stream_info_sll_probe(
13175 decision,
13176 prediction_precedence,
13177 &mut self.parser.input,
13178 ) {
13179 Ok(prediction)
13180 if prediction.requires_full_context && prediction_mode != PredictionMode::Sll =>
13181 {
13182 self.simulator.adaptive_predict_stream_info_with_context(
13183 decision,
13184 prediction_precedence,
13185 &mut self.parser.input,
13186 prediction_context,
13187 )
13188 }
13189 prediction => prediction,
13190 };
13191 let mut prediction = match prediction {
13192 Ok(prediction) => prediction,
13193 Err(ParserAtnSimulatorError::NoViableAlt { index, .. })
13194 if state.precedence_rule_decision() =>
13195 {
13196 let enter_alt = state.transitions().iter().position(|transition| {
13197 self.atn
13198 .state(transition.target())
13199 .is_some_and(|target| target.kind() != AtnStateKind::LoopEnd)
13200 });
13201 let exit_alt = state.transitions().iter().position(|transition| {
13202 self.atn
13203 .state(transition.target())
13204 .is_some_and(|target| target.kind() == AtnStateKind::LoopEnd)
13205 });
13206 let selected = if self.parser.left_recursive_loop_enter_matches(
13207 self.atn,
13208 state.state_number(),
13209 decision_context.precedence,
13210 ) {
13211 enter_alt
13212 } else {
13213 exit_alt
13214 };
13215 let Some(selected) = selected else {
13216 return Err(self
13217 .parser
13218 .no_viable_alternative_error_at(decision_start, index));
13219 };
13220 ParserAtnPrediction {
13221 alt: selected + 1,
13222 requires_full_context: true,
13223 has_semantic_context: true,
13224 diagnostic: None,
13225 }
13226 }
13227 Err(ParserAtnSimulatorError::NoViableAlt { index, .. }) => {
13228 return Err(self
13229 .parser
13230 .no_viable_alternative_error_at(decision_start, index));
13231 }
13232 Err(ParserAtnSimulatorError::PredictionRequiresMoreLookahead) => {
13233 return Err(self.parser.no_viable_alternative_error(decision_start));
13234 }
13235 Err(error) => {
13236 return Err(AntlrError::Unsupported(format!(
13237 "committed parser prediction failed at decision {decision}: {error:?}"
13238 )));
13239 }
13240 };
13241 let mut selected = prediction
13242 .alt
13243 .checked_sub(1)
13244 .filter(|index| *index < transition_count)
13245 .ok_or_else(|| self.parser.no_viable_alternative_error(decision_start))?;
13246
13247 let semantic_candidates = self.simulator.prediction_semantic_candidates();
13248 if !semantic_candidates.is_empty() {
13249 let predicted_alt = prediction.alt;
13250 let mut semantic_results = BTreeMap::new();
13251 let selected_alt = selected + 1;
13252 let selected_matches = self.semantic_alternative_matches(
13253 selected_alt,
13254 decision_context,
13255 &semantic_candidates,
13256 );
13257 semantic_results.insert(selected_alt, selected_matches);
13258 if !selected_matches {
13259 let alternatives = semantic_candidates
13260 .iter()
13261 .map(|candidate| candidate.alt)
13262 .filter(|alternative| *alternative != 0 && *alternative <= transition_count)
13263 .collect::<BTreeSet<_>>();
13264 selected = alternatives
13265 .into_iter()
13266 .find(|alternative| {
13267 let matches = self.semantic_alternative_matches(
13268 *alternative,
13269 decision_context,
13270 &semantic_candidates,
13271 );
13272 semantic_results.insert(*alternative, matches);
13273 matches
13274 })
13275 .and_then(|alternative| alternative.checked_sub(1))
13276 .ok_or_else(|| self.parser.no_viable_alternative_error(decision_start))?;
13277 }
13278 if self.parser.report_diagnostic_errors
13279 && let Some(diagnostic) = prediction.diagnostic.as_ref()
13280 {
13281 for alternative in diagnostic.conflicting_alts.clone() {
13282 if semantic_results.contains_key(&alternative)
13283 || !semantic_candidates
13284 .iter()
13285 .any(|candidate| candidate.alt == alternative)
13286 {
13287 continue;
13288 }
13289 let matches = self.semantic_alternative_matches(
13290 alternative,
13291 decision_context,
13292 &semantic_candidates,
13293 );
13294 semantic_results.insert(alternative, matches);
13295 }
13296 }
13297 Self::filter_prediction_diagnostic(
13298 &mut prediction,
13299 predicted_alt,
13300 selected + 1,
13301 &semantic_results,
13302 );
13303 }
13304 self.parser.record_generated_prediction_diagnostic(
13305 self.atn,
13306 state.state_number(),
13307 &prediction,
13308 );
13309
13310 self.update_loop_selection(state, selected, decision_context);
13311 Ok(selected)
13312 }
13313
13314 fn semantic_alternative_matches(
13315 &mut self,
13316 alternative: usize,
13317 decision_context: &CommittedDecisionContext<'_>,
13318 candidates: &[ParserSemanticCandidate],
13319 ) -> bool {
13320 candidates
13321 .iter()
13322 .filter(|candidate| candidate.alt == alternative)
13323 .any(|candidate| {
13324 self.semantic_context_matches(&candidate.context, decision_context, candidate)
13325 })
13326 }
13327
13328 fn filter_prediction_diagnostic(
13329 prediction: &mut ParserAtnPrediction,
13330 predicted_alt: usize,
13331 selected_alt: usize,
13332 semantic_results: &BTreeMap<usize, bool>,
13333 ) {
13334 prediction.alt = selected_alt;
13335 if selected_alt != predicted_alt {
13336 prediction.diagnostic = None;
13337 return;
13338 }
13339 if let Some(diagnostic) = prediction.diagnostic.as_mut() {
13340 diagnostic
13341 .conflicting_alts
13342 .retain(|alternative| semantic_results.get(alternative).copied().unwrap_or(true));
13343 if diagnostic.conflicting_alts.len() < 2 {
13344 prediction.diagnostic = None;
13345 }
13346 }
13347 }
13348
13349 fn semantic_context_matches(
13350 &mut self,
13351 semantic_context: &SemanticContext,
13352 decision_context: &CommittedDecisionContext<'_>,
13353 candidate: &ParserSemanticCandidate,
13354 ) -> bool {
13355 match semantic_context {
13356 SemanticContext::None => true,
13357 SemanticContext::Predicate {
13358 rule_index,
13359 pred_index,
13360 ..
13361 } => {
13362 let mut matched_provenance = false;
13363 for predicate_call in candidate
13364 .predicate_calls
13365 .iter()
13366 .filter(|call| call.rule_index == *rule_index && call.pred_index == *pred_index)
13367 {
13368 matched_provenance = true;
13369 let mut local_int_arg = decision_context.local_int_arg;
13370 for rule_call in &predicate_call.rule_calls {
13371 local_int_arg = rule_local_int_arg(
13372 self.options.rule_args,
13373 rule_call.source_state,
13374 rule_call.rule_index,
13375 local_int_arg,
13376 );
13377 }
13378 if !self.semantic_predicate_matches(
13379 *rule_index,
13380 *pred_index,
13381 decision_context,
13382 local_int_arg,
13383 ) {
13384 return false;
13385 }
13386 }
13387 if matched_provenance {
13388 true
13389 } else {
13390 self.semantic_predicate_matches(
13391 *rule_index,
13392 *pred_index,
13393 decision_context,
13394 decision_context.local_int_arg,
13395 )
13396 }
13397 }
13398 SemanticContext::Precedence { precedence } => {
13399 *precedence >= decision_context.precedence
13400 }
13401 SemanticContext::And(children) => {
13402 for child in children {
13403 if !self.semantic_context_matches(child, decision_context, candidate) {
13404 return false;
13405 }
13406 }
13407 true
13408 }
13409 SemanticContext::Or(children) => {
13410 for child in children {
13411 if self.semantic_context_matches(child, decision_context, candidate) {
13412 return true;
13413 }
13414 }
13415 false
13416 }
13417 }
13418 }
13419
13420 fn semantic_predicate_matches(
13421 &mut self,
13422 rule_index: usize,
13423 pred_index: usize,
13424 decision_context: &CommittedDecisionContext<'_>,
13425 local_int_arg: Option<(usize, i64)>,
13426 ) -> bool {
13427 let member_values = self.parser.int_members.clone();
13428 self.parser.parser_predicate_matches(PredicateEval {
13429 index: self.parser.input.index(),
13430 rule_index,
13431 pred_index,
13432 predicates: self.options.predicates,
13433 semantics: self.options.semantics,
13434 context: Some(&*decision_context.context),
13435 local_int_arg,
13436 member_values: &member_values,
13437 })
13438 }
13439
13440 fn update_loop_selection(
13441 &self,
13442 state: AtnState<'_>,
13443 selected: usize,
13444 decision_context: &mut CommittedDecisionContext<'_>,
13445 ) {
13446 if state.kind() == AtnStateKind::StarLoopEntry {
13447 let enters = self
13448 .atn
13449 .state(
13450 state
13451 .transitions()
13452 .get(selected)
13453 .expect("selected transition is in bounds")
13454 .target(),
13455 )
13456 .is_some_and(|target| target.kind() != AtnStateKind::LoopEnd);
13457 if enters {
13458 decision_context.entered_loops.insert(state.state_number());
13459 } else {
13460 decision_context.entered_loops.remove(&state.state_number());
13461 }
13462 }
13463 }
13464
13465 #[allow(clippy::too_many_arguments)]
13466 fn apply_transition(
13467 &mut self,
13468 source_state: usize,
13469 transition: ParserTransition<'_>,
13470 precedence: i32,
13471 rule_start_index: usize,
13472 local_int_arg: Option<(usize, i64)>,
13473 context: &mut ParserRuleContext,
13474 consumed_eof: &mut bool,
13475 ) -> Result<usize, AntlrError> {
13476 self.parser.set_state(invoking_state_number(source_state));
13477 match transition.data() {
13478 Transition::Epsilon { target } => Ok(target),
13479 Transition::Atom { target, label } => {
13480 let matched = self
13481 .parser
13482 .match_token_recovering(label, target, self.atn)?;
13483 *consumed_eof |= matched.consumed_eof();
13484 for child in matched.into_child_iter() {
13485 self.parser.add_parse_child(context, child);
13486 }
13487 Ok(target)
13488 }
13489 Transition::Range {
13490 target,
13491 start,
13492 stop,
13493 } => {
13494 let matched =
13495 self.parser
13496 .match_set_recovering(&[(start, stop)], target, self.atn)?;
13497 *consumed_eof |= matched.consumed_eof();
13498 for child in matched.into_child_iter() {
13499 self.parser.add_parse_child(context, child);
13500 }
13501 Ok(target)
13502 }
13503 Transition::Set { target, set } => {
13504 let matched = self
13505 .parser
13506 .match_token_set_recovering(set, target, self.atn)?;
13507 *consumed_eof |= matched.consumed_eof();
13508 for child in matched.into_child_iter() {
13509 self.parser.add_parse_child(context, child);
13510 }
13511 Ok(target)
13512 }
13513 Transition::NotSet { target, set } => {
13514 let matched = self.parser.match_not_token_set_recovering(
13515 set,
13516 1,
13517 self.atn.max_token_type(),
13518 target,
13519 self.atn,
13520 )?;
13521 *consumed_eof |= matched.consumed_eof();
13522 for child in matched.into_child_iter() {
13523 self.parser.add_parse_child(context, child);
13524 }
13525 Ok(target)
13526 }
13527 Transition::Wildcard { target } => {
13528 let matched = self.parser.match_not_set_recovering(
13529 &[],
13530 1,
13531 self.atn.max_token_type(),
13532 target,
13533 self.atn,
13534 )?;
13535 *consumed_eof |= matched.consumed_eof();
13536 for child in matched.into_child_iter() {
13537 self.parser.add_parse_child(context, child);
13538 }
13539 Ok(target)
13540 }
13541 Transition::Rule {
13542 rule_index,
13543 follow_state,
13544 precedence: rule_precedence,
13545 ..
13546 } => {
13547 let marker = self
13548 .parser
13549 .push_invoking_state(invoking_state_number(source_state));
13550 let child = if self.parser.generated_rule_stack_check_due() {
13551 grow_generated_rule_stack(|| {
13552 self.parse_rule(
13553 rule_index,
13554 rule_precedence,
13555 local_int_arg,
13556 Some(follow_state),
13557 )
13558 })
13559 } else {
13560 self.parse_rule(
13561 rule_index,
13562 rule_precedence,
13563 local_int_arg,
13564 Some(follow_state),
13565 )
13566 };
13567 self.parser.discard_invoking_state(marker);
13568 let child = child?;
13569 *consumed_eof |= child.consumed_eof;
13570 self.parser.add_parse_child(context, child.tree);
13571 Ok(follow_state)
13572 }
13573 Transition::Predicate {
13574 target,
13575 rule_index,
13576 pred_index,
13577 ..
13578 } => {
13579 let member_values = self.parser.int_members.clone();
13580 if self.parser.parser_predicate_matches(PredicateEval {
13581 index: self.parser.input.index(),
13582 rule_index,
13583 pred_index,
13584 predicates: self.options.predicates,
13585 semantics: self.options.semantics,
13586 context: Some(context),
13587 local_int_arg,
13588 member_values: &member_values,
13589 }) {
13590 return Ok(target);
13591 }
13592 if let Some(message) = self
13593 .options
13594 .semantics
13595 .and_then(|semantics| {
13596 self.parser.parser_semantic_ir_predicate_failure_message(
13597 rule_index, pred_index, semantics,
13598 )
13599 })
13600 .or_else(|| {
13601 self.parser.parser_predicate_failure_message(
13602 rule_index,
13603 pred_index,
13604 self.options.predicates,
13605 )
13606 })
13607 {
13608 return Err(self
13609 .parser
13610 .failed_predicate_option_error(rule_index, message));
13611 }
13612 Err(self.parser.failed_predicate_error("semantic predicate"))
13613 }
13614 Transition::Action {
13615 target, rule_index, ..
13616 } => {
13617 self.apply_translated_actions(source_state, rule_index, context);
13618 if let Some(action_index) = self.action_index(source_state) {
13619 let action = self.parser.parser_action_at_current_indexed(
13620 source_state,
13621 rule_index,
13622 action_index,
13623 rule_start_index,
13624 *consumed_eof,
13625 );
13626 let _ = self.parser.parser_action_hook_inner(
13627 action,
13628 Some(context),
13629 None,
13630 local_int_arg,
13631 true,
13632 );
13633 }
13634 Ok(target)
13635 }
13636 Transition::Precedence {
13637 target,
13638 precedence: transition_precedence,
13639 } => {
13640 if transition_precedence >= precedence {
13641 Ok(target)
13642 } else {
13643 Err(self
13644 .parser
13645 .failed_predicate_error(format!("precpred(_ctx, {transition_precedence})")))
13646 }
13647 }
13648 }
13649 }
13650
13651 fn apply_translated_actions(
13652 &mut self,
13653 source_state: usize,
13654 rule_index: usize,
13655 context: &mut ParserRuleContext,
13656 ) {
13657 apply_member_actions(
13658 source_state,
13659 self.options.member_actions,
13660 self.options.semantics,
13661 &mut self.parser.int_members,
13662 );
13663 let return_values = return_values_after_action(
13664 source_state,
13665 rule_index,
13666 self.options.return_actions,
13667 self.options.semantics,
13668 &BTreeMap::new(),
13669 );
13670 for (name, value) in return_values {
13671 context.set_int_return(name, value);
13672 }
13673 }
13674
13675 fn action_index(&self, source_state: usize) -> Option<usize> {
13676 self.action_index_by_state.get(&source_state).copied()
13677 }
13678}
13679
13680fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
13683 if !state.precedence_rule_decision() {
13684 return None;
13685 }
13686 let target_state = atn.state(target)?;
13687 if target_state.kind() == AtnStateKind::LoopEnd {
13688 return None;
13689 }
13690 state.rule_index()
13691}
13692
13693fn next_alt_number(
13700 state: AtnState<'_>,
13701 transition_count: usize,
13702 transition_index: usize,
13703 current_alt_number: usize,
13704 track_alt_numbers: bool,
13705) -> usize {
13706 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
13707 return current_alt_number;
13708 }
13709 if matches!(
13710 state.kind(),
13711 AtnStateKind::Basic
13712 | AtnStateKind::BlockStart
13713 | AtnStateKind::PlusBlockStart
13714 | AtnStateKind::StarBlockStart
13715 | AtnStateKind::StarLoopEntry
13716 ) && !state.precedence_rule_decision()
13717 {
13718 return transition_index + 1;
13719 }
13720 current_alt_number
13721}
13722
13723fn invoking_state_number(state_number: usize) -> isize {
13726 isize::try_from(state_number).unwrap_or(isize::MAX)
13727}
13728
13729const fn packed_i32(value: u32) -> i32 {
13730 i32::from_le_bytes(value.to_le_bytes())
13731}
13732
13733fn direct_precedence(precedence: i32) -> usize {
13734 usize::try_from(precedence.max(0)).unwrap_or_default()
13735}
13736
13737fn token_input_display(token: &impl Token) -> String {
13738 format!("'{}'", token.text().unwrap_or("<EOF>"))
13739}
13740
13741fn display_input_text(text: &str) -> String {
13742 let mut out = String::new();
13743 for ch in text.chars() {
13744 match ch {
13745 '\n' => out.push_str("\\n"),
13746 '\r' => out.push_str("\\r"),
13747 '\t' => out.push_str("\\t"),
13748 other => out.push(other),
13749 }
13750 }
13751 out
13752}
13753
13754fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
13755 let (line, column, offending) = token.map_or((0, 0, None), |token| {
13756 (token.line(), token.column(), Some(token.token_id()))
13757 });
13758 ParserDiagnostic {
13759 line,
13760 column,
13761 message,
13762 offending,
13763 }
13764}
13765
13766fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
13767 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
13768}
13769
13770fn expected_symbols_display_iter(
13771 symbols: impl IntoIterator<Item = i32>,
13772 vocabulary: &Vocabulary,
13773) -> String {
13774 let items = symbols
13775 .into_iter()
13776 .map(|symbol| expected_symbol_display(symbol, vocabulary))
13777 .collect::<Vec<_>>();
13778 if let [single] = items.as_slice() {
13779 return single.clone();
13780 }
13781 format!("{{{}}}", items.join(", "))
13782}
13783
13784fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
13785 if symbol == TOKEN_EOF {
13786 return "<EOF>".to_owned();
13787 }
13788 vocabulary.display_name(symbol)
13789}
13790
13791fn caller_follow_token_info_for_stream<S: TokenSource>(
13792 input: &mut CommonTokenStream<S>,
13793 index: usize,
13794) -> (i32, bool, bool) {
13795 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
13798 input.fill();
13799 }
13800 let token_type = input.token_type_at_index(index);
13801 let visible_channel = input.channel();
13802 let token = input.get(index);
13803 let is_boundary = token
13804 .as_ref()
13805 .and_then(Token::text)
13806 .is_some_and(is_caller_follow_boundary_text);
13807 let is_boundary_gap = token.as_ref().is_some_and(|token| {
13808 token.channel() != visible_channel
13809 || is_caller_follow_boundary_gap_text(token.text_or_empty())
13810 });
13811 (token_type, is_boundary, is_boundary_gap)
13812}
13813
13814fn is_caller_follow_boundary_text(text: &str) -> bool {
13815 text.chars().any(|ch| ch == ';' || ch == '\n')
13816 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
13817}
13818
13819fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
13820 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
13821}
13822
13823fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
13827 let Some(rule_index) = state.rule_index() else {
13828 return false;
13829 };
13830 atn.rule_to_start_state()
13831 .get(rule_index)
13832 .and_then(|state_number| atn.state(state_number))
13833 .is_some_and(AtnState::left_recursive_rule)
13834}
13835
13836fn select_better_top_outcome(
13843 first: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
13844 second: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
13845 arena: &RecognitionArena,
13846) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
13847 match (first, second) {
13848 (Ok(first), Ok(second)) => {
13849 if arena.diagnostics(first.0.diagnostics).next().is_none() {
13850 Ok(first)
13851 } else {
13852 Ok(second)
13853 }
13854 }
13855 (Ok(first), Err(_)) => Ok(first),
13856 (Err(_), Ok(second)) => Ok(second),
13857 (Err(_), Err(second_expected)) => Err(second_expected),
13858 }
13859}
13860
13861fn select_best_fast_outcome(
13867 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
13868 prediction_mode: PredictionMode,
13869 caller_follow: Option<&TokenBitSet>,
13870 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
13871 arena: &RecognitionArena,
13872) -> Option<FastRecognizeOutcome> {
13873 let mut best = None;
13874 let mut best_caller_follow = None;
13875 for outcome in outcomes {
13876 if matches!(
13877 prediction_mode,
13878 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
13879 ) && outcome.diagnostics.is_empty()
13880 && let Some(follow) = caller_follow
13881 {
13882 let (token_type, is_boundary, _) = token_info_at(outcome.index);
13883 if is_boundary && follow.contains(token_type) {
13884 let replace =
13885 best_caller_follow
13886 .as_ref()
13887 .is_none_or(|existing: &FastRecognizeOutcome| {
13888 (outcome.index, outcome.consumed_eof)
13889 < (existing.index, existing.consumed_eof)
13890 });
13891 if replace {
13892 best_caller_follow = Some(outcome);
13893 }
13894 }
13895 }
13896 let Some(existing) = best else {
13897 best = Some(outcome);
13898 continue;
13899 };
13900 let outcome_position = (outcome.index, outcome.consumed_eof);
13901 let best_position = (existing.index, existing.consumed_eof);
13902 let better = match prediction_mode {
13903 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
13904 outcome_position,
13905 outcome.diagnostics,
13906 best_position,
13907 existing.diagnostics,
13908 arena,
13909 ),
13910 PredictionMode::Sll => outcome.index > existing.index,
13911 };
13912 best = Some(if better { outcome } else { existing });
13913 }
13914 let should_use_caller_follow =
13915 best_caller_follow
13916 .as_ref()
13917 .zip(best.as_ref())
13918 .is_some_and(|(candidate, selected)| {
13919 if !selected.diagnostics.is_empty() {
13920 return true;
13921 }
13922 candidate.index < selected.index
13923 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
13924 });
13925 if should_use_caller_follow {
13926 best_caller_follow
13927 } else {
13928 best
13929 }
13930}
13931
13932fn select_best_outcome(
13933 outcomes: impl Iterator<Item = RecognizeOutcome>,
13934 prediction_mode: PredictionMode,
13935 arena: &RecognitionArena,
13936) -> Option<RecognizeOutcome> {
13937 let outcomes = outcomes.collect::<Vec<_>>();
13938 let prefer_first_tie = outcomes
13939 .iter()
13940 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
13941 outcomes.into_iter().reduce(|best, outcome| {
13942 let outcome_position = (outcome.index, outcome.consumed_eof);
13943 let best_position = (best.index, best.consumed_eof);
13944 let better = match prediction_mode {
13945 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
13946 outcome_is_better(
13947 outcome_position,
13948 outcome.diagnostics,
13949 best_position,
13950 best.diagnostics,
13951 arena,
13952 ) || (outcome_position == best_position
13953 && arena.diagnostics_len(outcome.diagnostics)
13954 == arena.diagnostics_len(best.diagnostics)
13955 && arena.diagnostics_recovery_rank(outcome.diagnostics)
13956 == arena.diagnostics_recovery_rank(best.diagnostics)
13957 && (outcome.decisions < best.decisions
13958 || (!prefer_first_tie
13959 && outcome.decisions == best.decisions
13960 && outcome.actions > best.actions)))
13961 }
13962 PredictionMode::Sll => {
13963 outcome_position > best_position
13964 || (outcome_position == best_position
13965 && !prefer_first_tie
13966 && (outcome.decisions < best.decisions
13967 || (outcome.decisions == best.decisions
13968 && outcome_is_better(
13969 outcome_position,
13970 outcome.diagnostics,
13971 best_position,
13972 best.diagnostics,
13973 arena,
13974 ))))
13975 }
13976 };
13977 if better {
13978 return outcome;
13979 }
13980 best
13981 })
13982}
13983
13984fn transition_decision(
13991 atn: &Atn,
13992 state: AtnState<'_>,
13993 transition_count: usize,
13994 transition_index: usize,
13995 predicates: &[(usize, usize, ParserPredicate)],
13996) -> Option<usize> {
13997 if transition_count <= 1 || decision_reaches_unsupported_predicate(atn, state, predicates) {
13998 return None;
13999 }
14000 Some(transition_index)
14001}
14002
14003fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
14009 transition_count > 1
14010 && !matches!(
14011 state.kind(),
14012 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
14013 )
14014}
14015
14016fn record_no_viable_if_ambiguous(
14019 expected: &mut ExpectedTokens,
14020 decision_start_index: Option<usize>,
14021 index: usize,
14022) {
14023 if expected.index == Some(index) && expected.symbols.len() > 1 {
14024 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
14025 expected.record_no_viable(decision_start, index);
14026 }
14027 }
14028}
14029
14030const fn record_predicate_no_viable(
14033 expected: &mut ExpectedTokens,
14034 decision_start_index: Option<usize>,
14035 index: usize,
14036) {
14037 if let Some(decision_start) = decision_start_index {
14038 expected.record_no_viable(decision_start, index);
14039 }
14040}
14041
14042const fn no_viable_decision_start(
14044 decision_start_index: Option<usize>,
14045 index: usize,
14046) -> Option<usize> {
14047 match decision_start_index {
14048 Some(start) if index > start => Some(start),
14049 _ => None,
14050 }
14051}
14052
14053fn restore_expected(
14057 children: &[RecognizeOutcome],
14058 child_start_index: usize,
14059 expected: &mut ExpectedTokens,
14060 snapshot: ExpectedTokens,
14061 preserve_child_expected: bool,
14062) {
14063 if preserve_child_expected {
14064 return;
14065 }
14066 if children
14067 .iter()
14068 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
14069 {
14070 *expected = snapshot;
14071 }
14072}
14073
14074fn decision_reaches_unsupported_predicate(
14077 atn: &Atn,
14078 state: AtnState<'_>,
14079 predicates: &[(usize, usize, ParserPredicate)],
14080) -> bool {
14081 state.transitions().iter().any(|transition| {
14082 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
14083 })
14084}
14085
14086fn transition_reaches_unsupported_predicate(
14088 atn: &Atn,
14089 transition: ParserTransition<'_>,
14090 predicates: &[(usize, usize, ParserPredicate)],
14091 visited: &mut BTreeSet<usize>,
14092) -> bool {
14093 match &transition.data() {
14094 Transition::Predicate {
14095 rule_index,
14096 pred_index,
14097 ..
14098 } => !predicates
14099 .iter()
14100 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
14101 Transition::Epsilon { target }
14102 | Transition::Action { target, .. }
14103 | Transition::Rule { target, .. } => {
14104 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
14105 }
14106 Transition::Precedence { .. }
14107 | Transition::Atom { .. }
14108 | Transition::Range { .. }
14109 | Transition::Set { .. }
14110 | Transition::NotSet { .. }
14111 | Transition::Wildcard { .. } => false,
14112 }
14113}
14114
14115fn state_reaches_unsupported_predicate(
14117 atn: &Atn,
14118 state_number: usize,
14119 predicates: &[(usize, usize, ParserPredicate)],
14120 visited: &mut BTreeSet<usize>,
14121) -> bool {
14122 if !visited.insert(state_number) {
14123 return false;
14124 }
14125 let Some(state) = atn.state(state_number) else {
14126 return false;
14127 };
14128 state.transitions().iter().any(|transition| {
14129 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
14130 })
14131}
14132
14133fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
14135 if let Some(decision) = decision {
14136 outcome.decisions.insert(0, decision);
14137 }
14138}
14139
14140fn outcome_is_better(
14141 outcome_position: (usize, bool),
14142 outcome_diagnostics: DiagnosticSeqId,
14143 best_position: (usize, bool),
14144 best_diagnostics: DiagnosticSeqId,
14145 arena: &RecognitionArena,
14146) -> bool {
14147 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
14148 let best_len = arena.diagnostics_len(best_diagnostics);
14149 outcome_position > best_position
14150 || (outcome_position == best_position
14151 && (outcome_len < best_len
14152 || (outcome_len == best_len
14153 && arena.diagnostics_recovery_rank(outcome_diagnostics)
14154 < arena.diagnostics_recovery_rank(best_diagnostics))))
14155}
14156
14157fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
14158 if outcomes
14159 .iter()
14160 .any(|outcome| outcome.diagnostics.is_empty())
14161 {
14162 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
14163 }
14164}
14165
14166fn discard_recovered_outcomes_if_clean_path_exists(
14167 outcomes: &mut Vec<RecognizeOutcome>,
14168 arena: &RecognitionArena,
14169) {
14170 if outcomes
14171 .iter()
14172 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
14173 {
14174 return;
14175 }
14176 if outcomes
14177 .iter()
14178 .any(|outcome| outcome.diagnostics.is_empty())
14179 {
14180 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
14181 }
14182}
14183
14184fn outcome_has_rule_failure_diagnostic(
14187 outcome: &RecognizeOutcome,
14188 arena: &RecognitionArena,
14189) -> bool {
14190 arena
14191 .diagnostics(outcome.diagnostics)
14192 .any(|diagnostic| diagnostic.message.starts_with("rule "))
14193}
14194
14195fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
14209 if outcomes.len() < 2 {
14210 return;
14211 }
14212 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
14213 outcomes.retain(|outcome| {
14214 seen.insert((
14215 outcome.index,
14216 outcome.consumed_eof,
14217 arena.diagnostics_len(outcome.diagnostics),
14218 arena.diagnostics_recovery_rank(outcome.diagnostics),
14219 ))
14220 });
14221}
14222
14223const FAST_OUTCOME_INLINE_KEYS: usize = 8;
14224const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
14225const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
14226const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
14227
14228#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14229enum FastOutcomeDedupStrategy {
14230 Inline,
14231 Dense,
14232 Sparse,
14233}
14234
14235impl FastOutcomeDedupScratch {
14236 fn prepare_dense(&mut self, word_count: usize) {
14237 while let Some(word_index) = self.touched_dense_words.pop() {
14238 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
14239 }
14240 if self.dense_words.len() < word_count {
14241 self.dense_words.resize(word_count, 0);
14242 }
14243 }
14244}
14245
14246fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
14247 let first_index = outcomes.first()?.index;
14248 let (min_index, max_index) = outcomes[1..].iter().fold(
14249 (first_index, first_index),
14250 |(min_index, max_index), outcome| {
14251 (min_index.min(outcome.index), max_index.max(outcome.index))
14252 },
14253 );
14254 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
14255 let bit_count = index_span.checked_mul(2)?;
14256 let word_count =
14257 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
14258 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
14259 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
14260 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
14261 .then_some((min_index, word_count))
14262}
14263
14264#[cfg(feature = "perf-counters")]
14265fn record_clean_fast_outcome_dedup(
14266 strategy: FastOutcomeDedupStrategy,
14267 input_len: usize,
14268 output_len: usize,
14269 dense_words: usize,
14270) {
14271 let counter = match strategy {
14272 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
14273 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
14274 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
14275 };
14276 perf_counters::inc(
14277 &perf_counters::OUTCOME_DEDUPE_INPUTS,
14278 u64::try_from(input_len).unwrap_or(u64::MAX),
14279 );
14280 perf_counters::inc(
14281 &perf_counters::OUTCOME_DEDUPE_REMOVED,
14282 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
14283 );
14284 perf_counters::inc(counter, 1);
14285 perf_counters::inc(
14286 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
14287 u64::try_from(dense_words).unwrap_or(u64::MAX),
14288 );
14289}
14290
14291fn dedupe_clean_fast_outcomes(
14295 outcomes: &mut Vec<FastRecognizeOutcome>,
14296 scratch: &mut FastOutcomeDedupScratch,
14297) -> FastOutcomeDedupStrategy {
14298 #[cfg(feature = "perf-counters")]
14299 let input_len = outcomes.len();
14300 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
14301 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
14302 let mut inline_len = 0_usize;
14303 outcomes.retain(|outcome| {
14304 let key = (outcome.index, outcome.consumed_eof);
14305 if inline_keys[..inline_len].contains(&key) {
14306 return false;
14307 }
14308 inline_keys[inline_len] = key;
14309 inline_len += 1;
14310 true
14311 });
14312 #[cfg(feature = "perf-counters")]
14313 record_clean_fast_outcome_dedup(
14314 FastOutcomeDedupStrategy::Inline,
14315 input_len,
14316 outcomes.len(),
14317 0,
14318 );
14319 return FastOutcomeDedupStrategy::Inline;
14320 }
14321
14322 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
14323 scratch.prepare_dense(word_count);
14324 outcomes.retain(|outcome| {
14325 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
14326 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
14327 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
14328 let word = &mut scratch.dense_words[word_index];
14329 if *word & bit != 0 {
14330 return false;
14331 }
14332 if *word == 0 {
14333 scratch
14334 .touched_dense_words
14335 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
14336 }
14337 *word |= bit;
14338 true
14339 });
14340 #[cfg(feature = "perf-counters")]
14341 record_clean_fast_outcome_dedup(
14342 FastOutcomeDedupStrategy::Dense,
14343 input_len,
14344 outcomes.len(),
14345 word_count,
14346 );
14347 return FastOutcomeDedupStrategy::Dense;
14348 }
14349
14350 scratch.sparse_keys.clear();
14351 scratch.sparse_keys.reserve(outcomes.len());
14352 outcomes.retain(|outcome| {
14353 scratch
14354 .sparse_keys
14355 .insert((outcome.index, outcome.consumed_eof))
14356 });
14357 #[cfg(feature = "perf-counters")]
14358 record_clean_fast_outcome_dedup(
14359 FastOutcomeDedupStrategy::Sparse,
14360 input_len,
14361 outcomes.len(),
14362 0,
14363 );
14364 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
14365 scratch.sparse_keys = FxHashSet::default();
14366 }
14367 FastOutcomeDedupStrategy::Sparse
14368}
14369
14370fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
14373 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
14374 outcomes
14375 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
14376}
14377
14378fn compare_recognize_outcomes(
14379 left: &RecognizeOutcome,
14380 right: &RecognizeOutcome,
14381 arena: &RecognitionArena,
14382) -> Ordering {
14383 left.index
14384 .cmp(&right.index)
14385 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
14386 .then_with(|| left.alt_number.cmp(&right.alt_number))
14387 .then_with(|| left.member_values.cmp(&right.member_values))
14388 .then_with(|| left.return_values.cmp(&right.return_values))
14389 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
14390 .then_with(|| left.decisions.cmp(&right.decisions))
14391 .then_with(|| left.actions.cmp(&right.actions))
14392 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
14393}
14394
14395impl<S, H> Recognizer for BaseParser<S, H>
14396where
14397 S: TokenSource,
14398 H: SemanticHooks,
14399{
14400 fn data(&self) -> &RecognizerData {
14401 &self.data
14402 }
14403
14404 fn data_mut(&mut self) -> &mut RecognizerData {
14405 &mut self.data
14406 }
14407}
14408
14409impl<S, H> Parser for BaseParser<S, H>
14410where
14411 S: TokenSource,
14412 H: SemanticHooks,
14413{
14414 fn build_parse_trees(&self) -> bool {
14415 self.build_parse_trees
14416 }
14417
14418 fn set_build_parse_trees(&mut self, build: bool) {
14419 self.build_parse_trees = build;
14420 }
14421
14422 fn number_of_syntax_errors(&self) -> usize {
14423 Self::number_of_syntax_errors(self)
14424 }
14425
14426 fn report_diagnostic_errors(&self) -> bool {
14427 self.report_diagnostic_errors
14428 }
14429
14430 fn set_report_diagnostic_errors(&mut self, report: bool) {
14431 self.report_diagnostic_errors = report;
14432 }
14433
14434 fn prediction_mode(&self) -> PredictionMode {
14435 self.prediction_mode
14436 }
14437
14438 fn set_prediction_mode(&mut self, mode: PredictionMode) {
14439 self.prediction_mode = mode;
14440 }
14441
14442 fn max_rule_depth(&self) -> Option<usize> {
14443 self.max_rule_depth
14444 }
14445
14446 fn set_max_rule_depth(&mut self, depth: Option<usize>) {
14447 self.max_rule_depth = depth;
14448 }
14449
14450 fn add_parse_listener(&mut self, listener: Box<dyn ParseListener>) {
14451 self.parse_listeners.push(ParseListenerSlot(listener));
14452 }
14453
14454 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
14455 Self::remove_parse_listeners(self)
14456 }
14457}
14458
14459#[cfg(test)]
14460#[allow(clippy::disallowed_methods)] mod tests {
14462 use super::*;
14463 use crate::atn::parser::{
14464 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
14465 };
14466 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
14467 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
14468 use crate::token_stream::CommonTokenStream;
14469 use crate::tree::{NodeKind, ParseTreeStats};
14470 use crate::vocabulary::Vocabulary;
14471 use std::cell::RefCell;
14472 use std::mem::size_of;
14473 use std::rc::Rc;
14474 use std::sync::{Arc, Mutex};
14475
14476 #[test]
14477 fn fx_hasher_write_matches_typed_methods_for_full_words() {
14478 let value: u64 = 0x0102_0304_0506_0708;
14485 let mut typed = FxHasher::default();
14486 typed.write_u64(value);
14487 let mut bytewise = FxHasher::default();
14488 bytewise.write(&value.to_le_bytes());
14489 assert_eq!(typed.finish(), bytewise.finish());
14490 }
14491
14492 #[derive(Clone, Debug)]
14493 struct TestToken {
14494 spec: TokenSpec,
14495 id: TokenId,
14496 source_name: String,
14497 }
14498
14499 impl TestToken {
14500 fn new(token_type: i32) -> Self {
14501 Self {
14502 spec: TokenSpec::explicit(token_type, ""),
14503 id: TokenId::try_from(0).expect("zero token ID"),
14504 source_name: String::new(),
14505 }
14506 }
14507
14508 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
14509 Self {
14510 spec: TokenSpec::eof(index, index, line, column),
14511 id: TokenId::try_from(0).expect("zero token ID"),
14512 source_name: source_name.to_owned(),
14513 }
14514 }
14515
14516 fn with_text(mut self, text: impl Into<String>) -> Self {
14517 self.spec.text = Some(text.into());
14518 self
14519 }
14520
14521 const fn with_channel(mut self, channel: i32) -> Self {
14522 self.spec.channel = channel;
14523 self
14524 }
14525
14526 fn with_span(mut self, start: usize, stop: usize) -> Self {
14527 self.spec = self.spec.with_span(start, stop);
14528 self
14529 }
14530
14531 fn with_byte_span(mut self, start: usize, stop: usize) -> Self {
14532 self.spec = self.spec.with_byte_span(start, stop);
14533 self
14534 }
14535
14536 const fn with_position(mut self, line: usize, column: usize) -> Self {
14537 self.spec.line = line;
14538 self.spec.column = column;
14539 self
14540 }
14541
14542 fn set_token_index(&mut self, index: isize) {
14543 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
14544 }
14545 }
14546
14547 impl Token for TestToken {
14548 fn token_id(&self) -> TokenId {
14549 self.id
14550 }
14551
14552 fn token_type(&self) -> i32 {
14553 self.spec.token_type
14554 }
14555
14556 fn channel(&self) -> i32 {
14557 self.spec.channel
14558 }
14559
14560 fn start(&self) -> usize {
14561 self.spec.start
14562 }
14563
14564 fn stop(&self) -> usize {
14565 self.spec.stop
14566 }
14567
14568 fn line(&self) -> usize {
14569 self.spec.line
14570 }
14571
14572 fn column(&self) -> usize {
14573 self.spec.column
14574 }
14575
14576 fn text(&self) -> Option<&str> {
14577 self.spec.text.as_deref()
14578 }
14579
14580 fn source_name(&self) -> &str {
14581 &self.source_name
14582 }
14583
14584 fn start_byte(&self) -> Option<usize> {
14585 (self.spec.start_byte != usize::MAX).then_some(self.spec.start_byte)
14586 }
14587
14588 fn stop_byte(&self) -> Option<usize> {
14589 (self.spec.stop_byte != usize::MAX).then_some(self.spec.stop_byte)
14590 }
14591 }
14592
14593 #[derive(Debug)]
14594 struct Source {
14595 tokens: Vec<TestToken>,
14596 index: usize,
14597 }
14598
14599 impl TokenSource for Source {
14600 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
14601 let token = self
14602 .tokens
14603 .get(self.index)
14604 .cloned()
14605 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
14606 self.index += 1;
14607 sink.push(token.spec)
14608 }
14609
14610 fn line(&self) -> usize {
14611 1
14612 }
14613
14614 fn column(&self) -> usize {
14615 self.index
14616 }
14617
14618 fn source_name(&self) -> &'static str {
14619 "parser-test"
14620 }
14621 }
14622
14623 #[derive(Clone, Debug, Eq, PartialEq)]
14624 struct RecordedDiagnostic {
14625 grammar_file_name: String,
14626 offending_text: Option<String>,
14627 line: usize,
14628 column: usize,
14629 span: Option<std::ops::Range<usize>>,
14630 message: String,
14631 error: Option<AntlrError>,
14632 }
14633
14634 #[derive(Clone, Debug)]
14635 struct RecordingErrorListener {
14636 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
14637 }
14638
14639 impl<R> crate::ErrorListener<R> for RecordingErrorListener
14640 where
14641 R: Recognizer + ?Sized,
14642 {
14643 fn syntax_error(&mut self, recognizer: &R, event: &SyntaxErrorEvent<'_>) {
14644 self.diagnostics
14645 .lock()
14646 .expect("recorded diagnostics lock")
14647 .push(RecordedDiagnostic {
14648 grammar_file_name: recognizer.grammar_file_name().to_owned(),
14649 offending_text: event
14650 .offending
14651 .and_then(|token| token.text().map(str::to_owned)),
14652 line: event.line,
14653 column: event.column,
14654 span: event.span.clone(),
14655 message: event.message.to_owned(),
14656 error: event.error.cloned(),
14657 });
14658 }
14659 }
14660
14661 #[derive(Debug)]
14662 struct ReportingSource {
14663 source: Source,
14664 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
14665 }
14666
14667 impl TokenSource for ReportingSource {
14668 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
14669 self.source.next_token(sink)
14670 }
14671
14672 fn line(&self) -> usize {
14673 self.source.line()
14674 }
14675
14676 fn column(&self) -> usize {
14677 self.source.column()
14678 }
14679
14680 fn source_name(&self) -> &str {
14681 self.source.source_name()
14682 }
14683
14684 fn report_error(&self, error: &TokenSourceError) -> bool {
14685 self.diagnostics.borrow_mut().push(error.clone());
14686 true
14687 }
14688 }
14689
14690 fn mini_parser_data() -> RecognizerData {
14691 RecognizerData::new(
14692 "Mini.g4",
14693 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14694 )
14695 .with_rule_names(["s"])
14696 }
14697
14698 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
14699 let data = mini_parser_data();
14700 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
14701 }
14702
14703 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
14704 where
14705 H: SemanticHooks,
14706 {
14707 BaseParser::with_semantic_hooks(
14708 CommonTokenStream::new(Source { tokens, index: 0 }),
14709 mini_parser_data(),
14710 hooks,
14711 )
14712 }
14713
14714 #[test]
14715 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
14716 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
14717 parser.remove_error_listeners();
14718 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14719 parser.add_error_listener(RecordingErrorListener {
14720 diagnostics: Arc::clone(&diagnostics),
14721 });
14722 let parser_diagnostics = [ParserDiagnostic {
14723 line: 1,
14724 column: 2,
14725 message: "missing 'x' at 'y'".to_owned(),
14726 offending: None,
14727 }];
14728 let token_errors = [
14729 TokenSourceError::new(1, 1, "token recognition error at: '@'").with_span(1..2),
14730 TokenSourceError::new(1, 3, "token recognition error at: '#'").with_span(3..4),
14731 ];
14732
14733 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
14734
14735 insta::assert_debug_snapshot!(
14738 "parser_dispatches_recovery_diagnostics_through_registered_listeners",
14739 *diagnostics.lock().expect("recorded diagnostics lock")
14740 );
14741
14742 parser.remove_error_listeners();
14743 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
14744 assert_eq!(
14745 diagnostics.lock().expect("recorded diagnostics lock").len(),
14746 3
14747 );
14748 }
14749
14750 #[test]
14751 fn recovery_diagnostics_expose_the_offending_token_to_listeners() {
14752 let mut parser = mini_parser(vec![
14753 TestToken::new(7)
14754 .with_text("oops")
14755 .with_span(0, 3)
14756 .with_byte_span(0, 4)
14757 .with_position(1, 2),
14758 TestToken::eof("parser-test", 4, 1, 6),
14759 ]);
14760 parser.remove_error_listeners();
14761 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14762 parser.add_error_listener(RecordingErrorListener {
14763 diagnostics: Arc::clone(&diagnostics),
14764 });
14765 let offending = parser.input.lt_id(1);
14766 assert!(offending.is_some(), "current token should be buffered");
14767 let parser_diagnostics = [ParserDiagnostic {
14768 line: 1,
14769 column: 2,
14770 message: "extraneous input 'oops'".to_owned(),
14771 offending,
14772 }];
14773
14774 parser.dispatch_generated_diagnostics(&parser_diagnostics, &[]);
14775
14776 let recorded = diagnostics
14780 .lock()
14781 .expect("recorded diagnostics lock")
14782 .clone();
14783 insta::assert_debug_snapshot!(
14784 "recovery_diagnostics_expose_the_offending_token_to_listeners",
14785 recorded
14786 );
14787 }
14788
14789 #[test]
14790 fn recovery_diagnostics_preserve_unknown_custom_token_span() {
14791 let mut parser = mini_parser(vec![
14792 TestToken::new(7)
14793 .with_text("oops")
14794 .with_span(0, 3)
14795 .with_position(1, 2),
14796 TestToken::eof("parser-test", 4, 1, 6),
14797 ]);
14798 parser.remove_error_listeners();
14799 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14800 parser.add_error_listener(RecordingErrorListener {
14801 diagnostics: Arc::clone(&diagnostics),
14802 });
14803 let offending = parser.input.lt_id(1);
14804 assert!(offending.is_some(), "current token should be buffered");
14805
14806 parser.dispatch_parser_diagnostic(&ParserDiagnostic {
14807 line: 1,
14808 column: 2,
14809 message: "extraneous input 'oops'".to_owned(),
14810 offending,
14811 });
14812
14813 let span = {
14814 let diagnostics = diagnostics.lock().expect("recorded diagnostics lock");
14815 assert_eq!(diagnostics.len(), 1);
14816 diagnostics[0].span.clone()
14817 };
14818 assert_eq!(span, None);
14819 }
14820
14821 #[test]
14822 fn parser_leaves_token_errors_to_source_owned_listeners() {
14823 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
14824 let source = ReportingSource {
14825 source: Source {
14826 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
14827 index: 0,
14828 },
14829 diagnostics: Rc::clone(&source_diagnostics),
14830 };
14831 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
14832 parser.remove_error_listeners();
14833 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
14834 parser.add_error_listener(RecordingErrorListener {
14835 diagnostics: Arc::clone(&parser_diagnostics),
14836 });
14837 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
14838
14839 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
14840
14841 assert_eq!(*source_diagnostics.borrow(), [source_error]);
14842 assert!(
14843 parser_diagnostics
14844 .lock()
14845 .expect("recorded diagnostics lock")
14846 .is_empty()
14847 );
14848 }
14849
14850 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
14851 builder.finish().expect("valid packed parser ATN")
14852 }
14853
14854 fn nested_rule_chain_atn(depth: usize) -> Atn {
14855 nested_rule_graph_atn(depth, false, false)
14856 }
14857
14858 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
14859 assert!(depth > 0);
14860 let mut atn = ParserAtnBuilder::new(2);
14861 let mut starts = Vec::with_capacity(depth);
14862 let mut stops = Vec::with_capacity(depth);
14863 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
14864 for rule_index in 0..depth {
14865 starts.push(
14866 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
14867 .expect("rule start")
14868 .index(),
14869 );
14870 }
14871 for rule_index in 0..depth {
14872 stops.push(
14873 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
14874 .expect("rule stop")
14875 .index(),
14876 );
14877 }
14878 if consuming_follows {
14879 for rule_index in 0..depth - 1 {
14880 follows.push(
14881 atn.add_state(AtnStateKind::Basic, Some(rule_index))
14882 .expect("rule follow")
14883 .index(),
14884 );
14885 }
14886 }
14887 atn.set_rule_to_start_state(starts.clone())
14888 .expect("rule start states");
14889 atn.set_rule_to_stop_state(stops.clone())
14890 .expect("rule stop states");
14891 for rule_index in 0..depth - 1 {
14892 let follow_state = if consuming_follows {
14893 follows[rule_index]
14894 } else {
14895 stops[rule_index]
14896 };
14897 atn.add_transition(
14898 starts[rule_index],
14899 ParserTransitionSpec::Rule {
14900 target: starts[rule_index + 1],
14901 rule_index: rule_index + 1,
14902 follow_state,
14903 precedence: 0,
14904 },
14905 )
14906 .expect("nested rule transition");
14907 if branching {
14908 atn.add_transition(
14909 starts[rule_index],
14910 ParserTransitionSpec::Atom {
14911 target: stops[rule_index],
14912 label: 2,
14913 },
14914 )
14915 .expect("dead branch transition");
14916 }
14917 if consuming_follows {
14918 atn.add_transition(
14919 follow_state,
14920 ParserTransitionSpec::Atom {
14921 target: stops[rule_index],
14922 label: 1,
14923 },
14924 )
14925 .expect("consuming follow transition");
14926 }
14927 }
14928 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
14929 atn.add_transition(
14930 starts[depth - 1],
14931 ParserTransitionSpec::Set {
14932 target: stops[depth - 1],
14933 set: token_set,
14934 },
14935 )
14936 .expect("terminal set transition");
14937 if branching {
14938 atn.add_transition(
14939 starts[depth - 1],
14940 ParserTransitionSpec::Atom {
14941 target: stops[depth - 1],
14942 label: 2,
14943 },
14944 )
14945 .expect("dead leaf branch transition");
14946 }
14947 finish_atn(atn)
14948 }
14949
14950 fn ordinary_star_loop_atn() -> Atn {
14951 let mut atn = ParserAtnBuilder::new(2);
14952 for (state_number, kind, rule_index) in [
14953 (0, AtnStateKind::RuleStart, 0),
14954 (1, AtnStateKind::StarLoopEntry, 0),
14955 (2, AtnStateKind::Basic, 0),
14956 (3, AtnStateKind::StarLoopBack, 0),
14957 (4, AtnStateKind::LoopEnd, 0),
14958 (5, AtnStateKind::Basic, 0),
14959 (6, AtnStateKind::RuleStop, 0),
14960 (7, AtnStateKind::RuleStart, 1),
14961 (8, AtnStateKind::Basic, 1),
14962 (9, AtnStateKind::RuleStop, 1),
14963 ] {
14964 assert_eq!(
14965 atn.add_state(kind, Some(rule_index))
14966 .expect("state")
14967 .index(),
14968 state_number
14969 );
14970 }
14971 atn.set_rule_to_start_state(vec![0, 7])
14972 .expect("rule start states");
14973 atn.set_rule_to_stop_state(vec![6, 9])
14974 .expect("rule stop states");
14975 atn.add_decision_state(1).expect("decision state");
14976 atn.set_loop_back_state(4, 3).expect("loop back state");
14977 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14978 .expect("transition");
14979 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14980 .expect("transition");
14981 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
14982 .expect("transition");
14983 atn.add_transition(
14984 2,
14985 ParserTransitionSpec::Rule {
14986 target: 7,
14987 rule_index: 1,
14988 follow_state: 3,
14989 precedence: 0,
14990 },
14991 )
14992 .expect("transition");
14993 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
14994 .expect("transition");
14995 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14996 .expect("transition");
14997 atn.add_transition(
14998 5,
14999 ParserTransitionSpec::Atom {
15000 target: 6,
15001 label: TOKEN_EOF,
15002 },
15003 )
15004 .expect("transition");
15005 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
15006 .expect("transition");
15007 atn.add_transition(
15008 8,
15009 ParserTransitionSpec::Atom {
15010 target: 9,
15011 label: 1,
15012 },
15013 )
15014 .expect("transition");
15015 finish_atn(atn)
15016 }
15017
15018 fn ambiguous_ordinary_star_loop_atn() -> Atn {
15020 let mut atn = ParserAtnBuilder::new(1);
15021 for (state_number, kind) in [
15022 (0, AtnStateKind::RuleStart),
15023 (1, AtnStateKind::StarLoopEntry),
15024 (2, AtnStateKind::StarBlockStart),
15025 (3, AtnStateKind::Basic),
15026 (4, AtnStateKind::BlockEnd),
15027 (5, AtnStateKind::StarLoopBack),
15028 (6, AtnStateKind::LoopEnd),
15029 (7, AtnStateKind::Basic),
15030 (8, AtnStateKind::RuleStop),
15031 ] {
15032 assert_eq!(
15033 atn.add_state(kind, Some(0)).expect("state").index(),
15034 state_number
15035 );
15036 }
15037 atn.set_rule_to_start_state(vec![0])
15038 .expect("rule start states");
15039 atn.set_rule_to_stop_state(vec![8])
15040 .expect("rule stop states");
15041 atn.set_end_state(2, 4).expect("block end state");
15042 atn.set_loop_back_state(6, 5).expect("loop back state");
15043 atn.add_decision_state(1).expect("decision state");
15044 atn.add_decision_state(2).expect("decision state");
15045 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15046 .expect("transition");
15047 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15048 .expect("transition");
15049 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
15050 .expect("transition");
15051 atn.add_transition(
15052 2,
15053 ParserTransitionSpec::Atom {
15054 target: 4,
15055 label: 1,
15056 },
15057 )
15058 .expect("transition");
15059 atn.add_transition(
15060 2,
15061 ParserTransitionSpec::Atom {
15062 target: 3,
15063 label: 1,
15064 },
15065 )
15066 .expect("transition");
15067 atn.add_transition(
15068 3,
15069 ParserTransitionSpec::Atom {
15070 target: 4,
15071 label: 1,
15072 },
15073 )
15074 .expect("transition");
15075 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15076 .expect("transition");
15077 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
15078 .expect("transition");
15079 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15080 .expect("transition");
15081 atn.add_transition(
15082 7,
15083 ParserTransitionSpec::Atom {
15084 target: 8,
15085 label: TOKEN_EOF,
15086 },
15087 )
15088 .expect("transition");
15089 finish_atn(atn)
15090 }
15091
15092 fn ordinary_plus_loop_atn() -> Atn {
15093 let mut atn = ParserAtnBuilder::new(2);
15094 for (state_number, kind, rule_index) in [
15095 (0, AtnStateKind::RuleStart, 0),
15096 (1, AtnStateKind::Basic, 0),
15097 (2, AtnStateKind::PlusLoopBack, 0),
15098 (3, AtnStateKind::LoopEnd, 0),
15099 (4, AtnStateKind::Basic, 0),
15100 (5, AtnStateKind::RuleStop, 0),
15101 (6, AtnStateKind::RuleStart, 1),
15102 (7, AtnStateKind::Basic, 1),
15103 (8, AtnStateKind::RuleStop, 1),
15104 ] {
15105 assert_eq!(
15106 atn.add_state(kind, Some(rule_index))
15107 .expect("state")
15108 .index(),
15109 state_number
15110 );
15111 }
15112 atn.set_rule_to_start_state(vec![0, 6])
15113 .expect("rule start states");
15114 atn.set_rule_to_stop_state(vec![5, 8])
15115 .expect("rule stop states");
15116 atn.add_decision_state(2).expect("decision state");
15117 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15118 .expect("transition");
15119 atn.add_transition(
15120 1,
15121 ParserTransitionSpec::Rule {
15122 target: 6,
15123 rule_index: 1,
15124 follow_state: 2,
15125 precedence: 0,
15126 },
15127 )
15128 .expect("transition");
15129 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
15130 .expect("transition");
15131 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15132 .expect("transition");
15133 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15134 .expect("transition");
15135 atn.add_transition(
15136 4,
15137 ParserTransitionSpec::Atom {
15138 target: 5,
15139 label: TOKEN_EOF,
15140 },
15141 )
15142 .expect("transition");
15143 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15144 .expect("transition");
15145 atn.add_transition(
15146 7,
15147 ParserTransitionSpec::Atom {
15148 target: 8,
15149 label: 1,
15150 },
15151 )
15152 .expect("transition");
15153 finish_atn(atn)
15154 }
15155
15156 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
15157 let mut tokens = (0..count)
15158 .map(|_| TestToken::new(1).with_text("x"))
15159 .collect::<Vec<_>>();
15160 tokens.push(TestToken::eof("parser-test", count, 1, count));
15161 tokens
15162 }
15163
15164 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
15165 let mut atn = ParserAtnBuilder::new(2);
15166 assert_eq!(
15167 atn.add_state(AtnStateKind::RuleStart, Some(0))
15168 .expect("state")
15169 .index(),
15170 0
15171 );
15172 assert_eq!(
15173 atn.add_state(AtnStateKind::Basic, Some(0))
15174 .expect("state")
15175 .index(),
15176 1
15177 );
15178 assert_eq!(
15179 atn.add_state(AtnStateKind::Basic, Some(0))
15180 .expect("state")
15181 .index(),
15182 2
15183 );
15184 assert_eq!(
15185 atn.add_state(AtnStateKind::RuleStart, Some(1))
15186 .expect("state")
15187 .index(),
15188 3
15189 );
15190 atn.set_left_recursive_rule(3)
15191 .expect("left-recursive rule start");
15192 assert_eq!(
15193 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
15194 .expect("state")
15195 .index(),
15196 4
15197 );
15198 atn.set_precedence_rule_decision(4)
15199 .expect("precedence decision");
15200 assert_eq!(
15201 atn.add_state(AtnStateKind::Basic, Some(1))
15202 .expect("state")
15203 .index(),
15204 5
15205 );
15206 assert_eq!(
15207 atn.add_state(AtnStateKind::Basic, Some(1))
15208 .expect("state")
15209 .index(),
15210 6
15211 );
15212 assert_eq!(
15213 atn.add_state(AtnStateKind::LoopEnd, Some(1))
15214 .expect("state")
15215 .index(),
15216 7
15217 );
15218 assert_eq!(
15219 atn.add_state(AtnStateKind::RuleStop, Some(1))
15220 .expect("state")
15221 .index(),
15222 8
15223 );
15224 assert_eq!(
15225 atn.add_state(AtnStateKind::RuleStop, Some(0))
15226 .expect("state")
15227 .index(),
15228 9
15229 );
15230 atn.set_rule_to_start_state(vec![0, 3])
15231 .expect("rule start states");
15232 atn.set_rule_to_stop_state(vec![9, 8])
15233 .expect("rule stop states");
15234 atn.add_transition(
15235 1,
15236 ParserTransitionSpec::Rule {
15237 target: 3,
15238 rule_index: 1,
15239 follow_state: 2,
15240 precedence: 0,
15241 },
15242 )
15243 .expect("transition");
15244 atn.add_transition(
15245 2,
15246 ParserTransitionSpec::Atom {
15247 target: 9,
15248 label: caller_symbol,
15249 },
15250 )
15251 .expect("transition");
15252 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15253 .expect("transition");
15254 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
15255 .expect("transition");
15256 atn.add_transition(
15257 5,
15258 ParserTransitionSpec::Precedence {
15259 target: 6,
15260 precedence: 1,
15261 },
15262 )
15263 .expect("transition");
15264 atn.add_transition(
15265 6,
15266 ParserTransitionSpec::Atom {
15267 target: 4,
15268 label: 1,
15269 },
15270 )
15271 .expect("transition");
15272 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
15273 .expect("transition");
15274 finish_atn(atn)
15275 }
15276
15277 fn labeled_left_recursive_operator_atn() -> Atn {
15278 let mut atn = ParserAtnBuilder::new(4);
15279 for (state, kind) in [
15280 (0, AtnStateKind::RuleStart),
15281 (1, AtnStateKind::BlockStart),
15282 (2, AtnStateKind::StarLoopEntry),
15283 (3, AtnStateKind::StarBlockStart),
15284 (4, AtnStateKind::Basic),
15285 (5, AtnStateKind::Basic),
15286 (6, AtnStateKind::Basic),
15287 (7, AtnStateKind::StarLoopBack),
15288 (8, AtnStateKind::LoopEnd),
15289 (9, AtnStateKind::RuleStop),
15290 ] {
15291 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15292 }
15293 atn.set_left_recursive_rule(0)
15294 .expect("left-recursive rule start");
15295 atn.set_precedence_rule_decision(2)
15296 .expect("precedence decision");
15297 atn.set_loop_back_state(8, 7).expect("loop-back state");
15298 atn.set_rule_to_start_state(vec![0])
15299 .expect("rule start states");
15300 atn.set_rule_to_stop_state(vec![9])
15301 .expect("rule stop states");
15302 for state in [1, 2, 3] {
15303 atn.add_decision_state(state).expect("decision state");
15304 }
15305 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
15306 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
15307 .expect("epsilon transition");
15308 }
15309 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3), (6, 7, 1)] {
15310 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
15311 .expect("token transition");
15312 }
15313 for (target, precedence) in [(4, 2), (5, 1)] {
15314 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
15315 .expect("operator precedence");
15316 }
15317 finish_atn(atn)
15318 }
15319
15320 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
15321 let mut parser = mini_parser(vec![
15322 TestToken::new(symbol).with_text("lookahead"),
15323 TestToken::eof("parser-test", 1, 1, 1),
15324 ]);
15325 parser.rule_context_stack = vec![
15326 RuleContextFrame {
15327 rule_index: 0,
15328 invoking_state: -1,
15329 },
15330 RuleContextFrame {
15331 rule_index: 1,
15332 invoking_state: 1,
15333 },
15334 ];
15335 parser
15336 }
15337
15338 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
15339 let mut atn = ParserAtnBuilder::new(1);
15343 for (state, kind, rule) in [
15344 (0, AtnStateKind::RuleStart, 0),
15345 (1, AtnStateKind::StarLoopEntry, 0),
15346 (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),
15353 (9, AtnStateKind::RuleStop, 0),
15354 ] {
15355 assert_eq!(
15356 atn.add_state(kind, Some(rule)).expect("state").index(),
15357 state
15358 );
15359 if state == 0 {
15360 atn.set_left_recursive_rule(state)
15361 .expect("left-recursive rule start");
15362 } else if state == 1 {
15363 atn.set_precedence_rule_decision(state)
15364 .expect("precedence decision");
15365 }
15366 }
15367 atn.set_rule_to_start_state(vec![0])
15368 .expect("rule start states");
15369 atn.set_rule_to_stop_state(vec![9])
15370 .expect("rule stop states");
15371 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15372 .expect("ops");
15373 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
15374 .expect("exit");
15375 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15376 .expect("to shift");
15377 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15378 .expect("to rel");
15379 atn.add_transition(
15380 3,
15381 ParserTransitionSpec::Precedence {
15382 target: 4,
15383 precedence: 2,
15384 },
15385 )
15386 .expect("shift prec");
15387 atn.add_transition(
15388 4,
15389 ParserTransitionSpec::Atom {
15390 target: 5,
15391 label: 1,
15392 },
15393 )
15394 .expect("shift first >");
15395 atn.add_transition(
15396 5,
15397 ParserTransitionSpec::Atom {
15398 target: 1,
15399 label: 1,
15400 },
15401 )
15402 .expect("shift second >");
15403 atn.add_transition(
15404 6,
15405 ParserTransitionSpec::Precedence {
15406 target: 7,
15407 precedence: 1,
15408 },
15409 )
15410 .expect("rel prec");
15411 atn.add_transition(
15412 7,
15413 ParserTransitionSpec::Atom {
15414 target: 1,
15415 label: 1,
15416 },
15417 )
15418 .expect("rel >");
15419 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15420 .expect("loop end");
15421 finish_atn(atn)
15422 }
15423
15424 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
15425 let mut atn = ParserAtnBuilder::new(2);
15426 for (state, kind, rule) in [
15427 (0, AtnStateKind::RuleStart, 0),
15428 (1, AtnStateKind::StarLoopEntry, 0),
15429 (2, AtnStateKind::Basic, 0),
15430 (3, AtnStateKind::Basic, 0),
15431 (4, AtnStateKind::Basic, 0),
15432 (5, AtnStateKind::Basic, 0),
15433 (6, AtnStateKind::Basic, 0),
15434 (7, AtnStateKind::Basic, 0),
15435 (8, AtnStateKind::LoopEnd, 0),
15436 (9, AtnStateKind::RuleStop, 0),
15437 (10, AtnStateKind::RuleStart, 1),
15438 (11, AtnStateKind::Basic, 1),
15439 (12, AtnStateKind::RuleStop, 1),
15440 ] {
15441 assert_eq!(
15442 atn.add_state(kind, Some(rule)).expect("state").index(),
15443 state
15444 );
15445 if state == 0 {
15446 atn.set_left_recursive_rule(state)
15447 .expect("left-recursive rule start");
15448 } else if state == 1 {
15449 atn.set_precedence_rule_decision(state)
15450 .expect("precedence decision");
15451 }
15452 }
15453 atn.set_rule_to_start_state(vec![0, 10])
15454 .expect("rule start states");
15455 atn.set_rule_to_stop_state(vec![9, 12])
15456 .expect("rule stop states");
15457 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15458 .expect("ops");
15459 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
15460 .expect("exit");
15461 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15462 .expect("to shift");
15463 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15464 .expect("to relational");
15465 atn.add_transition(
15466 3,
15467 ParserTransitionSpec::Precedence {
15468 target: 4,
15469 precedence: 2,
15470 },
15471 )
15472 .expect("shift precedence");
15473 atn.add_transition(
15474 4,
15475 ParserTransitionSpec::Rule {
15476 target: 10,
15477 rule_index: 1,
15478 follow_state: 5,
15479 precedence: 0,
15480 },
15481 )
15482 .expect("first shift token helper");
15483 atn.add_transition(
15484 5,
15485 ParserTransitionSpec::Atom {
15486 target: 1,
15487 label: 1,
15488 },
15489 )
15490 .expect("second shift token");
15491 atn.add_transition(
15492 6,
15493 ParserTransitionSpec::Precedence {
15494 target: 7,
15495 precedence: 1,
15496 },
15497 )
15498 .expect("relational precedence");
15499 atn.add_transition(
15500 7,
15501 ParserTransitionSpec::Atom {
15502 target: 1,
15503 label: 1,
15504 },
15505 )
15506 .expect("relational token");
15507 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15508 .expect("loop end");
15509 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
15510 .expect("helper entry");
15511 atn.add_transition(
15512 11,
15513 ParserTransitionSpec::Atom {
15514 target: 12,
15515 label: 1,
15516 },
15517 )
15518 .expect("first shift token");
15519 finish_atn(atn)
15520 }
15521
15522 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
15523 let mut atn = ParserAtnBuilder::new(1);
15524 for (state, kind) in [
15525 (0, AtnStateKind::RuleStart),
15526 (1, AtnStateKind::StarLoopEntry),
15527 (2, AtnStateKind::Basic),
15528 (3, AtnStateKind::Basic),
15529 (4, AtnStateKind::Basic),
15530 (5, AtnStateKind::Basic),
15531 (6, AtnStateKind::Basic),
15532 (7, AtnStateKind::Basic),
15533 (8, AtnStateKind::Basic),
15534 (9, AtnStateKind::LoopEnd),
15535 (10, AtnStateKind::RuleStop),
15536 ] {
15537 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15538 if state == 0 {
15539 atn.set_left_recursive_rule(state)
15540 .expect("left-recursive rule start");
15541 } else if state == 1 {
15542 atn.set_precedence_rule_decision(state)
15543 .expect("precedence decision");
15544 }
15545 }
15546 atn.set_rule_to_start_state(vec![0])
15547 .expect("rule start states");
15548 atn.set_rule_to_stop_state(vec![10])
15549 .expect("rule stop states");
15550 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15551 .expect("ops");
15552 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
15553 .expect("exit");
15554 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15555 .expect("to multi-token operator");
15556 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15557 .expect("to predicate operator");
15558 atn.add_transition(
15559 3,
15560 ParserTransitionSpec::Precedence {
15561 target: 4,
15562 precedence: 2,
15563 },
15564 )
15565 .expect("multi-token precedence");
15566 atn.add_transition(
15567 4,
15568 ParserTransitionSpec::Atom {
15569 target: 5,
15570 label: 1,
15571 },
15572 )
15573 .expect("multi-token first");
15574 atn.add_transition(
15575 5,
15576 ParserTransitionSpec::Atom {
15577 target: 1,
15578 label: 1,
15579 },
15580 )
15581 .expect("multi-token second");
15582 atn.add_transition(
15583 6,
15584 ParserTransitionSpec::Precedence {
15585 target: 7,
15586 precedence: 2,
15587 },
15588 )
15589 .expect("predicate precedence");
15590 atn.add_transition(
15591 7,
15592 ParserTransitionSpec::Predicate {
15593 target: 8,
15594 rule_index: 0,
15595 pred_index: 0,
15596 context_dependent: false,
15597 },
15598 )
15599 .expect("operator predicate");
15600 atn.add_transition(
15601 8,
15602 ParserTransitionSpec::Atom {
15603 target: 1,
15604 label: 1,
15605 },
15606 )
15607 .expect("predicate single token");
15608 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15609 .expect("loop end");
15610 finish_atn(atn)
15611 }
15612
15613 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
15614 let mut atn = ParserAtnBuilder::new(2);
15615 for (state, kind, rule) in [
15616 (0, AtnStateKind::RuleStart, 0),
15617 (1, AtnStateKind::StarLoopEntry, 0),
15618 (2, AtnStateKind::Basic, 0),
15619 (3, AtnStateKind::Basic, 0),
15620 (4, AtnStateKind::Basic, 0),
15621 (5, AtnStateKind::LoopEnd, 0),
15622 (6, AtnStateKind::RuleStop, 0),
15623 (7, AtnStateKind::RuleStart, 1),
15624 (8, AtnStateKind::RuleStop, 1),
15625 (9, AtnStateKind::Basic, 1),
15626 ] {
15627 assert_eq!(
15628 atn.add_state(kind, Some(rule)).expect("state").index(),
15629 state
15630 );
15631 if state == 0 {
15632 atn.set_left_recursive_rule(state)
15633 .expect("left-recursive rule start");
15634 } else if state == 1 {
15635 atn.set_precedence_rule_decision(state)
15636 .expect("precedence decision");
15637 }
15638 }
15639 atn.set_rule_to_start_state(vec![0, 7])
15640 .expect("rule start states");
15641 atn.set_rule_to_stop_state(vec![6, 8])
15642 .expect("rule stop states");
15643 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15644 .expect("transition");
15645 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
15646 .expect("transition");
15647 atn.add_transition(
15648 2,
15649 ParserTransitionSpec::Precedence {
15650 target: 3,
15651 precedence: 3,
15652 },
15653 )
15654 .expect("transition");
15655 atn.add_transition(
15656 3,
15657 ParserTransitionSpec::Rule {
15658 target: 7,
15659 rule_index: 1,
15660 follow_state: 4,
15661 precedence: 0,
15662 },
15663 )
15664 .expect("transition");
15665 atn.add_transition(
15666 4,
15667 ParserTransitionSpec::Atom {
15668 target: 1,
15669 label: 1,
15670 },
15671 )
15672 .expect("transition");
15673 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15674 .expect("transition");
15675 atn.add_transition(
15676 7,
15677 ParserTransitionSpec::Precedence {
15678 target: 9,
15679 precedence: 1,
15680 },
15681 )
15682 .expect("transition");
15683 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
15684 .expect("transition");
15685 finish_atn(atn)
15686 }
15687
15688 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
15689 let mut atn = ParserAtnBuilder::new(2);
15690 for (state, kind) in [
15691 (0, AtnStateKind::RuleStart),
15692 (1, AtnStateKind::StarLoopEntry),
15693 (2, AtnStateKind::Basic),
15694 (3, AtnStateKind::Basic),
15695 (4, AtnStateKind::Basic),
15696 (5, AtnStateKind::LoopEnd),
15697 (6, AtnStateKind::RuleStop),
15698 ] {
15699 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15700 if state == 0 {
15701 atn.set_left_recursive_rule(state)
15702 .expect("left-recursive rule start");
15703 } else if state == 1 {
15704 atn.set_precedence_rule_decision(state)
15705 .expect("precedence decision");
15706 }
15707 }
15708 atn.set_rule_to_start_state(vec![0])
15709 .expect("rule start states");
15710 atn.set_rule_to_stop_state(vec![6])
15711 .expect("rule stop states");
15712 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15713 .expect("transition");
15714 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
15715 .expect("transition");
15716 atn.add_transition(
15717 2,
15718 ParserTransitionSpec::Precedence {
15719 target: 3,
15720 precedence: 1,
15721 },
15722 )
15723 .expect("transition");
15724 atn.add_transition(
15725 3,
15726 ParserTransitionSpec::Predicate {
15727 target: 4,
15728 rule_index: 0,
15729 pred_index: 0,
15730 context_dependent: false,
15731 },
15732 )
15733 .expect("transition");
15734 atn.add_transition(
15735 4,
15736 ParserTransitionSpec::Atom {
15737 target: 1,
15738 label: 1,
15739 },
15740 )
15741 .expect("transition");
15742 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15743 .expect("transition");
15744 finish_atn(atn)
15745 }
15746
15747 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
15748 let mut atn = ParserAtnBuilder::new(2);
15749 for (state, kind, rule) in [
15750 (0, AtnStateKind::RuleStart, 0),
15751 (1, AtnStateKind::Basic, 0),
15752 (2, AtnStateKind::Basic, 0),
15753 (3, AtnStateKind::Basic, 0),
15754 (4, AtnStateKind::RuleStop, 0),
15755 (5, AtnStateKind::RuleStart, 1),
15756 (6, AtnStateKind::StarLoopEntry, 1),
15757 (7, AtnStateKind::Basic, 1),
15758 (8, AtnStateKind::Basic, 1),
15759 (9, AtnStateKind::LoopEnd, 1),
15760 (10, AtnStateKind::RuleStop, 1),
15761 (11, AtnStateKind::RuleStart, 2),
15762 (12, AtnStateKind::RuleStop, 2),
15763 ] {
15764 assert_eq!(
15765 atn.add_state(kind, Some(rule)).expect("state").index(),
15766 state
15767 );
15768 if state == 5 {
15769 atn.set_left_recursive_rule(state)
15770 .expect("left-recursive rule start");
15771 } else if state == 6 {
15772 atn.set_precedence_rule_decision(state)
15773 .expect("precedence decision");
15774 }
15775 }
15776 atn.set_rule_to_start_state(vec![0, 5, 11])
15777 .expect("rule start states");
15778 atn.set_rule_to_stop_state(vec![4, 10, 12])
15779 .expect("rule stop states");
15780 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15781 .expect("transition");
15782 atn.add_transition(
15783 1,
15784 ParserTransitionSpec::Rule {
15785 target: 5,
15786 rule_index: 1,
15787 follow_state: 2,
15788 precedence: 0,
15789 },
15790 )
15791 .expect("transition");
15792 atn.add_transition(
15793 2,
15794 ParserTransitionSpec::Rule {
15795 target: 11,
15796 rule_index: 2,
15797 follow_state: 3,
15798 precedence: 0,
15799 },
15800 )
15801 .expect("transition");
15802 atn.add_transition(
15803 3,
15804 ParserTransitionSpec::Atom {
15805 target: 4,
15806 label: caller_symbol,
15807 },
15808 )
15809 .expect("transition");
15810 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15811 .expect("transition");
15812 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
15813 .expect("transition");
15814 atn.add_transition(
15815 7,
15816 ParserTransitionSpec::Precedence {
15817 target: 8,
15818 precedence: 1,
15819 },
15820 )
15821 .expect("transition");
15822 atn.add_transition(
15823 8,
15824 ParserTransitionSpec::Atom {
15825 target: 6,
15826 label: 1,
15827 },
15828 )
15829 .expect("transition");
15830 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15831 .expect("transition");
15832 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
15833 .expect("transition");
15834 finish_atn(atn)
15835 }
15836
15837 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
15838 let mut atn = ParserAtnBuilder::new(2);
15839 for (state, kind, rule) in [
15840 (0, AtnStateKind::RuleStart, 0),
15841 (1, AtnStateKind::Basic, 0),
15842 (2, AtnStateKind::Basic, 0),
15843 (3, AtnStateKind::RuleStop, 0),
15844 (4, AtnStateKind::RuleStart, 1),
15845 (5, AtnStateKind::Basic, 1),
15846 (6, AtnStateKind::Basic, 1),
15847 (7, AtnStateKind::RuleStop, 1),
15848 (8, AtnStateKind::RuleStart, 2),
15849 (9, AtnStateKind::StarLoopEntry, 2),
15850 (10, AtnStateKind::Basic, 2),
15851 (11, AtnStateKind::Basic, 2),
15852 (12, AtnStateKind::LoopEnd, 2),
15853 (13, AtnStateKind::RuleStop, 2),
15854 ] {
15855 assert_eq!(
15856 atn.add_state(kind, Some(rule)).expect("state").index(),
15857 state
15858 );
15859 if state == 8 {
15860 atn.set_left_recursive_rule(state)
15861 .expect("left-recursive rule start");
15862 } else if state == 9 {
15863 atn.set_precedence_rule_decision(state)
15864 .expect("precedence decision");
15865 }
15866 }
15867 atn.set_rule_to_start_state(vec![0, 4, 8])
15868 .expect("rule start states");
15869 atn.set_rule_to_stop_state(vec![3, 7, 13])
15870 .expect("rule stop states");
15871 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15872 .expect("transition");
15873 atn.add_transition(
15874 1,
15875 ParserTransitionSpec::Rule {
15876 target: 4,
15877 rule_index: 1,
15878 follow_state: 2,
15879 precedence: 0,
15880 },
15881 )
15882 .expect("transition");
15883 atn.add_transition(
15884 2,
15885 ParserTransitionSpec::Atom {
15886 target: 3,
15887 label: caller_symbol,
15888 },
15889 )
15890 .expect("transition");
15891 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15892 .expect("transition");
15893 atn.add_transition(
15894 5,
15895 ParserTransitionSpec::Rule {
15896 target: 8,
15897 rule_index: 2,
15898 follow_state: 6,
15899 precedence: 0,
15900 },
15901 )
15902 .expect("transition");
15903 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15904 .expect("transition");
15905 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15906 .expect("transition");
15907 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
15908 .expect("transition");
15909 atn.add_transition(
15910 10,
15911 ParserTransitionSpec::Precedence {
15912 target: 11,
15913 precedence: 1,
15914 },
15915 )
15916 .expect("transition");
15917 atn.add_transition(
15918 11,
15919 ParserTransitionSpec::Atom {
15920 target: 9,
15921 label: 1,
15922 },
15923 )
15924 .expect("transition");
15925 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
15926 .expect("transition");
15927 finish_atn(atn)
15928 }
15929
15930 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
15931 let mut atn = ParserAtnBuilder::new(2);
15932 for (state, kind, rule) in [
15933 (0, AtnStateKind::RuleStart, 0),
15934 (1, AtnStateKind::Basic, 0),
15935 (2, AtnStateKind::Basic, 0),
15936 (3, AtnStateKind::RuleStop, 0),
15937 (4, AtnStateKind::RuleStart, 1),
15938 (5, AtnStateKind::StarLoopEntry, 1),
15939 (6, AtnStateKind::Basic, 1),
15940 (7, AtnStateKind::Basic, 1),
15941 (8, AtnStateKind::Basic, 1),
15942 (9, AtnStateKind::Basic, 1),
15943 (10, AtnStateKind::LoopEnd, 1),
15944 (11, AtnStateKind::RuleStop, 1),
15945 ] {
15946 assert_eq!(
15947 atn.add_state(kind, Some(rule)).expect("state").index(),
15948 state
15949 );
15950 if state == 4 {
15951 atn.set_left_recursive_rule(state)
15952 .expect("left-recursive rule start");
15953 } else if state == 5 {
15954 atn.set_precedence_rule_decision(state)
15955 .expect("precedence decision");
15956 }
15957 }
15958 atn.set_rule_to_start_state(vec![0, 4])
15959 .expect("rule start states");
15960 atn.set_rule_to_stop_state(vec![3, 11])
15961 .expect("rule stop states");
15962 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15963 .expect("transition");
15964 atn.add_transition(
15965 1,
15966 ParserTransitionSpec::Rule {
15967 target: 4,
15968 rule_index: 1,
15969 follow_state: 2,
15970 precedence: 0,
15971 },
15972 )
15973 .expect("transition");
15974 atn.add_transition(
15975 2,
15976 ParserTransitionSpec::Atom {
15977 target: 3,
15978 label: caller_symbol,
15979 },
15980 )
15981 .expect("transition");
15982 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15983 .expect("transition");
15984 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
15985 .expect("transition");
15986 atn.add_transition(
15987 6,
15988 ParserTransitionSpec::Precedence {
15989 target: 7,
15990 precedence: 1,
15991 },
15992 )
15993 .expect("transition");
15994 atn.add_transition(
15995 7,
15996 ParserTransitionSpec::Atom {
15997 target: 8,
15998 label: 1,
15999 },
16000 )
16001 .expect("transition");
16002 atn.add_transition(
16003 8,
16004 ParserTransitionSpec::Rule {
16005 target: 4,
16006 rule_index: 1,
16007 follow_state: 9,
16008 precedence: 2,
16009 },
16010 )
16011 .expect("transition");
16012 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
16013 .expect("transition");
16014 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
16015 .expect("transition");
16016 finish_atn(atn)
16017 }
16018
16019 #[test]
16020 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
16021 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
16022 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
16023
16024 let mut overlapping = parser_inside_left_recursive_callee(1);
16025 assert_eq!(
16026 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
16027 None
16028 );
16029
16030 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
16031 assert_eq!(
16032 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
16033 Some(true)
16034 );
16035
16036 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
16037 assert_eq!(
16038 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
16039 Some(false)
16040 );
16041
16042 assert_eq!(
16043 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
16044 Some(true),
16045 "overlap results must not leak across ATNs"
16046 );
16047 }
16048
16049 #[test]
16050 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
16051 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
16052 let mut parser = mini_parser(vec![
16053 TestToken::new(1).with_text("operator"),
16054 TestToken::eof("parser-test", 1, 1, 1),
16055 ]);
16056 parser.rule_context_stack = vec![RuleContextFrame {
16057 rule_index: 0,
16058 invoking_state: -1,
16059 }];
16060
16061 assert_eq!(
16062 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16063 Some(true)
16064 );
16065 assert_eq!(
16066 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16067 Some(true),
16068 "cached operator lookahead must preserve the nullable prefix return path"
16069 );
16070 assert_eq!(
16071 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16072 Some(true),
16073 "the nullable child must use its rule-call precedence, not the caller precedence"
16074 );
16075 }
16076
16077 #[test]
16078 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
16079 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
16084 let mut parser = mini_parser(vec![
16085 TestToken::new(1).with_text(">"),
16086 TestToken::new(2).with_text("id"),
16087 TestToken::eof("parser-test", 1, 1, 1),
16088 ]);
16089 parser.rule_context_stack = vec![RuleContextFrame {
16090 rule_index: 0,
16091 invoking_state: -1,
16092 }];
16093
16094 assert_eq!(
16095 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16096 Some(true),
16097 "at low precedence relational `>` is a single-token operator"
16098 );
16099 assert_eq!(
16100 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
16101 Some(true),
16102 "relational remains single-token at its own precedence"
16103 );
16104 assert_eq!(
16105 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16106 None,
16107 "at shift precedence, bare `>` must not force enter"
16108 );
16109 }
16110
16111 #[test]
16112 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
16113 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
16114 let mut parser = mini_parser(vec![
16115 TestToken::new(1).with_text(">"),
16116 TestToken::new(2).with_text("id"),
16117 TestToken::eof("parser-test", 1, 1, 1),
16118 ]);
16119 parser.rule_context_stack = vec![RuleContextFrame {
16120 rule_index: 0,
16121 invoking_state: -1,
16122 }];
16123
16124 assert_eq!(
16125 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16126 Some(true),
16127 "the direct relational alternative remains a one-token operator"
16128 );
16129 assert_eq!(
16130 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16131 None,
16132 "a token matched in the helper rule must return to the second shift token"
16133 );
16134 }
16135
16136 #[test]
16137 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
16138 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
16139 let mut parser = mini_parser(vec![
16140 TestToken::new(1).with_text(">"),
16141 TestToken::new(2).with_text("id"),
16142 TestToken::eof("parser-test", 1, 1, 1),
16143 ]);
16144 parser.rule_context_stack = vec![RuleContextFrame {
16145 rule_index: 0,
16146 invoking_state: -1,
16147 }];
16148
16149 assert_eq!(
16150 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16151 None,
16152 "a predicate-gated single-token path must not be hidden by a multi-token path"
16153 );
16154 }
16155
16156 #[test]
16157 fn left_recursive_loop_defers_predicate_guarded_operator() {
16158 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
16159 let mut parser = mini_parser_with_hooks(
16160 vec![
16161 TestToken::new(1).with_text("operator"),
16162 TestToken::eof("parser-test", 1, 1, 1),
16163 ],
16164 RejectingPredicateHooks::default(),
16165 );
16166 parser.rule_context_stack = vec![RuleContextFrame {
16167 rule_index: 0,
16168 invoking_state: -1,
16169 }];
16170
16171 assert_eq!(
16172 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16173 None,
16174 "a false predicate must be evaluated before entering the operator alternative"
16175 );
16176 assert_eq!(
16177 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16178 None,
16179 "cached predicate-dependent lookahead must keep deferring"
16180 );
16181 }
16182
16183 #[test]
16184 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
16185 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
16186 let mut parser = parser_inside_left_recursive_callee(1);
16187
16188 assert_eq!(
16189 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
16190 None
16191 );
16192 assert_eq!(
16193 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
16194 None,
16195 "the cached overlap must preserve the nullable child return path"
16196 );
16197 }
16198
16199 #[test]
16200 fn left_recursive_loop_defers_through_nullable_parent_return() {
16201 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
16202 let mut parser = mini_parser(vec![
16203 TestToken::new(1).with_text("lookahead"),
16204 TestToken::eof("parser-test", 1, 1, 1),
16205 ]);
16206 parser.rule_context_stack = vec![
16207 RuleContextFrame {
16208 rule_index: 0,
16209 invoking_state: -1,
16210 },
16211 RuleContextFrame {
16212 rule_index: 1,
16213 invoking_state: 1,
16214 },
16215 RuleContextFrame {
16216 rule_index: 2,
16217 invoking_state: 5,
16218 },
16219 ];
16220
16221 assert_eq!(
16222 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
16223 None,
16224 "a nullable caller must unwind to its parent's consuming follow path"
16225 );
16226 assert_eq!(
16227 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
16228 None,
16229 "the caller-overlap cache must not retain a false negative"
16230 );
16231 }
16232
16233 #[test]
16234 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
16235 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
16236 let mut parser = mini_parser(vec![
16237 TestToken::new(1).with_text("lookahead"),
16238 TestToken::eof("parser-test", 1, 1, 1),
16239 ]);
16240 parser.rule_context_stack = vec![
16241 RuleContextFrame {
16242 rule_index: 0,
16243 invoking_state: -1,
16244 },
16245 RuleContextFrame {
16246 rule_index: 1,
16247 invoking_state: 1,
16248 },
16249 RuleContextFrame {
16250 rule_index: 1,
16251 invoking_state: 8,
16252 },
16253 ];
16254
16255 assert_eq!(
16256 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
16257 None,
16258 "a recursive operand return must preserve its parent caller context"
16259 );
16260 assert_eq!(
16261 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
16262 None,
16263 "the caller-overlap cache must preserve the loop-boundary return"
16264 );
16265 }
16266
16267 fn token_then_eof_atn() -> Atn {
16268 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16269 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, ]))
16285 .deserialize_parser()
16286 .expect("artificial parser ATN should deserialize")
16287 }
16288
16289 fn epsilon_cycle_atn() -> Atn {
16290 let mut atn = ParserAtnBuilder::new(1);
16291 for (state_number, kind) in [
16292 (0, AtnStateKind::RuleStart),
16293 (1, AtnStateKind::Basic),
16294 (2, AtnStateKind::RuleStop),
16295 ] {
16296 assert_eq!(
16297 atn.add_state(kind, Some(0)).expect("state").index(),
16298 state_number
16299 );
16300 }
16301 atn.set_rule_to_start_state(vec![0])
16302 .expect("rule start states");
16303 atn.set_rule_to_stop_state(vec![2])
16304 .expect("rule stop states");
16305 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16306 .expect("transition");
16307 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
16308 .expect("self-cycle transition");
16309 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16310 .expect("exit transition");
16311 finish_atn(atn)
16312 }
16313
16314 fn committed_non_consuming_cycle_atn() -> Atn {
16315 let mut atn = ParserAtnBuilder::new(1);
16316 for (state_number, kind) in [
16317 (0, AtnStateKind::RuleStart),
16318 (1, AtnStateKind::Basic),
16319 (2, AtnStateKind::RuleStop),
16320 ] {
16321 assert_eq!(
16322 atn.add_state(kind, Some(0)).expect("state").index(),
16323 state_number
16324 );
16325 }
16326 atn.set_rule_to_start_state(vec![0])
16327 .expect("rule start states");
16328 atn.set_rule_to_stop_state(vec![2])
16329 .expect("rule stop states");
16330 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16331 .expect("cycle entry");
16332 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
16333 .expect("self-cycle transition");
16334 finish_atn(atn)
16335 }
16336
16337 fn eof_then_action_atn() -> Atn {
16338 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16339 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, ]))
16355 .deserialize_parser()
16356 .expect("artificial parser ATN should deserialize")
16357 }
16358
16359 fn noop_action_then_token_then_eof_atn() -> Atn {
16360 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16361 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, ]))
16379 .deserialize_parser()
16380 .expect("artificial no-op action ATN should deserialize")
16381 }
16382
16383 fn committed_action_then_predicate_atn() -> Atn {
16384 let mut atn = ParserAtnBuilder::new(1);
16385 for (state_number, kind) in [
16386 (0, AtnStateKind::RuleStart),
16387 (1, AtnStateKind::Basic),
16388 (2, AtnStateKind::Basic),
16389 (3, AtnStateKind::Basic),
16390 (4, AtnStateKind::RuleStop),
16391 ] {
16392 assert_eq!(
16393 atn.add_state(kind, Some(0)).expect("state").index(),
16394 state_number
16395 );
16396 }
16397 atn.set_rule_to_start_state(vec![0])
16398 .expect("rule start states");
16399 atn.set_rule_to_stop_state(vec![4])
16400 .expect("rule stop states");
16401 atn.add_transition(
16402 0,
16403 ParserTransitionSpec::Action {
16404 target: 1,
16405 rule_index: 0,
16406 action_index: None,
16407 context_dependent: false,
16408 },
16409 )
16410 .expect("action transition");
16411 atn.add_transition(
16412 1,
16413 ParserTransitionSpec::Predicate {
16414 target: 2,
16415 rule_index: 0,
16416 pred_index: 0,
16417 context_dependent: false,
16418 },
16419 )
16420 .expect("predicate transition");
16421 atn.add_transition(
16422 2,
16423 ParserTransitionSpec::Atom {
16424 target: 3,
16425 label: 1,
16426 },
16427 )
16428 .expect("token transition");
16429 atn.add_transition(
16430 3,
16431 ParserTransitionSpec::Atom {
16432 target: 4,
16433 label: TOKEN_EOF,
16434 },
16435 )
16436 .expect("EOF transition");
16437 finish_atn(atn)
16438 }
16439
16440 fn parameterized_child_action_eof_atn() -> Atn {
16442 let mut atn = ParserAtnBuilder::new(1);
16443 for (state_number, kind, rule_index) in [
16444 (0, AtnStateKind::RuleStart, 0),
16445 (1, AtnStateKind::Basic, 0),
16446 (2, AtnStateKind::Basic, 0),
16447 (3, AtnStateKind::RuleStop, 0),
16448 (4, AtnStateKind::RuleStart, 1),
16449 (5, AtnStateKind::Basic, 1),
16450 (6, AtnStateKind::RuleStop, 1),
16451 ] {
16452 assert_eq!(
16453 atn.add_state(kind, Some(rule_index))
16454 .expect("state")
16455 .index(),
16456 state_number
16457 );
16458 }
16459 atn.set_rule_to_start_state(vec![0, 4])
16460 .expect("rule start states");
16461 atn.set_rule_to_stop_state(vec![3, 6])
16462 .expect("rule stop states");
16463 atn.add_transition(
16464 0,
16465 ParserTransitionSpec::Rule {
16466 target: 4,
16467 rule_index: 1,
16468 follow_state: 1,
16469 precedence: 0,
16470 },
16471 )
16472 .expect("parameterized child call");
16473 atn.add_transition(
16474 1,
16475 ParserTransitionSpec::Action {
16476 target: 2,
16477 rule_index: 0,
16478 action_index: None,
16479 context_dependent: false,
16480 },
16481 )
16482 .expect("parent action");
16483 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
16484 .expect("parent stop");
16485 atn.add_transition(
16486 4,
16487 ParserTransitionSpec::Action {
16488 target: 5,
16489 rule_index: 1,
16490 action_index: None,
16491 context_dependent: false,
16492 },
16493 )
16494 .expect("child action");
16495 atn.add_transition(
16496 5,
16497 ParserTransitionSpec::Atom {
16498 target: 6,
16499 label: TOKEN_EOF,
16500 },
16501 )
16502 .expect("child EOF");
16503 finish_atn(atn)
16504 }
16505
16506 fn action_then_nested_rule_atn() -> Atn {
16507 let mut atn = ParserAtnBuilder::new(1);
16508 for (state_number, kind, rule_index) in [
16509 (0, AtnStateKind::RuleStart, 0),
16510 (1, AtnStateKind::Basic, 0),
16511 (2, AtnStateKind::Basic, 0),
16512 (3, AtnStateKind::RuleStop, 0),
16513 (4, AtnStateKind::RuleStart, 1),
16514 (5, AtnStateKind::RuleStop, 1),
16515 ] {
16516 assert_eq!(
16517 atn.add_state(kind, Some(rule_index))
16518 .expect("state")
16519 .index(),
16520 state_number
16521 );
16522 }
16523 atn.set_rule_to_start_state(vec![0, 4])
16524 .expect("rule start states");
16525 atn.set_rule_to_stop_state(vec![3, 5])
16526 .expect("rule stop states");
16527 atn.add_transition(
16528 0,
16529 ParserTransitionSpec::Action {
16530 target: 1,
16531 rule_index: 0,
16532 action_index: None,
16533 context_dependent: false,
16534 },
16535 )
16536 .expect("parent action");
16537 atn.add_transition(
16538 1,
16539 ParserTransitionSpec::Rule {
16540 target: 4,
16541 rule_index: 1,
16542 follow_state: 2,
16543 precedence: 0,
16544 },
16545 )
16546 .expect("nested rule call");
16547 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
16548 .expect("parent stop");
16549 atn.add_transition(
16550 4,
16551 ParserTransitionSpec::Atom {
16552 target: 5,
16553 label: TOKEN_EOF,
16554 },
16555 )
16556 .expect("child EOF");
16557 finish_atn(atn)
16558 }
16559
16560 fn losing_alternative_action_atn() -> Atn {
16561 let mut atn = ParserAtnBuilder::new(2);
16562 for (state_number, kind) in [
16563 (0, AtnStateKind::RuleStart),
16564 (1, AtnStateKind::BlockStart),
16565 (2, AtnStateKind::Basic),
16566 (3, AtnStateKind::Basic),
16567 (4, AtnStateKind::BlockEnd),
16568 (5, AtnStateKind::RuleStop),
16569 ] {
16570 assert_eq!(
16571 atn.add_state(kind, Some(0)).expect("state").index(),
16572 state_number
16573 );
16574 }
16575 atn.set_rule_to_start_state(vec![0])
16576 .expect("rule start states");
16577 atn.set_rule_to_stop_state(vec![5])
16578 .expect("rule stop states");
16579 atn.set_end_state(1, 4).expect("block end state");
16580 atn.add_decision_state(1).expect("decision state");
16581 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16582 .expect("entry transition");
16583 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16584 .expect("first alternative");
16585 atn.add_transition(
16586 1,
16587 ParserTransitionSpec::Atom {
16588 target: 4,
16589 label: 2,
16590 },
16591 )
16592 .expect("second alternative");
16593 atn.add_transition(
16594 2,
16595 ParserTransitionSpec::Action {
16596 target: 3,
16597 rule_index: 0,
16598 action_index: None,
16599 context_dependent: false,
16600 },
16601 )
16602 .expect("losing action");
16603 atn.add_transition(
16604 3,
16605 ParserTransitionSpec::Atom {
16606 target: 4,
16607 label: 1,
16608 },
16609 )
16610 .expect("first alternative token");
16611 atn.add_transition(
16612 4,
16613 ParserTransitionSpec::Atom {
16614 target: 5,
16615 label: TOKEN_EOF,
16616 },
16617 )
16618 .expect("EOF transition");
16619 finish_atn(atn)
16620 }
16621
16622 fn committed_action_star_loop_atn() -> Atn {
16623 let mut atn = ParserAtnBuilder::new(1);
16624 for (state_number, kind) in [
16625 (0, AtnStateKind::RuleStart),
16626 (1, AtnStateKind::StarLoopEntry),
16627 (2, AtnStateKind::Basic),
16628 (3, AtnStateKind::Basic),
16629 (4, AtnStateKind::StarLoopBack),
16630 (5, AtnStateKind::LoopEnd),
16631 (6, AtnStateKind::RuleStop),
16632 ] {
16633 assert_eq!(
16634 atn.add_state(kind, Some(0)).expect("state").index(),
16635 state_number
16636 );
16637 }
16638 atn.set_rule_to_start_state(vec![0])
16639 .expect("rule start states");
16640 atn.set_rule_to_stop_state(vec![6])
16641 .expect("rule stop states");
16642 atn.add_decision_state(1).expect("decision state");
16643 atn.set_loop_back_state(5, 4).expect("loop back state");
16644 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16645 .expect("entry transition");
16646 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16647 .expect("loop body");
16648 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
16649 .expect("loop exit");
16650 atn.add_transition(
16651 2,
16652 ParserTransitionSpec::Action {
16653 target: 3,
16654 rule_index: 0,
16655 action_index: None,
16656 context_dependent: false,
16657 },
16658 )
16659 .expect("loop action");
16660 atn.add_transition(
16661 3,
16662 ParserTransitionSpec::Atom {
16663 target: 4,
16664 label: 1,
16665 },
16666 )
16667 .expect("loop token");
16668 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
16669 .expect("loop back");
16670 atn.add_transition(
16671 5,
16672 ParserTransitionSpec::Atom {
16673 target: 6,
16674 label: TOKEN_EOF,
16675 },
16676 )
16677 .expect("EOF transition");
16678 finish_atn(atn)
16679 }
16680
16681 fn committed_action_left_recursive_atn() -> Atn {
16682 let mut atn = ParserAtnBuilder::new(4);
16683 for (state, kind) in [
16684 (0, AtnStateKind::RuleStart),
16685 (1, AtnStateKind::BlockStart),
16686 (2, AtnStateKind::StarLoopEntry),
16687 (3, AtnStateKind::StarBlockStart),
16688 (4, AtnStateKind::Basic),
16689 (5, AtnStateKind::Basic),
16690 (6, AtnStateKind::Basic),
16691 (7, AtnStateKind::StarLoopBack),
16692 (8, AtnStateKind::LoopEnd),
16693 (9, AtnStateKind::RuleStop),
16694 (10, AtnStateKind::Basic),
16695 ] {
16696 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
16697 }
16698 atn.set_left_recursive_rule(0)
16699 .expect("left-recursive rule start");
16700 atn.set_precedence_rule_decision(2)
16701 .expect("precedence decision");
16702 atn.set_loop_back_state(8, 7).expect("loop-back state");
16703 atn.set_rule_to_start_state(vec![0])
16704 .expect("rule start states");
16705 atn.set_rule_to_stop_state(vec![9])
16706 .expect("rule stop states");
16707 for state in [1, 2, 3] {
16708 atn.add_decision_state(state).expect("decision state");
16709 }
16710 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
16711 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
16712 .expect("epsilon transition");
16713 }
16714 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3)] {
16715 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
16716 .expect("token transition");
16717 }
16718 for (target, precedence) in [(4, 2), (5, 1)] {
16719 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
16720 .expect("operator precedence");
16721 }
16722 atn.add_transition(
16723 6,
16724 ParserTransitionSpec::Action {
16725 target: 10,
16726 rule_index: 0,
16727 action_index: None,
16728 context_dependent: false,
16729 },
16730 )
16731 .expect("operator action");
16732 atn.add_transition(
16733 10,
16734 ParserTransitionSpec::Atom {
16735 target: 7,
16736 label: 1,
16737 },
16738 )
16739 .expect("right operand");
16740 finish_atn(atn)
16741 }
16742
16743 fn two_alt_decision_atn() -> Atn {
16744 let mut atn = ParserAtnBuilder::new(2);
16745 assert_eq!(
16746 atn.add_state(AtnStateKind::RuleStart, Some(0))
16747 .expect("state")
16748 .index(),
16749 0
16750 );
16751 assert_eq!(
16752 atn.add_state(AtnStateKind::BlockStart, Some(0))
16753 .expect("state")
16754 .index(),
16755 1
16756 );
16757 assert_eq!(
16758 atn.add_state(AtnStateKind::Basic, Some(0))
16759 .expect("state")
16760 .index(),
16761 2
16762 );
16763 assert_eq!(
16764 atn.add_state(AtnStateKind::Basic, Some(0))
16765 .expect("state")
16766 .index(),
16767 3
16768 );
16769 assert_eq!(
16770 atn.add_state(AtnStateKind::BlockEnd, Some(0))
16771 .expect("state")
16772 .index(),
16773 4
16774 );
16775 assert_eq!(
16776 atn.add_state(AtnStateKind::RuleStop, Some(0))
16777 .expect("state")
16778 .index(),
16779 5
16780 );
16781 atn.set_rule_to_start_state(vec![0])
16782 .expect("rule start states");
16783 atn.set_rule_to_stop_state(vec![5])
16784 .expect("rule stop states");
16785 atn.add_decision_state(1).expect("decision state");
16786 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16787 .expect("transition");
16788 atn.add_transition(
16789 1,
16790 ParserTransitionSpec::Atom {
16791 target: 2,
16792 label: 1,
16793 },
16794 )
16795 .expect("transition");
16796 atn.add_transition(
16797 1,
16798 ParserTransitionSpec::Atom {
16799 target: 3,
16800 label: 2,
16801 },
16802 )
16803 .expect("transition");
16804 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
16805 .expect("transition");
16806 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
16807 .expect("transition");
16808 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
16809 .expect("transition");
16810 finish_atn(atn)
16811 }
16812
16813 fn optional_then_b_eof_atn() -> Atn {
16816 let mut atn = ParserAtnBuilder::new(3);
16817 assert_eq!(
16818 atn.add_state(AtnStateKind::RuleStart, Some(0))
16819 .expect("state")
16820 .index(),
16821 0
16822 );
16823 assert_eq!(
16824 atn.add_state(AtnStateKind::BlockStart, Some(0))
16825 .expect("state")
16826 .index(),
16827 1
16828 );
16829 assert_eq!(
16830 atn.add_state(AtnStateKind::Basic, Some(0))
16831 .expect("state")
16832 .index(),
16833 2
16834 );
16835 assert_eq!(
16836 atn.add_state(AtnStateKind::Basic, Some(0))
16837 .expect("state")
16838 .index(),
16839 3
16840 );
16841 assert_eq!(
16842 atn.add_state(AtnStateKind::Basic, Some(0))
16843 .expect("state")
16844 .index(),
16845 4
16846 );
16847 assert_eq!(
16848 atn.add_state(AtnStateKind::RuleStop, Some(0))
16849 .expect("state")
16850 .index(),
16851 5
16852 );
16853 atn.set_rule_to_start_state(vec![0])
16854 .expect("rule start states");
16855 atn.set_rule_to_stop_state(vec![5])
16856 .expect("rule stop states");
16857 atn.add_decision_state(1).expect("decision state");
16858 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16859 .expect("transition");
16860 atn.add_transition(
16862 1,
16863 ParserTransitionSpec::Atom {
16864 target: 3,
16865 label: 1,
16866 },
16867 )
16868 .expect("transition");
16869 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
16870 .expect("transition");
16871 atn.add_transition(
16873 3,
16874 ParserTransitionSpec::Atom {
16875 target: 4,
16876 label: 2,
16877 },
16878 )
16879 .expect("transition");
16880 atn.add_transition(
16881 4,
16882 ParserTransitionSpec::Atom {
16883 target: 5,
16884 label: TOKEN_EOF,
16885 },
16886 )
16887 .expect("transition");
16888 finish_atn(atn)
16889 }
16890
16891 #[test]
16892 fn sync_decision_deletes_only_a_single_token() {
16893 let atn = optional_then_b_eof_atn();
16901
16902 let mut single = mini_parser(vec![
16903 TestToken::new(3).with_text("c"),
16904 TestToken::new(2).with_text("b"),
16905 TestToken::eof("parser-test", 1, 2, 2),
16906 ]);
16907 single.rule_context_stack = vec![RuleContextFrame {
16908 rule_index: 0,
16909 invoking_state: 0,
16910 }];
16911 let children = single
16912 .sync_decision(&atn, 1, true, false)
16913 .expect("single extraneous token recovers");
16914 assert_eq!(children.len(), 1);
16915 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
16916 assert_eq!(single.number_of_syntax_errors(), 1);
16917 assert_eq!(single.la(1), 2);
16919
16920 let mut double = mini_parser(vec![
16921 TestToken::new(3).with_text("c"),
16922 TestToken::new(3).with_text("c"),
16923 TestToken::new(2).with_text("b"),
16924 TestToken::eof("parser-test", 1, 3, 3),
16925 ]);
16926 double.rule_context_stack = vec![RuleContextFrame {
16927 rule_index: 0,
16928 invoking_state: 0,
16929 }];
16930 let result = double.sync_decision(&atn, 1, true, false);
16931 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
16936 match error {
16937 AntlrError::ParserError { message, .. } => {
16938 assert!(message.starts_with("mismatched input"), "got: {message}");
16939 }
16940 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
16941 }
16942 assert_eq!(double.la(1), 3);
16943 }
16944
16945 fn star_loop_then_eof_atn() -> Atn {
16949 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16950 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,
16951 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,
16952 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,
16953 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
16954 ]))
16955 .deserialize_parser()
16956 .expect("star-loop-then-EOF ATN should deserialize")
16957 }
16958
16959 fn nested_star_rule_atn() -> Atn {
16963 let mut atn = ParserAtnBuilder::new(2);
16964 for (state_number, kind, rule_index) in [
16965 (0, AtnStateKind::RuleStart, 0),
16966 (1, AtnStateKind::Basic, 0),
16967 (2, AtnStateKind::Basic, 0),
16968 (3, AtnStateKind::RuleStop, 0),
16969 (4, AtnStateKind::RuleStart, 1),
16970 (5, AtnStateKind::StarLoopEntry, 1),
16971 (6, AtnStateKind::Basic, 1),
16972 (7, AtnStateKind::StarLoopBack, 1),
16973 (8, AtnStateKind::LoopEnd, 1),
16974 (9, AtnStateKind::RuleStop, 1),
16975 ] {
16976 assert_eq!(
16977 atn.add_state(kind, Some(rule_index))
16978 .expect("state")
16979 .index(),
16980 state_number
16981 );
16982 }
16983 atn.set_rule_to_start_state(vec![0, 4])
16984 .expect("rule start states");
16985 atn.set_rule_to_stop_state(vec![3, 9])
16986 .expect("rule stop states");
16987 atn.add_decision_state(5).expect("decision state");
16988 atn.set_loop_back_state(8, 7).expect("loop back state");
16989 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16990 .expect("transition");
16991 atn.add_transition(
16992 1,
16993 ParserTransitionSpec::Rule {
16994 target: 4,
16995 rule_index: 1,
16996 follow_state: 2,
16997 precedence: 0,
16998 },
16999 )
17000 .expect("transition");
17001 atn.add_transition(
17002 2,
17003 ParserTransitionSpec::Atom {
17004 target: 3,
17005 label: TOKEN_EOF,
17006 },
17007 )
17008 .expect("transition");
17009 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
17010 .expect("transition");
17011 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
17012 .expect("transition");
17013 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 8 })
17014 .expect("transition");
17015 atn.add_transition(
17016 6,
17017 ParserTransitionSpec::Atom {
17018 target: 7,
17019 label: 1,
17020 },
17021 )
17022 .expect("transition");
17023 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 5 })
17024 .expect("transition");
17025 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17026 .expect("transition");
17027 finish_atn(atn)
17028 }
17029
17030 fn plus_loop_with_recovering_body_atn() -> Atn {
17036 let mut atn = ParserAtnBuilder::new(2);
17037 assert_eq!(
17038 atn.add_state(AtnStateKind::RuleStart, Some(0))
17039 .expect("state")
17040 .index(),
17041 0
17042 );
17043 assert_eq!(
17044 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
17045 .expect("state")
17046 .index(),
17047 1
17048 );
17049 assert_eq!(
17050 atn.add_state(AtnStateKind::Basic, Some(0))
17051 .expect("state")
17052 .index(),
17053 2
17054 );
17055 assert_eq!(
17056 atn.add_state(AtnStateKind::BlockEnd, Some(0))
17057 .expect("state")
17058 .index(),
17059 3
17060 );
17061 assert_eq!(
17062 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
17063 .expect("state")
17064 .index(),
17065 4
17066 );
17067 assert_eq!(
17068 atn.add_state(AtnStateKind::LoopEnd, Some(0))
17069 .expect("state")
17070 .index(),
17071 5
17072 );
17073 assert_eq!(
17074 atn.add_state(AtnStateKind::RuleStop, Some(0))
17075 .expect("state")
17076 .index(),
17077 6
17078 );
17079 assert_eq!(
17080 atn.add_state(AtnStateKind::RuleStart, Some(1))
17081 .expect("state")
17082 .index(),
17083 7
17084 );
17085 assert_eq!(
17086 atn.add_state(AtnStateKind::Basic, Some(1))
17087 .expect("state")
17088 .index(),
17089 8
17090 );
17091 assert_eq!(
17092 atn.add_state(AtnStateKind::RuleStop, Some(1))
17093 .expect("state")
17094 .index(),
17095 9
17096 );
17097 atn.set_rule_to_start_state(vec![0, 7])
17098 .expect("rule start states");
17099 atn.set_rule_to_stop_state(vec![6, 9])
17100 .expect("rule stop states");
17101 atn.set_end_state(1, 3).expect("block end state");
17102 atn.set_loop_back_state(5, 4).expect("loop back state");
17103 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17104 .expect("transition");
17105 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17106 .expect("transition");
17107 atn.add_transition(
17108 2,
17109 ParserTransitionSpec::Rule {
17110 target: 7,
17111 rule_index: 1,
17112 follow_state: 3,
17113 precedence: 0,
17114 },
17115 )
17116 .expect("transition");
17117 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
17118 .expect("transition");
17119 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
17120 .expect("transition");
17121 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
17122 .expect("transition");
17123 atn.add_transition(
17124 5,
17125 ParserTransitionSpec::Atom {
17126 target: 6,
17127 label: 2,
17128 },
17129 )
17130 .expect("transition");
17131 atn.add_transition(
17132 7,
17133 ParserTransitionSpec::Atom {
17134 target: 8,
17135 label: 1,
17136 },
17137 )
17138 .expect("transition");
17139 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17140 .expect("transition");
17141 finish_atn(atn)
17142 }
17143
17144 #[test]
17145 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
17146 let atn = plus_loop_with_recovering_body_atn();
17147 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17148
17149 let error = parser
17150 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17151 .expect_err("EOF recovery should report a bounded mismatch");
17152
17153 let AntlrError::ParserError { message, .. } = error else {
17154 panic!("expected ParserError, got {error:?}");
17155 };
17156 insta::assert_snapshot!(message, @"mismatched input '<EOF>' expecting {'x', 2}");
17157 assert_eq!(parser.number_of_syntax_errors(), 1);
17158 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
17159 }
17160
17161 #[test]
17162 fn sync_decision_deletes_token_before_eof_at_loop_back() {
17163 let atn = star_loop_then_eof_atn();
17169 let mut parser = mini_parser(vec![
17170 TestToken::new(2).with_text("c"),
17171 TestToken::eof("parser-test", 1, 1, 1),
17172 ]);
17173 parser.rule_context_stack = vec![RuleContextFrame {
17174 rule_index: 0,
17175 invoking_state: 0,
17176 }];
17177 let children = parser
17178 .sync_decision(&atn, 5, true, false)
17179 .expect("single token before EOF recovers");
17180 assert_eq!(children.len(), 1);
17181 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
17182 assert_eq!(parser.number_of_syntax_errors(), 1);
17183 assert_eq!(
17184 parser.la(1),
17185 TOKEN_EOF,
17186 "EOF is left for the rule's EOF match"
17187 );
17188 }
17189
17190 #[test]
17191 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
17192 let atn = star_loop_then_eof_atn();
17197 let mut parser = mini_parser(vec![
17198 TestToken::new(2).with_text("c"),
17199 TestToken::new(2).with_text("c"),
17200 TestToken::eof("parser-test", 1, 2, 2),
17201 ]);
17202 parser.rule_context_stack = vec![RuleContextFrame {
17203 rule_index: 0,
17204 invoking_state: 0,
17205 }];
17206 let error = parser
17207 .sync_decision(&atn, 5, true, false)
17208 .expect_err("two tokens at the loop entry must not be deleted");
17209 match error {
17210 AntlrError::ParserError { message, .. } => {
17211 assert!(message.starts_with("mismatched input"), "got: {message}");
17212 }
17213 other => panic!("expected mismatched-input ParserError, got {other:?}"),
17214 }
17215 assert_eq!(
17216 parser.la(1),
17217 2,
17218 "nothing consumed; cursor still on first `c`"
17219 );
17220 }
17221
17222 #[test]
17223 fn sync_decision_consumes_until_eof_at_loop_back() {
17224 let atn = star_loop_then_eof_atn();
17230 let mut parser = mini_parser(vec![
17231 TestToken::new(2).with_text("c"),
17232 TestToken::new(2).with_text("c"),
17233 TestToken::eof("parser-test", 1, 2, 2),
17234 ]);
17235 parser.rule_context_stack = vec![RuleContextFrame {
17236 rule_index: 0,
17237 invoking_state: 0,
17238 }];
17239 let children = parser
17240 .sync_decision(&atn, 5, false, true)
17241 .expect("loop-back multi-token deletion recovers onto EOF");
17242 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
17243 assert!(
17244 children
17245 .iter()
17246 .all(|child| parser.node(*child).kind() == NodeKind::Error)
17247 );
17248 assert_eq!(parser.number_of_syntax_errors(), 1);
17249 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
17250 }
17251
17252 #[test]
17253 fn sync_decision_returns_before_recovery_for_nullable_exit() {
17254 let atn = nested_star_rule_atn();
17255 for (current_context_empty, loop_back) in [(true, false), (false, true)] {
17256 let mut parser = mini_parser(vec![
17257 TestToken::new(2).with_text("c"),
17258 TestToken::new(1).with_text("a"),
17259 TestToken::eof("parser-test", 1, 2, 2),
17260 ]);
17261 parser.rule_context_stack = vec![
17262 RuleContextFrame {
17263 rule_index: 0,
17264 invoking_state: 0,
17265 },
17266 RuleContextFrame {
17267 rule_index: 1,
17268 invoking_state: 1,
17269 },
17270 ];
17271
17272 let children = parser
17273 .sync_decision(&atn, 5, current_context_empty, loop_back)
17274 .expect("nullable synchronization is a no-op");
17275
17276 assert!(children.is_empty());
17277 assert_eq!(parser.la(1), 2, "the caller must receive the current token");
17278 assert_eq!(parser.number_of_syntax_errors(), 0);
17279 assert_eq!(
17280 parser
17281 .generated_sync_expected
17282 .as_ref()
17283 .expect("nullable sync preserves expected symbols")
17284 .to_btree_set(),
17285 BTreeSet::from([TOKEN_EOF, 1])
17286 );
17287 }
17288 }
17289
17290 fn predicate_after_token_atn() -> Atn {
17291 let mut atn = ParserAtnBuilder::new(2);
17292 assert_eq!(
17293 atn.add_state(AtnStateKind::RuleStart, Some(0))
17294 .expect("state")
17295 .index(),
17296 0
17297 );
17298 assert_eq!(
17299 atn.add_state(AtnStateKind::Basic, Some(0))
17300 .expect("state")
17301 .index(),
17302 1
17303 );
17304 assert_eq!(
17305 atn.add_state(AtnStateKind::Basic, Some(0))
17306 .expect("state")
17307 .index(),
17308 2
17309 );
17310 assert_eq!(
17311 atn.add_state(AtnStateKind::Basic, Some(0))
17312 .expect("state")
17313 .index(),
17314 3
17315 );
17316 assert_eq!(
17317 atn.add_state(AtnStateKind::RuleStop, Some(0))
17318 .expect("state")
17319 .index(),
17320 4
17321 );
17322 atn.set_rule_to_start_state(vec![0])
17323 .expect("rule start states");
17324 atn.set_rule_to_stop_state(vec![4])
17325 .expect("rule stop states");
17326 atn.add_transition(
17327 0,
17328 ParserTransitionSpec::Atom {
17329 target: 1,
17330 label: 1,
17331 },
17332 )
17333 .expect("transition");
17334 atn.add_transition(
17335 1,
17336 ParserTransitionSpec::Predicate {
17337 target: 2,
17338 rule_index: 0,
17339 pred_index: 0,
17340 context_dependent: false,
17341 },
17342 )
17343 .expect("transition");
17344 atn.add_transition(
17345 2,
17346 ParserTransitionSpec::Atom {
17347 target: 3,
17348 label: 2,
17349 },
17350 )
17351 .expect("transition");
17352 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
17353 .expect("transition");
17354 finish_atn(atn)
17355 }
17356
17357 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
17358 let mut atn = ParserAtnBuilder::new(1);
17359 for (state_number, kind) in [
17360 (0, AtnStateKind::RuleStart),
17361 (1, AtnStateKind::BlockStart),
17362 (2, AtnStateKind::Basic),
17363 (3, AtnStateKind::Basic),
17364 (4, AtnStateKind::Basic),
17365 (5, AtnStateKind::Basic),
17366 (6, AtnStateKind::BlockEnd),
17367 (7, AtnStateKind::RuleStop),
17368 ] {
17369 assert_eq!(
17370 atn.add_state(kind, Some(0)).expect("state").index(),
17371 state_number
17372 );
17373 }
17374 atn.set_rule_to_start_state(vec![0])
17375 .expect("rule start states");
17376 atn.set_rule_to_stop_state(vec![7])
17377 .expect("rule stop states");
17378 atn.add_decision_state(1).expect("decision state");
17379 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17380 .expect("transition");
17381 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17382 .expect("transition");
17383 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17384 .expect("transition");
17385 atn.add_transition(
17386 2,
17387 ParserTransitionSpec::Predicate {
17388 target: 4,
17389 rule_index: 0,
17390 pred_index: pred_indexes[0],
17391 context_dependent: false,
17392 },
17393 )
17394 .expect("transition");
17395 atn.add_transition(
17396 3,
17397 ParserTransitionSpec::Predicate {
17398 target: 5,
17399 rule_index: 0,
17400 pred_index: pred_indexes[1],
17401 context_dependent: false,
17402 },
17403 )
17404 .expect("transition");
17405 atn.add_transition(
17406 4,
17407 ParserTransitionSpec::Atom {
17408 target: 6,
17409 label: 1,
17410 },
17411 )
17412 .expect("transition");
17413 atn.add_transition(
17414 5,
17415 ParserTransitionSpec::Atom {
17416 target: 6,
17417 label: 1,
17418 },
17419 )
17420 .expect("transition");
17421 atn.add_transition(
17422 6,
17423 ParserTransitionSpec::Atom {
17424 target: 7,
17425 label: TOKEN_EOF,
17426 },
17427 )
17428 .expect("transition");
17429 finish_atn(atn)
17430 }
17431
17432 fn semantic_fallback_viability_atn() -> Atn {
17434 let mut atn = ParserAtnBuilder::new(3);
17435 for (state_number, kind) in [
17436 (0, AtnStateKind::RuleStart),
17437 (1, AtnStateKind::BlockStart),
17438 (2, AtnStateKind::Basic),
17439 (3, AtnStateKind::Basic),
17440 (4, AtnStateKind::Basic),
17441 (5, AtnStateKind::Basic),
17442 (6, AtnStateKind::Basic),
17443 (7, AtnStateKind::Basic),
17444 (8, AtnStateKind::Basic),
17445 (9, AtnStateKind::BlockEnd),
17446 (10, AtnStateKind::RuleStop),
17447 ] {
17448 assert_eq!(
17449 atn.add_state(kind, Some(0)).expect("state").index(),
17450 state_number
17451 );
17452 }
17453 atn.set_rule_to_start_state(vec![0])
17454 .expect("rule start states");
17455 atn.set_rule_to_stop_state(vec![10])
17456 .expect("rule stop states");
17457 atn.set_end_state(1, 9).expect("block end state");
17458 atn.add_decision_state(1).expect("decision state");
17459 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17460 .expect("entry transition");
17461 atn.add_transition(
17462 1,
17463 ParserTransitionSpec::Atom {
17464 target: 2,
17465 label: 1,
17466 },
17467 )
17468 .expect("first alternative");
17469 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17470 .expect("second alternative");
17471 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
17472 .expect("third alternative");
17473 atn.add_transition(
17474 2,
17475 ParserTransitionSpec::Atom {
17476 target: 9,
17477 label: 2,
17478 },
17479 )
17480 .expect("first alternative suffix");
17481 for (source, target, pred_index) in [(3, 4, 0), (6, 7, 1)] {
17482 atn.add_transition(
17483 source,
17484 ParserTransitionSpec::Predicate {
17485 target,
17486 rule_index: 0,
17487 pred_index,
17488 context_dependent: false,
17489 },
17490 )
17491 .expect("predicate transition");
17492 }
17493 for (source, target, label) in [(4, 5, 1), (5, 9, 3), (7, 8, 1), (8, 9, 3)] {
17494 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
17495 .expect("predicate alternative token");
17496 }
17497 atn.add_transition(
17498 9,
17499 ParserTransitionSpec::Atom {
17500 target: 10,
17501 label: TOKEN_EOF,
17502 },
17503 )
17504 .expect("EOF transition");
17505 finish_atn(atn)
17506 }
17507
17508 fn rule_call_predicate_decision_atn() -> Atn {
17510 let mut atn = ParserAtnBuilder::new(1);
17511 for (state_number, kind, rule_index) in [
17512 (0, AtnStateKind::RuleStart, 0),
17513 (1, AtnStateKind::BlockStart, 0),
17514 (2, AtnStateKind::Basic, 0),
17515 (3, AtnStateKind::Basic, 0),
17516 (4, AtnStateKind::BlockEnd, 0),
17517 (5, AtnStateKind::RuleStop, 0),
17518 (6, AtnStateKind::RuleStart, 1),
17519 (7, AtnStateKind::Basic, 1),
17520 (8, AtnStateKind::RuleStop, 1),
17521 ] {
17522 assert_eq!(
17523 atn.add_state(kind, Some(rule_index))
17524 .expect("state")
17525 .index(),
17526 state_number
17527 );
17528 }
17529 atn.set_rule_to_start_state(vec![0, 6])
17530 .expect("rule start states");
17531 atn.set_rule_to_stop_state(vec![5, 8])
17532 .expect("rule stop states");
17533 atn.set_end_state(1, 4).expect("block end state");
17534 atn.add_decision_state(1).expect("decision state");
17535 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17536 .expect("entry transition");
17537 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17538 .expect("gated alternative entry");
17539 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17540 .expect("direct alternative entry");
17541 atn.add_transition(
17542 2,
17543 ParserTransitionSpec::Rule {
17544 target: 6,
17545 rule_index: 1,
17546 follow_state: 4,
17547 precedence: 0,
17548 },
17549 )
17550 .expect("gated alternative");
17551 atn.add_transition(
17552 3,
17553 ParserTransitionSpec::Atom {
17554 target: 4,
17555 label: 1,
17556 },
17557 )
17558 .expect("direct alternative");
17559 atn.add_transition(
17560 4,
17561 ParserTransitionSpec::Atom {
17562 target: 5,
17563 label: TOKEN_EOF,
17564 },
17565 )
17566 .expect("EOF transition");
17567 atn.add_transition(
17568 6,
17569 ParserTransitionSpec::Predicate {
17570 target: 7,
17571 rule_index: 1,
17572 pred_index: 0,
17573 context_dependent: false,
17574 },
17575 )
17576 .expect("callee predicate");
17577 atn.add_transition(
17578 7,
17579 ParserTransitionSpec::Atom {
17580 target: 8,
17581 label: 1,
17582 },
17583 )
17584 .expect("callee token");
17585 finish_atn(atn)
17586 }
17587
17588 fn predicate_gated_star_loop_atn() -> Atn {
17590 let mut atn = ParserAtnBuilder::new(2);
17591 for (state_number, kind) in [
17592 (0, AtnStateKind::RuleStart),
17593 (1, AtnStateKind::StarLoopEntry),
17594 (2, AtnStateKind::Basic),
17595 (3, AtnStateKind::Basic),
17596 (4, AtnStateKind::StarLoopBack),
17597 (5, AtnStateKind::LoopEnd),
17598 (6, AtnStateKind::RuleStop),
17599 ] {
17600 assert_eq!(
17601 atn.add_state(kind, Some(0)).expect("state").index(),
17602 state_number
17603 );
17604 }
17605 atn.set_rule_to_start_state(vec![0])
17606 .expect("rule start states");
17607 atn.set_rule_to_stop_state(vec![6])
17608 .expect("rule stop states");
17609 atn.add_decision_state(1).expect("decision state");
17610 atn.set_loop_back_state(5, 4).expect("loop back state");
17611 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17612 .expect("entry transition");
17613 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17614 .expect("loop enter");
17615 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
17616 .expect("loop exit");
17617 atn.add_transition(
17618 2,
17619 ParserTransitionSpec::Predicate {
17620 target: 3,
17621 rule_index: 0,
17622 pred_index: 0,
17623 context_dependent: false,
17624 },
17625 )
17626 .expect("loop predicate");
17627 atn.add_transition(
17628 3,
17629 ParserTransitionSpec::Atom {
17630 target: 4,
17631 label: 1,
17632 },
17633 )
17634 .expect("loop token");
17635 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
17636 .expect("loop back");
17637 atn.add_transition(
17638 5,
17639 ParserTransitionSpec::Atom {
17640 target: 6,
17641 label: TOKEN_EOF,
17642 },
17643 )
17644 .expect("EOF transition");
17645 finish_atn(atn)
17646 }
17647
17648 fn nested_nullable_context_atn() -> Atn {
17649 let mut atn = ParserAtnBuilder::new(1);
17650 for state_number in 0..=20 {
17651 let kind = match state_number {
17652 0 | 10 | 16 => AtnStateKind::RuleStart,
17653 9 | 15 | 20 => AtnStateKind::RuleStop,
17654 _ => AtnStateKind::Basic,
17655 };
17656 let rule_index = match state_number {
17657 0..=9 => 0,
17658 10..=15 => 1,
17659 _ => 2,
17660 };
17661 assert_eq!(
17662 atn.add_state(kind, Some(rule_index))
17663 .expect("state")
17664 .index(),
17665 state_number
17666 );
17667 }
17668 atn.set_rule_to_start_state(vec![0, 10, 16])
17669 .expect("rule start states");
17670 atn.set_rule_to_stop_state(vec![9, 15, 20])
17671 .expect("rule stop states");
17672 atn.add_transition(
17673 1,
17674 ParserTransitionSpec::Rule {
17675 target: 10,
17676 rule_index: 1,
17677 follow_state: 8,
17678 precedence: 0,
17679 },
17680 )
17681 .expect("transition");
17682 atn.add_transition(
17683 8,
17684 ParserTransitionSpec::Atom {
17685 target: 9,
17686 label: 1,
17687 },
17688 )
17689 .expect("transition");
17690 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17691 .expect("transition");
17692 atn.add_transition(
17693 2,
17694 ParserTransitionSpec::Rule {
17695 target: 16,
17696 rule_index: 2,
17697 follow_state: 14,
17698 precedence: 0,
17699 },
17700 )
17701 .expect("transition");
17702 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
17703 .expect("transition");
17704 finish_atn(atn)
17705 }
17706
17707 fn generated_match_recovery_atn() -> Atn {
17708 let mut atn = ParserAtnBuilder::new(2);
17709 assert_eq!(
17710 atn.add_state(AtnStateKind::RuleStart, Some(0))
17711 .expect("state")
17712 .index(),
17713 0
17714 );
17715 assert_eq!(
17716 atn.add_state(AtnStateKind::Basic, Some(0))
17717 .expect("state")
17718 .index(),
17719 1
17720 );
17721 assert_eq!(
17722 atn.add_state(AtnStateKind::Basic, Some(0))
17723 .expect("state")
17724 .index(),
17725 2
17726 );
17727 assert_eq!(
17728 atn.add_state(AtnStateKind::RuleStop, Some(0))
17729 .expect("state")
17730 .index(),
17731 3
17732 );
17733 assert_eq!(
17734 atn.add_state(AtnStateKind::RuleStart, Some(1))
17735 .expect("state")
17736 .index(),
17737 4
17738 );
17739 assert_eq!(
17740 atn.add_state(AtnStateKind::RuleStop, Some(1))
17741 .expect("state")
17742 .index(),
17743 5
17744 );
17745 atn.set_rule_to_start_state(vec![0, 4])
17746 .expect("rule start states");
17747 atn.set_rule_to_stop_state(vec![3, 5])
17748 .expect("rule stop states");
17749 atn.add_transition(
17750 1,
17751 ParserTransitionSpec::Rule {
17752 target: 4,
17753 rule_index: 1,
17754 follow_state: 2,
17755 precedence: 0,
17756 },
17757 )
17758 .expect("transition");
17759 atn.add_transition(
17760 2,
17761 ParserTransitionSpec::Atom {
17762 target: 3,
17763 label: TOKEN_EOF,
17764 },
17765 )
17766 .expect("transition");
17767 finish_atn(atn)
17768 }
17769
17770 fn complement_set_atn() -> Atn {
17771 let mut atn = ParserAtnBuilder::new(1);
17772 assert_eq!(
17773 atn.add_state(AtnStateKind::RuleStart, Some(0))
17774 .expect("state")
17775 .index(),
17776 0
17777 );
17778 assert_eq!(
17779 atn.add_state(AtnStateKind::RuleStop, Some(0))
17780 .expect("state")
17781 .index(),
17782 1
17783 );
17784 atn.set_rule_to_start_state(vec![0])
17785 .expect("rule start states");
17786 atn.set_rule_to_stop_state(vec![1])
17787 .expect("rule stop states");
17788 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
17789 atn.add_transition(
17790 0,
17791 ParserTransitionSpec::NotSet {
17792 target: 1,
17793 set: excluded,
17794 },
17795 )
17796 .expect("transition");
17797 finish_atn(atn)
17798 }
17799
17800 fn wildcard_then_eof_atn() -> Atn {
17803 let mut atn = ParserAtnBuilder::new(1);
17804 assert_eq!(
17805 atn.add_state(AtnStateKind::RuleStart, Some(0))
17806 .expect("state")
17807 .index(),
17808 0
17809 );
17810 assert_eq!(
17811 atn.add_state(AtnStateKind::RuleStop, Some(0))
17812 .expect("state")
17813 .index(),
17814 1
17815 );
17816 assert_eq!(
17817 atn.add_state(AtnStateKind::Basic, Some(0))
17818 .expect("state")
17819 .index(),
17820 2
17821 );
17822 atn.set_rule_to_start_state(vec![0])
17823 .expect("rule start states");
17824 atn.set_rule_to_stop_state(vec![1])
17825 .expect("rule stop states");
17826 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
17827 .expect("transition");
17828 atn.add_transition(
17829 2,
17830 ParserTransitionSpec::Atom {
17831 target: 1,
17832 label: TOKEN_EOF,
17833 },
17834 )
17835 .expect("transition");
17836 finish_atn(atn)
17837 }
17838
17839 #[test]
17840 fn parser_matches_token_and_reports_mismatch() {
17841 let source = Source {
17842 tokens: vec![
17843 TestToken::new(1).with_text("x"),
17844 TestToken::eof("parser-test", 1, 1, 1),
17845 ],
17846 index: 0,
17847 };
17848 let data = RecognizerData::new(
17849 "Mini.g4",
17850 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17851 );
17852 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17853 let matched = parser.match_token(1).expect("token 1 should match");
17854 assert_eq!(parser.node(matched).text(), "x");
17855 assert!(parser.match_token(1).is_err());
17856 }
17857
17858 #[test]
17859 fn parser_matches_token_sets() {
17860 let mut parser = mini_parser(vec![
17861 TestToken::new(1).with_text("x"),
17862 TestToken::eof("parser-test", 1, 1, 1),
17863 ]);
17864
17865 let matched = parser
17866 .match_set(&[(1, 1), (3, 4)])
17867 .expect("token set should match");
17868 assert_eq!(parser.node(matched).text(), "x");
17869 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
17870 }
17871
17872 #[test]
17873 fn generated_rule_api_tracks_state_and_precedence() {
17874 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17875
17876 let context = parser.enter_rule(7, 2);
17877 assert_eq!(context.rule_index(), 2);
17878 assert_eq!(parser.state(), 7);
17879 assert_eq!(
17880 parser.rule_context_stack,
17881 vec![RuleContextFrame {
17882 rule_index: 2,
17883 invoking_state: 7
17884 }]
17885 );
17886
17887 let recursive = parser.enter_recursion_rule(11, 3, 4);
17888 assert_eq!(recursive.rule_index(), 3);
17889 assert!(parser.precpred(4));
17890 assert!(parser.precpred(5));
17891 assert!(!parser.precpred(3));
17892
17893 let next = parser.push_new_recursion_context(13, 3);
17894 assert_eq!(next.invoking_state(), 13);
17895 parser.unroll_recursion_context();
17896 assert_eq!(parser.precedence_stack, vec![0]);
17897 assert_eq!(
17898 parser.rule_context_stack,
17899 vec![RuleContextFrame {
17900 rule_index: 2,
17901 invoking_state: 7
17902 }]
17903 );
17904
17905 parser.exit_rule();
17906 assert!(parser.rule_context_stack.is_empty());
17907 }
17908
17909 #[test]
17910 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
17911 let mut parser = mini_parser(vec![
17912 TestToken::new(1).with_text("x"),
17913 TestToken::eof("parser-test", 1, 1, 1),
17914 ]);
17915 let matched = parser.match_token(1).expect("token should match");
17916 assert_eq!(parser.node(matched).text(), "x");
17917 parser.record_generated_syntax_error();
17918 parser.set_int_member(7, 11);
17919 parser.set_build_parse_trees(false);
17920 parser.set_report_diagnostic_errors(true);
17921 parser.set_prediction_mode(PredictionMode::Sll);
17922 parser.set_bail_on_error(true);
17923 let _context = parser.enter_recursion_rule(9, 0, 4);
17924 parser.pending_invoking_states.push(5);
17925 parser.unknown_predicate_hits.push((0, 1));
17926 parser.unhandled_action_hits.push((0, 2));
17927
17928 parser.reset();
17929
17930 assert_eq!(parser.input.index(), 0);
17931 assert_eq!(parser.la(1), 1);
17932 assert_eq!(parser.state(), -1);
17933 assert_eq!(parser.number_of_syntax_errors(), 0);
17934 assert_eq!(parser.parse_tree_storage().node_count(), 0);
17935 assert!(parser.rule_context_stack.is_empty());
17936 assert!(parser.pending_invoking_states.is_empty());
17937 assert_eq!(parser.precedence_stack, [0]);
17938 assert!(parser.unknown_predicate_hits.is_empty());
17939 assert!(parser.unhandled_action_hits.is_empty());
17940 assert_eq!(parser.int_member(7), Some(11));
17941 assert!(!parser.build_parse_trees());
17942 assert!(parser.report_diagnostic_errors());
17943 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
17944 assert!(parser.bail_on_error());
17945 }
17946
17947 #[test]
17948 fn set_token_stream_replaces_input_and_resets_parser() {
17949 let mut parser = mini_parser(vec![
17950 TestToken::new(1).with_text("old"),
17951 TestToken::eof("parser-test", 1, 1, 1),
17952 ]);
17953 parser.consume();
17954 parser.record_generated_syntax_error();
17955 let replacement = CommonTokenStream::new(Source {
17956 tokens: vec![
17957 TestToken::new(2).with_text("new"),
17958 TestToken::eof("parser-test", 1, 1, 1),
17959 ],
17960 index: 0,
17961 });
17962
17963 parser.set_token_stream(replacement);
17964
17965 assert_eq!(parser.input.index(), 0);
17966 assert_eq!(parser.la(1), 2);
17967 assert_eq!(parser.input.text_all(), "new");
17968 assert_eq!(parser.number_of_syntax_errors(), 0);
17969 }
17970
17971 #[test]
17972 fn active_invocation_states_exclude_the_root_frame() {
17973 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17974
17975 let _root = parser.enter_rule(0, 0);
17976 assert!(parser.active_invocation_states().is_empty());
17977
17978 let marker = parser.push_invoking_state(6);
17979 let _child = parser.enter_rule(2, 1);
17980 parser.discard_invoking_state(marker);
17981 assert_eq!(parser.active_invocation_states(), [6]);
17982
17983 let marker = parser.push_invoking_state(13);
17984 let _grandchild = parser.enter_rule(4, 2);
17985 parser.discard_invoking_state(marker);
17986 assert_eq!(parser.active_invocation_states(), [13, 6]);
17987
17988 parser.exit_rule();
17989 parser.exit_rule();
17990 parser.exit_rule();
17991 }
17992
17993 #[test]
17994 fn parser_predicates_support_token_adjacency() {
17995 let mut parser = mini_parser(vec![
17996 TestToken::new(1).with_text("=").with_span(0, 0),
17997 TestToken::new(1).with_text(">").with_span(1, 1),
17998 TestToken::eof("parser-test", 2, 1, 2),
17999 ]);
18000 parser.consume();
18001 parser.consume();
18002
18003 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
18004
18005 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
18006
18007 let mut parser = mini_parser(vec![
18008 TestToken::new(1).with_text("=").with_span(0, 0),
18009 TestToken::new(1)
18010 .with_text(" ")
18011 .with_channel(HIDDEN_CHANNEL)
18012 .with_span(1, 1),
18013 TestToken::new(1).with_text(">").with_span(2, 2),
18014 TestToken::eof("parser-test", 3, 1, 3),
18015 ]);
18016 parser.consume();
18017 parser.consume();
18018
18019 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
18020 }
18021
18022 #[test]
18023 fn parser_predicates_support_context_child_text_checks() {
18024 let mut parser = mini_parser(vec![
18025 TestToken::new(1).with_text("var"),
18026 TestToken::eof("parser-test", 1, 1, 1),
18027 ]);
18028 let mut context = ParserRuleContext::new(1, 0);
18029 let mut child_context = ParserRuleContext::new(2, 0);
18030 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
18031 parser.tree.add_child(&mut child_context, terminal);
18032 let child = parser.rule_node(child_context);
18033 parser.tree.add_child(&mut context, child);
18034 let predicates = [(
18035 1,
18036 0,
18037 ParserPredicate::ContextChildRuleTextNotEquals {
18038 rule_index: 2,
18039 text: "var",
18040 },
18041 )];
18042
18043 assert!(
18044 !parser.parser_semantic_predicate_matches_with_context_and_local(
18045 &predicates,
18046 1,
18047 0,
18048 &context,
18049 0,
18050 )
18051 );
18052 }
18053
18054 #[test]
18055 fn context_expected_symbols_walks_nullable_parent_contexts() {
18056 let atn = nested_nullable_context_atn();
18057 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18058 parser.rule_context_stack = vec![
18059 RuleContextFrame {
18060 rule_index: 0,
18061 invoking_state: 0,
18062 },
18063 RuleContextFrame {
18064 rule_index: 1,
18065 invoking_state: 1,
18066 },
18067 RuleContextFrame {
18068 rule_index: 2,
18069 invoking_state: 2,
18070 },
18071 ];
18072
18073 let expected = parser.context_expected_symbols(&atn);
18074
18075 assert!(expected.contains(&1));
18076 assert!(expected.contains(&TOKEN_EOF));
18077 }
18078
18079 #[test]
18080 fn prediction_context_return_states_track_rule_stack_changes() {
18081 let atn = nested_nullable_context_atn();
18082 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18083 parser.rule_context_stack = vec![
18084 RuleContextFrame {
18085 rule_index: 0,
18086 invoking_state: 0,
18087 },
18088 RuleContextFrame {
18089 rule_index: 1,
18090 invoking_state: 1,
18091 },
18092 RuleContextFrame {
18093 rule_index: 2,
18094 invoking_state: 2,
18095 },
18096 ];
18097
18098 let initial_version = parser.rule_context_version();
18099 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
18100 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
18101 assert_eq!(first, second);
18102 assert_eq!(parser.rule_context_version(), initial_version);
18103
18104 parser.exit_rule();
18105 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
18106 assert_ne!(first, after_pop);
18107 assert_ne!(parser.rule_context_version(), initial_version);
18108 }
18109
18110 #[test]
18111 fn generated_match_token_recovers_missing_token_from_context_follow() {
18112 let atn = generated_match_recovery_atn();
18113 let data = RecognizerData::new(
18114 "Mini.g4",
18115 Vocabulary::new(
18116 [None, Some("'X'"), Some("'Y'")],
18117 [None, Some("X"), Some("Y")],
18118 [None::<&str>, None, None],
18119 ),
18120 );
18121 let mut parser = BaseParser::new(
18122 CommonTokenStream::new(Source {
18123 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
18124 index: 0,
18125 }),
18126 data,
18127 );
18128 parser.rule_context_stack = vec![
18129 RuleContextFrame {
18130 rule_index: 0,
18131 invoking_state: 0,
18132 },
18133 RuleContextFrame {
18134 rule_index: 1,
18135 invoking_state: 1,
18136 },
18137 ];
18138 assert_eq!(parser.number_of_syntax_errors(), 0);
18139
18140 let node = parser
18141 .match_token_recovering(2, 5, &atn)
18142 .expect("generated match should insert missing token");
18143
18144 assert_eq!(node.children().len(), 1);
18145 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
18146 assert_eq!(
18147 node.clone()
18148 .into_child_iter()
18149 .map(|child| parser.node(child).text())
18150 .collect::<Vec<_>>(),
18151 ["<missing 'Y'>"]
18152 );
18153 assert!(!node.consumed_eof());
18156 assert_eq!(parser.la(1), TOKEN_EOF);
18157 assert_eq!(parser.number_of_syntax_errors(), 1);
18158 assert_eq!(
18159 parser.generated_parser_diagnostics,
18160 [ParserDiagnostic {
18161 line: 1,
18162 column: 3,
18163 message: "missing 'Y' at '<EOF>'".to_owned(),
18164 offending: parser.input.lt_id(1),
18165 }]
18166 );
18167 }
18168
18169 #[test]
18170 fn generated_match_token_counts_single_token_deletion_recovery() {
18171 let atn = generated_match_recovery_atn();
18172 let data = RecognizerData::new(
18173 "Mini.g4",
18174 Vocabulary::new(
18175 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
18176 [None, Some("X"), Some("Y"), Some("Z")],
18177 [None::<&str>, None, None, None],
18178 ),
18179 );
18180 let mut parser = BaseParser::new(
18181 CommonTokenStream::new(Source {
18182 tokens: vec![
18183 TestToken::new(3).with_text("z"),
18184 TestToken::new(2).with_text("y"),
18185 TestToken::eof("parser-test", 3, 1, 3),
18186 ],
18187 index: 0,
18188 }),
18189 data,
18190 );
18191
18192 let node = parser
18193 .match_token_recovering(2, 5, &atn)
18194 .expect("generated match should delete the extraneous token");
18195
18196 assert_eq!(node.children().len(), 2);
18197 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
18198 assert_eq!(parser.node(node.children()[0]).text(), "z");
18199 assert_eq!(parser.node(node.children()[1]).text(), "y");
18200 assert_eq!(
18201 node.into_child_iter()
18202 .map(|child| parser.node(child).text())
18203 .collect::<Vec<_>>(),
18204 ["z", "y"]
18205 );
18206 assert_eq!(parser.number_of_syntax_errors(), 1);
18207 }
18208
18209 #[test]
18210 fn generated_match_token_iterates_single_success_without_a_children_vec() {
18211 let atn = generated_match_recovery_atn();
18212 let data = RecognizerData::new(
18213 "Mini.g4",
18214 Vocabulary::new(
18215 [None, Some("'X'"), Some("'Y'")],
18216 [None, Some("X"), Some("Y")],
18217 [None::<&str>, None, None],
18218 ),
18219 );
18220 let mut parser = BaseParser::new(
18221 CommonTokenStream::new(Source {
18222 tokens: vec![
18223 TestToken::new(2).with_text("y"),
18224 TestToken::eof("parser-test", 1, 1, 1),
18225 ],
18226 index: 0,
18227 }),
18228 data,
18229 );
18230
18231 let node = parser
18232 .match_token_recovering(2, 5, &atn)
18233 .expect("generated match should consume the expected token");
18234
18235 assert_eq!(
18236 node.into_child_iter()
18237 .map(|child| parser.node(child).text())
18238 .collect::<Vec<_>>(),
18239 ["y"]
18240 );
18241 assert_eq!(parser.number_of_syntax_errors(), 0);
18242 }
18243
18244 #[test]
18245 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
18246 let atn = generated_match_recovery_atn();
18247 let data = RecognizerData::new(
18248 "Mini.g4",
18249 Vocabulary::new(
18250 [None, Some("'X'"), Some("'Y'")],
18251 [None, Some("X"), Some("Y")],
18252 [None::<&str>, None, None],
18253 ),
18254 );
18255 let mut parser = BaseParser::new(
18256 CommonTokenStream::new(Source {
18257 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
18258 index: 0,
18259 }),
18260 data,
18261 );
18262 parser.rule_context_stack = vec![
18263 RuleContextFrame {
18264 rule_index: 0,
18265 invoking_state: 0,
18266 },
18267 RuleContextFrame {
18268 rule_index: 1,
18269 invoking_state: 1,
18270 },
18271 ];
18272 let marker = parser.generated_diagnostics_checkpoint();
18273
18274 let _ = parser
18275 .match_token_recovering(2, 5, &atn)
18276 .expect("generated match should insert missing token");
18277 assert_eq!(parser.number_of_syntax_errors(), 1);
18278
18279 parser.restore_generated_diagnostics(marker);
18280
18281 assert_eq!(parser.number_of_syntax_errors(), 0);
18282 assert!(parser.generated_parser_diagnostics.is_empty());
18283 }
18284
18285 #[test]
18286 fn generated_prediction_diagnostics_use_adaptive_context() {
18287 let atn = two_alt_decision_atn();
18288 let data = RecognizerData::new(
18289 "Mini.g4",
18290 Vocabulary::new(
18291 [None, Some("'x'"), Some("'y'")],
18292 [None, Some("X"), Some("Y")],
18293 [None::<&str>, None, None],
18294 ),
18295 )
18296 .with_rule_names(["s"]);
18297 let mut parser = BaseParser::new(
18298 CommonTokenStream::new(Source {
18299 tokens: vec![
18300 TestToken::new(1)
18301 .with_text("x")
18302 .with_position(1, 0)
18303 .with_span(0, 0),
18304 TestToken::new(2)
18305 .with_text("y")
18306 .with_position(1, 2)
18307 .with_span(1, 1),
18308 TestToken::eof("parser-test", 2, 1, 3),
18309 ],
18310 index: 0,
18311 }),
18312 data,
18313 );
18314 parser.set_report_diagnostic_errors(true);
18315
18316 parser.record_generated_prediction_diagnostic(
18317 &atn,
18318 1,
18319 &ParserAtnPrediction {
18320 alt: 1,
18321 requires_full_context: true,
18322 has_semantic_context: false,
18323 diagnostic: Some(ParserAtnPredictionDiagnostic {
18324 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
18325 start_index: 0,
18326 sll_stop_index: 1,
18327 ll_stop_index: 0,
18328 conflicting_alts: vec![1, 2],
18329 exact: false,
18330 }),
18331 },
18332 );
18333 parser.record_generated_prediction_diagnostic(
18338 &atn,
18339 1,
18340 &ParserAtnPrediction {
18341 alt: 1,
18342 requires_full_context: true,
18343 has_semantic_context: false,
18344 diagnostic: Some(ParserAtnPredictionDiagnostic {
18345 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
18346 start_index: 0,
18347 sll_stop_index: 1,
18348 ll_stop_index: 1,
18349 conflicting_alts: vec![1, 2],
18350 exact: false,
18351 }),
18352 },
18353 );
18354
18355 insta::assert_debug_snapshot!(
18358 "generated_prediction_diagnostics_use_adaptive_context",
18359 parser.generated_parser_diagnostics
18360 );
18361 }
18362
18363 #[test]
18364 fn generated_match_not_set_recovers_empty_complement_at_eof() {
18365 let atn = complement_set_atn();
18366 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18367 parser.rule_context_stack = vec![RuleContextFrame {
18368 rule_index: 0,
18369 invoking_state: 0,
18370 }];
18371
18372 let node = parser
18373 .match_not_token_set_recovering(
18374 atn.token_set(0).expect("excluded token set"),
18375 1,
18376 1,
18377 1,
18378 &atn,
18379 )
18380 .expect("empty complement should recover at EOF");
18381
18382 assert_eq!(node.children().len(), 1);
18383 assert!(!node.consumed_eof());
18386 assert_eq!(parser.la(1), TOKEN_EOF);
18387 assert_eq!(
18388 parser.generated_parser_diagnostics,
18389 [ParserDiagnostic {
18390 line: 1,
18391 column: 1,
18392 message: "missing {} at '<EOF>'".to_owned(),
18393 offending: parser.input.lt_id(1),
18394 }]
18395 );
18396 }
18397
18398 #[test]
18399 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
18400 let atn = wildcard_then_eof_atn();
18406 let data = RecognizerData::new(
18407 "Mini.g4",
18408 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18409 );
18410 let mut parser = BaseParser::new(
18411 CommonTokenStream::new(Source {
18412 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
18413 index: 0,
18414 }),
18415 data,
18416 );
18417 parser.rule_context_stack = vec![RuleContextFrame {
18418 rule_index: 0,
18419 invoking_state: 0,
18420 }];
18421
18422 let node = parser
18423 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
18424 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
18425
18426 assert_eq!(node.children().len(), 1);
18428 assert!(!node.consumed_eof());
18429 assert!(
18430 parser
18431 .node(node.children()[0])
18432 .text()
18433 .starts_with("<missing")
18434 );
18435 assert_eq!(parser.la(1), TOKEN_EOF);
18436 assert_eq!(
18437 parser.generated_parser_diagnostics,
18438 [ParserDiagnostic {
18439 line: 1,
18440 column: 1,
18441 message: "missing 'x' at '<EOF>'".to_owned(),
18442 offending: parser.input.lt_id(1),
18443 }]
18444 );
18445 }
18446
18447 #[test]
18448 fn generated_rule_recovery_consumes_to_parent_follow() {
18449 let atn = generated_match_recovery_atn();
18450 let data = RecognizerData::new(
18451 "Mini.g4",
18452 Vocabulary::new(
18453 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
18454 [None, Some("X"), Some("Y"), Some("Z")],
18455 [None::<&str>, None, None, None],
18456 ),
18457 );
18458 let mut parser = BaseParser::new(
18459 CommonTokenStream::new(Source {
18460 tokens: vec![
18461 TestToken::new(3).with_text("z"),
18462 TestToken::eof("parser-test", 1, 1, 1),
18463 ],
18464 index: 0,
18465 }),
18466 data,
18467 );
18468 let _parent = parser.enter_rule(0, 0);
18469 let marker = parser.push_invoking_state(1);
18470 let mut child = parser.enter_rule(4, 1);
18471 parser.discard_invoking_state(marker);
18472
18473 let offending = parser.input.lt_id(1);
18476 assert!(offending.is_some(), "the 'z' token should be buffered");
18477 parser.recover_generated_rule(
18478 &mut child,
18479 &atn,
18480 AntlrError::ParserError {
18481 line: 1,
18482 column: 0,
18483 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
18484 offending,
18485 },
18486 );
18487 let tree = parser.finish_rule(child, false);
18488
18489 assert_eq!(parser.la(1), TOKEN_EOF);
18490 assert_eq!(
18491 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
18492 "(a z)"
18493 );
18494 assert_eq!(parser.number_of_syntax_errors(), 1);
18495 assert_eq!(
18496 parser.generated_parser_diagnostics,
18497 [ParserDiagnostic {
18498 line: 1,
18499 column: 0,
18500 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
18501 offending,
18502 }]
18503 );
18504 parser.exit_rule();
18505 }
18506
18507 #[test]
18508 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
18509 let atn = nested_nullable_context_atn();
18510 let mut parser = mini_parser(vec![
18511 TestToken::new(1).with_text("x"),
18512 TestToken::eof("parser-test", 1, 1, 1),
18513 ]);
18514 parser.rule_context_stack = vec![
18515 RuleContextFrame {
18516 rule_index: 0,
18517 invoking_state: 0,
18518 },
18519 RuleContextFrame {
18520 rule_index: 1,
18521 invoking_state: 1,
18522 },
18523 RuleContextFrame {
18524 rule_index: 2,
18525 invoking_state: 2,
18526 },
18527 ];
18528 parser.set_state(20);
18529 let mut context = ParserRuleContext::new(2, 2);
18530
18531 parser.recover_generated_rule(
18532 &mut context,
18533 &atn,
18534 AntlrError::NoViableAlternative {
18535 input: "'x'".to_owned(),
18536 },
18537 );
18538 assert_eq!(parser.input.index(), 0);
18539
18540 parser.set_state(21);
18541 parser.recover_generated_rule(
18542 &mut context,
18543 &atn,
18544 AntlrError::NoViableAlternative {
18545 input: "'x'".to_owned(),
18546 },
18547 );
18548 assert_eq!(parser.input.index(), 0);
18549 assert_eq!(
18550 parser.generated_recovery_error_states,
18551 BTreeSet::from([20, 21])
18552 );
18553
18554 parser.set_state(20);
18555 parser.recover_generated_rule(
18556 &mut context,
18557 &atn,
18558 AntlrError::NoViableAlternative {
18559 input: "'x'".to_owned(),
18560 },
18561 );
18562
18563 assert_eq!(parser.input.index(), 1);
18564 assert_eq!(parser.la(1), TOKEN_EOF);
18565 assert!(context.has_matched_child());
18566 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
18567
18568 parser.match_eof().expect("EOF should match");
18569 assert_eq!(parser.generated_recovery_error_index, None);
18570 assert!(parser.generated_recovery_error_states.is_empty());
18571 }
18572
18573 #[test]
18574 fn greedy_ll1_alt_handles_nullable_loop_exit() {
18575 let mut body_symbols = TokenBitSet::default();
18576 body_symbols.insert(1);
18577 let entry = DecisionLookahead {
18578 transitions: vec![
18579 TransitionLookSet {
18580 symbols: body_symbols,
18581 nullable: false,
18582 },
18583 TransitionLookSet {
18584 symbols: TokenBitSet::default(),
18585 nullable: true,
18586 },
18587 ],
18588 };
18589
18590 assert_eq!(ll1_unique_alt(&entry, 2), None);
18591 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
18592 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
18593 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
18594 }
18595
18596 #[test]
18597 fn ordinary_repetition_builds_tree_in_input_order() {
18598 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18599 let mut parser = mini_parser(repeated_x_tokens(3));
18600 let tree = parser
18601 .parse_atn_rule(&atn, 0)
18602 .expect("ordinary repetition should parse");
18603
18604 let root = parser
18605 .node(tree)
18606 .as_rule()
18607 .expect("entry result should be a rule");
18608 let body_rules = root.child_rules(1).collect::<Vec<_>>();
18609 assert_eq!(root.text(), "xxx<EOF>");
18610 assert_eq!(body_rules.len(), 3);
18611 assert_eq!(
18612 body_rules
18613 .iter()
18614 .map(|rule| rule.start_id().expect("body start").index())
18615 .collect::<Vec<_>>(),
18616 [0, 1, 2]
18617 );
18618 assert_eq!(
18619 body_rules
18620 .iter()
18621 .map(|rule| rule.stop_id().expect("body stop").index())
18622 .collect::<Vec<_>>(),
18623 [0, 1, 2]
18624 );
18625 assert_eq!(parser.number_of_syntax_errors(), 0);
18626 }
18627 }
18628
18629 #[test]
18630 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
18631 const DEPTH: usize = 20_000;
18632
18633 std::thread::Builder::new()
18634 .name("deferred-rule-materialization".to_owned())
18635 .stack_size(256 * 1024)
18636 .spawn(|| {
18637 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
18638 let mut root = FastDeferredNodeId::EMPTY;
18639 for depth in 0..DEPTH {
18640 root = parser
18641 .recognition_arena
18642 .deferred_rule_node(FastDeferredRule {
18643 rule_index: u32::try_from(depth).expect("depth fits in u32"),
18644 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
18645 start_index: 0,
18646 stop_index: None,
18647 deferred_children: root,
18648 children: NodeSeqId::EMPTY,
18649 });
18650 }
18651
18652 let (mut children, alt_number) =
18653 parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
18654 assert_eq!(alt_number, 0);
18655 for expected_rule in (0..DEPTH).rev() {
18656 let mut nodes = parser.recognition_arena.iter(children);
18657 let node = nodes.next().expect("nested rule node");
18658 assert!(nodes.next().is_none(), "each rule has one child");
18659 let ArenaRecognizedNode::Rule {
18660 rule_index,
18661 children: nested,
18662 ..
18663 } = parser.recognition_arena.node(node)
18664 else {
18665 panic!("expected nested rule");
18666 };
18667 assert_eq!(rule_index as usize, expected_rule);
18668 children = nested;
18669 }
18670 assert!(children.is_empty());
18671 })
18672 .expect("small-stack thread should start")
18673 .join()
18674 .expect("deferred rules should materialize without recursion");
18675 }
18676
18677 #[test]
18678 fn deferred_alternatives_preserve_left_recursive_contexts() {
18679 let mut parser = mini_parser(vec![
18680 TestToken::new(1).with_text("1"),
18681 TestToken::new(2).with_text("+"),
18682 TestToken::new(1).with_text("2"),
18683 TestToken::eof("parser-test", 3, 1, 3),
18684 ]);
18685 let base = parser.arena_token_node(0, false);
18686 let operator = parser.arena_token_node(1, false);
18687 let right = parser.arena_token_node(2, false);
18688
18689 let base = parser.recognition_arena.prepend(NodeSeqId::EMPTY, base);
18690 let base = parser.recognition_arena.deferred_fragment(base);
18691 let operator = parser.recognition_arena.prepend(NodeSeqId::EMPTY, operator);
18692 let operator = parser.recognition_arena.deferred_fragment(operator);
18693 let right = parser.recognition_arena.prepend(NodeSeqId::EMPTY, right);
18694 let right = parser.recognition_arena.deferred_fragment(right);
18695 let base_alt = parser.recognition_arena.deferred_alternative(1);
18696 let boundary = parser.recognition_arena.deferred_left_recursive_boundary(0);
18697 let operator_alt = parser.recognition_arena.deferred_alternative(6);
18698
18699 let mut deferred = FastDeferredNodeId::EMPTY;
18700 for fragment in [base_alt, base, boundary, operator_alt, operator, right] {
18701 deferred = parser
18702 .recognition_arena
18703 .concat_deferred_nodes(deferred, fragment);
18704 }
18705 let (nodes, root_alt_number) =
18706 parser.materialize_fast_deferred_nodes(deferred, NodeSeqId::EMPTY);
18707 let nodes = parser
18708 .recognition_arena
18709 .fold_left_recursive_boundaries(nodes);
18710
18711 let mut root = ParserRuleContext::new(0, -1);
18712 root.set_context_alt_number(root_alt_number);
18713 let mut cursor = nodes;
18714 while let Some(link) = parser.recognition_arena.link(cursor) {
18715 let child = parser
18716 .arena_recognized_node_tree(link.head, false, true)
18717 .expect("materialized child should become a public tree");
18718 parser.tree.add_child(&mut root, child);
18719 cursor = link.tail;
18720 }
18721 let tree = parser.rule_node(root);
18722 let contexts = parser
18723 .node(tree)
18724 .descendants()
18725 .filter_map(Node::as_rule)
18726 .map(|rule| {
18727 (
18728 rule.rule_index(),
18729 rule.alt_number(),
18730 rule.context_alt_number(),
18731 rule.text(),
18732 )
18733 })
18734 .collect::<Vec<_>>();
18735
18736 insta::assert_debug_snapshot!(
18737 "deferred_alternatives_preserve_left_recursive_contexts",
18738 contexts
18739 );
18740 }
18741
18742 #[test]
18743 fn fast_recognizer_preserves_labeled_left_recursive_operator_context() {
18744 let atn = labeled_left_recursive_operator_atn();
18745 let mut parser = mini_parser(vec![
18746 TestToken::new(1).with_text("a"),
18747 TestToken::new(3).with_text("+"),
18748 TestToken::new(1).with_text("b"),
18749 TestToken::eof("parser-test", 3, 1, 3),
18750 ]);
18751
18752 let (tree, _) = parser
18753 .parse_atn_rule_with_runtime_options(
18754 &atn,
18755 0,
18756 ParserRuntimeOptions {
18757 track_context_alt_numbers: true,
18758 ..ParserRuntimeOptions::default()
18759 },
18760 )
18761 .expect("labeled left-recursive addition should parse");
18762 let contexts = parser
18763 .node(tree)
18764 .descendants()
18765 .filter_map(Node::as_rule)
18766 .map(|rule| {
18767 let operator = rule
18768 .children()
18769 .next()
18770 .and_then(Node::as_rule)
18771 .is_some_and(|child| child.rule_index() == rule.rule_index());
18772 (operator, rule.context_alt_number(), rule.text())
18773 })
18774 .collect::<Vec<_>>();
18775
18776 insta::assert_debug_snapshot!(
18777 "fast_recognizer_preserves_labeled_left_recursive_operator_context",
18778 contexts
18779 );
18780 assert!(!parser.recognition_arena.deferred_nodes.is_empty());
18781 assert_eq!(parser.number_of_syntax_errors(), 0);
18782 }
18783
18784 #[test]
18785 fn deeply_nested_rule_calls_grow_the_stack() {
18786 const DEPTH: usize = 4_096;
18787 const STACK_SIZE: usize = 256 * 1024;
18788 let atn = nested_rule_chain_atn(DEPTH);
18789 std::thread::Builder::new()
18790 .name("nested-adaptive-set-rules".to_owned())
18791 .stack_size(STACK_SIZE)
18792 .spawn(move || {
18793 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
18794 parser.set_build_parse_trees(false);
18795 parser.fast_first_set_prefilter = false;
18798 parser
18799 .parse_atn_rule(&atn, 0)
18800 .expect("nested rule chain should grow the native stack");
18801 assert_eq!(parser.input.index(), 1);
18802 })
18803 .expect("small-stack thread should start")
18804 .join()
18805 .expect("nested rule chain should not overflow its stack");
18806 }
18807
18808 #[test]
18809 fn deeply_nested_branching_rules_grow_the_stack() {
18810 const DEPTH: usize = 4_096;
18811 const STACK_SIZE: usize = 256 * 1024;
18812 let atn = nested_rule_graph_atn(DEPTH, true, false);
18813 std::thread::Builder::new()
18814 .name("nested-branching-rules".to_owned())
18815 .stack_size(STACK_SIZE)
18816 .spawn(move || {
18817 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
18818 parser.set_build_parse_trees(false);
18819 parser
18820 .parse_atn_rule(&atn, 0)
18821 .expect("branching rule chain should grow the native stack");
18822 assert_eq!(parser.input.index(), 1);
18823 })
18824 .expect("small-stack thread should start")
18825 .join()
18826 .expect("branching rule chain should not overflow its stack");
18827 }
18828
18829 #[test]
18830 fn deeply_nested_rule_follows_grow_the_stack() {
18831 const DEPTH: usize = 4_096;
18832 const STACK_SIZE: usize = 256 * 1024;
18833 let atn = nested_rule_graph_atn(DEPTH, false, true);
18834 std::thread::Builder::new()
18835 .name("nested-rule-follows".to_owned())
18836 .stack_size(STACK_SIZE)
18837 .spawn(move || {
18838 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
18839 parser.set_build_parse_trees(false);
18840 parser.fast_first_set_prefilter = false;
18841 parser
18842 .parse_atn_rule(&atn, 0)
18843 .expect("rule follow chain should grow the native stack");
18844 assert_eq!(parser.input.index(), DEPTH);
18845 })
18846 .expect("small-stack thread should start")
18847 .join()
18848 .expect("nested rule follow chain should not overflow its stack");
18849 }
18850
18851 #[test]
18852 fn deeply_nested_recovery_grows_the_stack() {
18853 const DEPTH: usize = 4_096;
18854 const STACK_SIZE: usize = 256 * 1024;
18855 let atn = nested_rule_chain_atn(DEPTH);
18856 std::thread::Builder::new()
18857 .name("nested-rule-recovery".to_owned())
18858 .stack_size(STACK_SIZE)
18859 .spawn(move || {
18860 let mut parser = mini_parser(vec![
18861 TestToken::new(2).with_text("z"),
18862 TestToken::new(1).with_text("x"),
18863 TestToken::eof("parser-test", 2, 1, 2),
18864 ]);
18865 parser.set_build_parse_trees(false);
18866 parser.fast_first_set_prefilter = false;
18867 parser
18868 .parse_atn_rule(&atn, 0)
18869 .expect("nested recovery should grow the native stack");
18870 assert_eq!(parser.input.index(), 2);
18871 assert_eq!(parser.number_of_syntax_errors(), 1);
18872 })
18873 .expect("small-stack thread should start")
18874 .join()
18875 .expect("nested rule recovery should not overflow its stack");
18876 }
18877
18878 #[test]
18879 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
18880 const REPETITIONS: usize = 64;
18881
18882 let atn = ambiguous_ordinary_star_loop_atn();
18883 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18884 let tree = parser
18885 .parse_atn_rule(&atn, 0)
18886 .expect("ambiguous ordinary repetition should parse");
18887
18888 let root = parser
18889 .node(tree)
18890 .as_rule()
18891 .expect("entry result should be a rule");
18892 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
18893 assert_eq!(parser.input.index(), REPETITIONS);
18894 assert!(
18895 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
18896 "equivalent segmentations should keep deferred storage linear"
18897 );
18898 assert_eq!(parser.number_of_syntax_errors(), 0);
18899 }
18900
18901 #[test]
18902 fn long_ordinary_repetition_does_not_consume_native_stack() {
18903 const REPETITIONS: usize = 20_000;
18904
18905 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18906 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18907 parser.set_build_parse_trees(false);
18908 parser
18909 .parse_atn_rule(&atn, 0)
18910 .expect("long ordinary repetition should parse");
18911
18912 assert_eq!(parser.input.index(), REPETITIONS);
18913 assert_eq!(parser.number_of_syntax_errors(), 0);
18914 }
18915 }
18916
18917 #[test]
18918 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
18919 const REPETITIONS: usize = 2_000;
18920 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
18921
18922 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18923 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18924 let tree = parser
18925 .parse_atn_rule(&atn, 0)
18926 .expect("long rule repetition should parse");
18927
18928 let root = parser
18929 .node(tree)
18930 .as_rule()
18931 .expect("entry result should be a rule");
18932 assert_eq!(root.text(), expected_text);
18933 assert_eq!(root.child_rules(1).count(), REPETITIONS);
18934 let first_body = root.child_rules(1).next().expect("first body rule");
18935 let last_body = root.child_rules(1).next_back().expect("last body rule");
18936 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
18937 assert_eq!(
18938 last_body.stop_id().expect("last body stop").index(),
18939 REPETITIONS - 1
18940 );
18941
18942 let stats = parser.recognition_arena_stats();
18943 assert_eq!(
18944 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18945 (REPETITIONS, REPETITIONS, 0)
18946 );
18947 assert_eq!(
18948 (stats.total_links, stats.live_links, stats.dead_links),
18949 (REPETITIONS, REPETITIONS, 0)
18950 );
18951 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
18952 assert_eq!(
18953 parser.recognition_arena.deferred_nodes.len(),
18954 REPETITIONS * 2 - 1
18955 );
18956 assert_eq!(parser.number_of_syntax_errors(), 0);
18957 }
18958 }
18959
18960 #[test]
18961 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
18962 let key = |state_number| FastRecognizeKey {
18963 state_number,
18964 stop_state: 10,
18965 index: state_number,
18966 rule_start_index: 0,
18967 decision_start_index: None,
18968 precedence: 0,
18969 recovery_symbols_id: 0,
18970 recovery_state: None,
18971 };
18972
18973 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18974 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
18975 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
18976 }
18977 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
18978 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
18979
18980 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18981 let repeated = key(1);
18982 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
18983 assert!(promote.clean_memo_enabled_for_key(&repeated));
18984 }
18985 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
18986
18987 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
18988 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
18989 }
18990 assert!(sparse.clean_memo_enabled_for_key(&repeated));
18991 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
18992 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
18993 assert!(sparse.clean_memo_enabled_for_key(&repeated));
18994 }
18995 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
18996 }
18997
18998 #[test]
18999 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
19000 assert_eq!(
19001 fast_recognize_memo_capacity(0),
19002 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
19003 );
19004 assert_eq!(
19005 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
19006 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
19007 );
19008 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
19009 assert_eq!(
19010 fast_recognize_memo_capacity(usize::MAX),
19011 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
19012 );
19013 }
19014
19015 #[test]
19016 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
19017 let mut scratch = FastRecognizeTopScratch::default();
19018 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
19019 let retained_capacity = scratch.memo.capacity();
19020 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
19021 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
19022
19023 let larger_capacity = retained_capacity + 1;
19024 scratch.prepare(larger_capacity);
19025 let grown_capacity = scratch.memo.capacity();
19026 assert!(grown_capacity >= larger_capacity);
19027 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
19028
19029 scratch.memo.insert(
19030 FastRecognizeKey {
19031 state_number: 0,
19032 stop_state: 0,
19033 index: 0,
19034 rule_start_index: 0,
19035 decision_start_index: None,
19036 precedence: 0,
19037 recovery_symbols_id: 0,
19038 recovery_state: None,
19039 },
19040 Rc::from([FastRecognizeOutcome {
19041 index: 0,
19042 consumed_eof: false,
19043 diagnostics: DiagnosticSeqId::EMPTY,
19044 deferred_nodes: FastDeferredNodeId::EMPTY,
19045 nodes: NodeSeqId::EMPTY,
19046 }]),
19047 );
19048 scratch.release_oversized_memo();
19049 assert!(scratch.memo.is_empty());
19050 assert_eq!(scratch.memo.capacity(), grown_capacity);
19051
19052 scratch
19053 .memo
19054 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
19055 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
19056
19057 scratch.release_oversized_memo();
19058 assert!(scratch.memo.is_empty());
19059 assert_eq!(scratch.memo.capacity(), 0);
19060 }
19061
19062 #[test]
19063 fn clean_empty_multi_alt_outcomes_are_memoized() {
19064 let mut atn = ParserAtnBuilder::new(2);
19065 assert_eq!(
19066 atn.add_state(AtnStateKind::RuleStart, Some(0))
19067 .expect("state")
19068 .index(),
19069 0
19070 );
19071 assert_eq!(
19072 atn.add_state(AtnStateKind::BlockStart, Some(0))
19073 .expect("state")
19074 .index(),
19075 1
19076 );
19077 assert_eq!(
19078 atn.add_state(AtnStateKind::RuleStop, Some(0))
19079 .expect("state")
19080 .index(),
19081 2
19082 );
19083 atn.set_rule_to_start_state(vec![0])
19084 .expect("rule start states");
19085 atn.set_rule_to_stop_state(vec![2])
19086 .expect("rule stop states");
19087 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
19088 .expect("transition");
19089 atn.add_transition(
19090 1,
19091 ParserTransitionSpec::Atom {
19092 target: 2,
19093 label: 1,
19094 },
19095 )
19096 .expect("transition");
19097 atn.add_transition(
19098 1,
19099 ParserTransitionSpec::Atom {
19100 target: 2,
19101 label: 2,
19102 },
19103 )
19104 .expect("transition");
19105 let atn = finish_atn(atn);
19106
19107 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
19108 parser.fast_recovery_enabled = false;
19109 let mut visiting = FxHashSet::default();
19110 let mut memo = FxHashMap::default();
19111 let mut expected = ExpectedTokens::default();
19112 let outcomes = parser.recognize_state_fast(
19113 &atn,
19114 FastRecognizeRequest {
19115 state_number: 1,
19116 stop_state: 2,
19117 index: 0,
19118 rule_start_index: 0,
19119 decision_start_index: None,
19120 precedence: 0,
19121 depth: 0,
19122 recovery_symbols: parser.empty_recovery_symbols(),
19123 recovery_state: None,
19124 },
19125 FastRecognizeScratch {
19126 predicate_context: None,
19127 visiting: &mut visiting,
19128 memo: &mut memo,
19129 expected: &mut expected,
19130 native_depth: 0,
19131 },
19132 );
19133
19134 assert!(outcomes.is_empty());
19135 assert_eq!(memo.len(), 1);
19136 assert!(memo.values().next().expect("memo entry").is_empty());
19137
19138 parser.clean_memo_mode = CleanMemoMode::Sparse;
19139 visiting.clear();
19140 memo.clear();
19141 expected = ExpectedTokens::default();
19142 let sparse_outcomes = parser.recognize_state_fast(
19143 &atn,
19144 FastRecognizeRequest {
19145 state_number: 1,
19146 stop_state: 2,
19147 index: 0,
19148 rule_start_index: 0,
19149 decision_start_index: None,
19150 precedence: 0,
19151 depth: 0,
19152 recovery_symbols: parser.empty_recovery_symbols(),
19153 recovery_state: None,
19154 },
19155 FastRecognizeScratch {
19156 predicate_context: None,
19157 visiting: &mut visiting,
19158 memo: &mut memo,
19159 expected: &mut expected,
19160 native_depth: 0,
19161 },
19162 );
19163
19164 assert!(sparse_outcomes.is_empty());
19165 assert!(memo.is_empty());
19166 }
19167
19168 #[test]
19169 fn wildcard_matches_non_eof_only() {
19170 let mut parser = mini_parser(vec![
19171 TestToken::new(1).with_text("x"),
19172 TestToken::eof("parser-test", 1, 1, 1),
19173 ]);
19174 let matched = parser.match_wildcard().expect("wildcard");
19175 assert_eq!(parser.node(matched).text(), "x");
19176 assert!(parser.match_wildcard().is_err());
19177 }
19178
19179 #[test]
19180 fn add_parse_child_records_match_even_without_tree_building() {
19181 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
19186 let token = TestToken::new(1).with_text("x");
19187
19188 parser.set_build_parse_trees(false);
19189 let mut ctx = ParserRuleContext::new(0, 0);
19190 assert!(!ctx.has_matched_child());
19191 let child = parser.terminal_tree(token.id);
19192 parser.add_parse_child(&mut ctx, child);
19193 assert_eq!(ctx.child_count(), 0);
19195 assert_eq!(parser.parse_tree_storage().node_count(), 0);
19196 assert!(ctx.has_matched_child());
19198
19199 parser.set_build_parse_trees(true);
19201 let mut ctx = ParserRuleContext::new(0, 0);
19202 let child = parser.terminal_tree(token.id);
19203 parser.add_parse_child(&mut ctx, child);
19204 assert_eq!(ctx.child_count(), 1);
19205 assert!(ctx.has_matched_child());
19206 }
19207
19208 #[test]
19209 fn disabled_tree_building_does_not_grow_flat_storage() {
19210 let mut parser = mini_parser(vec![
19211 TestToken::new(1).with_text("x"),
19212 TestToken::new(1).with_text("y"),
19213 TestToken::eof("parser-test", 2, 1, 2),
19214 ]);
19215 parser.set_build_parse_trees(false);
19216 let mut context = ParserRuleContext::new(0, -1);
19217
19218 for _ in 0..2 {
19219 let child = parser.match_token(1).expect("token should match");
19220 parser.add_parse_child(&mut context, child);
19221 }
19222 let current = parser.input.lt_id(1).expect("EOF token");
19223 let error = parser.error_tree(current);
19224 parser.add_parse_child(&mut context, error);
19225 let root = parser.rule_node(context);
19226
19227 assert_eq!(
19228 parser.parse_tree_storage().stats(),
19229 ParseTreeStats::default()
19230 );
19231 assert!(
19232 parser
19233 .parse_tree_storage()
19234 .node(parser.token_store(), root)
19235 .is_none(),
19236 "the no-tree sentinel must not resolve to stored data"
19237 );
19238 }
19239
19240 #[test]
19241 fn disabled_tree_building_skips_recognition_rule_node_storage() {
19242 let atn = ordinary_star_loop_atn();
19243 let mut parser = mini_parser(repeated_x_tokens(3));
19244 parser.set_build_parse_trees(false);
19245
19246 parser
19247 .parse_atn_rule(&atn, 0)
19248 .expect("ordinary repetition should parse without a tree");
19249
19250 assert_eq!(parser.input.index(), 3);
19251 assert!(parser.recognition_arena.nodes.is_empty());
19252 assert!(parser.recognition_arena.seq_links.is_empty());
19253 assert!(parser.recognition_arena.deferred_nodes.is_empty());
19254 assert!(parser.recognition_arena.deferred_rules.is_empty());
19255 assert!(!parser.fast_token_nodes_enabled);
19256 assert!(parser.fast_recognize_scratch.memo.is_empty());
19257 }
19258
19259 #[test]
19260 fn parser_interprets_simple_atn_rule() {
19261 let atn = token_then_eof_atn();
19262 let mut parser = mini_parser(vec![
19263 TestToken::new(1).with_text("x"),
19264 TestToken::eof("parser-test", 1, 1, 1),
19265 ]);
19266
19267 let tree = parser
19268 .parse_atn_rule(&atn, 0)
19269 .expect("artificial parser rule should parse");
19270 assert_eq!(parser.node(tree).text(), "x<EOF>");
19271 assert_eq!(parser.number_of_syntax_errors(), 0);
19272 assert_eq!(
19273 parser
19274 .node(tree)
19275 .first_rule_stop(0)
19276 .expect("rule should stop at EOF")
19277 .token_type(),
19278 TOKEN_EOF
19279 );
19280
19281 let mut parser = mini_parser(vec![
19282 TestToken::new(1).with_text("x"),
19283 TestToken::eof("parser-test", 1, 1, 1),
19284 ]);
19285 let (tree, actions) = parser
19286 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19287 .expect("runtime-option parser rule should parse");
19288 assert!(actions.is_empty());
19289 assert_eq!(
19290 parser
19291 .node(tree)
19292 .first_rule_stop(0)
19293 .expect("rule should stop at EOF")
19294 .token_type(),
19295 TOKEN_EOF
19296 );
19297 }
19298
19299 #[test]
19300 fn runtime_options_default_ignores_noop_action_transitions() {
19301 let atn = noop_action_then_token_then_eof_atn();
19302 let mut parser = mini_parser(vec![
19303 TestToken::new(1).with_text("x"),
19304 TestToken::eof("parser-test", 1, 1, 1),
19305 ]);
19306
19307 let (tree, actions) = parser
19308 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19309 .expect("no-op parser action should not force action replay");
19310
19311 assert_eq!(parser.node(tree).text(), "x<EOF>");
19312 assert!(
19313 actions.is_empty(),
19314 "action_index=None transitions are ANTLR metadata, not replay actions"
19315 );
19316 assert_eq!(parser.number_of_syntax_errors(), 0);
19317 }
19318
19319 #[test]
19320 fn parser_exposes_buffered_token_stream_after_parse() {
19321 let atn = token_then_eof_atn();
19322 let mut parser = mini_parser(vec![
19323 TestToken::new(1).with_text("x"),
19324 TestToken::eof("parser-test", 1, 1, 1),
19325 ]);
19326
19327 let tree = parser
19328 .parse_atn_rule(&atn, 0)
19329 .expect("artificial parser rule should parse");
19330 assert_eq!(parser.node(tree).text(), "x<EOF>");
19331
19332 let stream = parser.token_stream();
19333 let source_index_after_parse = stream.token_source().index;
19334 let buffered = stream.tokens().collect::<Vec<_>>();
19335 assert_eq!(buffered.len(), 2);
19336 assert_eq!(buffered[0].text(), Some("x"));
19337 assert_eq!(buffered[0].token_id().index(), 0);
19338 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
19339 assert_eq!(stream.token_source().index, source_index_after_parse);
19340 drop(buffered);
19341
19342 let stream = parser.into_token_stream();
19343 assert_eq!(stream.token_source().index, source_index_after_parse);
19344 assert_eq!(
19345 stream.tokens().next().expect("first token").text(),
19346 Some("x")
19347 );
19348 assert_eq!(
19349 stream.tokens().nth(1).expect("EOF token").token_type(),
19350 TOKEN_EOF
19351 );
19352 }
19353
19354 #[test]
19355 fn parsed_file_exposes_all_buffered_tokens() {
19356 let atn = token_then_eof_atn();
19357 let mut parser = mini_parser(vec![
19358 TestToken::new(99)
19359 .with_text(" comment")
19360 .with_channel(HIDDEN_CHANNEL),
19361 TestToken::new(1).with_text("x"),
19362 TestToken::eof("parser-test", 9, 1, 9),
19363 ]);
19364
19365 let tree = parser
19366 .parse_atn_rule(&atn, 0)
19367 .expect("artificial parser rule should parse");
19368 let parsed = parser.into_parsed_file(tree);
19369
19370 insta::assert_debug_snapshot!(
19373 "parsed_file_exposes_all_buffered_tokens",
19374 parsed
19375 .tokens()
19376 .iter()
19377 .map(|token| (token.token_type(), token.channel(), token.text()))
19378 .collect::<Vec<_>>()
19379 );
19380 assert_eq!(parsed.tokens().into_iter().count(), 3);
19381 }
19382
19383 #[test]
19384 fn parser_syntax_error_count_tracks_interpreted_recovery() {
19385 let atn = token_then_eof_atn();
19386 let mut parser = mini_parser(vec![
19387 TestToken::new(1).with_text("x"),
19388 TestToken::new(2).with_text("y"),
19389 TestToken::eof("parser-test", 2, 1, 2),
19390 ]);
19391
19392 let tree = parser
19393 .parse_atn_rule(&atn, 0)
19394 .expect("invalid token should recover into an error node");
19395
19396 assert_eq!(parser.number_of_syntax_errors(), 1);
19397 assert_eq!(
19398 parser
19399 .node(tree)
19400 .first_error_token()
19401 .expect("recovery should embed an error token")
19402 .text(),
19403 Some("y")
19404 );
19405 }
19406
19407 #[test]
19408 fn failed_interpreted_parse_notifies_error_listener() {
19409 let atn = token_then_eof_atn();
19410 let mut parser = mini_parser(vec![
19411 TestToken::new(2)
19412 .with_text("y")
19413 .with_span(0, 0)
19414 .with_byte_span(0, 1)
19415 .with_position(3, 5),
19416 TestToken::eof("parser-test", 1, 1, 1),
19417 ]);
19418 parser.remove_error_listeners();
19419 let diagnostics = Arc::new(Mutex::new(Vec::new()));
19420 parser.add_error_listener(RecordingErrorListener {
19421 diagnostics: Arc::clone(&diagnostics),
19422 });
19423
19424 let error = parser
19425 .parse_atn_rule(&atn, 0)
19426 .expect_err("start-rule mismatch should remain a parser error");
19427
19428 assert_eq!(parser.number_of_syntax_errors(), 1);
19429 assert!(matches!(&error, AntlrError::ParserError { .. }));
19430 insta::assert_debug_snapshot!(
19431 "failed_interpreted_parse_notifies_error_listener",
19432 *diagnostics.lock().expect("recorded diagnostics lock")
19433 );
19434 }
19435
19436 #[test]
19437 fn adaptive_direct_rule_uses_simulator_decision() {
19438 let atn = two_alt_decision_atn();
19439 let mut simulator = ParserAtnSimulator::new(&atn);
19440 let mut parser = mini_parser(vec![
19441 TestToken::new(2).with_text("y"),
19442 TestToken::eof("parser-test", 1, 1, 1),
19443 ]);
19444
19445 let tree = parser
19446 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
19447 .expect("direct adaptive rule should parse");
19448
19449 assert_eq!(parser.node(tree).text(), "y");
19450 assert_eq!(parser.input.index(), 1);
19451 }
19452
19453 #[test]
19454 fn adaptive_direct_rule_restores_input_on_fallback() {
19455 let atn = predicate_after_token_atn();
19456 let mut simulator = ParserAtnSimulator::new(&atn);
19457 let mut parser = mini_parser(vec![
19458 TestToken::new(1).with_text("x"),
19459 TestToken::new(2).with_text("y"),
19460 TestToken::eof("parser-test", 2, 1, 2),
19461 ]);
19462
19463 let tree = parser
19464 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
19465 .expect("fallback recognizer should parse");
19466
19467 assert_eq!(parser.node(tree).text(), "xy");
19468 assert_eq!(parser.input.index(), 2);
19469 let stats = parser.parse_tree_storage().stats();
19470 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
19471 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
19472 assert_eq!(stats.scratch_links, 0);
19473 }
19474
19475 #[test]
19476 fn unknown_predicate_policy_defaults_to_assume_true() {
19477 let atn = predicate_after_token_atn();
19478 let mut parser = mini_parser(vec![
19479 TestToken::new(1).with_text("x"),
19480 TestToken::new(2).with_text("y"),
19481 TestToken::eof("parser-test", 2, 1, 2),
19482 ]);
19483
19484 let (tree, _) = parser
19485 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19486 .expect("unknown predicate should pass under the default policy");
19487
19488 assert_eq!(parser.node(tree).text(), "xy");
19489 assert_eq!(parser.number_of_syntax_errors(), 0);
19490 }
19491
19492 #[test]
19493 fn private_context_alt_tracking_keeps_fast_predicate_recognition() {
19494 let atn = predicate_gated_same_lookahead_atn([0, 1]);
19495 let mut parser = mini_parser(vec![
19496 TestToken::new(1).with_text("x"),
19497 TestToken::eof("parser-test", 1, 1, 1),
19498 ]);
19499
19500 let (tree, _) = parser
19501 .parse_atn_rule_with_runtime_options(
19502 &atn,
19503 0,
19504 ParserRuntimeOptions {
19505 predicates: &[
19506 (0, 0, ParserPredicate::False),
19507 (0, 1, ParserPredicate::True),
19508 ],
19509 track_context_alt_numbers: true,
19510 ..ParserRuntimeOptions::default()
19511 },
19512 )
19513 .expect("the second predicate-gated alternative should match");
19514
19515 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19516 insta::assert_debug_snapshot!(
19517 "private_context_alt_tracking_keeps_fast_predicate_recognition",
19518 (root.alt_number(), root.context_alt_number(), root.text())
19519 );
19520 assert_eq!(parser.number_of_syntax_errors(), 0);
19521 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
19522 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
19523 }
19524
19525 #[test]
19526 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
19527 let atn = token_then_eof_atn();
19531 let mut parser = mini_parser(vec![
19532 TestToken::new(1).with_text("x"),
19533 TestToken::eof("parser-test", 1, 1, 1),
19534 ]);
19535
19536 parser.unknown_predicate_hits.push((7, 3));
19538
19539 parser
19541 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19542 .expect("child rule parses");
19543
19544 let error = parser
19546 .take_unknown_semantic_error()
19547 .expect("parent's recorded coordinate must survive the nested interpreted parse");
19548 let AntlrError::Unsupported(message) = error else {
19549 panic!("expected AntlrError::Unsupported, got {error:?}");
19550 };
19551 assert!(message.contains("pred_index=3"), "message: {message}");
19552 }
19553
19554 #[test]
19555 fn nested_committed_parse_preserves_prior_unhandled_action_hits() {
19556 let atn = token_then_eof_atn();
19557 let mut parser = mini_parser(vec![
19558 TestToken::new(1).with_text("x"),
19559 TestToken::eof("parser-test", 1, 1, 1),
19560 ]);
19561 parser.unhandled_action_hits.push((7, 42));
19562
19563 parser
19564 .parse_atn_rule_with_runtime_options(
19565 &atn,
19566 0,
19567 ParserRuntimeOptions {
19568 action_indices: &[(usize::MAX, 0)],
19569 ..ParserRuntimeOptions::default()
19570 },
19571 )
19572 .expect("a child with no action miss must not observe its parent's miss");
19573
19574 let error = parser
19575 .take_unknown_semantic_error()
19576 .expect("the parent's action miss must survive the nested committed parse");
19577 let AntlrError::Unsupported(message) = error else {
19578 panic!("expected AntlrError::Unsupported, got {error:?}");
19579 };
19580 assert!(
19581 message.contains("rule_index=7") && message.contains("state=42"),
19582 "message: {message}"
19583 );
19584 }
19585
19586 #[test]
19587 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
19588 let atn = predicate_after_token_atn();
19589 let mut parser = mini_parser(vec![
19590 TestToken::new(1).with_text("x"),
19591 TestToken::new(2).with_text("y"),
19592 TestToken::eof("parser-test", 2, 1, 2),
19593 ]);
19594
19595 let result = parser.parse_atn_rule_with_runtime_options(
19596 &atn,
19597 0,
19598 ParserRuntimeOptions {
19599 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
19600 ..ParserRuntimeOptions::default()
19601 },
19602 );
19603
19604 assert!(
19605 result.is_err(),
19606 "the only path is predicate-guarded, so assume-false must fail the parse"
19607 );
19608 }
19609
19610 #[test]
19611 fn predicate_failure_message_keeps_semantic_recovery_path() {
19612 let atn = predicate_after_token_atn();
19613 let mut parser = mini_parser(vec![
19614 TestToken::new(1).with_text("x"),
19615 TestToken::new(2).with_text("y"),
19616 TestToken::eof("parser-test", 2, 1, 2),
19617 ]);
19618
19619 let (tree, _) = parser
19620 .parse_atn_rule_with_runtime_options(
19621 &atn,
19622 0,
19623 ParserRuntimeOptions {
19624 predicates: &[(
19625 0,
19626 0,
19627 ParserPredicate::FalseWithMessage {
19628 message: "predicate rejected input",
19629 },
19630 )],
19631 ..ParserRuntimeOptions::default()
19632 },
19633 )
19634 .expect("failure-message predicates recover through the semantic interpreter");
19635
19636 assert_eq!(parser.node(tree).text(), "xy");
19637 assert_eq!(parser.number_of_syntax_errors(), 1);
19638 assert!(
19639 parser.fast_predicate_cache.is_empty(),
19640 "failure-message predicates need the semantic interpreter's recovery outcome"
19641 );
19642 }
19643
19644 #[test]
19645 fn unknown_predicate_policy_error_names_the_coordinate() {
19646 let atn = predicate_after_token_atn();
19647 let mut parser = mini_parser(vec![
19648 TestToken::new(1).with_text("x"),
19649 TestToken::new(2).with_text("y"),
19650 TestToken::eof("parser-test", 2, 1, 2),
19651 ]);
19652
19653 let error = parser
19654 .parse_atn_rule_with_runtime_options(
19655 &atn,
19656 0,
19657 ParserRuntimeOptions {
19658 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19659 ..ParserRuntimeOptions::default()
19660 },
19661 )
19662 .expect_err("evaluating an unknown predicate under Error policy must fail");
19663
19664 let AntlrError::Unsupported(message) = error else {
19665 panic!("expected AntlrError::Unsupported, got {error:?}");
19666 };
19667 assert!(
19668 message.contains("unsupported semantic predicate"),
19669 "message should name the failure class: {message}"
19670 );
19671 assert!(
19672 message.contains("pred_index=0"),
19673 "message should carry the coordinate: {message}"
19674 );
19675 }
19676
19677 #[test]
19678 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
19679 let atn = predicate_after_token_atn();
19685 let mut parser = mini_parser(vec![
19686 TestToken::new(1).with_text("x"),
19687 TestToken::new(2).with_text("y"),
19688 TestToken::eof("parser-test", 2, 1, 2),
19689 ]);
19690
19691 parser
19692 .parse_atn_rule_with_runtime_options(
19693 &atn,
19694 0,
19695 ParserRuntimeOptions {
19696 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19697 ..ParserRuntimeOptions::default()
19698 },
19699 )
19700 .expect_err("first parse fails loud under the Error policy");
19701
19702 parser.reset_unknown_semantic_hits();
19707 assert!(
19708 parser.take_unknown_semantic_error().is_none(),
19709 "reset must drop stale unknown-predicate coordinates before a reused parse"
19710 );
19711 }
19712
19713 #[derive(Debug, Default)]
19714 struct RecordingHooks {
19715 predicates: Vec<(usize, usize, usize, Option<String>)>,
19716 actions: Vec<(usize, String, Option<String>)>,
19717 action_trees: Vec<Option<String>>,
19718 }
19719
19720 impl SemanticHooks for RecordingHooks {
19721 fn sempred<S>(
19722 &mut self,
19723 ctx: &mut ParserSemCtx<'_, S>,
19724 rule_index: usize,
19725 pred_index: usize,
19726 ) -> Option<bool>
19727 where
19728 S: TokenSource,
19729 {
19730 self.predicates.push((
19731 ctx.input_index(),
19732 rule_index,
19733 pred_index,
19734 ctx.token_text(1)
19735 .and_then(|token| token.text().map(str::to_owned)),
19736 ));
19737 Some(true)
19738 }
19739
19740 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19741 where
19742 S: TokenSource,
19743 {
19744 self.actions.push((
19745 action.source_state(),
19746 ctx.action_text(),
19747 ctx.rule_name().map(str::to_owned),
19748 ));
19749 self.action_trees.push(ctx.tree().map(Node::text));
19750 true
19751 }
19752 }
19753
19754 #[derive(Debug, Default)]
19755 struct StatefulActionHooks {
19756 entered: bool,
19757 events: Vec<String>,
19758 }
19759
19760 impl SemanticHooks for StatefulActionHooks {
19761 fn sempred<S>(
19762 &mut self,
19763 _ctx: &mut ParserSemCtx<'_, S>,
19764 _rule_index: usize,
19765 _pred_index: usize,
19766 ) -> Option<bool>
19767 where
19768 S: TokenSource,
19769 {
19770 self.events.push(format!("predicate:{}", self.entered));
19771 Some(self.entered)
19772 }
19773
19774 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19775 where
19776 S: TokenSource,
19777 {
19778 self.events.push(format!(
19779 "action:{}",
19780 action
19781 .action_index()
19782 .map_or_else(|| "legacy".to_owned(), |index| index.to_string())
19783 ));
19784 self.entered = true;
19785 true
19786 }
19787 }
19788
19789 #[derive(Debug, Default)]
19790 struct InitOrderingHooks {
19791 initialized: bool,
19792 events: Vec<String>,
19793 }
19794
19795 impl SemanticHooks for InitOrderingHooks {
19796 fn sempred<S>(
19797 &mut self,
19798 _ctx: &mut ParserSemCtx<'_, S>,
19799 _rule_index: usize,
19800 _pred_index: usize,
19801 ) -> Option<bool>
19802 where
19803 S: TokenSource,
19804 {
19805 self.events.push(format!("predicate:{}", self.initialized));
19806 Some(self.initialized)
19807 }
19808
19809 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19810 where
19811 S: TokenSource,
19812 {
19813 if action.is_rule_init() {
19814 self.initialized = true;
19815 self.events.push("init".to_owned());
19816 } else {
19817 self.events.push(format!(
19818 "action:{}:initialized={}",
19819 action
19820 .action_index()
19821 .map_or_else(|| "legacy".to_owned(), |index| index.to_string()),
19822 self.initialized
19823 ));
19824 }
19825 true
19826 }
19827 }
19828
19829 #[derive(Debug, Default)]
19830 struct ActionContextHooks {
19831 actions: Vec<(usize, Option<i64>, Option<usize>)>,
19832 }
19833
19834 impl SemanticHooks for ActionContextHooks {
19835 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19836 where
19837 S: TokenSource,
19838 {
19839 self.actions.push((
19840 action.action_index().unwrap_or(usize::MAX),
19841 ctx.local_int_arg(),
19842 action.stop_index(),
19843 ));
19844 true
19845 }
19846 }
19847
19848 #[derive(Debug, Default)]
19849 struct DecliningActionHooks {
19850 actions: Vec<usize>,
19851 }
19852
19853 impl SemanticHooks for DecliningActionHooks {
19854 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19855 where
19856 S: TokenSource,
19857 {
19858 self.actions.push(action.source_state());
19859 false
19860 }
19861 }
19862
19863 #[derive(Debug, Default)]
19864 struct ForcedSecondAlternativeHooks {
19865 decisions: Vec<(usize, usize, usize)>,
19866 }
19867
19868 impl SemanticHooks for ForcedSecondAlternativeHooks {
19869 fn observes_parser_decisions(&self) -> bool {
19870 true
19871 }
19872
19873 fn parser_decision_override(
19874 &mut self,
19875 decision: usize,
19876 input_index: usize,
19877 alternative_count: usize,
19878 ) -> Option<usize> {
19879 self.decisions
19880 .push((decision, input_index, alternative_count));
19881 Some(2)
19882 }
19883 }
19884
19885 struct RecordingParseListener {
19886 events: Arc<Mutex<Vec<String>>>,
19887 }
19888
19889 impl ParseListener for RecordingParseListener {
19890 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
19891 self.events
19892 .lock()
19893 .expect("parse-listener event lock")
19894 .push(format!("enter:{}", event.rule_index));
19895 Ok(())
19896 }
19897
19898 fn exit_every_rule(&mut self, rule_index: usize) {
19899 self.events
19900 .lock()
19901 .expect("parse-listener event lock")
19902 .push(format!("exit:{rule_index}"));
19903 }
19904 }
19905
19906 #[derive(Debug, Default)]
19907 struct RejectingPredicateHooks {
19908 predicates: Vec<(usize, usize, usize, Option<String>)>,
19909 }
19910
19911 impl SemanticHooks for RejectingPredicateHooks {
19912 fn sempred<S>(
19913 &mut self,
19914 ctx: &mut ParserSemCtx<'_, S>,
19915 rule_index: usize,
19916 pred_index: usize,
19917 ) -> Option<bool>
19918 where
19919 S: TokenSource,
19920 {
19921 self.predicates.push((
19922 ctx.input_index(),
19923 rule_index,
19924 pred_index,
19925 ctx.token_text(1)
19926 .and_then(|token| token.text().map(str::to_owned)),
19927 ));
19928 Some(false)
19929 }
19930 }
19931
19932 #[test]
19933 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
19934 let atn = predicate_gated_same_lookahead_atn([0, 0]);
19935 let mut parser = mini_parser_with_hooks(
19936 vec![
19937 TestToken::new(1).with_text("x"),
19938 TestToken::eof("parser-test", 1, 1, 1),
19939 ],
19940 RecordingHooks::default(),
19941 );
19942
19943 let (tree, _) = parser
19944 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19945 .expect("both alternatives share one replay-safe predicate result");
19946
19947 assert_eq!(parser.node(tree).text(), "x<EOF>");
19948 assert_eq!(
19949 parser.semantic_hooks.predicates,
19950 vec![(0, 0, 0, Some("x".to_owned()))]
19951 );
19952 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
19953 }
19954
19955 #[test]
19956 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
19957 let atn = predicate_after_token_atn();
19958 let mut parser = mini_parser_with_hooks(
19959 vec![
19960 TestToken::new(1).with_text("x"),
19961 TestToken::new(2).with_text("y"),
19962 TestToken::eof("parser-test", 2, 1, 2),
19963 ],
19964 RecordingHooks::default(),
19965 );
19966
19967 let (tree, _) = parser
19968 .parse_atn_rule_with_runtime_options(
19969 &atn,
19970 0,
19971 ParserRuntimeOptions {
19972 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19973 ..ParserRuntimeOptions::default()
19974 },
19975 )
19976 .expect("hook supplies the missing predicate result");
19977
19978 assert_eq!(parser.node(tree).text(), "xy");
19979 assert_eq!(
19980 parser.semantic_hooks.predicates,
19981 vec![(1, 0, 0, Some("y".to_owned()))]
19982 );
19983 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
19984 }
19985
19986 #[test]
19987 fn runtime_options_default_preserves_semantic_hook_predicates() {
19988 let atn = predicate_after_token_atn();
19989 let mut parser = mini_parser_with_hooks(
19990 vec![
19991 TestToken::new(1).with_text("x"),
19992 TestToken::new(2).with_text("y"),
19993 TestToken::eof("parser-test", 2, 1, 2),
19994 ],
19995 RejectingPredicateHooks::default(),
19996 );
19997
19998 let result =
19999 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
20000
20001 assert!(
20002 result.is_err(),
20003 "default runtime options must not bypass semantic hooks for predicate ATNs"
20004 );
20005 assert_eq!(
20006 parser.semantic_hooks.predicates,
20007 vec![(1, 0, 0, Some("y".to_owned()))]
20008 );
20009 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
20010 }
20011
20012 #[test]
20013 fn committed_action_runs_before_later_predicate() {
20014 let atn = committed_action_then_predicate_atn();
20015 let mut parser = mini_parser_with_hooks(
20016 vec![
20017 TestToken::new(1).with_text("x"),
20018 TestToken::eof("parser-test", 1, 1, 1),
20019 ],
20020 StatefulActionHooks::default(),
20021 );
20022
20023 let (tree, deferred_actions) = parser
20024 .parse_atn_rule_with_runtime_options(
20025 &atn,
20026 0,
20027 ParserRuntimeOptions {
20028 action_indices: &[(0, 7)],
20029 ..ParserRuntimeOptions::default()
20030 },
20031 )
20032 .expect("the predicate should observe the preceding committed action");
20033
20034 assert_eq!(parser.node(tree).text(), "x<EOF>");
20035 assert!(deferred_actions.is_empty());
20036 assert_eq!(parser.semantic_hooks.events, ["action:7", "predicate:true"]);
20037 }
20038
20039 #[test]
20040 fn committed_action_hook_observes_parameterized_rule_argument() {
20041 let atn = parameterized_child_action_eof_atn();
20042 let rule_args = [ParserRuleArg {
20043 source_state: 0,
20044 rule_index: 1,
20045 value: 42,
20046 inherit_local: false,
20047 }];
20048 let mut parser = mini_parser_with_hooks(
20049 vec![TestToken::eof("parser-test", 0, 1, 0)],
20050 ActionContextHooks::default(),
20051 );
20052
20053 parser
20054 .parse_atn_rule_with_runtime_options(
20055 &atn,
20056 0,
20057 ParserRuntimeOptions {
20058 action_indices: &[(1, 20), (4, 10)],
20059 rule_args: &rule_args,
20060 ..ParserRuntimeOptions::default()
20061 },
20062 )
20063 .expect("the parameterized child should parse");
20064
20065 assert_eq!(
20066 parser.semantic_hooks.actions[0],
20067 (10, Some(42), None),
20068 "the child action should observe its invocation argument"
20069 );
20070 }
20071
20072 #[test]
20073 fn committed_parent_propagates_child_eof_consumption() {
20074 let atn = parameterized_child_action_eof_atn();
20075 let mut parser = mini_parser_with_hooks(
20076 vec![TestToken::eof("parser-test", 0, 1, 0)],
20077 ActionContextHooks::default(),
20078 );
20079
20080 let (tree, _) = parser
20081 .parse_atn_rule_with_runtime_options(
20082 &atn,
20083 0,
20084 ParserRuntimeOptions {
20085 action_indices: &[(1, 20), (4, 10)],
20086 ..ParserRuntimeOptions::default()
20087 },
20088 )
20089 .expect("the parent should retain its child's EOF boundary");
20090
20091 assert_eq!(
20092 parser.semantic_hooks.actions[1],
20093 (20, None, Some(0)),
20094 "the parent action should stop at EOF"
20095 );
20096 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20097 assert_eq!(root.stop().map(|token| token.token_type()), Some(TOKEN_EOF));
20098 let child = root
20099 .child_rules(1)
20100 .next()
20101 .expect("the parent should contain the child rule");
20102 assert_eq!(
20103 child.stop().map(|token| token.token_type()),
20104 Some(TOKEN_EOF)
20105 );
20106 }
20107
20108 #[test]
20109 fn committed_walker_does_not_run_action_in_losing_alternative() {
20110 let atn = losing_alternative_action_atn();
20111 let mut parser = mini_parser_with_hooks(
20112 vec![
20113 TestToken::new(2).with_text("y"),
20114 TestToken::eof("parser-test", 1, 1, 1),
20115 ],
20116 StatefulActionHooks::default(),
20117 );
20118
20119 let (tree, deferred_actions) = parser
20120 .parse_atn_rule_with_runtime_options(
20121 &atn,
20122 0,
20123 ParserRuntimeOptions {
20124 action_indices: &[(2, 0)],
20125 ..ParserRuntimeOptions::default()
20126 },
20127 )
20128 .expect("the token-led second alternative should be selected");
20129
20130 assert_eq!(parser.node(tree).text(), "y");
20131 assert!(deferred_actions.is_empty());
20132 assert!(parser.semantic_hooks.events.is_empty());
20133 }
20134
20135 #[test]
20136 fn committed_walker_honors_decision_overrides() {
20137 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20138 let predicates = [(0, 0, ParserPredicate::True), (0, 1, ParserPredicate::True)];
20139 let mut parser = mini_parser_with_hooks(
20140 vec![
20141 TestToken::new(1).with_text("x"),
20142 TestToken::eof("parser-test", 1, 1, 1),
20143 ],
20144 ForcedSecondAlternativeHooks::default(),
20145 );
20146
20147 let (tree, deferred_actions) = parser
20148 .parse_atn_rule_with_runtime_options(
20149 &atn,
20150 0,
20151 ParserRuntimeOptions {
20152 action_indices: &[(usize::MAX, 0)],
20153 track_alt_numbers: true,
20154 predicates: &predicates,
20155 ..ParserRuntimeOptions::default()
20156 },
20157 )
20158 .expect("the forced second alternative should parse");
20159
20160 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20161 assert_eq!(root.alt_number(), 2);
20162 assert_eq!(root.text(), "x<EOF>");
20163 assert!(deferred_actions.is_empty());
20164 assert_eq!(parser.semantic_hooks.decisions, [(0, 0, 2)]);
20165 assert_eq!(parser.number_of_syntax_errors(), 0);
20166 }
20167
20168 #[test]
20169 fn committed_walker_sll_mode_does_not_report_full_context_diagnostics() {
20170 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20171 let predicates = [(0, 0, ParserPredicate::True), (0, 1, ParserPredicate::True)];
20172 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20173 let mut parser = mini_parser(vec![
20174 TestToken::new(1).with_text("x"),
20175 TestToken::eof("parser-test", 1, 1, 1),
20176 ]);
20177 parser.set_prediction_mode(PredictionMode::Sll);
20178 parser.set_report_diagnostic_errors(true);
20179 parser.remove_error_listeners();
20180 parser.add_error_listener(RecordingErrorListener {
20181 diagnostics: Arc::clone(&diagnostics),
20182 });
20183
20184 let (tree, deferred_actions) = parser
20185 .parse_atn_rule_with_runtime_options(
20186 &atn,
20187 0,
20188 ParserRuntimeOptions {
20189 action_indices: &[(usize::MAX, 0)],
20190 predicates: &predicates,
20191 ..ParserRuntimeOptions::default()
20192 },
20193 )
20194 .expect("SLL prediction should select the first viable alternative");
20195
20196 assert_eq!(parser.node(tree).text(), "x<EOF>");
20197 assert!(deferred_actions.is_empty());
20198 assert_eq!(parser.number_of_syntax_errors(), 0);
20199 assert!(
20200 diagnostics
20201 .lock()
20202 .expect("recorded diagnostics lock")
20203 .is_empty(),
20204 "SLL mode must not retry with full context or report LL diagnostics"
20205 );
20206 }
20207
20208 #[test]
20209 fn committed_walker_filters_diagnostics_after_semantic_selection() {
20210 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20211 let predicates = [
20212 (0, 0, ParserPredicate::False),
20213 (0, 1, ParserPredicate::True),
20214 ];
20215 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20216 let mut parser = mini_parser(vec![
20217 TestToken::new(1).with_text("x"),
20218 TestToken::eof("parser-test", 1, 1, 1),
20219 ]);
20220 parser.set_prediction_mode(PredictionMode::LlExactAmbigDetection);
20221 parser.set_report_diagnostic_errors(true);
20222 parser.remove_error_listeners();
20223 parser.add_error_listener(RecordingErrorListener {
20224 diagnostics: Arc::clone(&diagnostics),
20225 });
20226
20227 let (tree, _) = parser
20228 .parse_atn_rule_with_runtime_options(
20229 &atn,
20230 0,
20231 ParserRuntimeOptions {
20232 action_indices: &[(usize::MAX, 0)],
20233 track_alt_numbers: true,
20234 predicates: &predicates,
20235 ..ParserRuntimeOptions::default()
20236 },
20237 )
20238 .expect("the true predicate should make the second alternative unique");
20239
20240 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20241 assert_eq!(root.alt_number(), 2);
20242 assert!(
20243 diagnostics
20244 .lock()
20245 .expect("recorded diagnostics lock")
20246 .is_empty(),
20247 "predicate filtering made the decision unambiguous"
20248 );
20249 }
20250
20251 #[test]
20252 fn committed_walker_skips_diagnostic_only_predicates_when_reporting_is_disabled() {
20253 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20254 let mut parser = mini_parser_with_hooks(
20255 vec![
20256 TestToken::new(1).with_text("x"),
20257 TestToken::eof("parser-test", 1, 1, 1),
20258 ],
20259 RecordingHooks::default(),
20260 );
20261 parser.set_prediction_mode(PredictionMode::LlExactAmbigDetection);
20262
20263 let (tree, _) = parser
20264 .parse_atn_rule_with_runtime_options(
20265 &atn,
20266 0,
20267 ParserRuntimeOptions {
20268 action_indices: &[(usize::MAX, 0)],
20269 track_alt_numbers: true,
20270 ..ParserRuntimeOptions::default()
20271 },
20272 )
20273 .expect("the first predicate-bearing alternative should parse");
20274
20275 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20276 assert_eq!(root.alt_number(), 1);
20277 assert_eq!(
20278 parser.semantic_hooks.predicates,
20279 [
20280 (0, 0, 0, Some("x".to_owned())),
20281 (0, 0, 0, Some("x".to_owned())),
20282 ],
20283 "diagnostic-only alternatives must not invoke semantic hooks"
20284 );
20285 }
20286
20287 #[test]
20288 fn committed_walker_falls_back_only_to_simulator_viable_alternatives() {
20289 let atn = semantic_fallback_viability_atn();
20290 let predicates = [
20291 (0, 0, ParserPredicate::False),
20292 (0, 1, ParserPredicate::True),
20293 ];
20294 let mut parser = mini_parser(vec![
20295 TestToken::new(1).with_text("a"),
20296 TestToken::new(3).with_text("c"),
20297 TestToken::eof("parser-test", 2, 1, 2),
20298 ]);
20299
20300 let (tree, deferred_actions) = parser
20301 .parse_atn_rule_with_runtime_options(
20302 &atn,
20303 0,
20304 ParserRuntimeOptions {
20305 action_indices: &[(usize::MAX, 0)],
20306 track_alt_numbers: true,
20307 predicates: &predicates,
20308 ..ParserRuntimeOptions::default()
20309 },
20310 )
20311 .expect("the true A C alternative should survive semantic fallback");
20312
20313 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20314 assert_eq!(root.alt_number(), 3);
20315 assert_eq!(root.text(), "ac<EOF>");
20316 assert!(deferred_actions.is_empty());
20317 assert_eq!(parser.number_of_syntax_errors(), 0);
20318 }
20319
20320 #[test]
20321 fn committed_walker_evaluates_predicates_reached_through_rule_calls() {
20322 let atn = rule_call_predicate_decision_atn();
20323 let predicates = [(1, 0, ParserPredicate::False)];
20324 let mut parser = mini_parser(vec![
20325 TestToken::new(1).with_text("a"),
20326 TestToken::eof("parser-test", 1, 1, 1),
20327 ]);
20328
20329 let (tree, deferred_actions) = parser
20330 .parse_atn_rule_with_runtime_options(
20331 &atn,
20332 0,
20333 ParserRuntimeOptions {
20334 action_indices: &[(usize::MAX, 0)],
20335 track_alt_numbers: true,
20336 predicates: &predicates,
20337 ..ParserRuntimeOptions::default()
20338 },
20339 )
20340 .expect("the direct caller alternative should survive the false callee predicate");
20341
20342 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20343 assert_eq!(root.alt_number(), 2);
20344 assert_eq!(root.text(), "a<EOF>");
20345 assert_eq!(root.child_rules(1).count(), 0);
20346 assert!(deferred_actions.is_empty());
20347 assert_eq!(parser.number_of_syntax_errors(), 0);
20348 }
20349
20350 #[test]
20351 fn committed_walker_uses_callee_argument_for_prediction_predicates() {
20352 let atn = rule_call_predicate_decision_atn();
20353 let predicates = [(1, 0, ParserPredicate::LocalIntEquals { value: 1 })];
20354 let rule_args = [ParserRuleArg {
20355 source_state: 2,
20356 rule_index: 1,
20357 value: 2,
20358 inherit_local: false,
20359 }];
20360 let mut parser = mini_parser(vec![
20361 TestToken::new(1).with_text("a"),
20362 TestToken::eof("parser-test", 1, 1, 1),
20363 ]);
20364
20365 let (tree, _) = parser
20366 .parse_atn_rule_with_runtime_options(
20367 &atn,
20368 0,
20369 ParserRuntimeOptions {
20370 action_indices: &[(usize::MAX, 0)],
20371 track_alt_numbers: true,
20372 predicates: &predicates,
20373 rule_args: &rule_args,
20374 ..ParserRuntimeOptions::default()
20375 },
20376 )
20377 .expect("the direct alternative should survive the false callee predicate");
20378
20379 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20380 assert_eq!(root.alt_number(), 2);
20381 assert_eq!(root.child_rules(1).count(), 0);
20382 assert_eq!(parser.number_of_syntax_errors(), 0);
20383 }
20384
20385 #[test]
20386 fn committed_predicate_star_loop_uses_single_token_deletion() {
20387 let atn = predicate_gated_star_loop_atn();
20388 let predicates = [(0, 0, ParserPredicate::True)];
20389 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20390 let mut parser = mini_parser(vec![
20391 TestToken::new(2).with_text("x"),
20392 TestToken::new(1).with_text("a"),
20393 TestToken::eof("parser-test", 2, 1, 2),
20394 ]);
20395 parser.remove_error_listeners();
20396 parser.add_error_listener(RecordingErrorListener {
20397 diagnostics: Arc::clone(&diagnostics),
20398 });
20399
20400 let (tree, deferred_actions) = parser
20401 .parse_atn_rule_with_runtime_options(
20402 &atn,
20403 0,
20404 ParserRuntimeOptions {
20405 action_indices: &[(usize::MAX, 0)],
20406 predicates: &predicates,
20407 ..ParserRuntimeOptions::default()
20408 },
20409 )
20410 .expect("the loop decision should delete the extraneous token and continue");
20411
20412 assert_eq!(parser.node(tree).text(), "xa<EOF>");
20413 assert!(deferred_actions.is_empty());
20414 assert_eq!(parser.number_of_syntax_errors(), 1);
20415 insta::assert_debug_snapshot!(
20416 "committed_predicate_star_loop_uses_single_token_deletion",
20417 *diagnostics.lock().expect("recorded diagnostics lock")
20418 );
20419 }
20420
20421 #[test]
20422 fn committed_walker_applies_legacy_and_semir_actions_before_indexed_hooks() {
20423 let atn = committed_action_then_predicate_atn();
20424 let member_actions = [ParserMemberAction {
20425 source_state: 0,
20426 member: 0,
20427 delta: 2,
20428 }];
20429 let return_actions = [ParserReturnAction {
20430 source_state: 0,
20431 rule_index: 0,
20432 name: "legacy",
20433 value: 3,
20434 }];
20435 let predicates = [(
20436 0,
20437 0,
20438 ParserPredicate::MemberEquals {
20439 member: 0,
20440 value: 7,
20441 equals: true,
20442 },
20443 )];
20444 let mut ir = SemIr::new();
20445 let semantic_member = ParserMemberAction {
20446 source_state: 0,
20447 member: 0,
20448 delta: 5,
20449 }
20450 .lower_into_semir(&mut ir);
20451 let semantic_return = ParserReturnAction {
20452 source_state: 0,
20453 rule_index: 0,
20454 name: "semantic",
20455 value: 11,
20456 }
20457 .lower_into_semir(&mut ir);
20458 let semantics = ParserSemantics {
20459 ir,
20460 predicates: Vec::new(),
20461 actions: vec![semantic_member, semantic_return],
20462 };
20463 let mut parser = mini_parser_with_hooks(
20464 vec![
20465 TestToken::new(1).with_text("x"),
20466 TestToken::eof("parser-test", 1, 1, 1),
20467 ],
20468 StatefulActionHooks::default(),
20469 );
20470
20471 let (tree, deferred_actions) = parser
20472 .parse_atn_rule_with_runtime_options(
20473 &atn,
20474 0,
20475 ParserRuntimeOptions {
20476 action_indices: &[(0, 7)],
20477 predicates: &predicates,
20478 semantics: Some(&semantics),
20479 member_actions: &member_actions,
20480 return_actions: &return_actions,
20481 ..ParserRuntimeOptions::default()
20482 },
20483 )
20484 .expect("the predicate should observe both committed member actions");
20485
20486 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20487 assert_eq!(root.text(), "x<EOF>");
20488 assert_eq!(root.int_return("legacy"), Some(3));
20489 assert_eq!(root.int_return("semantic"), Some(11));
20490 assert_eq!(parser.int_member(0), Some(7));
20491 assert!(deferred_actions.is_empty());
20492 assert_eq!(parser.semantic_hooks.events, ["action:7"]);
20493 assert_eq!(parser.number_of_syntax_errors(), 0);
20494 }
20495
20496 #[test]
20497 fn committed_walker_runs_action_once_per_star_loop_iteration() {
20498 let atn = committed_action_star_loop_atn();
20499 let mut parser = mini_parser_with_hooks(
20500 vec![
20501 TestToken::new(1).with_text("a"),
20502 TestToken::new(1).with_text("b"),
20503 TestToken::eof("parser-test", 2, 1, 2),
20504 ],
20505 StatefulActionHooks::default(),
20506 );
20507
20508 let (tree, deferred_actions) = parser
20509 .parse_atn_rule_with_runtime_options(
20510 &atn,
20511 0,
20512 ParserRuntimeOptions {
20513 action_indices: &[(2, 3)],
20514 ..ParserRuntimeOptions::default()
20515 },
20516 )
20517 .expect("the committed star loop should parse");
20518
20519 assert_eq!(parser.node(tree).text(), "ab<EOF>");
20520 assert!(deferred_actions.is_empty());
20521 assert_eq!(parser.semantic_hooks.events, ["action:3", "action:3"]);
20522 }
20523
20524 #[test]
20525 fn committed_walker_has_no_total_step_cap() {
20526 const TOKEN_COUNT: usize = RECOGNITION_DEPTH_LIMIT + 1;
20527 let atn = committed_action_star_loop_atn();
20528 let mut parser = mini_parser(repeated_x_tokens(TOKEN_COUNT));
20529 parser.set_build_parse_trees(false);
20530
20531 parser
20532 .parse_atn_rule_with_runtime_options(
20533 &atn,
20534 0,
20535 ParserRuntimeOptions {
20536 action_indices: &[(usize::MAX, 0)],
20537 ..ParserRuntimeOptions::default()
20538 },
20539 )
20540 .expect("valid committed loops must not have a total-work cap");
20541
20542 assert_eq!(parser.input.index(), TOKEN_COUNT);
20543 assert_eq!(parser.number_of_syntax_errors(), 0);
20544 }
20545
20546 #[test]
20547 fn committed_walker_rejects_non_consuming_cycles() {
20548 let atn = committed_non_consuming_cycle_atn();
20549 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
20550 parser.set_bail_on_error(true);
20551
20552 let error = parser
20553 .parse_atn_rule_with_runtime_options(
20554 &atn,
20555 0,
20556 ParserRuntimeOptions {
20557 action_indices: &[(usize::MAX, 0)],
20558 ..ParserRuntimeOptions::default()
20559 },
20560 )
20561 .expect_err("a non-consuming cycle must not spin forever");
20562
20563 assert!(
20564 error.to_string().contains("non-consuming ATN cycle"),
20565 "unexpected error: {error}"
20566 );
20567 }
20568
20569 #[test]
20570 fn deeply_nested_committed_rule_calls_grow_the_stack() {
20571 const DEPTH: usize = 4_096;
20572 const STACK_SIZE: usize = 256 * 1024;
20573 let atn = nested_rule_chain_atn(DEPTH);
20574 std::thread::Builder::new()
20575 .name("nested-committed-rules".to_owned())
20576 .stack_size(STACK_SIZE)
20577 .spawn(move || {
20578 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
20579 parser.set_build_parse_trees(false);
20580 parser
20581 .parse_atn_rule_with_runtime_options(
20582 &atn,
20583 0,
20584 ParserRuntimeOptions {
20585 action_indices: &[(usize::MAX, 0)],
20586 ..ParserRuntimeOptions::default()
20587 },
20588 )
20589 .expect("nested committed rules should grow the native stack");
20590 assert_eq!(parser.input.index(), 1);
20591 })
20592 .expect("small-stack thread should start")
20593 .join()
20594 .expect("nested committed rules should not overflow their stack");
20595 }
20596
20597 #[test]
20598 fn committed_walker_runs_action_once_per_left_recursive_operator() {
20599 let atn = committed_action_left_recursive_atn();
20600 let mut parser = mini_parser_with_hooks(
20601 vec![
20602 TestToken::new(1).with_text("a"),
20603 TestToken::new(3).with_text("+"),
20604 TestToken::new(1).with_text("b"),
20605 TestToken::new(3).with_text("+"),
20606 TestToken::new(1).with_text("c"),
20607 TestToken::eof("parser-test", 5, 1, 5),
20608 ],
20609 StatefulActionHooks::default(),
20610 );
20611
20612 let (tree, deferred_actions) = parser
20613 .parse_atn_rule_with_runtime_options(
20614 &atn,
20615 0,
20616 ParserRuntimeOptions {
20617 action_indices: &[(6, 11)],
20618 ..ParserRuntimeOptions::default()
20619 },
20620 )
20621 .expect("the committed left-recursive rule should parse");
20622
20623 assert_eq!(parser.node(tree).text(), "a+b+c");
20624 assert!(deferred_actions.is_empty());
20625 assert_eq!(parser.semantic_hooks.events, ["action:11", "action:11"]);
20626 }
20627
20628 #[test]
20629 fn committed_left_recursive_depth_cap_keeps_listener_events_balanced() {
20630 let atn = committed_action_left_recursive_atn();
20631 let events = Arc::new(Mutex::new(Vec::new()));
20632 let mut parser = mini_parser(vec![
20633 TestToken::new(1).with_text("a"),
20634 TestToken::new(3).with_text("+"),
20635 TestToken::new(1).with_text("b"),
20636 TestToken::eof("parser-test", 3, 1, 3),
20637 ]);
20638 parser.set_max_rule_depth(Some(1));
20639 parser.add_parse_listener(RecordingParseListener {
20640 events: Arc::clone(&events),
20641 });
20642
20643 let error = parser
20644 .parse_atn_rule_with_runtime_options(
20645 &atn,
20646 0,
20647 ParserRuntimeOptions {
20648 action_indices: &[(6, 11)],
20649 ..ParserRuntimeOptions::default()
20650 },
20651 )
20652 .expect_err("the left-recursive expansion should exceed the depth cap");
20653
20654 insta::assert_debug_snapshot!(
20655 "committed_left_recursive_depth_cap_keeps_listener_events_balanced",
20656 (
20657 error.to_string(),
20658 events.lock().expect("parse-listener event lock").as_slice(),
20659 )
20660 );
20661 }
20662
20663 #[test]
20664 fn committed_walker_preserves_nested_rule_listener_events() {
20665 let atn = ordinary_star_loop_atn();
20666 let events = Arc::new(Mutex::new(Vec::new()));
20667 let mut parser = mini_parser(vec![
20668 TestToken::new(1).with_text("a"),
20669 TestToken::new(1).with_text("b"),
20670 TestToken::eof("parser-test", 2, 1, 2),
20671 ]);
20672 parser.add_parse_listener(RecordingParseListener {
20673 events: Arc::clone(&events),
20674 });
20675
20676 let (tree, _) = parser
20677 .parse_atn_rule_with_runtime_options(
20678 &atn,
20679 0,
20680 ParserRuntimeOptions {
20681 action_indices: &[(usize::MAX, 0)],
20682 ..ParserRuntimeOptions::default()
20683 },
20684 )
20685 .expect("the committed nested-rule path should parse");
20686
20687 assert_eq!(parser.node(tree).text(), "ab<EOF>");
20688 assert_eq!(
20689 *events.lock().expect("parse-listener event lock"),
20690 [
20691 "enter:0", "enter:1", "exit:1", "enter:1", "exit:1", "exit:0",
20692 ]
20693 );
20694 }
20695
20696 #[test]
20697 fn committed_walker_enforces_rule_depth_cap() {
20698 let atn = ordinary_star_loop_atn();
20699 let mut parser = mini_parser(vec![
20700 TestToken::new(1).with_text("a"),
20701 TestToken::eof("parser-test", 1, 1, 1),
20702 ]);
20703 parser.set_max_rule_depth(Some(1));
20704
20705 let error = parser
20706 .parse_atn_rule_with_runtime_options(
20707 &atn,
20708 0,
20709 ParserRuntimeOptions {
20710 action_indices: &[(usize::MAX, 0)],
20711 ..ParserRuntimeOptions::default()
20712 },
20713 )
20714 .expect_err("the nested rule should exceed the committed-path cap");
20715
20716 assert!(
20717 error
20718 .to_string()
20719 .contains("rule nesting depth limit of 1 exceeded"),
20720 "unexpected error: {error}"
20721 );
20722 }
20723
20724 #[test]
20725 fn committed_abort_precedes_and_clears_unhandled_action_error() {
20726 let atn = action_then_nested_rule_atn();
20727 let mut parser = mini_parser_with_hooks(
20728 vec![TestToken::eof("parser-test", 0, 1, 0)],
20729 DecliningActionHooks::default(),
20730 );
20731 parser.set_max_rule_depth(Some(1));
20732
20733 let error = parser
20734 .parse_atn_rule_with_runtime_options(
20735 &atn,
20736 0,
20737 ParserRuntimeOptions {
20738 action_indices: &[(0, 7)],
20739 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20740 ..ParserRuntimeOptions::default()
20741 },
20742 )
20743 .expect_err("the recovered child abort must outrank the earlier action miss");
20744
20745 assert_eq!(parser.semantic_hooks.actions, [0]);
20746 assert!(
20747 error
20748 .to_string()
20749 .contains("rule nesting depth limit of 1 exceeded"),
20750 "unexpected error: {error}"
20751 );
20752 assert!(
20753 parser.take_parse_abort().is_none(),
20754 "the returned abort must not remain sticky"
20755 );
20756 assert!(
20757 parser.take_unknown_semantic_error().is_none(),
20758 "the masked action miss must not poison parser reuse"
20759 );
20760 }
20761
20762 #[test]
20763 fn top_level_committed_semantic_error_does_not_poison_reuse() {
20764 let atn = committed_action_then_predicate_atn();
20765 let predicates = [(0, 0, ParserPredicate::True)];
20766 let mut parser = mini_parser_with_hooks(
20767 vec![
20768 TestToken::new(1).with_text("x"),
20769 TestToken::eof("parser-test", 1, 1, 1),
20770 ],
20771 DecliningActionHooks::default(),
20772 );
20773
20774 let error = parser
20775 .parse_atn_rule_with_runtime_options(
20776 &atn,
20777 0,
20778 ParserRuntimeOptions {
20779 action_indices: &[(0, 7)],
20780 predicates: &predicates,
20781 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20782 ..ParserRuntimeOptions::default()
20783 },
20784 )
20785 .expect_err("the declined committed action must fail loud");
20786 assert!(
20787 error.to_string().contains("unhandled semantic action"),
20788 "unexpected error: {error}"
20789 );
20790
20791 parser.input.seek(0);
20792 let (tree, _) = parser
20793 .parse_atn_rule_with_runtime_options(
20794 &atn,
20795 0,
20796 ParserRuntimeOptions {
20797 predicates: &predicates,
20798 ..ParserRuntimeOptions::default()
20799 },
20800 )
20801 .expect("a clean interpreted reuse must not observe the prior action miss");
20802
20803 assert_eq!(parser.node(tree).text(), "x<EOF>");
20804 assert!(
20805 parser.take_unknown_semantic_error().is_none(),
20806 "the returned top-level semantic error must drain its recorded hit"
20807 );
20808 }
20809
20810 #[test]
20811 fn committed_walker_runs_handled_rule_init_before_indexed_action() {
20812 let atn = committed_action_then_predicate_atn();
20813 let mut parser = mini_parser_with_hooks(
20814 vec![
20815 TestToken::new(1).with_text("x"),
20816 TestToken::eof("parser-test", 1, 1, 1),
20817 ],
20818 InitOrderingHooks::default(),
20819 );
20820
20821 let (_, deferred_actions) = parser
20822 .parse_atn_rule_with_runtime_options(
20823 &atn,
20824 0,
20825 ParserRuntimeOptions {
20826 init_action_rules: &[0],
20827 action_indices: &[(0, 7)],
20828 ..ParserRuntimeOptions::default()
20829 },
20830 )
20831 .expect("the named action should observe rule-init state");
20832
20833 assert!(deferred_actions.is_empty());
20834 assert_eq!(
20835 parser.semantic_hooks.events,
20836 ["init", "action:7:initialized=true", "predicate:true",]
20837 );
20838 }
20839
20840 #[test]
20841 fn committed_walker_defers_unhandled_rule_init_for_legacy_replay() {
20842 let atn = token_then_eof_atn();
20843 let mut parser = mini_parser(vec![
20844 TestToken::new(1).with_text("x"),
20845 TestToken::eof("parser-test", 1, 1, 1),
20846 ]);
20847
20848 let (_, deferred_actions) = parser
20849 .parse_atn_rule_with_runtime_options(
20850 &atn,
20851 0,
20852 ParserRuntimeOptions {
20853 init_action_rules: &[0],
20854 action_indices: &[(usize::MAX, 0)],
20855 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20856 ..ParserRuntimeOptions::default()
20857 },
20858 )
20859 .expect("a declined init should remain available for legacy replay");
20860
20861 assert_eq!(
20862 deferred_actions,
20863 [ParserAction::new_rule_init(0, 0, Some(0))]
20864 );
20865 }
20866
20867 #[test]
20868 fn committed_walker_dispatches_recovery_diagnostics() {
20869 let atn = noop_action_then_token_then_eof_atn();
20870 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20871 let mut parser = mini_parser_with_hooks(
20872 vec![
20873 TestToken::new(1).with_text("x"),
20874 TestToken::new(2).with_text("y"),
20875 TestToken::eof("parser-test", 2, 1, 2),
20876 ],
20877 StatefulActionHooks::default(),
20878 );
20879 parser.remove_error_listeners();
20880 parser.add_error_listener(RecordingErrorListener {
20881 diagnostics: Arc::clone(&diagnostics),
20882 });
20883
20884 let (tree, _) = parser
20885 .parse_atn_rule_with_runtime_options(
20886 &atn,
20887 0,
20888 ParserRuntimeOptions {
20889 action_indices: &[(0, 5)],
20890 ..ParserRuntimeOptions::default()
20891 },
20892 )
20893 .expect("the committed rule should recover");
20894
20895 assert_eq!(parser.node(tree).text(), "xy<EOF>");
20896 assert_eq!(parser.number_of_syntax_errors(), 1);
20897 insta::assert_debug_snapshot!(
20898 "committed_walker_dispatches_recovery_diagnostics",
20899 *diagnostics.lock().expect("recorded diagnostics lock")
20900 );
20901 }
20902
20903 #[test]
20904 fn committed_bail_error_notifies_error_listener() {
20905 let atn = noop_action_then_token_then_eof_atn();
20906 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20907 let mut parser = mini_parser(vec![
20908 TestToken::new(2)
20909 .with_text("y")
20910 .with_span(0, 0)
20911 .with_byte_span(0, 1)
20912 .with_position(3, 5),
20913 TestToken::eof("parser-test", 1, 1, 1),
20914 ]);
20915 parser.set_bail_on_error(true);
20916 parser.remove_error_listeners();
20917 parser.add_error_listener(RecordingErrorListener {
20918 diagnostics: Arc::clone(&diagnostics),
20919 });
20920
20921 let error = parser
20922 .parse_atn_rule_with_runtime_options(
20923 &atn,
20924 0,
20925 ParserRuntimeOptions {
20926 action_indices: &[(0, 5)],
20927 ..ParserRuntimeOptions::default()
20928 },
20929 )
20930 .expect_err("bail mode must return the committed token mismatch");
20931 let diagnostics = diagnostics
20932 .lock()
20933 .expect("recorded diagnostics lock")
20934 .clone();
20935
20936 insta::assert_debug_snapshot!(
20937 "committed_bail_error_notifies_error_listener",
20938 (error, diagnostics)
20939 );
20940 }
20941
20942 #[test]
20943 fn semantic_hook_handles_committed_parser_action() {
20944 let atn = token_then_eof_atn();
20945 let mut parser = mini_parser_with_hooks(
20946 vec![
20947 TestToken::new(1).with_text("x"),
20948 TestToken::eof("parser-test", 1, 1, 1),
20949 ],
20950 RecordingHooks::default(),
20951 );
20952 let (tree, _) = parser
20953 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
20954 .expect("rule parses before action hook is tested");
20955
20956 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20957 assert_eq!(
20958 parser.semantic_hooks.actions,
20959 vec![(42, "x".to_owned(), Some("s".to_owned()))]
20960 );
20961 assert_eq!(
20962 parser.semantic_hooks.action_trees,
20963 [Some("x<EOF>".to_owned())]
20964 );
20965 }
20966
20967 #[test]
20968 fn unhandled_committed_action_fails_loud_under_error_policy() {
20969 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
20973 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
20974 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
20975
20976 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20978
20979 let error = parser
20980 .take_unknown_semantic_error()
20981 .expect("an unhandled committed action under Error policy must fail loud");
20982 let AntlrError::Unsupported(message) = error else {
20983 panic!("expected AntlrError::Unsupported, got {error:?}");
20984 };
20985 assert!(
20986 message.contains("unhandled semantic action") && message.contains("state=42"),
20987 "message should name the dropped action coordinate: {message}"
20988 );
20989
20990 let mut lenient =
20992 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
20993 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
20994 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20995 assert!(lenient.take_unknown_semantic_error().is_none());
20996 }
20997
20998 #[test]
20999 fn translated_predicate_is_unaffected_by_error_policy() {
21000 let atn = predicate_after_token_atn();
21001 let mut parser = mini_parser(vec![
21002 TestToken::new(1).with_text("x"),
21003 TestToken::new(2).with_text("y"),
21004 TestToken::eof("parser-test", 2, 1, 2),
21005 ]);
21006
21007 let (tree, _) = parser
21008 .parse_atn_rule_with_runtime_options(
21009 &atn,
21010 0,
21011 ParserRuntimeOptions {
21012 predicates: &[(0, 0, ParserPredicate::True)],
21013 unknown_predicate_policy: UnknownSemanticPolicy::Error,
21014 ..ParserRuntimeOptions::default()
21015 },
21016 )
21017 .expect("a predicate covered by the table is not an unknown coordinate");
21018
21019 assert_eq!(parser.node(tree).text(), "xy");
21020 }
21021
21022 #[test]
21027 fn parser_speculative_replay_threads_stack_member_state() {
21028 let mut ir = SemIr::new();
21029 let one = ir.expr(PExpr::Int(1));
21030 let push = ir.stmt(AStmt::PushMember(0, one));
21031 let pop = ir.stmt(AStmt::PopMember(0));
21032 let semantics = ParserSemantics {
21033 ir,
21034 predicates: Vec::new(),
21035 actions: vec![
21036 ParserSemanticAction {
21037 source_state: 1,
21038 rule_index: usize::MAX,
21039 stmt: push,
21040 speculative: true,
21041 },
21042 ParserSemanticAction {
21043 source_state: 2,
21044 rule_index: usize::MAX,
21045 stmt: pop,
21046 speculative: true,
21047 },
21048 ],
21049 };
21050
21051 let pushed = member_values_after_action(1, &[], Some(&semantics), &MemberEnv::new());
21053 assert_eq!(pushed.stack_top(0), Some(1));
21054 assert_eq!(pushed.stack_len(0), 1);
21055
21056 assert_eq!(MemberEnv::new().stack_len(0), 0);
21059
21060 let popped = member_values_after_action(2, &[], Some(&semantics), &pushed);
21063 assert_eq!(popped.stack_top(0), None);
21064 assert_eq!(popped, MemberEnv::new(), "emptied stack must canonicalize");
21065
21066 let underflowed = member_values_after_action(2, &[], Some(&semantics), &MemberEnv::new());
21068 assert_eq!(underflowed, MemberEnv::new());
21069 }
21070
21071 fn hook_predicate_semantics() -> ParserSemantics {
21076 let mut ir = SemIr::new();
21077 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
21078 ParserSemantics {
21079 ir,
21080 predicates: vec![ParserSemanticPredicate {
21081 rule_index: 0,
21082 pred_index: 0,
21083 expr,
21084 failure_message: None,
21085 }],
21086 actions: Vec::new(),
21087 }
21088 }
21089
21090 #[derive(Debug, Default)]
21091 struct DecliningHooks;
21092
21093 impl SemanticHooks for DecliningHooks {}
21094
21095 #[test]
21096 fn semir_hook_none_falls_through_to_assume_true() {
21097 let atn = predicate_after_token_atn();
21098 let semantics = hook_predicate_semantics();
21099 let mut parser = mini_parser_with_hooks(
21100 vec![
21101 TestToken::new(1).with_text("x"),
21102 TestToken::new(2).with_text("y"),
21103 TestToken::eof("parser-test", 2, 1, 2),
21104 ],
21105 DecliningHooks,
21106 );
21107
21108 let (tree, _) = parser
21109 .parse_atn_rule_with_runtime_options(
21110 &atn,
21111 0,
21112 ParserRuntimeOptions {
21113 semantics: Some(&semantics),
21114 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
21115 ..ParserRuntimeOptions::default()
21116 },
21117 )
21118 .expect("a declined SemIR hook must pass under assume-true");
21119
21120 assert_eq!(parser.node(tree).text(), "xy");
21121 }
21122
21123 #[test]
21124 fn semir_hook_none_falls_through_to_assume_false() {
21125 let atn = predicate_after_token_atn();
21126 let semantics = hook_predicate_semantics();
21127 let mut parser = mini_parser_with_hooks(
21128 vec![
21129 TestToken::new(1).with_text("x"),
21130 TestToken::new(2).with_text("y"),
21131 TestToken::eof("parser-test", 2, 1, 2),
21132 ],
21133 DecliningHooks,
21134 );
21135
21136 let result = parser.parse_atn_rule_with_runtime_options(
21137 &atn,
21138 0,
21139 ParserRuntimeOptions {
21140 semantics: Some(&semantics),
21141 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
21142 ..ParserRuntimeOptions::default()
21143 },
21144 );
21145
21146 assert!(
21147 result.is_err(),
21148 "a declined SemIR hook must fail the only guarded path under assume-false"
21149 );
21150 }
21151
21152 #[test]
21153 fn semir_hook_none_records_coordinate_under_error_policy() {
21154 let atn = predicate_after_token_atn();
21155 let semantics = hook_predicate_semantics();
21156 let mut parser = mini_parser_with_hooks(
21157 vec![
21158 TestToken::new(1).with_text("x"),
21159 TestToken::new(2).with_text("y"),
21160 TestToken::eof("parser-test", 2, 1, 2),
21161 ],
21162 DecliningHooks,
21163 );
21164
21165 let error = parser
21166 .parse_atn_rule_with_runtime_options(
21167 &atn,
21168 0,
21169 ParserRuntimeOptions {
21170 semantics: Some(&semantics),
21171 unknown_predicate_policy: UnknownSemanticPolicy::Error,
21172 ..ParserRuntimeOptions::default()
21173 },
21174 )
21175 .expect_err("a declined SemIR hook under Error policy must fail the parse");
21176
21177 let AntlrError::Unsupported(message) = error else {
21178 panic!("expected AntlrError::Unsupported, got {error:?}");
21179 };
21180 assert!(
21181 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
21182 "message should name the unresolved coordinate: {message}"
21183 );
21184 }
21185
21186 #[test]
21187 fn generated_direct_predicate_honors_installed_policy() {
21188 let semantics = hook_predicate_semantics();
21194 let context = ParserRuleContext::new(0, -1);
21195
21196 let mut assume_true =
21197 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21198 assert!(
21199 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
21200 &semantics, 0, 0, &context, 0
21201 ),
21202 "default AssumeTrue accepts a declined hook"
21203 );
21204 assert!(assume_true.take_unknown_semantic_error().is_none());
21205
21206 let mut error_policy =
21207 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21208 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
21209 assert!(
21210 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
21211 &semantics, 0, 0, &context, 0
21212 ),
21213 "Error policy rejects a declined hook on the generated-direct path"
21214 );
21215 let error = error_policy
21216 .take_unknown_semantic_error()
21217 .expect("Error policy records the unresolved coordinate for the generated path");
21218 let AntlrError::Unsupported(message) = error else {
21219 panic!("expected AntlrError::Unsupported, got {error:?}");
21220 };
21221 assert!(message.contains("pred_index=0"), "message: {message}");
21222 }
21223
21224 #[test]
21225 fn parser_rule_start_skips_leading_hidden_tokens() {
21226 let atn = token_then_eof_atn();
21227 let mut parser = mini_parser(vec![
21228 TestToken::new(99)
21229 .with_text(" ")
21230 .with_channel(HIDDEN_CHANNEL),
21231 TestToken::new(1).with_text("x"),
21232 TestToken::eof("parser-test", 2, 1, 2),
21233 ]);
21234
21235 let tree = parser
21236 .parse_atn_rule(&atn, 0)
21237 .expect("artificial parser rule should parse");
21238 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
21239 panic!("rule node should be present");
21240 };
21241 assert_eq!(
21242 rule.start()
21243 .expect("rule should have a start token")
21244 .token_type(),
21245 1
21246 );
21247 }
21248
21249 #[test]
21250 fn parser_action_after_eof_stops_at_eof_token() {
21251 let atn = eof_then_action_atn();
21252 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
21253
21254 let (_, actions) = parser
21255 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
21256 .expect("EOF action rule should parse");
21257
21258 assert_eq!(actions.len(), 1);
21259 assert_eq!(actions[0].stop_index(), Some(0));
21260 assert_eq!(
21261 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
21262 ""
21263 );
21264 }
21265
21266 #[test]
21267 fn after_action_stop_uses_rule_context_stop_not_cursor() {
21268 let mut id = TestToken::new(1).with_text("x");
21273 id.set_token_index(0);
21274 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
21275 eof.set_token_index(1);
21276 let mut parser = mini_parser(vec![id.clone(), eof]);
21277 parser.consume();
21279 assert_eq!(parser.la(1), TOKEN_EOF);
21280
21281 let mut ctx = ParserRuleContext::new(0, 0);
21284 parser.set_context_stop(
21285 &mut ctx,
21286 parser.token_id_at(0).expect("ID token should be buffered"),
21287 );
21288 let tree = parser.rule_node(ctx);
21289
21290 let current_index = parser.input.index();
21291 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
21293 assert_eq!(
21295 parser.after_action_stop_index_for_tree(tree, current_index),
21296 Some(0)
21297 );
21298 }
21299
21300 #[test]
21301 fn after_action_start_uses_rule_context_start_not_cursor() {
21302 let mut parser = mini_parser(vec![
21307 TestToken::new(9)
21308 .with_text(" ")
21309 .with_channel(HIDDEN_CHANNEL),
21310 TestToken::new(9)
21311 .with_text(" ")
21312 .with_channel(HIDDEN_CHANNEL),
21313 TestToken::new(1).with_text("x"),
21314 TestToken::eof("parser-test", 3, 1, 3),
21315 ]);
21316
21317 let mut ctx = ParserRuleContext::new(0, 0);
21318 parser.set_context_start(
21319 &mut ctx,
21320 parser.token_id_at(2).expect("ID token should be buffered"),
21321 );
21322 let tree = parser.rule_node(ctx);
21323
21324 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
21327
21328 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
21330 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
21331 }
21332
21333 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
21334 FastRecognizeOutcome {
21335 index,
21336 consumed_eof,
21337 diagnostics: DiagnosticSeqId::EMPTY,
21338 deferred_nodes: FastDeferredNodeId::EMPTY,
21339 nodes: NodeSeqId(marker),
21340 }
21341 }
21342
21343 #[test]
21344 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
21345 let mut outcomes = vec![
21346 clean_fast_outcome(4, false, 0),
21347 clean_fast_outcome(2, false, 1),
21348 clean_fast_outcome(4, false, 2),
21349 clean_fast_outcome(4, true, 3),
21350 clean_fast_outcome(2, false, 4),
21351 ];
21352 let mut scratch = FastOutcomeDedupScratch::default();
21353
21354 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21355
21356 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
21357 assert_eq!(
21358 outcomes
21359 .iter()
21360 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
21361 .collect::<Vec<_>>(),
21362 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
21363 );
21364 assert!(scratch.dense_words.is_empty());
21365 assert!(scratch.sparse_keys.is_empty());
21366 }
21367
21368 #[test]
21369 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
21370 let mut scratch = FastOutcomeDedupScratch::default();
21371 let mut outcomes = (100..109)
21372 .flat_map(|index| {
21373 [
21374 clean_fast_outcome(
21375 index,
21376 false,
21377 u32::try_from(index).expect("test index fits in u32"),
21378 ),
21379 clean_fast_outcome(index, false, u32::MAX),
21380 ]
21381 })
21382 .collect();
21383
21384 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21385
21386 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
21387 assert_eq!(outcomes.len(), 9);
21388 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
21389 let dense_capacity = scratch.dense_words.capacity();
21390
21391 let mut reused = (1_000..1_009)
21392 .map(|index| {
21393 clean_fast_outcome(
21394 index,
21395 false,
21396 u32::try_from(index).expect("test index fits in u32"),
21397 )
21398 })
21399 .collect();
21400 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
21401
21402 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
21403 assert_eq!(reused.len(), 9);
21404 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
21405 }
21406
21407 #[test]
21408 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
21409 let mut scratch = FastOutcomeDedupScratch::default();
21410 let sparse_indexes = [
21411 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
21412 ];
21413 let mut outcomes = sparse_indexes
21414 .into_iter()
21415 .chain([400_000])
21416 .enumerate()
21417 .map(|(marker, index)| {
21418 clean_fast_outcome(
21419 index,
21420 false,
21421 u32::try_from(marker).expect("test marker fits in u32"),
21422 )
21423 })
21424 .collect();
21425
21426 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21427
21428 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21429 assert_eq!(outcomes.len(), sparse_indexes.len());
21430 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
21431 let sparse_capacity = scratch.sparse_keys.capacity();
21432
21433 let mut reused = sparse_indexes
21434 .into_iter()
21435 .map(|index| {
21436 clean_fast_outcome(
21437 index,
21438 false,
21439 u32::try_from(index).expect("test index fits in u32"),
21440 )
21441 })
21442 .collect();
21443 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
21444
21445 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21446 assert_eq!(reused.len(), sparse_indexes.len());
21447 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
21448 }
21449
21450 #[test]
21451 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
21452 let mut scratch = FastOutcomeDedupScratch::default();
21453 scratch
21454 .sparse_keys
21455 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
21456 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
21457 let mut outcomes = (0..9)
21458 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
21459 .collect();
21460
21461 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21462
21463 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21464 assert!(scratch.sparse_keys.is_empty());
21465 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
21466 }
21467
21468 #[test]
21469 fn fast_outcome_selection_respects_sll_tie_order() {
21470 let mut arena = RecognitionArena::default();
21471 let first = FastRecognizeOutcome {
21472 index: 1,
21473 consumed_eof: false,
21474 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21475 line: 1,
21476 column: 0,
21477 message: "mismatched input 'x'".to_owned(),
21478 offending: None,
21479 }]),
21480 deferred_nodes: FastDeferredNodeId::EMPTY,
21481 nodes: NodeSeqId::EMPTY,
21482 };
21483 let second = FastRecognizeOutcome {
21484 index: first.index,
21485 consumed_eof: first.consumed_eof,
21486 diagnostics: DiagnosticSeqId::EMPTY,
21487 deferred_nodes: FastDeferredNodeId::EMPTY,
21488 nodes: NodeSeqId::EMPTY,
21489 };
21490
21491 let selected = select_best_fast_outcome(
21492 [first, second].into_iter(),
21493 PredictionMode::Sll,
21494 None,
21495 |_| panic!("caller-follow token probe should not run"),
21496 &arena,
21497 )
21498 .expect("one outcome should be selected");
21499 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
21500 let eof_second = FastRecognizeOutcome {
21501 index: second.index,
21502 consumed_eof: true,
21503 diagnostics: DiagnosticSeqId::EMPTY,
21504 deferred_nodes: FastDeferredNodeId::EMPTY,
21505 nodes: NodeSeqId::EMPTY,
21506 };
21507 let selected = select_best_fast_outcome(
21508 [first, eof_second].into_iter(),
21509 PredictionMode::Sll,
21510 None,
21511 |_| panic!("caller-follow token probe should not run"),
21512 &arena,
21513 )
21514 .expect("one outcome should be selected");
21515 assert!(!selected.consumed_eof);
21516 let selected = select_best_fast_outcome(
21517 [first, second].into_iter(),
21518 PredictionMode::Ll,
21519 None,
21520 |_| panic!("caller-follow token probe should not run"),
21521 &arena,
21522 )
21523 .expect("one outcome should be selected");
21524 assert!(selected.diagnostics.is_empty());
21525 }
21526
21527 #[test]
21528 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
21529 let mut arena = RecognitionArena::default();
21530 let first = FastRecognizeOutcome {
21531 index: 3,
21532 consumed_eof: false,
21533 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21534 line: 1,
21535 column: 0,
21536 message: "mismatched input 'x' expecting 'a'".to_owned(),
21537 offending: None,
21538 }]),
21539 deferred_nodes: FastDeferredNodeId::EMPTY,
21540 nodes: NodeSeqId::EMPTY,
21541 };
21542 let same_rank = FastRecognizeOutcome {
21543 index: first.index,
21544 consumed_eof: first.consumed_eof,
21545 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21546 line: 1,
21547 column: 0,
21548 message: "mismatched input 'x' expecting 'b'".to_owned(),
21549 offending: None,
21550 }]),
21551 deferred_nodes: FastDeferredNodeId::EMPTY,
21552 nodes: NodeSeqId::EMPTY,
21553 };
21554 let better_rank = FastRecognizeOutcome {
21555 index: first.index,
21556 consumed_eof: first.consumed_eof,
21557 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21558 line: 1,
21559 column: 0,
21560 message: "missing 'a' at 'x'".to_owned(),
21561 offending: None,
21562 }]),
21563 deferred_nodes: FastDeferredNodeId::EMPTY,
21564 nodes: NodeSeqId::EMPTY,
21565 };
21566 let mut outcomes = vec![first, same_rank, better_rank];
21567
21568 dedupe_fast_outcomes(&mut outcomes, &arena);
21569
21570 assert_eq!(outcomes.len(), 2);
21571 assert_eq!(
21572 arena
21573 .diagnostics(outcomes[0].diagnostics)
21574 .next()
21575 .expect("first diagnostic")
21576 .message,
21577 "mismatched input 'x' expecting 'a'"
21578 );
21579 assert_eq!(
21580 arena
21581 .diagnostics(outcomes[1].diagnostics)
21582 .next()
21583 .expect("second diagnostic")
21584 .message,
21585 "missing 'a' at 'x'"
21586 );
21587 }
21588
21589 #[test]
21590 fn fast_outcome_selection_prefers_generated_caller_follow() {
21591 let arena = RecognitionArena::default();
21592 let earlier = FastRecognizeOutcome {
21593 index: 7,
21594 consumed_eof: false,
21595 diagnostics: DiagnosticSeqId::EMPTY,
21596 deferred_nodes: FastDeferredNodeId::EMPTY,
21597 nodes: NodeSeqId::EMPTY,
21598 };
21599 let later = FastRecognizeOutcome {
21600 index: 8,
21601 consumed_eof: false,
21602 diagnostics: DiagnosticSeqId::EMPTY,
21603 deferred_nodes: FastDeferredNodeId::EMPTY,
21604 nodes: NodeSeqId::EMPTY,
21605 };
21606 let mut follow = TokenBitSet::default();
21607 follow.insert(5);
21608
21609 let selected = select_best_fast_outcome(
21610 [later, earlier].into_iter(),
21611 PredictionMode::Ll,
21612 Some(&follow),
21613 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
21614 &arena,
21615 )
21616 .expect("one outcome should be selected");
21617 assert_eq!(selected.index, 7);
21618
21619 let selected = select_best_fast_outcome(
21620 [later, earlier].into_iter(),
21621 PredictionMode::Ll,
21622 Some(&follow),
21623 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
21624 &arena,
21625 )
21626 .expect("one outcome should be selected");
21627 assert_eq!(selected.index, 8);
21628
21629 let indented_next_statement = FastRecognizeOutcome {
21630 index: 9,
21631 consumed_eof: false,
21632 diagnostics: DiagnosticSeqId::EMPTY,
21633 deferred_nodes: FastDeferredNodeId::EMPTY,
21634 nodes: NodeSeqId::EMPTY,
21635 };
21636 let selected = select_best_fast_outcome(
21637 [indented_next_statement, earlier].into_iter(),
21638 PredictionMode::Ll,
21639 Some(&follow),
21640 |index| {
21641 let is_boundary = index == 7;
21642 let is_boundary_gap = matches!(index, 7 | 8);
21643 (
21644 if index == 7 { 5 } else { TOKEN_EOF },
21645 is_boundary,
21646 is_boundary_gap,
21647 )
21648 },
21649 &arena,
21650 )
21651 .expect("one outcome should be selected");
21652 assert_eq!(selected.index, 7);
21653
21654 let continuation = FastRecognizeOutcome {
21655 index: 10,
21656 consumed_eof: false,
21657 diagnostics: DiagnosticSeqId::EMPTY,
21658 deferred_nodes: FastDeferredNodeId::EMPTY,
21659 nodes: NodeSeqId::EMPTY,
21660 };
21661 let selected = select_best_fast_outcome(
21662 [continuation, earlier].into_iter(),
21663 PredictionMode::Ll,
21664 Some(&follow),
21665 |index| {
21666 let is_boundary = matches!(index, 7 | 9);
21667 (
21668 if index == 7 { 5 } else { TOKEN_EOF },
21669 is_boundary,
21670 is_boundary,
21671 )
21672 },
21673 &arena,
21674 )
21675 .expect("one outcome should be selected");
21676 assert_eq!(selected.index, 10);
21677
21678 let selected = select_best_fast_outcome(
21679 [earlier, later].into_iter(),
21680 PredictionMode::Sll,
21681 Some(&follow),
21682 |_| panic!("caller-follow token probe should not run in SLL mode"),
21683 &arena,
21684 )
21685 .expect("one outcome should be selected");
21686 assert_eq!(selected.index, 8);
21687 }
21688
21689 #[test]
21690 fn caller_follow_boundary_text_requires_separator_shape() {
21691 assert!(is_caller_follow_boundary_text(";"));
21692 assert!(is_caller_follow_boundary_text("\n"));
21693 assert!(is_caller_follow_boundary_text("\r\n "));
21694 assert!(is_caller_follow_boundary_text(";\n"));
21695 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
21696 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
21697 assert!(!is_caller_follow_boundary_text("identifier"));
21698 assert!(is_caller_follow_boundary_gap_text(" \t "));
21699 assert!(is_caller_follow_boundary_gap_text("\n "));
21700 assert!(is_caller_follow_boundary_gap_text(";\t"));
21701 assert!(!is_caller_follow_boundary_gap_text(
21702 "\"\"\"line1\nline2\"\"\""
21703 ));
21704 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
21705 }
21706
21707 #[test]
21708 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
21709 let mut parser = mini_parser(vec![
21710 TestToken::new(5).with_text("\n"),
21711 TestToken::new(6)
21712 .with_text("// comment\n")
21713 .with_channel(HIDDEN_CHANNEL),
21714 TestToken::new(1).with_text("x"),
21715 TestToken::eof("parser-test", 1, 2, 0),
21716 ]);
21717
21718 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
21719 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
21720 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
21721 }
21722
21723 #[test]
21724 fn caller_follow_token_info_uses_stream_visible_channel() {
21725 let source = Source {
21726 tokens: vec![
21727 TestToken::new(5).with_text("\n").with_channel(2),
21728 TestToken::new(1).with_text("x").with_channel(2),
21729 TestToken::new(6)
21730 .with_text("// comment\n")
21731 .with_channel(HIDDEN_CHANNEL),
21732 TestToken::eof("parser-test", 1, 2, 0),
21733 ],
21734 index: 0,
21735 };
21736 let data = RecognizerData::new(
21737 "Mini.g4",
21738 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21739 );
21740 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
21741
21742 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
21743 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
21744 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
21745 }
21746
21747 #[test]
21748 fn reset_per_parse_caches_clears_state_expected_token_cache() {
21749 let atn = token_then_eof_atn();
21750 let mut parser = mini_parser(Vec::new());
21751
21752 let _ = parser.cached_state_expected_token_set(&atn, 0);
21753 assert!(!parser.state_expected_token_cache.is_empty());
21754
21755 parser.reset_per_parse_caches();
21756 assert!(parser.state_expected_token_cache.is_empty());
21757 }
21758
21759 #[test]
21760 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
21761 let cyclic = epsilon_cycle_atn();
21762 let acyclic = token_then_eof_atn();
21763 let mut parser = mini_parser(Vec::new());
21764
21765 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
21766 assert_eq!(
21767 parser.empty_cycle_cache_atn,
21768 Some(SharedAtnCacheKey::for_atn(&cyclic))
21769 );
21770 assert_eq!(parser.empty_cycle_cache[1], Some(true));
21771
21772 parser.reset_per_parse_caches();
21773 assert_eq!(parser.empty_cycle_cache[1], Some(true));
21774 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
21775
21776 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
21777 assert_eq!(
21778 parser.empty_cycle_cache_atn,
21779 Some(SharedAtnCacheKey::for_atn(&acyclic))
21780 );
21781 assert_eq!(parser.empty_cycle_cache[1], Some(false));
21782 }
21783
21784 #[test]
21785 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
21786 let source = Source {
21787 tokens: vec![
21788 TestToken::new(1).with_text("x"),
21789 TestToken::eof("parser-test", 1, 1, 1),
21790 ],
21791 index: 0,
21792 };
21793 let data = RecognizerData::new(
21794 "Mini.g4",
21795 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21796 );
21797 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
21798 let expected = ExpectedTokens {
21799 index: Some(0),
21800 symbols: BTreeSet::new(),
21801 no_viable: None,
21802 };
21803
21804 let (_, message) = parser.expected_error_message(0, 0, &expected);
21805
21806 assert_eq!(message, "mismatched input 'x'");
21807 }
21808
21809 #[test]
21810 fn eof_rule_stop_index_points_at_eof_token() {
21811 let source = Source {
21812 tokens: vec![
21813 TestToken::new(1).with_text("x"),
21814 TestToken::eof("parser-test", 1, 1, 1),
21815 ],
21816 index: 0,
21817 };
21818 let data = RecognizerData::new(
21819 "Mini.g4",
21820 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21821 );
21822 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
21823
21824 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
21825 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
21826 }
21827
21828 #[test]
21829 fn generated_parser_action_uses_current_rule_stop_boundary() {
21830 let mut parser = mini_parser(vec![
21831 TestToken::new(1).with_text("x"),
21832 TestToken::eof("parser-test", 1, 1, 1),
21833 ]);
21834
21835 parser.match_token(1).expect("token should match");
21836 let action = parser.parser_action_at_current(7, 0, 0, false);
21837 assert_eq!(action.source_state(), 7);
21838 assert_eq!(action.rule_index(), 0);
21839 assert_eq!(action.start_index(), 0);
21840 assert_eq!(action.stop_index(), Some(0));
21841
21842 parser.match_eof().expect("EOF should match");
21843 let action = parser.parser_action_at_current(8, 0, 0, true);
21844 assert_eq!(action.stop_index(), Some(1));
21845 }
21846
21847 #[test]
21848 fn folds_left_recursive_boundary_into_rule_node() {
21849 let mut arena = RecognitionArena::default();
21850 let first = arena.push_node(ArenaRecognizedNode::Token {
21851 token: TokenId::try_from(0).expect("test token ID"),
21852 });
21853 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
21854 rule_index: 1,
21855 alt_number: 3,
21856 });
21857 let second = arena.push_node(ArenaRecognizedNode::Token {
21858 token: TokenId::try_from(1).expect("test token ID"),
21859 });
21860 let mut nodes = NodeSeqId::EMPTY;
21861 for node in [first, boundary, second].into_iter().rev() {
21862 nodes = arena.prepend(nodes, node);
21863 }
21864
21865 let folded = arena.fold_left_recursive_boundaries(nodes);
21866 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
21867
21868 assert_eq!(folded_nodes.len(), 2);
21869 let ArenaRecognizedNode::Rule {
21870 rule_index,
21871 invoking_state,
21872 alt_number,
21873 start_index,
21874 stop_index,
21875 children,
21876 ..
21877 } = arena.node(folded_nodes[0])
21878 else {
21879 panic!("first folded node should be a rule");
21880 };
21881 insta::assert_debug_snapshot!(
21885 "folds_left_recursive_boundary_into_rule_node",
21886 (
21887 rule_index,
21888 invoking_state,
21889 alt_number,
21890 start_index,
21891 stop_index
21892 )
21893 );
21894 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
21895 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
21896
21897 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
21898 assert_eq!(
21899 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
21900 (4, 3, 1)
21901 );
21902 assert_eq!(
21903 (stats.total_links, stats.live_links, stats.dead_links),
21904 (9, 3, 6)
21905 );
21906 }
21907
21908 #[test]
21909 fn recognition_arena_reports_live_dead_and_retained_capacity() {
21910 let mut arena = RecognitionArena::default();
21911 let token = arena.push_node(ArenaRecognizedNode::Token {
21912 token: TokenId::try_from(0).expect("test token ID"),
21913 });
21914 let extra = arena.push_extra(RecognitionExtra::MissingToken {
21915 token_type: 2,
21916 at_index: 1,
21917 text: "<missing X>".to_owned(),
21918 });
21919 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
21920 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
21921 token: TokenId::try_from(1).expect("test token ID"),
21922 });
21923 let mut live = NodeSeqId::EMPTY;
21924 live = arena.prepend(live, missing);
21925 live = arena.prepend(live, token);
21926 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
21927 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
21928 line: 1,
21929 column: 0,
21930 message: "missing X".to_owned(),
21931 offending: None,
21932 }]);
21933 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
21934 line: 1,
21935 column: 1,
21936 message: "discarded".to_owned(),
21937 offending: None,
21938 }]);
21939 let deferred_children = arena.deferred_fragment(live);
21940 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
21941 rule_index: 0,
21942 invoking_state: -1,
21943 start_index: 0,
21944 stop_index: Some(1),
21945 deferred_children,
21946 children: NodeSeqId::EMPTY,
21947 });
21948
21949 let stats = arena.stats(live, live_diagnostics);
21950
21951 assert_eq!(
21952 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
21953 (3, 2, 1)
21954 );
21955 assert_eq!(
21956 (stats.total_links, stats.live_links, stats.dead_links),
21957 (5, 3, 2)
21958 );
21959 assert_eq!(
21960 (stats.total_extras, stats.live_extras, stats.dead_extras),
21961 (3, 2, 1)
21962 );
21963 assert!(size_of::<SeqLink>() <= 8);
21964 assert!(size_of::<DiagnosticLink>() <= 8);
21965 assert!(size_of::<FastDeferredNode>() <= 12);
21966 assert!(size_of::<FastDeferredRule>() <= 28);
21967 assert!(size_of::<FastRecognizeOutcome>() <= 24);
21968 let capacities = (
21969 stats.node_capacity,
21970 stats.link_capacity,
21971 stats.extra_capacity,
21972 );
21973 let deferred_capacities = (
21974 arena.deferred_nodes.capacity(),
21975 arena.deferred_rules.capacity(),
21976 );
21977
21978 arena.reset();
21979 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
21980 assert_eq!(
21981 (reset.total_nodes, reset.total_links, reset.total_extras),
21982 (0, 0, 0)
21983 );
21984 assert_eq!(
21985 (
21986 reset.node_capacity,
21987 reset.link_capacity,
21988 reset.extra_capacity,
21989 ),
21990 capacities
21991 );
21992 assert!(arena.deferred_nodes.is_empty());
21993 assert!(arena.deferred_rules.is_empty());
21994 assert_eq!(
21995 (
21996 arena.deferred_nodes.capacity(),
21997 arena.deferred_rules.capacity(),
21998 ),
21999 deferred_capacities
22000 );
22001 }
22002
22003 #[test]
22004 fn parser_computes_recognition_arena_stats_on_demand() {
22005 let mut parser = mini_parser(Vec::new());
22006 let live = parser
22007 .recognition_arena
22008 .push_node(ArenaRecognizedNode::Token {
22009 token: TokenId::try_from(0).expect("test token ID"),
22010 });
22011 let discarded = parser
22012 .recognition_arena
22013 .push_node(ArenaRecognizedNode::ErrorToken {
22014 token: TokenId::try_from(1).expect("test token ID"),
22015 });
22016 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
22017 let _discarded_root = parser
22018 .recognition_arena
22019 .prepend(NodeSeqId::EMPTY, discarded);
22020 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
22021
22022 let stats = parser.recognition_arena_stats();
22023
22024 assert_eq!(
22025 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
22026 (2, 1, 1)
22027 );
22028 assert_eq!(
22029 (stats.total_links, stats.live_links, stats.dead_links),
22030 (2, 1, 1)
22031 );
22032 }
22033
22034 #[test]
22035 fn recognition_arena_drops_capacity_above_retention_limit() {
22036 let mut storage = Vec::<u8>::with_capacity(4);
22037 storage.extend([1, 2, 3]);
22038
22039 reset_arena_vec(&mut storage, 3);
22040
22041 assert!(storage.is_empty());
22042 assert_eq!(storage.capacity(), 0);
22043 }
22044
22045 #[test]
22046 fn recognition_arena_concatenates_diagnostics_in_source_order() {
22047 let mut arena = RecognitionArena::default();
22048 let prefix = arena.diagnostic_sequence([
22049 ParserDiagnostic {
22050 line: 1,
22051 column: 0,
22052 message: "first".to_owned(),
22053 offending: None,
22054 },
22055 ParserDiagnostic {
22056 line: 1,
22057 column: 1,
22058 message: "second".to_owned(),
22059 offending: None,
22060 },
22061 ]);
22062 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
22063 line: 1,
22064 column: 2,
22065 message: "third".to_owned(),
22066 offending: None,
22067 }]);
22068 let extras_before = arena.extras.len();
22069
22070 let combined = arena.concat_diagnostics(prefix, suffix);
22071 let messages = arena
22072 .diagnostics(combined)
22073 .map(|diagnostic| diagnostic.message.as_str())
22074 .collect::<Vec<_>>();
22075
22076 assert_eq!(messages, ["first", "second", "third"]);
22077 assert_eq!(arena.extras.len(), extras_before);
22078 }
22079
22080 #[test]
22081 fn outcome_ties_keep_later_non_recursive_alternative() {
22082 let arena = RecognitionArena::default();
22083 let first = RecognizeOutcome {
22084 index: 1,
22085 consumed_eof: false,
22086 alt_number: 0,
22087 member_values: MemberEnv::new(),
22088 return_values: BTreeMap::new(),
22089 diagnostics: DiagnosticSeqId::EMPTY,
22090 decisions: Vec::new(),
22091 actions: vec![ParserAction::new(1, 0, 0, None)],
22092 nodes: NodeSeqId::EMPTY,
22093 };
22094 let second = RecognizeOutcome {
22095 actions: vec![ParserAction::new(2, 0, 0, None)],
22096 ..first.clone()
22097 };
22098
22099 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22100 .expect("one outcome should be selected");
22101 assert_eq!(selected.actions[0].source_state(), 2);
22102 }
22103
22104 #[test]
22105 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
22106 let arena = RecognitionArena::default();
22107 let first = RecognizeOutcome {
22108 index: 1,
22109 consumed_eof: false,
22110 alt_number: 0,
22111 member_values: MemberEnv::new(),
22112 return_values: BTreeMap::new(),
22113 diagnostics: DiagnosticSeqId::EMPTY,
22114 decisions: Vec::new(),
22115 actions: vec![ParserAction::new(1, 0, 0, None)],
22116 nodes: NodeSeqId::EMPTY,
22117 };
22118 let second = RecognizeOutcome {
22119 actions: vec![
22120 ParserAction::new(2, 0, 0, None),
22121 ParserAction::new(3, 0, 0, None),
22122 ],
22123 ..first.clone()
22124 };
22125
22126 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
22127 .expect("one outcome should be selected");
22128 assert_eq!(selected.actions.len(), 2);
22129 }
22130
22131 #[test]
22132 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
22133 let arena = RecognitionArena::default();
22134 let first = RecognizeOutcome {
22135 index: 7,
22136 consumed_eof: false,
22137 alt_number: 0,
22138 member_values: MemberEnv::new(),
22139 return_values: BTreeMap::new(),
22140 diagnostics: DiagnosticSeqId::EMPTY,
22141 decisions: vec![1, 0],
22142 actions: vec![
22143 ParserAction::new(23, 2, 2, Some(4)),
22144 ParserAction::new(23, 2, 0, Some(6)),
22145 ],
22146 nodes: NodeSeqId::EMPTY,
22147 };
22148 let second = RecognizeOutcome {
22149 decisions: vec![0, 1],
22150 actions: vec![
22151 ParserAction::new(23, 2, 2, Some(6)),
22152 ParserAction::new(23, 2, 0, Some(6)),
22153 ],
22154 ..first.clone()
22155 };
22156
22157 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22158 .expect("one outcome should be selected");
22159 assert_eq!(selected.actions[0].stop_index(), Some(6));
22160 }
22161
22162 #[test]
22163 fn outcome_ties_keep_first_recursive_tree_shape() {
22164 let mut arena = RecognitionArena::default();
22165 let token = arena.push_node(ArenaRecognizedNode::Token {
22166 token: TokenId::try_from(0).expect("test token ID"),
22167 });
22168 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
22169 let inner = arena.push_node(ArenaRecognizedNode::Rule {
22170 rule_index: 1,
22171 invoking_state: -1,
22172 alt_number: 0,
22173 start_index: 0,
22174 stop_index: Some(0),
22175 return_values: None,
22176 children: token_children,
22177 });
22178 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
22179 let outer = arena.push_node(ArenaRecognizedNode::Rule {
22180 rule_index: 1,
22181 invoking_state: -1,
22182 alt_number: 0,
22183 start_index: 0,
22184 stop_index: Some(0),
22185 return_values: None,
22186 children: inner_children,
22187 });
22188 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
22189 let first = RecognizeOutcome {
22190 index: 1,
22191 consumed_eof: false,
22192 alt_number: 0,
22193 member_values: MemberEnv::new(),
22194 return_values: BTreeMap::new(),
22195 diagnostics: DiagnosticSeqId::EMPTY,
22196 decisions: Vec::new(),
22197 actions: vec![ParserAction::new(1, 0, 0, None)],
22198 nodes: recursive_nodes,
22199 };
22200 let second = RecognizeOutcome {
22201 index: 1,
22202 consumed_eof: false,
22203 alt_number: 0,
22204 member_values: MemberEnv::new(),
22205 return_values: BTreeMap::new(),
22206 diagnostics: DiagnosticSeqId::EMPTY,
22207 decisions: Vec::new(),
22208 actions: vec![ParserAction::new(2, 0, 0, None)],
22209 nodes: recursive_nodes,
22210 };
22211
22212 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22213 .expect("one outcome should be selected");
22214 assert_eq!(selected.actions[0].source_state(), 1);
22215 }
22216
22217 #[test]
22218 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
22219 let mut arena = RecognitionArena::default();
22220 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
22221 line: 1,
22222 column: 3,
22223 message: "missing 'Y' at '<EOF>'".to_owned(),
22224 offending: None,
22225 }]);
22226 let first_alt = RecognizeOutcome {
22227 index: 2,
22228 consumed_eof: true,
22229 alt_number: 0,
22230 member_values: MemberEnv::new(),
22231 return_values: BTreeMap::new(),
22232 diagnostics: recovered_diagnostics,
22233 decisions: vec![0],
22234 actions: vec![ParserAction::new(1, 0, 0, None)],
22235 nodes: NodeSeqId::EMPTY,
22236 };
22237 let second_alt = RecognizeOutcome {
22238 diagnostics: DiagnosticSeqId::EMPTY,
22239 decisions: vec![1],
22240 actions: vec![ParserAction::new(2, 0, 0, None)],
22241 ..first_alt.clone()
22242 };
22243
22244 let selected = select_best_outcome(
22245 [second_alt, first_alt].into_iter(),
22246 PredictionMode::Sll,
22247 &arena,
22248 )
22249 .expect("one outcome should be selected");
22250 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
22251 assert_eq!(selected.decisions, [0]);
22252 }
22253}