1use std::cell::RefCell;
7use std::cmp::Ordering;
8#[allow(clippy::disallowed_types)]
9use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
10use std::hash::{BuildHasherDefault, Hash, Hasher};
11use std::rc::Rc;
12
13#[derive(Clone, Copy, Default)]
20struct FxHasher {
21 hash: u64,
22}
23
24const FX_ROT: u32 = 5;
25const FX_SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
26
27impl Hasher for FxHasher {
28 #[inline]
36 fn write(&mut self, mut bytes: &[u8]) {
37 while bytes.len() >= 8 {
38 let (head, rest) = bytes.split_at(8);
39 let word = u64::from_le_bytes(head.try_into().expect("8-byte chunk"));
40 self.hash = (self.hash.rotate_left(FX_ROT) ^ word).wrapping_mul(FX_SEED);
41 bytes = rest;
42 }
43 for byte in bytes {
44 self.hash = (self.hash.rotate_left(FX_ROT) ^ u64::from(*byte)).wrapping_mul(FX_SEED);
45 }
46 }
47 #[inline]
48 fn write_u64(&mut self, value: u64) {
49 self.hash = (self.hash.rotate_left(FX_ROT) ^ value).wrapping_mul(FX_SEED);
50 }
51 #[inline]
52 fn write_usize(&mut self, value: usize) {
53 self.write_u64(value as u64);
54 }
55 #[inline]
56 fn write_u32(&mut self, value: u32) {
57 self.write_u64(u64::from(value));
58 }
59 #[inline]
60 fn write_i32(&mut self, value: i32) {
61 self.write_u64(u64::from(i32::cast_unsigned(value)));
62 }
63 #[inline]
64 fn finish(&self) -> u64 {
65 self.hash
66 }
67}
68
69type FxBuildHasher = BuildHasherDefault<FxHasher>;
70#[allow(clippy::disallowed_types)]
71type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;
72#[allow(clippy::disallowed_types)]
73type FxHashSet<K> = HashSet<K, FxBuildHasher>;
74
75use crate::atn::AtnStateKind;
76use crate::atn::parser::{
77 ParserAtnPrediction, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
78 ParserAtnSimulatorError, ParserSemanticCandidate,
79};
80use crate::atn::parser_atn::{
81 ParserAtn as Atn, ParserAtnState as AtnState, ParserIntervalSet, ParserTransition,
82 ParserTransitionData as Transition, ParserTransitionKind,
83};
84#[cfg(test)]
85use crate::atn::parser_atn::{ParserAtnBuilder, ParserTransitionSpec};
86use crate::char_stream::CharStream;
87use crate::errors::{AntlrError, SyntaxErrorEvent};
88use crate::int_stream::IntStream;
89use crate::lexer::{LexerCustomAction, LexerLifecycleCtx, LexerSemCtx};
90use crate::prediction::SemanticContext;
91use crate::recognizer::{Recognizer, RecognizerData};
92use crate::semir::{self, AStmt, ArithOp, CmpOp, ExprId, HookId, MemberEnv, PExpr, SemIr, StmtId};
93use crate::token::{
94 TOKEN_EOF, Token, TokenId, TokenSource, TokenSourceError, TokenSpec, TokenStore, TokenView,
95};
96use crate::token_stream::CommonTokenStream;
97use crate::tree::{
98 Node, NodeId, ParseTreeCheckpoint, ParseTreeStorage, ParsedFile, ParserRuleContext,
99};
100use crate::vocabulary::Vocabulary;
101
102type ParseTree = NodeId;
103
104const RECOGNITION_DEPTH_LIMIT: usize = 32_768;
108const FAST_RECOGNIZE_STACK_CHECK_INTERVAL: usize = 8;
111const FAST_RECOGNIZE_RED_ZONE: usize = 1024 * 1024;
112const FAST_RECOGNIZE_STACK_SIZE: usize = 4 * 1024 * 1024;
113const GENERATED_RULE_STACK_CHECK_INTERVAL: usize = 8;
119const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
123
124pub fn grow_generated_rule_stack<R>(body: impl FnOnce() -> R) -> R {
131 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, body)
132}
133
134#[doc(hidden)]
141#[macro_export]
142macro_rules! __antlr4_rust_generated_rule {
143 (
144 dispatch $parser:ident, $rule:expr, $fatal:path;
145 $body:expr
146 ) => {{
147 if let Some(error) = $parser.base.rule_depth_cap_violation() {
148 return Err($fatal(error));
149 }
150 if let Some(error) = $parser.base.parse_listener_enter_rule($rule) {
151 return Err($fatal(error));
152 }
153 let __listener_result = if $parser.base.generated_rule_stack_check_due() {
154 $crate::grow_generated_rule_stack(|| $body)
155 } else {
156 $body
157 };
158 $parser.base.parse_listener_exit_rule($rule);
159 __listener_result
160 }};
161 (
162 ordinary $parser:ident, $state:expr, $rule:expr, $allow_fallback:expr,
163 $atn:expr, $fatal:path;
164 retry [$($retry:tt)*];
165 bind ($ctx:ident, $rule_start:ident, $consumed_eof:ident, $sync_error:ident);
166 setup { $($setup:tt)* }
167 body { $($body:tt)* }
168 success { $($success:tt)* }
169 recovery { $($recovery:tt)* }
170 ) => {
171 $crate::__antlr4_rust_generated_rule! {
172 @body
173 parser $parser;
174 enter $parser.base.enter_rule($state, $rule);
175 finish finish_rule;
176 abort exit_rule;
177 allow_fallback $allow_fallback;
178 atn $atn;
179 fatal $fatal;
180 retry [$($retry)*];
181 bind ($ctx, $rule_start, $consumed_eof, $sync_error);
182 setup { $($setup)* }
183 body { $($body)* }
184 success { $($success)* }
185 recovery { $($recovery)* }
186 }
187 };
188 (
189 recursive $parser:ident, $state:expr, $rule:expr, $precedence:expr,
190 $allow_fallback:expr, $atn:expr, $fatal:path;
191 retry [$($retry:tt)*];
192 bind ($ctx:ident, $rule_start:ident, $consumed_eof:ident, $sync_error:ident);
193 setup { $($setup:tt)* }
194 body { $($body:tt)* }
195 success { $($success:tt)* }
196 recovery { $($recovery:tt)* }
197 ) => {
198 $crate::__antlr4_rust_generated_rule! {
199 @body
200 parser $parser;
201 enter $parser.base.enter_recursion_rule($state, $rule, $precedence);
202 finish finish_recursion_rule;
203 abort unroll_recursion_context;
204 allow_fallback $allow_fallback;
205 atn $atn;
206 fatal $fatal;
207 retry [$($retry)*];
208 bind ($ctx, $rule_start, $consumed_eof, $sync_error);
209 setup { $($setup)* }
210 body { $($body)* }
211 success { $($success)* }
212 recovery { $($recovery)* }
213 }
214 };
215 (
216 @body
217 parser $parser:ident;
218 enter $enter:expr;
219 finish $finish:ident;
220 abort $abort:ident;
221 allow_fallback $allow_fallback:expr;
222 atn $atn:expr;
223 fatal $fatal:path;
224 retry [$($retry:tt)*];
225 bind ($ctx:ident, $rule_start:ident, $consumed_eof:ident, $sync_error:ident);
226 setup { $($setup:tt)* }
227 body { $($body:tt)* }
228 success { $($success:tt)* }
229 recovery { $($recovery:tt)* }
230 ) => {{
231 let __generated_diagnostic_marker =
232 $parser.base.generated_diagnostics_checkpoint();
233 let mut $ctx = $enter;
234 let $rule_start = $crate::IntStream::index($parser.base.input());
235 $($setup)*
236 let mut $consumed_eof = false;
237 let mut $sync_error: Option<$crate::AntlrError> = None;
238 let __result = (|| -> Result<(), $crate::AntlrError> {
241 $($body)*
242 Ok(())
243 })();
244 match __result {
245 Ok(()) => {
246 $($success)*
247 let __tree = $parser.base.$finish($ctx, $consumed_eof);
248 Ok(__tree)
249 }
250 Err(__error) => {
251 $crate::__antlr4_rust_generated_rule! {
252 @retry
253 [$($retry)*]
254 parser $parser;
255 marker __generated_diagnostic_marker;
256 abort $abort;
257 }
258 let __error = if let Some(__sync_error) = $sync_error {
259 if $allow_fallback {
260 $parser.base.$abort();
261 $parser
262 .base
263 .rollback_generated_tree(__generated_diagnostic_marker);
264 $parser.base.record_generated_syntax_error();
265 return Err($fatal(__sync_error));
266 }
267 __sync_error
268 } else {
269 __error
270 };
271 $parser
272 .base
273 .recover_generated_rule(&mut $ctx, $atn, __error);
274 $($recovery)*
275 let __tree = $parser.base.$finish($ctx, $consumed_eof);
276 Ok(__tree)
277 }
278 }
279 }};
280 (
281 @retry
282 [none]
283 parser $parser:ident;
284 marker $marker:ident;
285 abort $abort:ident;
286 ) => {};
287 (
288 @retry
289 [$condition:expr => $retry_error:expr]
290 parser $parser:ident;
291 marker $marker:ident;
292 abort $abort:ident;
293 ) => {
294 if $condition {
295 $parser.base.$abort();
296 $parser.base.restore_generated_diagnostics($marker);
297 return Err($retry_error);
298 }
299 };
300}
301
302pub trait ParseListener: Send {
350 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError>;
355
356 fn exit_every_rule(&mut self, rule_index: usize) {
360 let _ = rule_index;
361 }
362}
363
364impl<T: ParseListener + ?Sized> ParseListener for Box<T> {
368 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
369 (**self).enter_every_rule(event)
370 }
371
372 fn exit_every_rule(&mut self, rule_index: usize) {
373 (**self).exit_every_rule(rule_index);
374 }
375}
376
377#[derive(Debug)]
382#[non_exhaustive]
383pub struct EnterRuleEvent<'a> {
384 pub rule_index: usize,
387 pub current: Option<TokenView<'a>>,
390}
391
392struct ParseListenerSlot(Box<dyn ParseListener>);
393
394impl std::fmt::Debug for ParseListenerSlot {
395 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
396 f.write_str("ParseListener")
397 }
398}
399const CLEAN_MEMO_PROBE_LIMIT: usize = 4096;
403const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
404const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
407const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
408const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
409const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
410const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
411
412#[derive(Clone, Copy, Debug, Eq, PartialEq)]
413enum CleanMemoMode {
414 Probe,
415 Promote,
416 Sparse,
417}
418
419fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
420 intervals
421 .iter()
422 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
423}
424
425fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
426 let mut symbols = BTreeSet::new();
427 for (start, stop) in intervals {
428 symbols.extend(*start..=*stop);
429 }
430 symbols
431}
432
433fn interval_complement_symbols(
434 intervals: &[(i32, i32)],
435 min_vocabulary: i32,
436 max_vocabulary: i32,
437) -> BTreeSet<i32> {
438 (min_vocabulary..=max_vocabulary)
439 .filter(|symbol| !interval_set_contains(intervals, *symbol))
440 .collect()
441}
442
443#[cfg(feature = "perf-counters")]
444mod perf_counters {
445 use std::cell::Cell;
446 thread_local! {
447 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
448 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
449 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
450 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
451 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
452 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
453 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
454 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
455 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
456 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
457 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
458 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
459 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
460 }
461 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
462 c.with(|v| v.set(v.get() + n));
463 }
464 thread_local! {
465 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
466 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
467 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
468 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
469 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
470 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
471 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
472 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
473 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
474 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
475 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
476 }
477 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
478 [
479 ("rfs_calls", RFS_CALLS.with(Cell::get)),
480 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
481 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
482 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
483 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
484 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
485 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
486 (
487 "outcome_dedupe_inputs",
488 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
489 ),
490 (
491 "outcome_dedupe_removed",
492 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
493 ),
494 (
495 "outcome_dedupe_inline",
496 OUTCOME_DEDUPE_INLINE.with(Cell::get),
497 ),
498 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
499 (
500 "outcome_dedupe_sparse",
501 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
502 ),
503 (
504 "outcome_dedupe_dense_words",
505 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
506 ),
507 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
508 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
509 (
510 "atom_range_transitions",
511 ATOM_RANGE_TRANSITIONS.with(Cell::get),
512 ),
513 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
514 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
515 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
516 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
517 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
518 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
519 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
520 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
521 ]
522 }
523 pub fn reset() {
524 RFS_CALLS.with(|c| c.set(0));
525 RFS_MEMO_HITS.with(|c| c.set(0));
526 RFS_MEMO_MISSES.with(|c| c.set(0));
527 RFS_VISITING_CYCLE.with(|c| c.set(0));
528 MEMO_INSERTED.with(|c| c.set(0));
529 OUTCOMES_PUSHED.with(|c| c.set(0));
530 OUTCOMES_CLONED.with(|c| c.set(0));
531 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
532 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
533 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
534 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
535 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
536 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
537 EPSILON_TRANSITIONS.with(|c| c.set(0));
538 RULE_TRANSITIONS.with(|c| c.set(0));
539 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
540 SINGLE_TRANS_BODY.with(|c| c.set(0));
541 MULTI_TRANS_BODY.with(|c| c.set(0));
542 SINGLE_TRANS_RULE.with(|c| c.set(0));
543 SINGLE_TRANS_ATOM.with(|c| c.set(0));
544 SINGLE_TRANS_OTHER.with(|c| c.set(0));
545 OUTCOMES_RETURN_0.with(|c| c.set(0));
546 OUTCOMES_RETURN_1.with(|c| c.set(0));
547 OUTCOMES_RETURN_N.with(|c| c.set(0));
548 }
549 pub fn dump() {
550 for (name, value) in snapshot() {
551 #[allow(clippy::print_stderr)]
552 {
553 eprintln!("perf {name}={value}");
554 }
555 }
556 }
557}
558
559#[cfg(feature = "perf-counters")]
560pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
561const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
566#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
575pub struct ParserAction {
576 source_state: usize,
577 rule_index: usize,
578 action_index: Option<usize>,
579 start_index: usize,
580 stop_index: Option<usize>,
581 rule_init: bool,
582 expected_state: Option<usize>,
583}
584
585impl ParserAction {
586 pub const fn new(
588 source_state: usize,
589 rule_index: usize,
590 start_index: usize,
591 stop_index: Option<usize>,
592 ) -> Self {
593 Self {
594 source_state,
595 rule_index,
596 action_index: None,
597 start_index,
598 stop_index,
599 rule_init: false,
600 expected_state: None,
601 }
602 }
603
604 pub const fn new_indexed(
606 source_state: usize,
607 rule_index: usize,
608 action_index: usize,
609 start_index: usize,
610 stop_index: Option<usize>,
611 ) -> Self {
612 Self {
613 source_state,
614 rule_index,
615 action_index: Some(action_index),
616 start_index,
617 stop_index,
618 rule_init: false,
619 expected_state: None,
620 }
621 }
622
623 pub const fn new_rule_init(
625 rule_index: usize,
626 start_index: usize,
627 expected_state: Option<usize>,
628 ) -> Self {
629 Self {
630 source_state: usize::MAX,
631 rule_index,
632 action_index: None,
633 start_index,
634 stop_index: None,
635 rule_init: true,
636 expected_state,
637 }
638 }
639
640 pub const fn source_state(&self) -> usize {
642 self.source_state
643 }
644
645 pub const fn rule_index(&self) -> usize {
647 self.rule_index
648 }
649
650 pub const fn action_index(&self) -> Option<usize> {
652 self.action_index
653 }
654
655 pub const fn start_index(&self) -> usize {
657 self.start_index
658 }
659
660 pub const fn stop_index(&self) -> Option<usize> {
662 self.stop_index
663 }
664
665 pub const fn is_rule_init(&self) -> bool {
667 self.rule_init
668 }
669
670 pub const fn expected_state(&self) -> Option<usize> {
672 self.expected_state
673 }
674}
675
676pub struct ParserSemCtx<'a, S>
684where
685 S: TokenSource,
686{
687 input: &'a mut CommonTokenStream<S>,
688 tree_storage: &'a ParseTreeStorage,
689 rule_index: usize,
690 coordinate_index: usize,
691 rule_name: Option<String>,
692 context: Option<&'a ParserRuleContext>,
693 tree: Option<ParseTree>,
694 local_int_arg: Option<(usize, i64)>,
695 member_values: &'a MemberEnv,
696 action: Option<ParserAction>,
697}
698
699impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
700where
701 S: TokenSource,
702{
703 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
704 f.debug_struct("ParserSemCtx")
705 .field("rule_index", &self.rule_index)
706 .field("coordinate_index", &self.coordinate_index)
707 .field("rule_name", &self.rule_name)
708 .field("context", &self.context)
709 .field("tree", &self.tree)
710 .field("local_int_arg", &self.local_int_arg)
711 .field("member_values", &self.member_values)
712 .field("action", &self.action)
713 .finish_non_exhaustive()
714 }
715}
716
717impl<'a, S> ParserSemCtx<'a, S>
718where
719 S: TokenSource,
720{
721 #[must_use]
723 pub const fn rule_index(&self) -> usize {
724 self.rule_index
725 }
726
727 #[must_use]
729 pub fn rule_name(&self) -> Option<&str> {
730 self.rule_name.as_deref()
731 }
732
733 #[must_use]
736 pub const fn coordinate_index(&self) -> usize {
737 self.coordinate_index
738 }
739
740 #[must_use]
742 pub fn input_index(&self) -> usize {
743 self.input.index()
744 }
745
746 pub fn la(&mut self, offset: isize) -> i32 {
748 self.input.la(offset)
749 }
750
751 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
753 self.input.lt(offset)
754 }
755
756 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
758 self.lt(offset)
759 }
760
761 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
768 self.input.get(index)
769 }
770
771 #[must_use]
774 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
775 self.context
776 }
777
778 #[must_use]
780 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
781 self.tree_storage
782 }
783
784 #[must_use]
786 pub const fn token_store(&self) -> &TokenStore {
787 self.input.token_store()
788 }
789
790 #[must_use]
792 pub const fn tree_id(&self) -> Option<NodeId> {
793 self.tree
794 }
795
796 #[must_use]
799 pub fn tree(&self) -> Option<Node<'_>> {
800 self.tree
801 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
802 }
803
804 #[must_use]
806 pub fn local_int_arg(&self) -> Option<i64> {
807 self.local_int_arg.map(|(_, value)| value)
808 }
809
810 #[must_use]
812 pub fn member_int(&self, member: usize) -> Option<i64> {
813 self.member_values.scalar(member)
814 }
815
816 #[must_use]
819 pub fn member_stack_top(&self, member: usize) -> Option<i64> {
820 self.member_values.stack_top(member)
821 }
822
823 #[must_use]
825 pub fn member_stack_len(&self, member: usize) -> usize {
826 self.member_values.stack_len(member)
827 }
828
829 #[must_use]
832 pub const fn action(&self) -> Option<ParserAction> {
833 self.action
834 }
835
836 pub fn action_text(&self) -> String {
844 let Some(action) = self.action else {
845 return String::new();
846 };
847 let Some(stop) = action.stop_index() else {
848 return String::new();
849 };
850 let stop = if self
851 .input
852 .get(stop)
853 .is_some_and(|token| token.token_type() == TOKEN_EOF)
854 {
855 let Some(previous) = self.input.previous_visible_token_index(stop) else {
856 return String::new();
857 };
858 previous
859 } else {
860 stop
861 };
862 self.input.text(action.start_index(), stop)
863 }
864}
865
866pub trait SemanticHooks {
873 const ENABLES_LEXER_LIFECYCLE: bool = true;
880
881 fn observes_parser_predicates(&self) -> bool {
886 true
887 }
888
889 fn observes_parser_decisions(&self) -> bool {
894 false
895 }
896
897 fn parser_decision_override(
903 &mut self,
904 decision: usize,
905 input_index: usize,
906 alternative_count: usize,
907 ) -> Option<usize> {
908 let _ = (decision, input_index, alternative_count);
909 None
910 }
911
912 fn sempred<S>(
913 &mut self,
914 ctx: &mut ParserSemCtx<'_, S>,
915 rule_index: usize,
916 pred_index: usize,
917 ) -> Option<bool>
918 where
919 S: TokenSource,
920 {
921 let _ = (ctx, rule_index, pred_index);
922 None
923 }
924
925 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
926 where
927 S: TokenSource,
928 {
929 let _ = (ctx, action);
930 false
931 }
932
933 fn lexer_sempred<I>(
934 &mut self,
935 ctx: &mut LexerSemCtx<'_, I>,
936 rule_index: usize,
937 pred_index: usize,
938 ) -> Option<bool>
939 where
940 I: CharStream,
941 {
942 let _ = (ctx, rule_index, pred_index);
943 None
944 }
945
946 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
956 where
957 I: CharStream,
958 {
959 let _ = (ctx, action);
960 false
961 }
962
963 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
967 where
968 I: CharStream,
969 {
970 let _ = ctx;
971 }
972
973 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
979 where
980 I: CharStream,
981 {
982 let _ = ctx;
983 }
984
985 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
994 where
995 I: CharStream,
996 {
997 let _ = ctx;
998 }
999
1000 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
1007 let _ = token;
1008 }
1009}
1010
1011#[derive(Clone, Copy, Debug, Default)]
1014pub struct NoSemanticHooks;
1015
1016impl SemanticHooks for NoSemanticHooks {
1017 const ENABLES_LEXER_LIFECYCLE: bool = false;
1018
1019 fn observes_parser_predicates(&self) -> bool {
1020 false
1021 }
1022}
1023
1024#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1031pub enum ParserPredicate {
1032 True,
1033 False,
1034 FalseWithMessage {
1036 message: &'static str,
1037 },
1038 Invoke {
1041 value: bool,
1042 },
1043 LookaheadTextEquals {
1044 offset: isize,
1045 text: &'static str,
1046 },
1047 LookaheadNotEquals {
1048 offset: isize,
1049 token_type: i32,
1050 },
1051 TokenPairAdjacent,
1054 ContextChildRuleTextNotEquals {
1059 rule_index: usize,
1060 text: &'static str,
1061 },
1062 LocalIntEquals {
1065 value: i64,
1066 },
1067 LocalIntLessOrEqual {
1070 value: i64,
1071 },
1072 MemberModuloEquals {
1074 member: usize,
1075 modulus: i64,
1076 value: i64,
1077 equals: bool,
1078 },
1079 MemberEquals {
1081 member: usize,
1082 value: i64,
1083 equals: bool,
1084 },
1085}
1086
1087impl ParserPredicate {
1088 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
1094 match self {
1095 Self::True => ir.expr(PExpr::Bool(true)),
1096 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
1097 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
1098 Self::LookaheadTextEquals { offset, text } => {
1099 let token = ir.expr(PExpr::TokenText(offset));
1100 let text = ir.intern(text);
1101 let text = ir.expr(PExpr::Str(text));
1102 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
1103 }
1104 Self::LookaheadNotEquals { offset, token_type } => {
1105 let actual = ir.expr(PExpr::La(offset));
1106 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
1107 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
1108 }
1109 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
1110 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
1111 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
1112 let expected = ir.intern(text);
1113 let expected = ir.expr(PExpr::Str(expected));
1114 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
1115 }
1116 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
1117 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
1118 Self::MemberModuloEquals {
1119 member,
1120 modulus,
1121 value,
1122 equals,
1123 } => {
1124 if modulus == 0 {
1125 return ir.expr(PExpr::Bool(false));
1126 }
1127 let member = ir.expr(PExpr::Member(member));
1128 let modulus = ir.expr(PExpr::Int(modulus));
1129 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
1130 let expected = ir.expr(PExpr::Int(value));
1131 ir.expr(PExpr::Cmp(
1132 if equals { CmpOp::Eq } else { CmpOp::Ne },
1133 actual,
1134 expected,
1135 ))
1136 }
1137 Self::MemberEquals {
1138 member,
1139 value,
1140 equals,
1141 } => {
1142 let actual = ir.expr(PExpr::Member(member));
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 }
1151 }
1152
1153 #[must_use]
1154 pub const fn failure_message(self) -> Option<&'static str> {
1155 match self {
1156 Self::FalseWithMessage { message } => Some(message),
1157 Self::True
1158 | Self::False
1159 | Self::Invoke { .. }
1160 | Self::LookaheadTextEquals { .. }
1161 | Self::LookaheadNotEquals { .. }
1162 | Self::TokenPairAdjacent
1163 | Self::ContextChildRuleTextNotEquals { .. }
1164 | Self::LocalIntEquals { .. }
1165 | Self::LocalIntLessOrEqual { .. }
1166 | Self::MemberModuloEquals { .. }
1167 | Self::MemberEquals { .. } => None,
1168 }
1169 }
1170}
1171
1172fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
1173 let local = ir.expr(PExpr::LocalArg);
1174 let absent = ir.expr(PExpr::IsNull(local));
1175 let expected = ir.expr(PExpr::Int(value));
1176 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
1177 ir.expr(PExpr::Or([absent, comparison].into()))
1178}
1179
1180#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1193pub enum UnknownSemanticPolicy {
1194 #[default]
1196 AssumeTrue,
1197 AssumeFalse,
1199 Error,
1202}
1203
1204fn apply_unknown_predicate_policy(
1213 policy: UnknownSemanticPolicy,
1214 rule_index: usize,
1215 pred_index: usize,
1216 hits: &mut Vec<(usize, usize)>,
1217) -> bool {
1218 match policy {
1219 UnknownSemanticPolicy::AssumeTrue => true,
1220 UnknownSemanticPolicy::AssumeFalse => false,
1221 UnknownSemanticPolicy::Error => {
1222 let coordinate = (rule_index, pred_index);
1223 if !hits.contains(&coordinate) {
1224 hits.push(coordinate);
1225 }
1226 false
1227 }
1228 }
1229}
1230
1231#[derive(Clone, Debug, Eq, PartialEq)]
1235pub struct ExpectedTokenSet {
1236 symbols: BTreeSet<i32>,
1237}
1238
1239impl ExpectedTokenSet {
1240 #[must_use]
1242 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
1243 expected_symbols_display(&self.symbols, vocabulary)
1244 }
1245}
1246
1247#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1252pub struct BailErrorStrategy;
1253
1254impl BailErrorStrategy {
1255 #[must_use]
1256 pub const fn new() -> Self {
1257 Self
1258 }
1259}
1260
1261#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1263pub enum PredictionMode {
1264 Ll,
1267 Sll,
1270 LlExactAmbigDetection,
1272}
1273
1274#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1280pub struct ParserRuleArg {
1281 pub source_state: usize,
1283 pub rule_index: usize,
1285 pub value: i64,
1287 pub inherit_local: bool,
1289}
1290
1291#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1293pub struct ParserMemberAction {
1294 pub source_state: usize,
1296 pub member: usize,
1298 pub delta: i64,
1300}
1301
1302#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1309pub struct ParserReturnAction {
1310 pub source_state: usize,
1312 pub rule_index: usize,
1314 pub name: &'static str,
1316 pub value: i64,
1318}
1319
1320impl ParserMemberAction {
1321 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1323 let delta = ir.expr(PExpr::Int(self.delta));
1324 ParserSemanticAction {
1325 source_state: self.source_state,
1326 rule_index: usize::MAX,
1327 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
1328 speculative: true,
1329 }
1330 }
1331}
1332
1333impl ParserReturnAction {
1334 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1336 let name = ir.intern(self.name);
1337 let value = ir.expr(PExpr::Int(self.value));
1338 ParserSemanticAction {
1339 source_state: self.source_state,
1340 rule_index: self.rule_index,
1341 stmt: ir.stmt(AStmt::SetReturn(name, value)),
1342 speculative: false,
1343 }
1344 }
1345}
1346
1347#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1349pub struct ParserSemanticPredicate {
1350 pub rule_index: usize,
1352 pub pred_index: usize,
1354 pub expr: ExprId,
1356 pub failure_message: Option<&'static str>,
1358}
1359
1360#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1362pub struct ParserSemanticAction {
1363 pub source_state: usize,
1365 pub rule_index: usize,
1367 pub stmt: StmtId,
1369 pub speculative: bool,
1371}
1372
1373#[derive(Clone, Debug, Default, Eq, PartialEq)]
1380pub struct ParserSemantics {
1381 pub ir: SemIr,
1382 pub predicates: Vec<ParserSemanticPredicate>,
1383 pub actions: Vec<ParserSemanticAction>,
1384}
1385
1386#[derive(Clone, Copy, Debug, Default)]
1388pub struct ParserRuntimeOptions<'a> {
1389 pub init_action_rules: &'a [usize],
1392 pub action_indices: &'a [(usize, usize)],
1398 pub track_alt_numbers: bool,
1400 #[doc(hidden)]
1405 pub track_context_alt_numbers: bool,
1406 pub predicates: &'a [(usize, usize, ParserPredicate)],
1408 pub semantics: Option<&'a ParserSemantics>,
1410 pub rule_args: &'a [ParserRuleArg],
1412 pub member_actions: &'a [ParserMemberAction],
1414 pub return_actions: &'a [ParserReturnAction],
1416 pub unknown_predicate_policy: UnknownSemanticPolicy,
1419}
1420
1421pub trait Parser: Recognizer {
1422 fn build_parse_trees(&self) -> bool;
1425
1426 fn set_build_parse_trees(&mut self, build: bool);
1428
1429 fn number_of_syntax_errors(&self) -> usize {
1432 0
1433 }
1434
1435 fn report_diagnostic_errors(&self) -> bool {
1438 false
1439 }
1440
1441 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1444
1445 fn prediction_mode(&self) -> PredictionMode {
1447 PredictionMode::Ll
1448 }
1449
1450 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1452
1453 fn max_rule_depth(&self) -> Option<usize> {
1456 None
1457 }
1458
1459 fn set_max_rule_depth(&mut self, _depth: Option<usize>) {}
1475
1476 fn add_parse_listener(&mut self, _listener: Box<dyn ParseListener>) {}
1481
1482 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
1485 Vec::new()
1486 }
1487}
1488
1489#[derive(Debug)]
1490struct LeftRecursiveCallerOverlap {
1491 atn_key: SharedAtnCacheKey,
1492 state_number: usize,
1493 symbol: i32,
1494 context_version: usize,
1495 overlaps: bool,
1496}
1497
1498const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1499
1500#[derive(Debug)]
1501pub struct BaseParser<S, H = NoSemanticHooks> {
1502 input: CommonTokenStream<S>,
1503 tree: ParseTreeStorage,
1504 data: RecognizerData,
1505 semantic_hooks: H,
1506 decision_override_generation: usize,
1507 build_parse_trees: bool,
1508 syntax_errors: usize,
1509 report_diagnostic_errors: bool,
1510 prediction_mode: PredictionMode,
1511 prediction_diagnostics: Vec<ParserDiagnostic>,
1512 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1513 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1514 generated_sync_expected: Option<TokenBitSet>,
1515 generated_recovery_error_index: Option<usize>,
1516 generated_recovery_error_states: BTreeSet<isize>,
1517 int_members: MemberEnv,
1518 rule_context_stack: Vec<RuleContextFrame>,
1519 rule_context_version: usize,
1520 left_recursive_caller_overlap_cache:
1521 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1522 pending_invoking_states: Vec<isize>,
1523 precedence_stack: Vec<i32>,
1524 invoked_predicates: Vec<(usize, usize)>,
1528 bail_on_error: bool,
1532 parse_listeners: Vec<ParseListenerSlot>,
1537 parse_listener_abort: Option<AntlrError>,
1542 max_rule_depth: Option<usize>,
1546 rule_depth_error: Option<AntlrError>,
1551 recursion_expansions: usize,
1557 recursion_expansion_marks: Vec<usize>,
1561 unknown_predicate_policy: UnknownSemanticPolicy,
1564 unknown_predicate_hits: Vec<(usize, usize)>,
1567 unhandled_action_hits: Vec<(usize, usize)>,
1572 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1577 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1583 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1588 rule_stop_reach_cache: Vec<Option<bool>>,
1593 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1598 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1604 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1610 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1614 empty_cycle_cache: Vec<Option<bool>>,
1620 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1621 clean_memo_mode: CleanMemoMode,
1624 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1625 clean_memo_probe_samples: usize,
1626 clean_memo_probe_repeats: usize,
1627 clean_memo_sparse_samples: usize,
1628 fast_recognize_scratch: FastRecognizeTopScratch,
1630 fast_outcome_dedup: FastOutcomeDedupScratch,
1632 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1635 fast_first_set_prefilter: bool,
1643 fast_recovery_enabled: bool,
1647 fast_token_nodes_enabled: bool,
1652 fast_track_alt_numbers: bool,
1655 recognition_arena: RecognitionArena,
1659 last_recognition_arena_root: NodeSeqId,
1660 last_recognition_arena_diagnostics: DiagnosticSeqId,
1661}
1662
1663#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1665pub struct GeneratedDiagnosticsCheckpoint {
1666 diagnostics_len: usize,
1667 syntax_errors: usize,
1668 tree: ParseTreeCheckpoint,
1669}
1670
1671#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1674pub struct RecognitionArenaStats {
1675 pub total_nodes: usize,
1676 pub live_nodes: usize,
1677 pub dead_nodes: usize,
1678 pub node_capacity: usize,
1679 pub total_links: usize,
1680 pub live_links: usize,
1681 pub dead_links: usize,
1682 pub link_capacity: usize,
1683 pub total_extras: usize,
1684 pub live_extras: usize,
1685 pub dead_extras: usize,
1686 pub extra_capacity: usize,
1687}
1688
1689#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1690struct RuleContextFrame {
1691 rule_index: usize,
1692 invoking_state: isize,
1693}
1694
1695#[derive(Clone, Debug, Eq, PartialEq)]
1696struct RecognizeOutcome {
1697 index: usize,
1698 consumed_eof: bool,
1699 alt_number: usize,
1700 member_values: MemberEnv,
1701 return_values: BTreeMap<String, i64>,
1702 diagnostics: DiagnosticSeqId,
1703 decisions: Vec<usize>,
1704 actions: Vec<ParserAction>,
1705 nodes: NodeSeqId,
1706}
1707
1708#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1709struct FastRecognizeOutcome {
1710 index: usize,
1711 consumed_eof: bool,
1712 diagnostics: DiagnosticSeqId,
1713 deferred_nodes: FastDeferredNodeId,
1714 nodes: NodeSeqId,
1718}
1719
1720#[derive(Debug, Default)]
1721struct FastRecognizeTopScratch {
1722 visiting: FxHashSet<FastRecognizeKey>,
1723 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1724}
1725
1726impl FastRecognizeTopScratch {
1727 fn prepare(&mut self, memo_capacity: usize) {
1728 self.visiting.clear();
1729 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1730 self.memo.clear();
1731 self.memo.reserve(memo_capacity);
1732 }
1733
1734 fn release_oversized_memo(&mut self) {
1735 self.memo.clear();
1736 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1737 self.memo = FxHashMap::default();
1738 }
1739 }
1740}
1741
1742fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1743 buffered_tokens.saturating_mul(8).clamp(
1744 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1745 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1746 )
1747}
1748
1749#[derive(Debug, Default)]
1750struct FastOutcomeDedupScratch {
1751 dense_words: Vec<u64>,
1752 touched_dense_words: Vec<u32>,
1753 sparse_keys: FxHashSet<(usize, bool)>,
1754}
1755
1756#[repr(transparent)]
1761#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1762struct FastDeferredNodeId(u32);
1763
1764impl FastDeferredNodeId {
1765 const EMPTY: Self = Self(u32::MAX);
1766
1767 const fn is_empty(self) -> bool {
1768 self.0 == Self::EMPTY.0
1769 }
1770}
1771
1772impl Default for FastDeferredNodeId {
1773 fn default() -> Self {
1774 Self::EMPTY
1775 }
1776}
1777
1778#[repr(transparent)]
1779#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1780struct FastDeferredRuleId(u32);
1781
1782#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1784enum FastDeferredNode {
1785 Fragment(NodeSeqId),
1786 Rule(FastDeferredRuleId),
1787 Alternative(u32),
1788 LeftRecursiveBoundary {
1789 rule_index: u32,
1790 },
1791 Concat {
1792 prefix: FastDeferredNodeId,
1793 suffix: FastDeferredNodeId,
1794 },
1795}
1796
1797#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1798struct FastDeferredRule {
1799 rule_index: u32,
1800 invoking_state: i32,
1801 start_index: u32,
1802 stop_index: Option<u32>,
1803 deferred_children: FastDeferredNodeId,
1804 children: NodeSeqId,
1805}
1806
1807#[repr(transparent)]
1808#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1809struct RecognizedNodeId(u32);
1810
1811#[repr(transparent)]
1812#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1813struct NodeSeqId(u32);
1814
1815impl NodeSeqId {
1816 const EMPTY: Self = Self(u32::MAX);
1817
1818 const fn is_empty(self) -> bool {
1819 self.0 == Self::EMPTY.0
1820 }
1821}
1822
1823impl Default for NodeSeqId {
1824 fn default() -> Self {
1825 Self::EMPTY
1826 }
1827}
1828
1829#[repr(transparent)]
1830#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1831struct DiagnosticSeqId(u32);
1832
1833impl DiagnosticSeqId {
1834 const EMPTY: Self = Self(u32::MAX);
1835
1836 const fn is_empty(self) -> bool {
1837 self.0 == Self::EMPTY.0
1838 }
1839}
1840
1841impl Default for DiagnosticSeqId {
1842 fn default() -> Self {
1843 Self::EMPTY
1844 }
1845}
1846
1847#[repr(transparent)]
1848#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1849struct RecognitionExtraId(u32);
1850
1851#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1852struct SeqLink {
1853 head: RecognizedNodeId,
1854 tail: NodeSeqId,
1855}
1856
1857#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1858struct DiagnosticLink {
1859 head: RecognitionExtraId,
1860 tail: DiagnosticSeqId,
1861}
1862
1863struct ArenaRuleSpec {
1864 rule_index: usize,
1865 invoking_state: isize,
1866 alt_number: usize,
1867 start_index: usize,
1868 stop_index: Option<usize>,
1869 return_values: BTreeMap<String, i64>,
1870 children: NodeSeqId,
1871}
1872
1873#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1876enum ArenaRecognizedNode {
1877 Token {
1878 token: TokenId,
1879 },
1880 ErrorToken {
1881 token: TokenId,
1882 },
1883 MissingToken {
1884 extra: RecognitionExtraId,
1885 },
1886 Rule {
1887 rule_index: u32,
1888 invoking_state: i32,
1889 alt_number: u32,
1890 start_index: u32,
1891 stop_index: Option<u32>,
1892 return_values: Option<RecognitionExtraId>,
1893 children: NodeSeqId,
1894 },
1895 LeftRecursiveBoundary {
1899 rule_index: u32,
1900 alt_number: u32,
1901 },
1902}
1903
1904#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1905enum RecognitionExtra {
1906 MissingToken {
1907 token_type: i32,
1908 at_index: u32,
1909 text: String,
1910 },
1911 ReturnValues(BTreeMap<String, i64>),
1912 Diagnostic(ParserDiagnostic),
1913}
1914
1915#[derive(Debug, Default)]
1916struct RecognitionArena {
1917 nodes: Vec<ArenaRecognizedNode>,
1918 seq_links: Vec<SeqLink>,
1919 diagnostic_links: Vec<DiagnosticLink>,
1920 extras: Vec<RecognitionExtra>,
1921 deferred_nodes: Vec<FastDeferredNode>,
1922 deferred_rules: Vec<FastDeferredRule>,
1923}
1924
1925const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1928const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1929const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1930const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1931const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1932const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1933
1934impl RecognitionArena {
1935 fn reset(&mut self) {
1936 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1937 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1938 reset_arena_vec(
1939 &mut self.diagnostic_links,
1940 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1941 );
1942 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1943 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1944 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1945 }
1946
1947 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1948 let id = RecognizedNodeId(
1949 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1950 );
1951 self.nodes.push(node);
1952 id
1953 }
1954
1955 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1956 let id = RecognitionExtraId(
1957 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1958 );
1959 self.extras.push(extra);
1960 id
1961 }
1962
1963 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1964 let id = NodeSeqId(
1965 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1966 );
1967 self.seq_links.push(SeqLink { head, tail });
1968 id
1969 }
1970
1971 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1972 let id = FastDeferredNodeId(
1973 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1974 );
1975 self.deferred_nodes.push(node);
1976 id
1977 }
1978
1979 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1980 let id = FastDeferredRuleId(
1981 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1982 );
1983 self.deferred_rules.push(rule);
1984 id
1985 }
1986
1987 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1988 if nodes.is_empty() {
1989 FastDeferredNodeId::EMPTY
1990 } else {
1991 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1992 }
1993 }
1994
1995 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1996 let rule = self.push_deferred_rule(rule);
1997 self.push_deferred_node(FastDeferredNode::Rule(rule))
1998 }
1999
2000 fn deferred_alternative(&mut self, alt_number: usize) -> FastDeferredNodeId {
2001 self.push_deferred_node(FastDeferredNode::Alternative(
2002 u32::try_from(alt_number).expect("alternative number fits in u32"),
2003 ))
2004 }
2005
2006 fn deferred_left_recursive_boundary(&mut self, rule_index: usize) -> FastDeferredNodeId {
2007 self.push_deferred_node(FastDeferredNode::LeftRecursiveBoundary {
2008 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
2009 })
2010 }
2011
2012 fn concat_deferred_nodes(
2013 &mut self,
2014 prefix: FastDeferredNodeId,
2015 suffix: FastDeferredNodeId,
2016 ) -> FastDeferredNodeId {
2017 if prefix.is_empty() {
2018 return suffix;
2019 }
2020 if suffix.is_empty() {
2021 return prefix;
2022 }
2023 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
2024 }
2025
2026 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
2027 self.deferred_nodes[id.0 as usize]
2028 }
2029
2030 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
2031 self.deferred_rules[id.0 as usize]
2032 }
2033
2034 fn prepend_diagnostic(
2035 &mut self,
2036 tail: DiagnosticSeqId,
2037 diagnostic: ParserDiagnostic,
2038 ) -> DiagnosticSeqId {
2039 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
2040 self.prepend_diagnostic_id(tail, head)
2041 }
2042
2043 fn prepend_diagnostic_id(
2044 &mut self,
2045 tail: DiagnosticSeqId,
2046 head: RecognitionExtraId,
2047 ) -> DiagnosticSeqId {
2048 let id = DiagnosticSeqId(
2049 u32::try_from(self.diagnostic_links.len())
2050 .expect("diagnostic sequence arena fits in u32"),
2051 );
2052 self.diagnostic_links.push(DiagnosticLink { head, tail });
2053 id
2054 }
2055
2056 fn concat_diagnostics(
2057 &mut self,
2058 prefix: DiagnosticSeqId,
2059 mut suffix: DiagnosticSeqId,
2060 ) -> DiagnosticSeqId {
2061 if prefix.is_empty() {
2062 return suffix;
2063 }
2064 if suffix.is_empty() {
2065 return prefix;
2066 }
2067 let mut reversed = DiagnosticSeqId::EMPTY;
2068 let mut cursor = prefix;
2069 while let Some(link) = self.diagnostic_link(cursor) {
2070 reversed = self.prepend_diagnostic_id(reversed, link.head);
2071 cursor = link.tail;
2072 }
2073 while let Some(link) = self.diagnostic_link(reversed) {
2074 suffix = self.prepend_diagnostic_id(suffix, link.head);
2075 reversed = link.tail;
2076 }
2077 suffix
2078 }
2079
2080 #[cfg(test)]
2081 fn diagnostic_sequence(
2082 &mut self,
2083 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
2084 ) -> DiagnosticSeqId {
2085 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
2086 let mut sequence = DiagnosticSeqId::EMPTY;
2087 for diagnostic in diagnostics.into_iter().rev() {
2088 sequence = self.prepend_diagnostic(sequence, diagnostic);
2089 }
2090 sequence
2091 }
2092
2093 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
2094 self.nodes[id.0 as usize]
2095 }
2096
2097 fn set_boundary_alt_number(&mut self, id: RecognizedNodeId, alt_number: u32) {
2098 let ArenaRecognizedNode::LeftRecursiveBoundary {
2099 alt_number: stored, ..
2100 } = &mut self.nodes[id.0 as usize]
2101 else {
2102 unreachable!("deferred boundary must materialize as a boundary node");
2103 };
2104 *stored = alt_number;
2105 }
2106
2107 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
2108 &self.extras[id.0 as usize]
2109 }
2110
2111 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
2112 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
2113 }
2114
2115 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
2116 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
2117 }
2118
2119 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
2120 NodeSeqIter {
2121 arena: self,
2122 cursor: sequence,
2123 }
2124 }
2125
2126 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
2127 DiagnosticSeqIter {
2128 arena: self,
2129 cursor: sequence,
2130 }
2131 }
2132
2133 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
2134 self.diagnostics(sequence).count()
2135 }
2136
2137 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
2138 self.diagnostics(sequence)
2139 .filter(|diagnostic| {
2140 diagnostic.message.starts_with("mismatched input ")
2141 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
2142 })
2143 .count()
2144 }
2145
2146 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
2147 self.diagnostics(left).cmp(self.diagnostics(right))
2148 }
2149
2150 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
2151 self.iter(sequence).count()
2152 }
2153
2154 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
2155 self.iter(sequence).any(|node| match self.node(node) {
2156 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
2157 ArenaRecognizedNode::Rule { children, .. } => {
2158 self.sequence_has_left_recursive_boundary(children)
2159 }
2160 ArenaRecognizedNode::Token { .. }
2161 | ArenaRecognizedNode::ErrorToken { .. }
2162 | ArenaRecognizedNode::MissingToken { .. } => false,
2163 })
2164 }
2165
2166 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
2167 self.iter(sequence).any(|node| {
2168 matches!(
2169 self.node(node),
2170 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
2171 )
2172 })
2173 }
2174
2175 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
2176 self.iter(sequence).any(|node| {
2177 matches!(
2178 self.node(node),
2179 ArenaRecognizedNode::Token { .. }
2180 | ArenaRecognizedNode::ErrorToken { .. }
2181 | ArenaRecognizedNode::MissingToken { .. }
2182 )
2183 })
2184 }
2185
2186 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
2187 match self.node(node) {
2188 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
2189 Some(token.index())
2190 }
2191 ArenaRecognizedNode::MissingToken { extra } => {
2192 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
2193 unreachable!("missing-token node must reference missing-token extra");
2194 };
2195 Some(*at_index as usize)
2196 }
2197 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
2198 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
2199 }
2200 }
2201
2202 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
2203 match self.node(node) {
2204 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
2205 Some(token.index())
2206 }
2207 ArenaRecognizedNode::MissingToken { extra } => {
2208 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
2209 unreachable!("missing-token node must reference missing-token extra");
2210 };
2211 (*at_index as usize).checked_sub(1)
2212 }
2213 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
2214 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
2215 }
2216 }
2217
2218 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
2219 let start = self.node_start_index(node)?;
2220 let stop = self.node_stop_index(node);
2221 Some((start, stop))
2222 }
2223
2224 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
2225 self.iter(sequence)
2226 .find_map(|node| self.node_start_index(node))
2227 }
2228
2229 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
2230 let mut stop = None;
2231 for node in self.iter(sequence) {
2232 if let Some(index) = self.node_stop_index(node) {
2233 stop = Some(index);
2234 }
2235 }
2236 stop
2237 }
2238
2239 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
2240 self.iter(sequence)
2241 .any(|node| self.node_needs_stable_tie(node))
2242 }
2243
2244 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
2245 match self.node(node) {
2246 ArenaRecognizedNode::Token { .. }
2247 | ArenaRecognizedNode::ErrorToken { .. }
2248 | ArenaRecognizedNode::MissingToken { .. } => false,
2249 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
2250 ArenaRecognizedNode::Rule {
2251 rule_index,
2252 children,
2253 ..
2254 } => self.iter(children).any(|child| {
2255 matches!(
2256 self.node(child),
2257 ArenaRecognizedNode::Rule {
2258 rule_index: child_rule,
2259 ..
2260 } if child_rule == rule_index
2261 ) || self.node_needs_stable_tie(child)
2262 }),
2263 }
2264 }
2265
2266 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
2267 loop {
2268 match (self.link(left), self.link(right)) {
2269 (Some(left_link), Some(right_link)) => {
2270 let order = self.compare_nodes(left_link.head, right_link.head);
2271 if order != Ordering::Equal {
2272 return order;
2273 }
2274 left = left_link.tail;
2275 right = right_link.tail;
2276 }
2277 (None, None) => return Ordering::Equal,
2278 (None, Some(_)) => return Ordering::Less,
2279 (Some(_), None) => return Ordering::Greater,
2280 }
2281 }
2282 }
2283
2284 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
2285 let left = self.node(left);
2286 let right = self.node(right);
2287 match (left, right) {
2288 (
2289 ArenaRecognizedNode::Token { token: left },
2290 ArenaRecognizedNode::Token { token: right },
2291 )
2292 | (
2293 ArenaRecognizedNode::ErrorToken { token: left },
2294 ArenaRecognizedNode::ErrorToken { token: right },
2295 ) => left.cmp(&right),
2296 (
2297 ArenaRecognizedNode::MissingToken { extra: left },
2298 ArenaRecognizedNode::MissingToken { extra: right },
2299 ) => self.extra(left).cmp(self.extra(right)),
2300 (
2301 ArenaRecognizedNode::Rule {
2302 rule_index: left_rule,
2303 invoking_state: left_invoking,
2304 alt_number: left_alt,
2305 start_index: left_start,
2306 stop_index: left_stop,
2307 return_values: left_returns,
2308 children: left_children,
2309 },
2310 ArenaRecognizedNode::Rule {
2311 rule_index: right_rule,
2312 invoking_state: right_invoking,
2313 alt_number: right_alt,
2314 start_index: right_start,
2315 stop_index: right_stop,
2316 return_values: right_returns,
2317 children: right_children,
2318 },
2319 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
2320 .cmp(&(
2321 right_rule,
2322 right_invoking,
2323 right_alt,
2324 right_start,
2325 right_stop,
2326 ))
2327 .then_with(|| {
2328 left_returns
2329 .map(|id| self.extra(id))
2330 .cmp(&right_returns.map(|id| self.extra(id)))
2331 })
2332 .then_with(|| self.compare_sequences(left_children, right_children)),
2333 (
2334 ArenaRecognizedNode::LeftRecursiveBoundary {
2335 rule_index: left_rule,
2336 alt_number: left_alt,
2337 },
2338 ArenaRecognizedNode::LeftRecursiveBoundary {
2339 rule_index: right_rule,
2340 alt_number: right_alt,
2341 },
2342 ) => (left_rule, left_alt).cmp(&(right_rule, right_alt)),
2343 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
2344 }
2345 }
2346
2347 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2348 let mut reversed = NodeSeqId::EMPTY;
2349 while let Some(link) = self.link(sequence) {
2350 reversed = self.prepend(reversed, link.head);
2351 sequence = link.tail;
2352 }
2353 reversed
2354 }
2355
2356 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2357 if !self.sequence_has_direct_boundary(sequence) {
2358 return sequence;
2359 }
2360 let mut reversed = NodeSeqId::EMPTY;
2361 while let Some(link) = self.link(sequence) {
2362 match self.node(link.head) {
2363 ArenaRecognizedNode::LeftRecursiveBoundary {
2364 rule_index,
2365 alt_number,
2366 } => {
2367 if !reversed.is_empty() {
2368 let children = self.reverse_sequence(reversed);
2369 let start_index = self.sequence_start_index(children).unwrap_or_default();
2370 let stop_index = self.sequence_stop_index(children);
2371 let rule = self.push_node(ArenaRecognizedNode::Rule {
2372 rule_index,
2373 invoking_state: -1,
2374 alt_number,
2375 start_index: u32::try_from(start_index)
2376 .expect("left-recursive start index fits in u32"),
2377 stop_index: stop_index.map(|index| {
2378 u32::try_from(index).expect("left-recursive stop index fits in u32")
2379 }),
2380 return_values: None,
2381 children,
2382 });
2383 reversed = self.prepend(NodeSeqId::EMPTY, rule);
2384 }
2385 }
2386 _ => {
2387 reversed = self.prepend(reversed, link.head);
2388 }
2389 }
2390 sequence = link.tail;
2391 }
2392 self.reverse_sequence(reversed)
2393 }
2394
2395 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
2396 let mut live_nodes = vec![false; self.nodes.len()];
2397 let mut live_links = vec![false; self.seq_links.len()];
2398 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
2399 let mut live_extras = vec![false; self.extras.len()];
2400 let mut pending = vec![root];
2401 while let Some(mut sequence) = pending.pop() {
2402 while let Some(link) = self.link(sequence) {
2403 let link_index = sequence.0 as usize;
2404 if live_links[link_index] {
2405 break;
2406 }
2407 live_links[link_index] = true;
2408 let node_index = link.head.0 as usize;
2409 if !live_nodes[node_index] {
2410 live_nodes[node_index] = true;
2411 match self.node(link.head) {
2412 ArenaRecognizedNode::MissingToken { extra } => {
2413 live_extras[extra.0 as usize] = true;
2414 }
2415 ArenaRecognizedNode::Rule {
2416 return_values,
2417 children,
2418 ..
2419 } => {
2420 if let Some(extra) = return_values {
2421 live_extras[extra.0 as usize] = true;
2422 }
2423 pending.push(children);
2424 }
2425 ArenaRecognizedNode::Token { .. }
2426 | ArenaRecognizedNode::ErrorToken { .. }
2427 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
2428 }
2429 }
2430 sequence = link.tail;
2431 }
2432 }
2433 let mut diagnostics = diagnostics;
2434 while let Some(link) = self.diagnostic_link(diagnostics) {
2435 let link_index = diagnostics.0 as usize;
2436 if live_diagnostic_links[link_index] {
2437 break;
2438 }
2439 live_diagnostic_links[link_index] = true;
2440 live_extras[link.head.0 as usize] = true;
2441 diagnostics = link.tail;
2442 }
2443 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
2444 let live_link_count = live_links.into_iter().filter(|live| *live).count()
2445 + live_diagnostic_links
2446 .into_iter()
2447 .filter(|live| *live)
2448 .count();
2449 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
2450 let total_links = self.seq_links.len() + self.diagnostic_links.len();
2451 RecognitionArenaStats {
2452 total_nodes: self.nodes.len(),
2453 live_nodes: live_node_count,
2454 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
2455 node_capacity: self.nodes.capacity(),
2456 total_links,
2457 live_links: live_link_count,
2458 dead_links: total_links.saturating_sub(live_link_count),
2459 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
2460 total_extras: self.extras.len(),
2461 live_extras: live_extra_count,
2462 dead_extras: self.extras.len().saturating_sub(live_extra_count),
2463 extra_capacity: self.extras.capacity(),
2464 }
2465 }
2466}
2467
2468fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
2469 if storage.capacity() > max_retained_capacity {
2470 *storage = Vec::new();
2471 } else {
2472 storage.clear();
2473 }
2474}
2475
2476const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2477 match node {
2478 ArenaRecognizedNode::Token { .. } => 0,
2479 ArenaRecognizedNode::ErrorToken { .. } => 1,
2480 ArenaRecognizedNode::MissingToken { .. } => 2,
2481 ArenaRecognizedNode::Rule { .. } => 3,
2482 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2483 }
2484}
2485
2486struct NodeSeqIter<'a> {
2487 arena: &'a RecognitionArena,
2488 cursor: NodeSeqId,
2489}
2490
2491impl Iterator for NodeSeqIter<'_> {
2492 type Item = RecognizedNodeId;
2493
2494 fn next(&mut self) -> Option<Self::Item> {
2495 let link = self.arena.link(self.cursor)?;
2496 self.cursor = link.tail;
2497 Some(link.head)
2498 }
2499}
2500
2501struct DiagnosticSeqIter<'a> {
2502 arena: &'a RecognitionArena,
2503 cursor: DiagnosticSeqId,
2504}
2505
2506impl<'a> Iterator for DiagnosticSeqIter<'a> {
2507 type Item = &'a ParserDiagnostic;
2508
2509 fn next(&mut self) -> Option<Self::Item> {
2510 let link = self.arena.diagnostic_link(self.cursor)?;
2511 self.cursor = link.tail;
2512 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2513 unreachable!("diagnostic link must reference diagnostic extra");
2514 };
2515 Some(diagnostic)
2516 }
2517}
2518
2519#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2520struct ParserDiagnostic {
2521 line: usize,
2522 column: usize,
2523 message: String,
2524 offending: Option<TokenId>,
2528}
2529
2530#[derive(Clone, Debug, Default, Eq, PartialEq)]
2531struct ExpectedTokens {
2532 index: Option<usize>,
2533 symbols: BTreeSet<i32>,
2534 no_viable: Option<NoViableAlternative>,
2535}
2536
2537#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2538struct NoViableAlternative {
2539 start_index: usize,
2540 error_index: usize,
2541}
2542
2543impl ExpectedTokens {
2544 fn record_transition(
2547 &mut self,
2548 index: usize,
2549 transition: ParserTransition<'_>,
2550 max_token_type: i32,
2551 ) {
2552 let symbols = transition_expected_symbols(transition, max_token_type);
2553 match self.index {
2554 Some(current) if index < current => {}
2555 Some(current) if index == current => self.symbols.extend(symbols),
2556 _ => {
2557 self.index = Some(index);
2558 self.symbols = symbols;
2559 }
2560 }
2561 }
2562
2563 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2566 match self.no_viable {
2567 Some(current) if error_index < current.error_index => {}
2568 _ => {
2569 self.no_viable = Some(NoViableAlternative {
2570 start_index,
2571 error_index,
2572 });
2573 }
2574 }
2575 }
2576}
2577
2578#[derive(Clone, Debug, Default, Eq, PartialEq)]
2585struct TokenBitSet {
2586 words: Vec<u64>,
2587}
2588
2589impl TokenBitSet {
2590 fn insert(&mut self, symbol: i32) {
2591 let Some(slot) = token_bit_slot(symbol) else {
2592 return;
2593 };
2594 let word = slot / u64::BITS as usize;
2595 if word >= self.words.len() {
2596 self.words.resize(word + 1, 0);
2597 }
2598 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2599 }
2600
2601 fn extend_range(&mut self, start: i32, stop: i32) {
2602 let (start, stop) = if start <= stop {
2603 (start, stop)
2604 } else {
2605 (stop, start)
2606 };
2607 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2608 self.insert(TOKEN_EOF);
2609 }
2610 let positive_start = start.max(1);
2611 if positive_start > stop {
2612 return;
2613 }
2614 let Some(start_slot) = token_bit_slot(positive_start) else {
2615 return;
2616 };
2617 let Some(stop_slot) = token_bit_slot(stop) else {
2618 return;
2619 };
2620 self.extend_slot_range(start_slot, stop_slot);
2621 }
2622
2623 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2624 if start_slot > stop_slot {
2625 return;
2626 }
2627 let start_word = start_slot / u64::BITS as usize;
2628 let stop_word = stop_slot / u64::BITS as usize;
2629 if stop_word >= self.words.len() {
2630 self.words.resize(stop_word + 1, 0);
2631 }
2632 let start_offset = start_slot % u64::BITS as usize;
2633 let stop_offset = stop_slot % u64::BITS as usize;
2634 if start_word == stop_word {
2635 self.words[start_word] |=
2636 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2637 return;
2638 }
2639 self.words[start_word] |= !0_u64 << start_offset;
2640 for word in &mut self.words[(start_word + 1)..stop_word] {
2641 *word = !0_u64;
2642 }
2643 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2644 }
2645
2646 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2647 for symbol in symbols {
2648 self.insert(symbol);
2649 }
2650 }
2651
2652 fn extend_from(&mut self, other: &Self) {
2653 if other.words.len() > self.words.len() {
2654 self.words.resize(other.words.len(), 0);
2655 }
2656 for (left, right) in self.words.iter_mut().zip(&other.words) {
2657 *left |= *right;
2658 }
2659 }
2660
2661 fn contains(&self, symbol: i32) -> bool {
2662 let Some(slot) = token_bit_slot(symbol) else {
2663 return false;
2664 };
2665 let word = slot / u64::BITS as usize;
2666 self.words
2667 .get(word)
2668 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2669 }
2670
2671 fn is_empty(&self) -> bool {
2672 self.words.iter().all(|word| *word == 0)
2673 }
2674
2675 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2676 self.words
2677 .iter()
2678 .copied()
2679 .enumerate()
2680 .flat_map(|(word_index, mut bits)| {
2681 std::iter::from_fn(move || {
2682 while bits != 0 {
2683 let bit = bits.trailing_zeros() as usize;
2684 bits &= bits - 1;
2685 if let Some(symbol) =
2686 token_bit_symbol(word_index * u64::BITS as usize + bit)
2687 {
2688 return Some(symbol);
2689 }
2690 }
2691 None
2692 })
2693 })
2694 }
2695
2696 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2697 target.extend(self.symbols());
2698 }
2699
2700 fn to_btree_set(&self) -> BTreeSet<i32> {
2701 let mut out = BTreeSet::new();
2702 self.extend_btree_set(&mut out);
2703 out
2704 }
2705}
2706
2707fn token_bit_slot(symbol: i32) -> Option<usize> {
2708 if symbol == TOKEN_EOF {
2709 Some(0)
2710 } else if symbol > 0 {
2711 usize::try_from(symbol).ok()
2712 } else {
2713 None
2714 }
2715}
2716
2717fn token_bit_symbol(slot: usize) -> Option<i32> {
2718 if slot == 0 {
2719 Some(TOKEN_EOF)
2720 } else {
2721 i32::try_from(slot).ok()
2722 }
2723}
2724
2725fn transition_expected_symbols(
2728 transition: ParserTransition<'_>,
2729 max_token_type: i32,
2730) -> BTreeSet<i32> {
2731 let mut symbols = BTreeSet::new();
2732 match &transition.data() {
2733 Transition::Atom { label, .. } => {
2734 symbols.insert(*label);
2735 }
2736 Transition::Range { start, stop, .. } => {
2737 symbols.extend(*start..=*stop);
2738 }
2739 Transition::Set { set, .. } => {
2740 for (start, stop) in set.ranges() {
2741 symbols.extend(start..=stop);
2742 }
2743 }
2744 Transition::NotSet { set, .. } => {
2745 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2746 }
2747 Transition::Wildcard { .. } => {
2748 symbols.extend(1..=max_token_type);
2749 }
2750 Transition::Epsilon { .. }
2751 | Transition::Rule { .. }
2752 | Transition::Predicate { .. }
2753 | Transition::Action { .. }
2754 | Transition::Precedence { .. } => {}
2755 }
2756 symbols
2757}
2758
2759fn transition_expected_token_set(
2760 transition: ParserTransition<'_>,
2761 max_token_type: i32,
2762) -> TokenBitSet {
2763 let mut symbols = TokenBitSet::default();
2764 match &transition.data() {
2765 Transition::Atom { label, .. } => {
2766 symbols.insert(*label);
2767 }
2768 Transition::Range { start, stop, .. } => {
2769 symbols.extend_range(*start, *stop);
2770 }
2771 Transition::Set { set, .. } => {
2772 for (start, stop) in set.ranges() {
2773 symbols.extend_range(start, stop);
2774 }
2775 }
2776 Transition::NotSet { set, .. } => {
2777 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2778 }
2779 Transition::Wildcard { .. } => {
2780 symbols.extend_range(1, max_token_type);
2781 }
2782 Transition::Epsilon { .. }
2783 | Transition::Rule { .. }
2784 | Transition::Predicate { .. }
2785 | Transition::Action { .. }
2786 | Transition::Precedence { .. } => {}
2787 }
2788 symbols
2789}
2790
2791fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2795 let mut symbols = BTreeSet::new();
2796 let mut stack = vec![state_number];
2797 let mut visited = BTreeSet::new();
2798 while let Some(current) = stack.pop() {
2799 if !visited.insert(current) {
2800 continue;
2801 }
2802 let Some(state) = atn.state(current) else {
2803 continue;
2804 };
2805 for transition in &state.transitions() {
2806 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2807 if transition_symbols.is_empty() {
2808 if transition.is_epsilon() {
2809 stack.push(transition.target());
2810 }
2811 } else {
2812 symbols.extend(transition_symbols);
2813 }
2814 }
2815 }
2816 symbols
2817}
2818
2819fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2820 let mut symbols = TokenBitSet::default();
2821 let mut stack = vec![state_number];
2822 let mut visited = BTreeSet::new();
2823 while let Some(current) = stack.pop() {
2824 if !visited.insert(current) {
2825 continue;
2826 }
2827 let Some(state) = atn.state(current) else {
2828 continue;
2829 };
2830 for transition in &state.transitions() {
2831 let transition_symbols =
2832 transition_expected_token_set(transition, atn.max_token_type());
2833 if transition_symbols.is_empty() {
2834 if transition.is_epsilon() {
2835 stack.push(transition.target());
2836 }
2837 } else {
2838 symbols.extend_from(&transition_symbols);
2839 }
2840 }
2841 }
2842 symbols
2843}
2844
2845fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2846 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2847 return false;
2848 };
2849 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2850 return false;
2851 };
2852 epsilon_reaches_state(atn, state_number, stop_state)
2853}
2854
2855fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2856 let mut stack = vec![start];
2857 let mut visited = BTreeSet::new();
2858 while let Some(current) = stack.pop() {
2859 if current == target {
2860 return true;
2861 }
2862 if !visited.insert(current) {
2863 continue;
2864 }
2865 let Some(state) = atn.state(current) else {
2866 continue;
2867 };
2868 stack.extend(
2869 state
2870 .transitions()
2871 .iter()
2872 .filter(|transition| transition.is_epsilon())
2873 .map(ParserTransition::target),
2874 );
2875 }
2876 false
2877}
2878
2879#[derive(Clone, Debug, Default, Eq, PartialEq)]
2886struct FirstSet {
2887 symbols: TokenBitSet,
2888 nullable: bool,
2889}
2890
2891type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2898
2899type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2906
2907#[derive(Debug, Default)]
2908struct LeftRecursiveOperatorLookahead {
2909 single_token: TokenBitSet,
2913 multi_token_prefix: TokenBitSet,
2918 predicate_dependent: TokenBitSet,
2919}
2920
2921#[derive(Default)]
2922struct SharedAtnCache {
2923 first_set: FirstSetCache,
2924 decision_lookahead: DecisionLookaheadCache,
2925 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2926 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2927 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2928 rule_stop_reach: FxHashMap<usize, bool>,
2929 observable_action_transitions: Option<bool>,
2930 predicate_transitions: Option<bool>,
2931}
2932
2933thread_local! {
2934 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2935 RefCell::new(FxHashMap::default());
2936}
2937
2938#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2949struct SharedAtnCacheKey {
2950 atn: usize,
2951 states: usize,
2952 state_count: usize,
2953 max_token_type: i32,
2954}
2955
2956impl SharedAtnCacheKey {
2957 fn for_atn(atn: &Atn) -> Self {
2958 let (states, state_count) = atn.storage_identity();
2959 Self {
2960 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2961 states,
2962 state_count,
2963 max_token_type: atn.max_token_type(),
2964 }
2965 }
2966}
2967
2968fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2969 SHARED_ATN_CACHES.with(|cell| {
2970 let key = SharedAtnCacheKey::for_atn(atn);
2971 let mut map = cell.borrow_mut();
2972 let cache = map.entry(key).or_default();
2973 f(&mut cache.first_set)
2974 })
2975}
2976
2977fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2978 SHARED_ATN_CACHES.with(|cell| {
2979 let key = SharedAtnCacheKey::for_atn(atn);
2980 let mut map = cell.borrow_mut();
2981 let cache = map.entry(key).or_default();
2982 f(cache)
2983 })
2984}
2985
2986#[derive(Debug, Default)]
2995struct DecisionLookahead {
2996 transitions: Vec<TransitionLookSet>,
2997}
2998
2999#[derive(Clone, Debug, Default)]
3006struct TransitionLookSet {
3007 symbols: TokenBitSet,
3008 nullable: bool,
3009}
3010
3011struct FirstSetCtx<'a> {
3015 cache: &'a mut FirstSetCache,
3016 in_progress: BTreeSet<(usize, usize)>,
3017 hit_cycle: bool,
3018}
3019
3020fn rule_first_set(
3029 atn: &Atn,
3030 target: usize,
3031 rule_stop_state: usize,
3032 cache: &mut FirstSetCache,
3033) -> Rc<FirstSet> {
3034 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
3035 return Rc::clone(cached);
3036 }
3037 let mut ctx = FirstSetCtx {
3038 cache,
3039 in_progress: BTreeSet::new(),
3040 hit_cycle: false,
3041 };
3042 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
3043}
3044
3045fn rule_first_set_cached(
3046 atn: &Atn,
3047 target: usize,
3048 rule_stop_state: usize,
3049 ctx: &mut FirstSetCtx<'_>,
3050) -> Rc<FirstSet> {
3051 let key = (target, rule_stop_state);
3052 if let Some(cached) = ctx.cache.get(&key) {
3053 return Rc::clone(cached);
3054 }
3055 if !ctx.in_progress.insert(key) {
3056 return Rc::new(FirstSet::default());
3060 }
3061 let saved_hit_cycle = ctx.hit_cycle;
3062 ctx.hit_cycle = false;
3063 let mut first = FirstSet::default();
3064 let mut visited = BTreeSet::new();
3065 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
3066 ctx.in_progress.remove(&key);
3067 let entry = Rc::new(first);
3068 if !ctx.hit_cycle {
3069 ctx.cache.insert(key, Rc::clone(&entry));
3070 }
3071 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3072 entry
3073}
3074
3075fn transition_first_set(
3079 atn: &Atn,
3080 transition: ParserTransition<'_>,
3081 rule_stop_state: usize,
3082 cache: &mut FirstSetCache,
3083) -> TransitionLookSet {
3084 match &transition.data() {
3085 Transition::Atom { label, .. } => {
3086 let mut symbols = TokenBitSet::default();
3087 symbols.insert(*label);
3088 TransitionLookSet {
3089 symbols,
3090 nullable: false,
3091 }
3092 }
3093 Transition::Range { start, stop, .. } => {
3094 let mut symbols = TokenBitSet::default();
3095 symbols.extend_range(*start, *stop);
3096 TransitionLookSet {
3097 symbols,
3098 nullable: false,
3099 }
3100 }
3101 Transition::Set { set, .. } => {
3102 let mut symbols = TokenBitSet::default();
3103 for (start, stop) in set.ranges() {
3104 symbols.extend_range(start, stop);
3105 }
3106 TransitionLookSet {
3107 symbols,
3108 nullable: false,
3109 }
3110 }
3111 Transition::NotSet { set, .. } => {
3112 let max = atn.max_token_type();
3113 let mut symbols = TokenBitSet::default();
3114 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
3115 TransitionLookSet {
3116 symbols,
3117 nullable: false,
3118 }
3119 }
3120 Transition::Wildcard { .. } => {
3121 let mut symbols = TokenBitSet::default();
3122 symbols.extend_range(1, atn.max_token_type());
3123 TransitionLookSet {
3124 symbols,
3125 nullable: false,
3126 }
3127 }
3128 Transition::Epsilon { target }
3129 | Transition::Action { target, .. }
3130 | Transition::Predicate { target, .. }
3131 | Transition::Precedence { target, .. } => {
3132 let first = rule_first_set(atn, *target, rule_stop_state, cache);
3135 TransitionLookSet {
3136 symbols: first.symbols.clone(),
3137 nullable: first.nullable,
3138 }
3139 }
3140 Transition::Rule {
3141 target,
3142 rule_index,
3143 follow_state,
3144 ..
3145 } => {
3146 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3147 return TransitionLookSet::default();
3148 };
3149 let child = rule_first_set(atn, *target, child_stop, cache);
3150 let mut symbols = child.symbols.clone();
3151 let nullable = if child.nullable {
3152 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
3153 symbols.extend_from(&follow.symbols);
3154 follow.nullable
3155 } else {
3156 false
3157 };
3158 TransitionLookSet { symbols, nullable }
3159 }
3160 }
3161}
3162
3163fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
3184 let mut chosen: Option<usize> = None;
3185 for (index, transition) in entry.transitions.iter().enumerate() {
3186 if transition.nullable {
3187 return None;
3188 }
3189 if transition.symbols.contains(symbol) {
3190 if chosen.is_some() {
3191 return None;
3192 }
3193 chosen = Some(index);
3194 }
3195 }
3196 chosen
3197}
3198
3199fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
3208 let mut matching_non_nullable_alt = None;
3209 let mut nullable_alt = None;
3210 for (index, transition) in entry.transitions.iter().enumerate() {
3211 if transition.nullable {
3212 if nullable_alt.is_some() {
3213 return None;
3214 }
3215 nullable_alt = Some(index);
3216 }
3217 if transition.symbols.contains(symbol) {
3218 if transition.nullable {
3219 continue;
3220 }
3221 if matching_non_nullable_alt.is_some() {
3222 return None;
3223 }
3224 matching_non_nullable_alt = Some(index);
3225 }
3226 }
3227 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
3228 return None;
3229 }
3230 if non_greedy {
3231 nullable_alt.or(matching_non_nullable_alt)
3232 } else {
3233 matching_non_nullable_alt.or(nullable_alt)
3234 }
3235}
3236
3237fn should_skip_via_lookahead(
3238 transition_kind: ParserTransitionKind,
3239 transition_index: usize,
3240 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
3241 index: usize,
3242 record_expected: bool,
3243 expected: &mut ExpectedTokens,
3244) -> bool {
3245 let prune_non_consuming = matches!(
3246 transition_kind,
3247 ParserTransitionKind::Epsilon
3248 | ParserTransitionKind::Action
3249 | ParserTransitionKind::Predicate
3250 | ParserTransitionKind::Rule
3251 | ParserTransitionKind::Precedence
3252 );
3253 if !prune_non_consuming {
3254 return false;
3255 }
3256 let Some((symbol, entry)) = lookahead_filter else {
3257 return false;
3258 };
3259 let Some(set) = entry.transitions.get(transition_index) else {
3260 return false;
3261 };
3262 if set.symbols.contains(*symbol) || set.nullable {
3263 return false;
3264 }
3265 if record_expected && !set.symbols.is_empty() {
3266 record_pruned_transition_expected(set, index, expected);
3267 }
3268 true
3269}
3270
3271fn should_skip_rule_via_first_set(
3272 first: &FirstSet,
3273 symbol: i32,
3274 record_expected: bool,
3275 index: usize,
3276 expected: &mut ExpectedTokens,
3277) -> bool {
3278 if first.nullable || first.symbols.contains(symbol) {
3279 return false;
3280 }
3281 if record_expected && !first.symbols.is_empty() {
3282 record_token_bit_expected(&first.symbols, index, expected);
3283 }
3284 true
3285}
3286
3287fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
3288 match expected.index {
3289 Some(current) if index < current => {}
3290 Some(current) if index == current => {
3291 symbols.extend_btree_set(&mut expected.symbols);
3292 }
3293 _ => {
3294 expected.index = Some(index);
3295 expected.symbols = symbols.to_btree_set();
3296 }
3297 }
3298}
3299
3300fn record_pruned_transition_expected(
3302 set: &TransitionLookSet,
3303 index: usize,
3304 expected: &mut ExpectedTokens,
3305) {
3306 match expected.index {
3307 Some(current) if index < current => {}
3308 Some(current) if index == current => {
3309 set.symbols.extend_btree_set(&mut expected.symbols);
3310 }
3311 _ => {
3312 expected.index = Some(index);
3313 expected.symbols = set.symbols.to_btree_set();
3314 }
3315 }
3316}
3317
3318fn rule_first_set_inner(
3319 atn: &Atn,
3320 state_number: usize,
3321 rule_stop_state: usize,
3322 ctx: &mut FirstSetCtx<'_>,
3323 visited: &mut BTreeSet<usize>,
3324 first: &mut FirstSet,
3325) {
3326 if !visited.insert(state_number) {
3327 return;
3328 }
3329 if state_number == rule_stop_state {
3330 first.nullable = true;
3331 return;
3332 }
3333 let Some(state) = atn.state(state_number) else {
3334 return;
3335 };
3336 for transition in &state.transitions() {
3337 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3338 if !transition_symbols.is_empty() {
3339 first.symbols.extend_iter(transition_symbols);
3340 continue;
3341 }
3342 match &transition.data() {
3343 Transition::Epsilon { target }
3344 | Transition::Action { target, .. }
3345 | Transition::Predicate { target, .. }
3346 | Transition::Precedence { target, .. } => {
3347 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
3348 }
3349 Transition::Rule {
3350 target,
3351 rule_index,
3352 follow_state,
3353 ..
3354 } => {
3355 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3356 continue;
3357 };
3358 let child_key = (*target, child_stop);
3359 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
3360 ctx.hit_cycle = true;
3361 }
3362 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
3363 first.symbols.extend_from(&child.symbols);
3364 if child.nullable {
3365 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
3366 }
3367 }
3368 Transition::Atom { .. }
3369 | Transition::Range { .. }
3370 | Transition::Set { .. }
3371 | Transition::NotSet { .. }
3372 | Transition::Wildcard { .. } => {}
3373 }
3374 }
3375}
3376
3377fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
3380 let mut symbols = BTreeSet::new();
3381 state_sync_symbols_inner(
3382 atn,
3383 state_number,
3384 stop_state,
3385 &mut BTreeSet::new(),
3386 &mut symbols,
3387 );
3388 symbols
3389}
3390
3391fn state_sync_symbols_inner(
3394 atn: &Atn,
3395 state_number: usize,
3396 stop_state: usize,
3397 visited: &mut BTreeSet<usize>,
3398 symbols: &mut BTreeSet<i32>,
3399) {
3400 if !visited.insert(state_number) {
3401 return;
3402 }
3403 if state_number == stop_state {
3404 symbols.insert(TOKEN_EOF);
3405 return;
3406 }
3407 let Some(state) = atn.state(state_number) else {
3408 return;
3409 };
3410 for transition in &state.transitions() {
3411 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3412 if transition_symbols.is_empty() {
3413 match &transition.data() {
3414 Transition::Rule { target, .. }
3415 | Transition::Epsilon { target }
3416 | Transition::Action { target, .. }
3417 | Transition::Predicate { target, .. }
3418 | Transition::Precedence { target, .. } => {
3419 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
3420 }
3421 Transition::Atom { .. }
3422 | Transition::Range { .. }
3423 | Transition::Set { .. }
3424 | Transition::NotSet { .. }
3425 | Transition::Wildcard { .. } => {}
3426 }
3427 } else {
3428 symbols.extend(transition_symbols);
3429 }
3430 }
3431}
3432
3433#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
3434struct OperatorSymbolReachability {
3435 single_token: bool,
3437 multi_token: bool,
3439 predicate_dependent: bool,
3441}
3442
3443impl OperatorSymbolReachability {
3444 const ADAPTIVE_FALLBACK: Self = Self {
3445 single_token: false,
3446 multi_token: false,
3447 predicate_dependent: true,
3448 };
3449
3450 const fn single_token(predicate_dependent: bool) -> Self {
3451 if predicate_dependent {
3452 Self {
3453 single_token: false,
3454 multi_token: false,
3455 predicate_dependent: true,
3456 }
3457 } else {
3458 Self {
3459 single_token: true,
3460 multi_token: false,
3461 predicate_dependent: false,
3462 }
3463 }
3464 }
3465
3466 const fn multi_token(predicate_dependent: bool) -> Self {
3467 if predicate_dependent {
3468 Self {
3469 single_token: false,
3470 multi_token: false,
3471 predicate_dependent: true,
3472 }
3473 } else {
3474 Self {
3475 single_token: false,
3476 multi_token: true,
3477 predicate_dependent: false,
3478 }
3479 }
3480 }
3481
3482 const fn union(self, other: Self) -> Self {
3483 Self {
3484 single_token: self.single_token || other.single_token,
3485 multi_token: self.multi_token || other.multi_token,
3486 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3487 }
3488 }
3489}
3490
3491#[derive(Clone, Copy)]
3492struct OperatorReachabilityRequest {
3493 symbol: i32,
3494 precedence: i32,
3495 predicate_dependent: bool,
3496 operator_rule_index: usize,
3497}
3498
3499#[derive(Clone, Copy, Debug)]
3500struct OperatorRuleContinuation {
3501 stop_state: usize,
3502 follow_state: usize,
3503 return_precedence: i32,
3504}
3505
3506struct NullablePrecedenceCtx {
3507 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3508 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3509 hit_cycle: bool,
3510}
3511
3512fn state_is_nullable_with_precedence(
3513 atn: &Atn,
3514 state_number: usize,
3515 stop_state_number: usize,
3516 precedence: i32,
3517 allow_predicates: bool,
3518 ctx: &mut NullablePrecedenceCtx,
3519) -> bool {
3520 let saved_hit_cycle = ctx.hit_cycle;
3521 ctx.hit_cycle = false;
3522 let nullable = state_is_nullable_with_precedence_cached(
3523 atn,
3524 state_number,
3525 stop_state_number,
3526 precedence,
3527 allow_predicates,
3528 ctx,
3529 );
3530 ctx.hit_cycle = saved_hit_cycle;
3531 nullable
3532}
3533
3534fn state_is_nullable_with_precedence_cached(
3535 atn: &Atn,
3536 state_number: usize,
3537 stop_state_number: usize,
3538 precedence: i32,
3539 allow_predicates: bool,
3540 ctx: &mut NullablePrecedenceCtx,
3541) -> bool {
3542 if state_number == stop_state_number {
3543 return true;
3544 }
3545 let key = (
3546 state_number,
3547 stop_state_number,
3548 precedence,
3549 allow_predicates,
3550 );
3551 if let Some(cached) = ctx.cache.get(&key) {
3552 return *cached;
3553 }
3554 if !ctx.in_progress.insert(key) {
3555 ctx.hit_cycle = true;
3556 return false;
3557 }
3558 let saved_hit_cycle = ctx.hit_cycle;
3559 ctx.hit_cycle = false;
3560 let nullable = atn.state(state_number).is_some_and(|state| {
3561 state
3562 .transitions()
3563 .iter()
3564 .any(|transition| match &transition.data() {
3565 Transition::Rule {
3566 target,
3567 rule_index,
3568 follow_state,
3569 precedence: rule_precedence,
3570 } => {
3571 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3572 return false;
3573 };
3574 state_is_nullable_with_precedence_cached(
3575 atn,
3576 *target,
3577 child_stop,
3578 *rule_precedence,
3579 allow_predicates,
3580 ctx,
3581 ) && state_is_nullable_with_precedence_cached(
3582 atn,
3583 *follow_state,
3584 stop_state_number,
3585 precedence,
3586 allow_predicates,
3587 ctx,
3588 )
3589 }
3590 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3591 state_is_nullable_with_precedence_cached(
3592 atn,
3593 *target,
3594 stop_state_number,
3595 precedence,
3596 allow_predicates,
3597 ctx,
3598 )
3599 }
3600 Transition::Predicate { target, .. } if allow_predicates => {
3601 state_is_nullable_with_precedence_cached(
3602 atn,
3603 *target,
3604 stop_state_number,
3605 precedence,
3606 allow_predicates,
3607 ctx,
3608 )
3609 }
3610 Transition::Precedence {
3611 target,
3612 precedence: transition_precedence,
3613 } if *transition_precedence >= precedence => {
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::Atom { .. }
3624 | Transition::Range { .. }
3625 | Transition::Set { .. }
3626 | Transition::NotSet { .. }
3627 | Transition::Wildcard { .. }
3628 | Transition::Predicate { .. }
3629 | Transition::Precedence { .. } => false,
3630 })
3631 });
3632 ctx.in_progress.remove(&key);
3633 if !ctx.hit_cycle {
3634 ctx.cache.insert(key, nullable);
3635 }
3636 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3637 nullable
3638}
3639
3640fn state_operator_token_prefix_reachability(
3642 atn: &Atn,
3643 state_number: usize,
3644 request: OperatorReachabilityRequest,
3645 continuations: &[OperatorRuleContinuation],
3646 visited: &mut BTreeSet<(usize, i32, bool)>,
3647) -> OperatorSymbolReachability {
3648 let key = (
3649 state_number,
3650 request.precedence,
3651 request.predicate_dependent,
3652 );
3653 if !visited.insert(key) {
3654 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3658 }
3659 if let Some((continuation, remaining)) = continuations.split_last()
3660 && state_number == continuation.stop_state
3661 {
3662 let result = state_operator_token_prefix_reachability(
3663 atn,
3664 continuation.follow_state,
3665 OperatorReachabilityRequest {
3666 precedence: continuation.return_precedence,
3667 ..request
3668 },
3669 remaining,
3670 visited,
3671 );
3672 visited.remove(&key);
3673 return result;
3674 }
3675 let Some(state) = atn.state(state_number) else {
3676 visited.remove(&key);
3677 return OperatorSymbolReachability::default();
3678 };
3679 let completes_operator = match state.kind() {
3680 AtnStateKind::RuleStop => continuations.is_empty(),
3681 AtnStateKind::StarLoopBack
3682 | AtnStateKind::StarLoopEntry
3683 | AtnStateKind::PlusLoopBack
3684 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3685 _ => false,
3686 };
3687 if completes_operator {
3688 visited.remove(&key);
3689 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3690 }
3691 let mut reachability = OperatorSymbolReachability::default();
3692 for transition in &state.transitions() {
3693 let transition_reachability = match &transition.data() {
3694 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3695 OperatorSymbolReachability::single_token(request.predicate_dependent)
3696 }
3697 Transition::Rule {
3698 target,
3699 rule_index,
3700 follow_state,
3701 precedence: rule_precedence,
3702 } => {
3703 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3704 continue;
3705 };
3706 let mut nested = continuations.to_vec();
3707 nested.push(OperatorRuleContinuation {
3708 stop_state: child_stop,
3709 follow_state: *follow_state,
3710 return_precedence: request.precedence,
3711 });
3712 state_operator_token_prefix_reachability(
3713 atn,
3714 *target,
3715 OperatorReachabilityRequest {
3716 precedence: *rule_precedence,
3717 ..request
3718 },
3719 &nested,
3720 visited,
3721 )
3722 }
3723 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3724 state_operator_token_prefix_reachability(
3725 atn,
3726 *target,
3727 request,
3728 continuations,
3729 visited,
3730 )
3731 }
3732 Transition::Precedence {
3733 target,
3734 precedence: transition_precedence,
3735 } => {
3736 if *transition_precedence < request.precedence {
3737 OperatorSymbolReachability::default()
3738 } else {
3739 state_operator_token_prefix_reachability(
3740 atn,
3741 *target,
3742 request,
3743 continuations,
3744 visited,
3745 )
3746 }
3747 }
3748 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3749 atn,
3750 *target,
3751 OperatorReachabilityRequest {
3752 predicate_dependent: true,
3753 ..request
3754 },
3755 continuations,
3756 visited,
3757 ),
3758 Transition::Atom { .. }
3759 | Transition::Range { .. }
3760 | Transition::Set { .. }
3761 | Transition::NotSet { .. }
3762 | Transition::Wildcard { .. } => {
3763 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3764 }
3765 };
3766 reachability = reachability.union(transition_reachability);
3767 }
3768 visited.remove(&key);
3769 reachability
3770}
3771
3772fn state_can_reach_symbol_with_precedence(
3773 atn: &Atn,
3774 state_number: usize,
3775 request: OperatorReachabilityRequest,
3776 nullable_ctx: &mut NullablePrecedenceCtx,
3777 continuations: &mut Vec<OperatorRuleContinuation>,
3778 visited: &mut BTreeSet<(usize, i32, bool)>,
3779) -> OperatorSymbolReachability {
3780 let key = (
3781 state_number,
3782 request.precedence,
3783 request.predicate_dependent,
3784 );
3785 if !visited.insert(key) {
3786 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3787 }
3788 let Some(state) = atn.state(state_number) else {
3789 visited.remove(&key);
3790 return OperatorSymbolReachability::default();
3791 };
3792 let mut reachability = OperatorSymbolReachability::default();
3793 for transition in &state.transitions() {
3794 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3795 reachability = reachability.union(state_operator_token_prefix_reachability(
3796 atn,
3797 transition.target(),
3798 request,
3799 continuations,
3800 &mut BTreeSet::new(),
3801 ));
3802 continue;
3803 }
3804 let transition_reachability = match &transition.data() {
3805 Transition::Rule {
3806 target,
3807 rule_index,
3808 follow_state,
3809 precedence: rule_precedence,
3810 } => {
3811 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3812 continue;
3813 };
3814 continuations.push(OperatorRuleContinuation {
3815 stop_state: child_stop,
3816 follow_state: *follow_state,
3817 return_precedence: request.precedence,
3818 });
3819 let mut result = state_can_reach_symbol_with_precedence(
3820 atn,
3821 *target,
3822 OperatorReachabilityRequest {
3823 precedence: *rule_precedence,
3824 ..request
3825 },
3826 nullable_ctx,
3827 continuations,
3828 visited,
3829 );
3830 continuations.pop();
3831 if state_is_nullable_with_precedence(
3832 atn,
3833 *target,
3834 child_stop,
3835 *rule_precedence,
3836 true,
3837 nullable_ctx,
3838 ) {
3839 let child_predicate_dependent = request.predicate_dependent
3840 || !state_is_nullable_with_precedence(
3841 atn,
3842 *target,
3843 child_stop,
3844 *rule_precedence,
3845 false,
3846 nullable_ctx,
3847 );
3848 result = result.union(state_can_reach_symbol_with_precedence(
3849 atn,
3850 *follow_state,
3851 OperatorReachabilityRequest {
3852 predicate_dependent: child_predicate_dependent,
3853 ..request
3854 },
3855 nullable_ctx,
3856 continuations,
3857 visited,
3858 ));
3859 }
3860 result
3861 }
3862 Transition::Epsilon { target }
3863 | Transition::Action { target, .. }
3864 | Transition::Precedence { target, .. } => {
3865 if matches!(
3866 &transition.data(),
3867 Transition::Precedence {
3868 precedence: transition_precedence,
3869 ..
3870 } if *transition_precedence < request.precedence
3871 ) {
3872 continue;
3873 }
3874 state_can_reach_symbol_with_precedence(
3875 atn,
3876 *target,
3877 request,
3878 nullable_ctx,
3879 continuations,
3880 visited,
3881 )
3882 }
3883 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3884 atn,
3885 *target,
3886 OperatorReachabilityRequest {
3887 predicate_dependent: true,
3888 ..request
3889 },
3890 nullable_ctx,
3891 continuations,
3892 visited,
3893 ),
3894 Transition::Atom { .. }
3895 | Transition::Range { .. }
3896 | Transition::Set { .. }
3897 | Transition::NotSet { .. }
3898 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3899 };
3900 reachability = reachability.union(transition_reachability);
3901 }
3902 visited.remove(&key);
3903 reachability
3904}
3905
3906fn left_recursive_operator_lookahead(
3907 atn: &Atn,
3908 state_number: usize,
3909 precedence: i32,
3910) -> LeftRecursiveOperatorLookahead {
3911 let Some(state) = atn.state(state_number) else {
3912 return LeftRecursiveOperatorLookahead::default();
3913 };
3914 let Some(operator_rule_index) = state.rule_index() else {
3915 return LeftRecursiveOperatorLookahead::default();
3916 };
3917 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3918 let mut nullable_ctx = NullablePrecedenceCtx {
3919 cache: FxHashMap::default(),
3920 in_progress: BTreeSet::new(),
3921 hit_cycle: false,
3922 };
3923 for transition in &state.transitions() {
3924 let target = transition.target();
3925 if atn
3926 .state(target)
3927 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3928 {
3929 continue;
3930 }
3931 for symbol in 1..=atn.max_token_type() {
3932 let reachability = state_can_reach_symbol_with_precedence(
3933 atn,
3934 target,
3935 OperatorReachabilityRequest {
3936 symbol,
3937 precedence,
3938 predicate_dependent: false,
3939 operator_rule_index,
3940 },
3941 &mut nullable_ctx,
3942 &mut Vec::new(),
3943 &mut BTreeSet::new(),
3944 );
3945 if reachability.single_token {
3946 lookahead.single_token.insert(symbol);
3947 }
3948 if reachability.multi_token {
3949 lookahead.multi_token_prefix.insert(symbol);
3950 }
3951 if reachability.predicate_dependent {
3952 lookahead.predicate_dependent.insert(symbol);
3953 }
3954 }
3955 }
3956 lookahead
3957}
3958
3959#[derive(Debug, Default)]
3960struct StateBeforeStopLookahead {
3961 symbols: TokenBitSet,
3962 reaches_context_boundary: bool,
3963}
3964
3965fn state_before_stop_lookahead(
3966 atn: &Atn,
3967 state_number: usize,
3968 stop_state_number: usize,
3969) -> Rc<StateBeforeStopLookahead> {
3970 with_shared_atn_caches(atn, |cache| {
3971 let key = (state_number, stop_state_number);
3972 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3973 return Rc::clone(cached);
3974 }
3975 let mut lookahead = StateBeforeStopLookahead::default();
3976 state_before_stop_lookahead_inner(
3977 atn,
3978 state_number,
3979 stop_state_number,
3980 &mut BTreeSet::new(),
3981 &mut cache.first_set,
3982 &mut lookahead,
3983 );
3984 let lookahead = Rc::new(lookahead);
3985 cache
3986 .state_before_stop_lookahead
3987 .insert(key, Rc::clone(&lookahead));
3988 lookahead
3989 })
3990}
3991
3992fn state_before_stop_lookahead_inner(
3993 atn: &Atn,
3994 state_number: usize,
3995 stop_state_number: usize,
3996 visited: &mut BTreeSet<usize>,
3997 first_set_cache: &mut FirstSetCache,
3998 lookahead: &mut StateBeforeStopLookahead,
3999) {
4000 if state_number == stop_state_number {
4001 lookahead.reaches_context_boundary = true;
4002 return;
4003 }
4004 if !visited.insert(state_number) {
4005 return;
4006 }
4007 let Some(state) = atn.state(state_number) else {
4008 return;
4009 };
4010 if state.kind() == AtnStateKind::RuleStop {
4011 lookahead.reaches_context_boundary = true;
4012 return;
4013 }
4014 for transition in &state.transitions() {
4015 match &transition.data() {
4016 Transition::Epsilon { target }
4017 | Transition::Action { target, .. }
4018 | Transition::Predicate { target, .. }
4019 | Transition::Precedence { target, .. } => {
4020 state_before_stop_lookahead_inner(
4021 atn,
4022 *target,
4023 stop_state_number,
4024 visited,
4025 first_set_cache,
4026 lookahead,
4027 );
4028 }
4029 Transition::Rule {
4030 target,
4031 rule_index,
4032 follow_state,
4033 ..
4034 } => {
4035 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
4036 continue;
4037 };
4038 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
4039 lookahead.symbols.extend_from(&child.symbols);
4040 if child.nullable {
4041 state_before_stop_lookahead_inner(
4042 atn,
4043 *follow_state,
4044 stop_state_number,
4045 visited,
4046 first_set_cache,
4047 lookahead,
4048 );
4049 }
4050 }
4051 Transition::Atom { .. }
4052 | Transition::Range { .. }
4053 | Transition::Set { .. }
4054 | Transition::NotSet { .. }
4055 | Transition::Wildcard { .. } => {
4056 lookahead.symbols.extend_iter(transition_expected_symbols(
4057 transition,
4058 atn.max_token_type(),
4059 ));
4060 }
4061 }
4062 }
4063}
4064
4065fn caller_context_can_match_symbol_before_state(
4066 atn: &Atn,
4067 return_states: impl DoubleEndedIterator<Item = usize>,
4068 stop_state_number: usize,
4069 symbol: i32,
4070) -> bool {
4071 for return_state in return_states.rev() {
4072 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
4073 if lookahead.symbols.contains(symbol) {
4074 return true;
4075 }
4076 if !lookahead.reaches_context_boundary {
4077 return false;
4078 }
4079 }
4080 false
4081}
4082
4083fn next_recovery_context(
4087 atn: &Atn,
4088 state: AtnState<'_>,
4089 inherited: &BTreeSet<i32>,
4090 inherited_state: Option<usize>,
4091) -> (BTreeSet<i32>, Option<usize>) {
4092 let state_symbols = state_expected_symbols(atn, state.state_number());
4093 if state.transitions().len() > 1 && !state_symbols.is_empty() {
4094 let mut symbols = state_symbols;
4095 symbols.extend(inherited.iter().copied());
4096 return (symbols, Some(state.state_number()));
4097 }
4098 (inherited.clone(), inherited_state)
4099}
4100
4101fn recovery_expected_symbols(
4102 atn: &Atn,
4103 state_number: usize,
4104 inherited: &BTreeSet<i32>,
4105) -> BTreeSet<i32> {
4106 let mut symbols = state_expected_symbols(atn, state_number);
4107 symbols.extend(inherited.iter().copied());
4108 symbols
4109}
4110
4111fn fast_next_recovery_context<S, H>(
4115 parser: &mut BaseParser<S, H>,
4116 atn: &Atn,
4117 state: AtnState<'_>,
4118 inherited: &Rc<BTreeSet<i32>>,
4119 inherited_state: Option<usize>,
4120) -> (Rc<BTreeSet<i32>>, Option<usize>)
4121where
4122 S: TokenSource,
4123 H: SemanticHooks,
4124{
4125 if state.transitions().len() <= 1 {
4126 return (Rc::clone(inherited), inherited_state);
4127 }
4128 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
4129 if state_symbols.is_empty() {
4130 return (Rc::clone(inherited), inherited_state);
4131 }
4132 if inherited.is_empty() {
4133 return (state_symbols, Some(state.state_number()));
4134 }
4135 if Rc::ptr_eq(&state_symbols, inherited) {
4136 return (state_symbols, Some(state.state_number()));
4137 }
4138 let mut combined = (*state_symbols).clone();
4139 combined.extend(inherited.iter().copied());
4140 (
4141 parser.intern_recovery_symbols(combined),
4142 Some(state.state_number()),
4143 )
4144}
4145
4146fn fast_recovery_expected_symbols<S, H>(
4150 parser: &mut BaseParser<S, H>,
4151 atn: &Atn,
4152 state_number: usize,
4153 inherited: &Rc<BTreeSet<i32>>,
4154) -> Rc<BTreeSet<i32>>
4155where
4156 S: TokenSource,
4157 H: SemanticHooks,
4158{
4159 let cached = parser.cached_state_expected_symbols(atn, state_number);
4160 if inherited.is_empty() {
4161 return cached;
4162 }
4163 if cached.is_empty() {
4164 return Rc::clone(inherited);
4165 }
4166 if Rc::ptr_eq(&cached, inherited) {
4167 return cached;
4168 }
4169 let mut combined = (*cached).clone();
4170 combined.extend(inherited.iter().copied());
4171 parser.intern_recovery_symbols(combined)
4172}
4173
4174struct ParserTableSemCtx<'a> {
4175 member_values: &'a mut MemberEnv,
4176 return_values: &'a mut BTreeMap<String, i64>,
4177}
4178
4179impl semir::PredContext for ParserTableSemCtx<'_> {
4180 type TokenText<'a>
4181 = &'a str
4182 where
4183 Self: 'a;
4184
4185 fn la(&mut self, _offset: isize) -> i64 {
4186 i64::from(TOKEN_EOF)
4187 }
4188
4189 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
4190 None
4191 }
4192
4193 fn token_index_adjacent(&mut self) -> bool {
4194 false
4195 }
4196
4197 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
4198 None
4199 }
4200
4201 fn member(&self, member: usize) -> Option<i64> {
4202 Some(self.member_values.scalar(member).unwrap_or_default())
4203 }
4204
4205 fn member_top(&self, member: usize) -> Option<i64> {
4206 self.member_values.stack_top(member)
4207 }
4208
4209 fn member_len(&self, member: usize) -> usize {
4210 self.member_values.stack_len(member)
4211 }
4212
4213 fn local_arg(&self) -> Option<i64> {
4214 None
4215 }
4216
4217 fn column(&self) -> Option<i64> {
4218 None
4219 }
4220
4221 fn token_start_column(&self) -> Option<i64> {
4222 None
4223 }
4224
4225 fn token_text_so_far(&self) -> Option<String> {
4226 None
4227 }
4228
4229 fn hook(&mut self, _hook: HookId) -> bool {
4230 false
4231 }
4232}
4233
4234impl semir::ActContext for ParserTableSemCtx<'_> {
4235 fn set_member(&mut self, member: usize, value: i64) {
4236 self.member_values.set_scalar(member, value);
4237 }
4238
4239 fn push_member(&mut self, member: usize, value: i64) {
4240 self.member_values.push_stack(member, value);
4241 }
4242
4243 fn pop_member(&mut self, member: usize) -> Option<i64> {
4244 self.member_values.pop_stack(member)
4245 }
4246
4247 fn set_return(&mut self, name: &str, value: i64) {
4248 self.return_values.insert(name.to_owned(), value);
4249 }
4250
4251 fn action_hook(&mut self, _hook: HookId) {}
4252}
4253
4254fn apply_member_actions(
4256 source_state: usize,
4257 actions: &[ParserMemberAction],
4258 semantics: Option<&ParserSemantics>,
4259 values: &mut MemberEnv,
4260) {
4261 for action in actions
4262 .iter()
4263 .filter(|action| action.source_state == source_state)
4264 {
4265 values.add_scalar(action.member, action.delta);
4266 }
4267 let Some(semantics) = semantics else {
4268 return;
4269 };
4270 let mut return_values = BTreeMap::new();
4271 let mut ctx = ParserTableSemCtx {
4272 member_values: values,
4273 return_values: &mut return_values,
4274 };
4275 for action in semantics
4276 .actions
4277 .iter()
4278 .filter(|action| action.source_state == source_state && action.speculative)
4279 {
4280 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4281 }
4282}
4283
4284fn member_values_after_action(
4286 source_state: usize,
4287 actions: &[ParserMemberAction],
4288 semantics: Option<&ParserSemantics>,
4289 values: &MemberEnv,
4290) -> MemberEnv {
4291 let mut values = values.clone();
4292 apply_member_actions(source_state, actions, semantics, &mut values);
4293 values
4294}
4295
4296fn return_values_after_action(
4298 source_state: usize,
4299 rule_index: usize,
4300 actions: &[ParserReturnAction],
4301 semantics: Option<&ParserSemantics>,
4302 values: &BTreeMap<String, i64>,
4303) -> BTreeMap<String, i64> {
4304 let mut values = values.clone();
4305 for action in actions
4306 .iter()
4307 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
4308 {
4309 values.insert(action.name.to_owned(), action.value);
4310 }
4311 if let Some(semantics) = semantics {
4312 let mut member_values = MemberEnv::new();
4313 let mut ctx = ParserTableSemCtx {
4314 member_values: &mut member_values,
4315 return_values: &mut values,
4316 };
4317 for action in semantics.actions.iter().filter(|action| {
4318 action.source_state == source_state
4319 && action.rule_index == rule_index
4320 && !action.speculative
4321 }) {
4322 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4323 }
4324 }
4325 values
4326}
4327
4328fn rule_local_int_arg(
4330 rule_args: &[ParserRuleArg],
4331 source_state: usize,
4332 rule_index: usize,
4333 local_int_arg: Option<(usize, i64)>,
4334) -> Option<(usize, i64)> {
4335 rule_args
4336 .iter()
4337 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
4338 .map(|arg| {
4339 let value = if arg.inherit_local {
4340 local_int_arg.map_or(arg.value, |(_, value)| value)
4341 } else {
4342 arg.value
4343 };
4344 (rule_index, value)
4345 })
4346}
4347
4348fn stop_outcome(
4351 index: usize,
4352 consumed_eof: bool,
4353 rule_alt_number: usize,
4354 member_values: MemberEnv,
4355 return_values: BTreeMap<String, i64>,
4356) -> Vec<RecognizeOutcome> {
4357 vec![RecognizeOutcome {
4358 index,
4359 consumed_eof,
4360 alt_number: rule_alt_number,
4361 member_values,
4362 return_values,
4363 diagnostics: DiagnosticSeqId::EMPTY,
4364 decisions: Vec::new(),
4365 actions: Vec::new(),
4366 nodes: NodeSeqId::EMPTY,
4367 }]
4368}
4369
4370fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
4371 with_shared_atn_caches(atn, |cache| {
4372 *cache.observable_action_transitions.get_or_insert_with(|| {
4373 atn.states().any(|state| {
4374 state.transitions().iter().any(|transition| {
4375 matches!(
4376 &transition.data(),
4377 Transition::Action {
4378 action_index: Some(_),
4379 ..
4380 }
4381 )
4382 })
4383 })
4384 })
4385 })
4386}
4387
4388fn atn_has_predicate_transitions(atn: &Atn) -> bool {
4389 with_shared_atn_caches(atn, |cache| {
4390 *cache.predicate_transitions.get_or_insert_with(|| {
4391 atn.states().any(|state| {
4392 state
4393 .transitions()
4394 .iter()
4395 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
4396 })
4397 })
4398 })
4399}
4400
4401fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
4406 options.init_action_rules.is_empty()
4407 && options.action_indices.is_empty()
4408 && !options.track_alt_numbers
4409 && options
4410 .predicates
4411 .iter()
4412 .all(|(_, _, predicate)| predicate.failure_message().is_none())
4413 && options.semantics.is_none_or(|semantics| {
4414 semantics.actions.is_empty()
4415 && semantics
4416 .predicates
4417 .iter()
4418 .all(|predicate| predicate.failure_message.is_none())
4419 })
4420 && options.rule_args.is_empty()
4421 && options.member_actions.is_empty()
4422 && options.return_actions.is_empty()
4423 && !atn_has_observable_action_transitions(atn)
4424}
4425
4426#[derive(Clone, Debug, Eq, PartialEq)]
4427struct RecognizeRequest<'a> {
4428 state_number: usize,
4429 stop_state: usize,
4430 index: usize,
4431 rule_start_index: usize,
4432 decision_start_index: Option<usize>,
4433 init_action_rules: &'a BTreeSet<usize>,
4434 predicates: &'a [(usize, usize, ParserPredicate)],
4435 semantics: Option<&'a ParserSemantics>,
4436 rule_args: &'a [ParserRuleArg],
4437 member_actions: &'a [ParserMemberAction],
4438 return_actions: &'a [ParserReturnAction],
4439 local_int_arg: Option<(usize, i64)>,
4440 member_values: MemberEnv,
4441 return_values: BTreeMap<String, i64>,
4442 rule_alt_number: usize,
4443 track_alt_numbers: bool,
4444 consumed_eof: bool,
4445 committed_decision: bool,
4446 precedence: i32,
4449 depth: usize,
4450 recovery_symbols: BTreeSet<i32>,
4451 recovery_state: Option<usize>,
4452}
4453
4454#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4455struct RecognizeKey {
4456 state_number: usize,
4457 stop_state: usize,
4458 index: usize,
4459 rule_start_index: usize,
4460 decision_start_index: Option<usize>,
4461 local_int_arg: Option<(usize, i64)>,
4462 member_values: MemberEnv,
4463 return_values: BTreeMap<String, i64>,
4464 rule_alt_number: usize,
4465 track_alt_numbers: bool,
4466 consumed_eof: bool,
4467 committed_decision: bool,
4468 precedence: i32,
4469 recovery_symbols: BTreeSet<i32>,
4470 recovery_state: Option<usize>,
4471}
4472
4473#[derive(Clone, Debug, Eq, PartialEq)]
4474struct EpsilonActionStep {
4475 source_state: usize,
4476 target: usize,
4477 action_rule_index: Option<usize>,
4478 action_index: Option<usize>,
4479 left_recursive_boundary: Option<usize>,
4480 decision: Option<usize>,
4481 decision_start_index: Option<usize>,
4482 alt_number: usize,
4483 recovery_symbols: BTreeSet<i32>,
4484 recovery_state: Option<usize>,
4485}
4486
4487struct RecognizeScratch<'a> {
4488 visiting: &'a mut BTreeSet<RecognizeKey>,
4489 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4490 expected: &'a mut ExpectedTokens,
4491}
4492
4493#[derive(Clone, Debug, Eq, PartialEq)]
4494struct FastRecognizeRequest {
4495 state_number: usize,
4496 stop_state: usize,
4497 index: usize,
4498 rule_start_index: usize,
4499 decision_start_index: Option<usize>,
4500 precedence: i32,
4501 depth: usize,
4502 recovery_symbols: Rc<BTreeSet<i32>>,
4503 recovery_state: Option<usize>,
4504}
4505
4506#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4507struct FastRecognizeTopRequest {
4508 start_state: usize,
4509 stop_state: usize,
4510 start_index: usize,
4511 precedence: i32,
4512 caller_follow_state: Option<usize>,
4513}
4514
4515#[derive(Clone, Copy, Debug)]
4516struct FastPredicateContext<'a> {
4517 predicates: &'a [(usize, usize, ParserPredicate)],
4518 semantics: Option<&'a ParserSemantics>,
4519 member_values: &'a MemberEnv,
4520}
4521
4522#[derive(Clone, Copy, Debug, Default)]
4523struct AltNumberTracking {
4524 public: bool,
4525 context: bool,
4526}
4527
4528impl AltNumberTracking {
4529 const fn any(self) -> bool {
4530 self.public || self.context
4531 }
4532}
4533
4534struct FastRecognizeScratch<'a, 'b> {
4535 predicate_context: Option<FastPredicateContext<'a>>,
4536 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4537 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4538 expected: &'b mut ExpectedTokens,
4539 native_depth: usize,
4540}
4541
4542#[derive(Clone, Copy, Debug)]
4543struct FastRepetitionShape {
4544 enter_target: usize,
4545 exit_target: usize,
4546 body_stop_state: usize,
4547 enter_transition_index: usize,
4548 exit_transition_index: usize,
4549}
4550
4551#[derive(Clone, Copy, Debug)]
4552struct FastRepetitionPath {
4553 index: usize,
4554 deferred_nodes: FastDeferredNodeId,
4555 diagnostics: DiagnosticSeqId,
4556 consumed_eof: bool,
4557}
4558
4559enum FastRepetitionWork {
4560 Enter(FastRepetitionPath),
4561 Exit(FastRepetitionPath),
4562}
4563
4564struct FastRepetitionCoordinates {
4569 base_index: usize,
4570 base_state: u8,
4571 later_states: Vec<u8>,
4572}
4573
4574impl FastRepetitionCoordinates {
4575 const ENTERED: u8 = 0;
4576 const EXITED: u8 = 2;
4577
4578 const fn new(base_index: usize) -> Self {
4579 Self {
4580 base_index,
4581 base_state: 0,
4582 later_states: Vec::new(),
4583 }
4584 }
4585
4586 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4587 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4588 }
4589
4590 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4591 self.insert(path.index, path.consumed_eof, Self::EXITED)
4592 }
4593
4594 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4595 let Some(offset) = index.checked_sub(self.base_index) else {
4596 return false;
4597 };
4598 let state = if offset == 0 {
4599 &mut self.base_state
4600 } else {
4601 if self.later_states.len() < offset {
4602 self.later_states.resize(offset, 0);
4603 }
4604 &mut self.later_states[offset - 1]
4605 };
4606 let bit = 1 << (base_bit + u8::from(consumed_eof));
4607 let is_new = *state & bit == 0;
4608 *state |= bit;
4609 is_new
4610 }
4611}
4612
4613fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4614 if state.precedence_rule_decision()
4615 || !matches!(
4616 state.kind(),
4617 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4618 )
4619 || state.transitions().len() != 2
4620 {
4621 return None;
4622 }
4623 let mut enter = None;
4624 let mut exit = None;
4625 for (index, transition) in state.transitions().iter().enumerate() {
4626 if transition.kind() != ParserTransitionKind::Epsilon {
4627 return None;
4628 }
4629 let target = transition.target();
4630 if atn
4631 .state(target)
4632 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4633 {
4634 if exit.replace((index, target)).is_some() {
4635 return None;
4636 }
4637 } else if enter.replace((index, target)).is_some() {
4638 return None;
4639 }
4640 }
4641 let (enter_transition_index, enter_target) = enter?;
4642 let (exit_transition_index, exit_target) = exit?;
4643 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4644 atn.state(exit_target)?.loop_back_state()?
4645 } else {
4646 state.state_number()
4647 };
4648 Some(FastRepetitionShape {
4649 enter_target,
4650 exit_target,
4651 body_stop_state,
4652 enter_transition_index,
4653 exit_transition_index,
4654 })
4655}
4656
4657fn push_fast_repetition_work(
4658 work: &mut Vec<FastRepetitionWork>,
4659 shape: FastRepetitionShape,
4660 path: FastRepetitionPath,
4661 lookahead: Option<&DecisionLookahead>,
4662 symbol: i32,
4663) {
4664 let transition_is_viable = |transition_index: usize| {
4667 let Some(entry) = lookahead else {
4668 return true;
4669 };
4670 let Some(transition) = entry.transitions.get(transition_index) else {
4671 return true;
4672 };
4673 transition.nullable || transition.symbols.contains(symbol)
4674 };
4675 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4676 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4677 if shape.enter_transition_index < shape.exit_transition_index {
4678 if exit_is_viable {
4679 work.push(FastRepetitionWork::Exit(path));
4680 }
4681 if enter_is_viable {
4682 work.push(FastRepetitionWork::Enter(path));
4683 }
4684 } else {
4685 if enter_is_viable {
4686 work.push(FastRepetitionWork::Enter(path));
4687 }
4688 if exit_is_viable {
4689 work.push(FastRepetitionWork::Exit(path));
4690 }
4691 }
4692}
4693
4694#[derive(Clone, Debug)]
4701struct FastRecognizeKey {
4702 state_number: usize,
4703 stop_state: usize,
4704 index: usize,
4705 rule_start_index: usize,
4706 decision_start_index: Option<usize>,
4707 precedence: i32,
4708 recovery_symbols_id: usize,
4709 recovery_state: Option<usize>,
4710}
4711
4712impl PartialEq for FastRecognizeKey {
4713 fn eq(&self, other: &Self) -> bool {
4714 if self.state_number != other.state_number
4715 || self.stop_state != other.stop_state
4716 || self.index != other.index
4717 || self.rule_start_index != other.rule_start_index
4718 || self.decision_start_index != other.decision_start_index
4719 || self.precedence != other.precedence
4720 || self.recovery_state != other.recovery_state
4721 || self.recovery_symbols_id != other.recovery_symbols_id
4722 {
4723 return false;
4724 }
4725 true
4726 }
4727}
4728
4729impl Eq for FastRecognizeKey {}
4730
4731impl Hash for FastRecognizeKey {
4732 fn hash<H: Hasher>(&self, hasher: &mut H) {
4733 self.state_number.hash(hasher);
4734 self.stop_state.hash(hasher);
4735 self.index.hash(hasher);
4736 self.rule_start_index.hash(hasher);
4737 self.decision_start_index.hash(hasher);
4738 self.precedence.hash(hasher);
4739 self.recovery_state.hash(hasher);
4740 self.recovery_symbols_id.hash(hasher);
4741 }
4742}
4743
4744struct FastRecoveryRequest<'a, 'b> {
4745 atn: &'a Atn,
4746 transition: ParserTransition<'a>,
4747 expected_symbols: Rc<BTreeSet<i32>>,
4748 target: usize,
4749 request: FastRecognizeRequest,
4750 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4751 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4752 expected: &'b mut ExpectedTokens,
4753}
4754
4755struct FastCurrentTokenDeletionRequest<'a, 'b> {
4756 atn: &'a Atn,
4757 expected_symbols: Rc<BTreeSet<i32>>,
4758 request: FastRecognizeRequest,
4759 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4760 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4761 expected: &'b mut ExpectedTokens,
4762}
4763
4764#[derive(Clone, Copy)]
4765struct FastChildRuleFailureRecoveryRequest<'a> {
4766 atn: &'a Atn,
4767 rule_index: usize,
4768 start_index: usize,
4769 follow_state: usize,
4770 stop_state: usize,
4771 expected: &'a ExpectedTokens,
4772}
4773
4774struct RecoveryRequest<'a, 'b> {
4775 atn: &'a Atn,
4776 transition: ParserTransition<'a>,
4777 expected_symbols: BTreeSet<i32>,
4778 target: usize,
4779 request: RecognizeRequest<'a>,
4780 visiting: &'b mut BTreeSet<RecognizeKey>,
4781 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4782 expected: &'b mut ExpectedTokens,
4783}
4784
4785struct CurrentTokenDeletionRequest<'a, 'b> {
4786 atn: &'a Atn,
4787 expected_symbols: BTreeSet<i32>,
4788 request: RecognizeRequest<'a>,
4789 visiting: &'b mut BTreeSet<RecognizeKey>,
4790 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4791 expected: &'b mut ExpectedTokens,
4792}
4793
4794struct ConsumingFailureFallback<'a> {
4797 atn: &'a Atn,
4798 target: usize,
4799 request: RecognizeRequest<'a>,
4800 symbol: i32,
4801 expected_symbols: BTreeSet<i32>,
4802 decision_start_index: Option<usize>,
4803 decision: Option<usize>,
4804}
4805
4806struct ChildRuleFailureRecovery<'a> {
4809 atn: &'a Atn,
4810 rule_index: usize,
4811 start_index: usize,
4812 follow_state: usize,
4813 stop_state: usize,
4814 member_values: MemberEnv,
4815 expected: &'a ExpectedTokens,
4816}
4817
4818#[derive(Clone, Copy, Debug)]
4820struct PredicateEval<'a> {
4821 index: usize,
4822 rule_index: usize,
4823 pred_index: usize,
4824 predicates: &'a [(usize, usize, ParserPredicate)],
4825 semantics: Option<&'a ParserSemantics>,
4826 context: Option<&'a ParserRuleContext>,
4827 local_int_arg: Option<(usize, i64)>,
4828 member_values: &'a MemberEnv,
4829}
4830
4831#[derive(Clone, Copy, Debug)]
4832struct ParserSemanticHookRequest<'a> {
4833 index: usize,
4834 rule_index: usize,
4835 pred_index: usize,
4836 context: Option<&'a ParserRuleContext>,
4837 local_int_arg: Option<(usize, i64)>,
4838 member_values: &'a MemberEnv,
4839}
4840
4841struct ParserSemIrCtx<'a, S, H>
4850where
4851 S: TokenSource,
4852 H: SemanticHooks,
4853{
4854 input: &'a mut CommonTokenStream<S>,
4855 tree_storage: &'a ParseTreeStorage,
4856 semantic_hooks: &'a mut H,
4857 rule_index: usize,
4858 coordinate_index: usize,
4859 rule_name: Option<&'a str>,
4860 context: Option<&'a ParserRuleContext>,
4861 local_int_arg: Option<(usize, i64)>,
4862 member_values: &'a MemberEnv,
4863 invoked_predicates: &'a mut Vec<(usize, usize)>,
4864 unknown_predicate_policy: UnknownSemanticPolicy,
4868 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4869}
4870
4871impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4872where
4873 S: TokenSource,
4874 H: SemanticHooks,
4875{
4876 type TokenText<'a>
4877 = TokenView<'a>
4878 where
4879 Self: 'a;
4880
4881 fn la(&mut self, offset: isize) -> i64 {
4882 i64::from(self.input.la(offset))
4883 }
4884
4885 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4886 self.input.lt(offset)
4887 }
4888
4889 fn token_index_adjacent(&mut self) -> bool {
4890 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4891 return false;
4892 };
4893 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4894 return false;
4895 };
4896 first + 1 == second
4897 }
4898
4899 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4900 self.context.and_then(|context| {
4901 context
4902 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4903 .next()
4904 .map(crate::tree::RuleNodeView::text)
4905 })
4906 }
4907
4908 fn member(&self, member: usize) -> Option<i64> {
4909 Some(self.member_values.scalar(member).unwrap_or_default())
4910 }
4911
4912 fn member_top(&self, member: usize) -> Option<i64> {
4913 self.member_values.stack_top(member)
4914 }
4915
4916 fn member_len(&self, member: usize) -> usize {
4917 self.member_values.stack_len(member)
4918 }
4919
4920 fn local_arg(&self) -> Option<i64> {
4921 self.local_int_arg.map(|(_, value)| value)
4922 }
4923
4924 fn column(&self) -> Option<i64> {
4925 None
4926 }
4927
4928 fn token_start_column(&self) -> Option<i64> {
4929 None
4930 }
4931
4932 fn token_text_so_far(&self) -> Option<String> {
4933 None
4934 }
4935
4936 fn hook(&mut self, _hook: HookId) -> bool {
4937 let mut ctx = ParserSemCtx {
4938 input: &mut *self.input,
4939 tree_storage: self.tree_storage,
4940 rule_index: self.rule_index,
4941 coordinate_index: self.coordinate_index,
4942 rule_name: self.rule_name.map(str::to_owned),
4943 context: self.context,
4944 tree: None,
4945 local_int_arg: self.local_int_arg,
4946 member_values: self.member_values,
4947 action: None,
4948 };
4949 match self
4950 .semantic_hooks
4951 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4952 {
4953 Some(result) => result,
4954 None => apply_unknown_predicate_policy(
4958 self.unknown_predicate_policy,
4959 self.rule_index,
4960 self.coordinate_index,
4961 self.unknown_predicate_hits,
4962 ),
4963 }
4964 }
4965
4966 fn trace_bool(&mut self, value: bool) -> bool {
4967 let key = (self.rule_index, self.coordinate_index);
4968 if !self.invoked_predicates.contains(&key) {
4969 self.invoked_predicates.push(key);
4970 use std::io::Write as _;
4971 let mut stdout = std::io::stdout().lock();
4972 let _ = writeln!(stdout, "eval={value}");
4973 }
4974 value
4975 }
4976}
4977
4978struct PredicateFailureRecovery<'a> {
4980 rule_index: usize,
4981 index: usize,
4982 message: &'a str,
4983 member_values: MemberEnv,
4984 return_values: BTreeMap<String, i64>,
4985 rule_alt_number: usize,
4986}
4987
4988#[derive(Debug)]
4989enum DirectAdaptiveParseControl {
4990 Fallback(DirectAdaptiveFallback),
4991}
4992
4993#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4994enum DirectAdaptiveFallback {
4995 Action,
4996 InvalidAlt,
4997 LeftRecursiveBoundary,
4998 MissingAtn,
4999 NoTransition,
5000 Predicate,
5001 Prediction,
5002 Precedence,
5003 RuleStop,
5004 SemanticContext,
5005 StepLimit,
5006 TokenMismatch,
5007 UnknownDecision,
5008}
5009
5010type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
5011
5012struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
5013where
5014 S: TokenSource,
5015 H: SemanticHooks,
5016{
5017 parser: &'sim mut BaseParser<S, H>,
5018 atn: &'atn Atn,
5019 simulator: &'sim mut ParserAtnSimulator<'atn>,
5020 decision_by_state: Vec<Option<usize>>,
5021 steps: usize,
5022}
5023
5024struct CommittedAtnParser<'atn, 'sim, 'options, S, H = NoSemanticHooks>
5025where
5026 S: TokenSource,
5027 H: SemanticHooks,
5028{
5029 parser: &'sim mut BaseParser<S, H>,
5030 atn: &'atn Atn,
5031 simulator: ParserAtnSimulator<'atn>,
5032 options: ParserRuntimeOptions<'options>,
5033 decision_by_state: Vec<Option<usize>>,
5034 action_index_by_state: FxHashMap<usize, usize>,
5035 deferred_actions: Vec<ParserAction>,
5036}
5037
5038struct CommittedRuleOutcome {
5039 tree: ParseTree,
5040 consumed_eof: bool,
5041}
5042
5043struct CommittedDecisionContext<'a> {
5044 precedence: i32,
5045 local_int_arg: Option<(usize, i64)>,
5046 context: &'a mut ParserRuleContext,
5047 entered_loops: &'a mut BTreeSet<usize>,
5048}
5049
5050#[derive(Clone, Debug, Eq, PartialEq)]
5060pub struct GeneratedMatch {
5061 children: GeneratedMatchChildren,
5062 consumed_eof: bool,
5063}
5064
5065#[derive(Clone, Copy)]
5066enum GeneratedExpectedSymbols<'a> {
5067 Tree(&'a BTreeSet<i32>),
5068 TokenSet(ParserIntervalSet<'a>),
5069 TokenSetComplement {
5070 set: ParserIntervalSet<'a>,
5071 min_vocabulary: i32,
5072 max_vocabulary: i32,
5073 },
5074}
5075
5076impl GeneratedExpectedSymbols<'_> {
5077 fn is_empty(self) -> bool {
5078 match self {
5079 Self::Tree(symbols) => symbols.is_empty(),
5080 Self::TokenSet(set) => set.is_empty(),
5081 Self::TokenSetComplement {
5082 set,
5083 min_vocabulary,
5084 max_vocabulary,
5085 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
5086 }
5087 }
5088
5089 fn first(self) -> Option<i32> {
5090 match self {
5091 Self::Tree(symbols) => symbols.iter().next().copied(),
5092 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
5093 Self::TokenSetComplement {
5094 set,
5095 min_vocabulary,
5096 max_vocabulary,
5097 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
5098 }
5099 }
5100
5101 fn display(self, vocabulary: &Vocabulary) -> String {
5102 match self {
5103 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
5104 Self::TokenSet(set) => expected_symbols_display_iter(
5105 set.ranges().flat_map(|(start, stop)| start..=stop),
5106 vocabulary,
5107 ),
5108 Self::TokenSetComplement {
5109 set,
5110 min_vocabulary,
5111 max_vocabulary,
5112 } => expected_symbols_display_iter(
5113 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
5114 vocabulary,
5115 ),
5116 }
5117 }
5118}
5119
5120#[derive(Clone, Debug, Eq, PartialEq)]
5121enum GeneratedMatchChildren {
5122 One(ParseTree),
5123 Many(Vec<ParseTree>),
5124}
5125
5126struct GeneratedMatchChildrenIntoIter {
5127 one: Option<ParseTree>,
5128 many: Option<std::vec::IntoIter<ParseTree>>,
5129}
5130
5131impl Iterator for GeneratedMatchChildrenIntoIter {
5132 type Item = ParseTree;
5133
5134 fn next(&mut self) -> Option<Self::Item> {
5135 self.one
5136 .take()
5137 .or_else(|| self.many.as_mut().and_then(Iterator::next))
5138 }
5139}
5140
5141impl GeneratedMatch {
5142 #[must_use]
5146 pub fn children(&self) -> &[ParseTree] {
5147 match &self.children {
5148 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
5149 GeneratedMatchChildren::Many(children) => children,
5150 }
5151 }
5152
5153 #[must_use]
5156 pub fn into_children(self) -> Vec<ParseTree> {
5157 match self.children {
5158 GeneratedMatchChildren::One(child) => vec![child],
5159 GeneratedMatchChildren::Many(children) => children,
5160 }
5161 }
5162
5163 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
5165 match self.children {
5166 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
5167 one: Some(child),
5168 many: None,
5169 },
5170 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
5171 one: None,
5172 many: Some(children.into_iter()),
5173 },
5174 }
5175 }
5176
5177 #[must_use]
5179 pub const fn consumed_eof(&self) -> bool {
5180 self.consumed_eof
5181 }
5182}
5183
5184impl<S> BaseParser<S, NoSemanticHooks>
5185where
5186 S: TokenSource,
5187{
5188 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
5191 Self::with_semantic_hooks(input, data, NoSemanticHooks)
5192 }
5193}
5194
5195impl<S, H> BaseParser<S, H>
5196where
5197 S: TokenSource,
5198 H: SemanticHooks,
5199{
5200 pub fn with_semantic_hooks(
5202 input: CommonTokenStream<S>,
5203 data: RecognizerData,
5204 semantic_hooks: H,
5205 ) -> Self {
5206 Self {
5207 input,
5208 tree: ParseTreeStorage::new(),
5209 data,
5210 semantic_hooks,
5211 decision_override_generation: 0,
5212 build_parse_trees: true,
5213 syntax_errors: 0,
5214 report_diagnostic_errors: false,
5215 prediction_mode: PredictionMode::Ll,
5216 prediction_diagnostics: Vec::new(),
5217 reported_prediction_diagnostics: BTreeSet::new(),
5218 generated_parser_diagnostics: Vec::new(),
5219 generated_sync_expected: None,
5220 generated_recovery_error_index: None,
5221 generated_recovery_error_states: BTreeSet::new(),
5222 int_members: MemberEnv::new(),
5223 rule_context_stack: Vec::new(),
5224 rule_context_version: 0,
5225 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
5226 pending_invoking_states: Vec::new(),
5227 precedence_stack: vec![0],
5228 invoked_predicates: Vec::new(),
5229 bail_on_error: false,
5230 parse_listeners: Vec::new(),
5231 parse_listener_abort: None,
5232 max_rule_depth: None,
5233 rule_depth_error: None,
5234 recursion_expansions: 0,
5235 recursion_expansion_marks: Vec::new(),
5236 unknown_predicate_policy: UnknownSemanticPolicy::default(),
5237 unknown_predicate_hits: Vec::new(),
5238 unhandled_action_hits: Vec::new(),
5239 rule_first_set_cache: Vec::new(),
5240 state_expected_cache: FxHashMap::default(),
5241 state_expected_token_cache: FxHashMap::default(),
5242 rule_stop_reach_cache: Vec::new(),
5243 recovery_symbols_intern: FxHashMap::default(),
5244 decision_lookahead_cache: FxHashMap::default(),
5245 ll1_decision_cache: FxHashMap::default(),
5246 fast_predicate_cache: FxHashMap::default(),
5247 empty_cycle_cache: Vec::new(),
5248 empty_cycle_cache_atn: None,
5249 clean_memo_mode: CleanMemoMode::Probe,
5250 clean_memo_probe_seen: FxHashSet::default(),
5251 clean_memo_probe_samples: 0,
5252 clean_memo_probe_repeats: 0,
5253 clean_memo_sparse_samples: 0,
5254 fast_recognize_scratch: FastRecognizeTopScratch::default(),
5255 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
5256 empty_recovery_symbols: Rc::new(BTreeSet::new()),
5257 fast_first_set_prefilter: true,
5258 fast_recovery_enabled: true,
5259 fast_token_nodes_enabled: true,
5260 fast_track_alt_numbers: false,
5261 recognition_arena: RecognitionArena::default(),
5262 last_recognition_arena_root: NodeSeqId::EMPTY,
5263 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
5264 }
5265 }
5266
5267 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
5268 &mut self.input
5269 }
5270
5271 pub fn reset(&mut self) {
5276 self.input.seek(0);
5277 self.tree.reset();
5278 self.data.set_state(-1);
5279 self.syntax_errors = 0;
5280 self.prediction_diagnostics.clear();
5281 self.reported_prediction_diagnostics.clear();
5282 self.generated_parser_diagnostics.clear();
5283 self.generated_sync_expected = None;
5284 self.reset_generated_recovery_state();
5285 self.rule_context_stack.clear();
5286 self.advance_rule_context_version();
5287 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
5288 self.pending_invoking_states.clear();
5289 self.precedence_stack.clear();
5290 self.precedence_stack.push(0);
5291 self.invoked_predicates.clear();
5292 self.decision_override_generation = 0;
5293 self.unknown_predicate_hits.clear();
5294 self.unhandled_action_hits.clear();
5295 self.parse_listener_abort = None;
5296 self.rule_depth_error = None;
5297 self.recursion_expansions = 0;
5298 self.recursion_expansion_marks.clear();
5299 self.reset_per_parse_caches();
5300 self.fast_first_set_prefilter = true;
5301 self.fast_recovery_enabled = true;
5302 self.fast_token_nodes_enabled = self.build_parse_trees;
5303 self.fast_track_alt_numbers = false;
5304 self.reset_recognition_arena();
5305 }
5306
5307 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
5309 self.input = input;
5310 self.reset();
5311 }
5312
5313 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
5324 self.unknown_predicate_policy = policy;
5325 }
5326
5327 #[must_use]
5333 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
5334 let error = self.unknown_semantic_error();
5335 self.unknown_predicate_hits.clear();
5336 self.unhandled_action_hits.clear();
5337 error
5338 }
5339
5340 pub fn reset_unknown_semantic_hits(&mut self) {
5347 self.unknown_predicate_hits.clear();
5348 self.unhandled_action_hits.clear();
5349 }
5350
5351 #[must_use]
5353 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
5354 &self.input
5355 }
5356
5357 #[must_use]
5359 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
5360 &mut self.input
5361 }
5362
5363 #[must_use]
5365 pub const fn token_store(&self) -> &TokenStore {
5366 self.input.token_store()
5367 }
5368
5369 #[must_use]
5371 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
5372 &self.tree
5373 }
5374
5375 #[must_use]
5377 pub fn node(&self, id: NodeId) -> Node<'_> {
5378 self.tree
5379 .node(self.input.token_store(), id)
5380 .expect("parser-produced node ID should remain valid")
5381 }
5382
5383 #[must_use]
5385 pub fn into_token_stream(self) -> CommonTokenStream<S> {
5386 self.input
5387 }
5388
5389 #[must_use]
5391 pub fn into_token_store(self) -> TokenStore {
5392 self.input.into_token_store()
5393 }
5394
5395 #[must_use]
5397 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
5398 ParsedFile::new(self.input.into_token_store(), self.tree, root)
5399 }
5400
5401 pub const fn number_of_syntax_errors(&self) -> usize {
5404 self.syntax_errors
5405 }
5406
5407 #[must_use]
5413 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
5414 self.recognition_arena.stats(
5415 self.last_recognition_arena_root,
5416 self.last_recognition_arena_diagnostics,
5417 )
5418 }
5419
5420 pub const fn record_generated_syntax_error(&mut self) {
5423 self.record_syntax_errors(1);
5424 }
5425
5426 const fn record_syntax_errors(&mut self, count: usize) {
5427 self.syntax_errors = self.syntax_errors.saturating_add(count);
5428 }
5429
5430 const fn is_top_level_entry(&self) -> bool {
5432 self.rule_context_stack.is_empty() && self.pending_invoking_states.is_empty()
5433 }
5434
5435 pub fn report_token_source_errors(&mut self) {
5438 let errors = self.input.drain_source_errors();
5439 self.dispatch_token_source_errors(&errors);
5440 }
5441
5442 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
5445 GeneratedDiagnosticsCheckpoint {
5446 diagnostics_len: self.generated_parser_diagnostics.len(),
5447 syntax_errors: self.syntax_errors,
5448 tree: self.tree.checkpoint(),
5449 }
5450 }
5451
5452 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5454 self.generated_parser_diagnostics
5455 .truncate(marker.diagnostics_len);
5456 self.syntax_errors = marker.syntax_errors;
5457 self.rollback_generated_tree(marker);
5458 }
5459
5460 pub fn rollback_generated_tree(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5466 self.generated_sync_expected = None;
5467 self.tree.rollback(marker.tree);
5468 }
5469
5470 pub fn report_generated_parser_diagnostics(&mut self) {
5472 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
5473 let token_errors = self.input.drain_source_errors();
5474 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
5475 }
5476
5477 fn syntax_error_event<'a>(
5478 &'a self,
5479 offending: Option<TokenId>,
5480 line: usize,
5481 column: usize,
5482 message: &'a str,
5483 error: Option<&'a AntlrError>,
5484 ) -> SyntaxErrorEvent<'a> {
5485 let offending = offending.and_then(|token| self.token_store().view(token));
5486 SyntaxErrorEvent {
5487 offending,
5488 line,
5489 column,
5490 span: offending.and_then(|token| token.byte_span()),
5491 message,
5492 error,
5493 }
5494 }
5495
5496 pub fn report_unrecovered_parser_error(&self, error: &AntlrError) {
5501 let AntlrError::ParserError {
5502 line,
5503 column,
5504 message,
5505 offending,
5506 } = error
5507 else {
5508 return;
5509 };
5510 self.notify_error_listeners(self.syntax_error_event(
5511 *offending,
5512 *line,
5513 *column,
5514 message,
5515 Some(error),
5516 ));
5517 }
5518
5519 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
5520 self.notify_error_listeners(self.syntax_error_event(
5521 diagnostic.offending,
5522 diagnostic.line,
5523 diagnostic.column,
5524 &diagnostic.message,
5525 None,
5526 ));
5527 }
5528
5529 fn dispatch_parser_diagnostics<'a>(
5530 &self,
5531 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
5532 ) {
5533 for diagnostic in diagnostics {
5534 self.dispatch_parser_diagnostic(diagnostic);
5535 }
5536 }
5537
5538 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
5539 if self.input.token_source().report_error(source_error) {
5540 return;
5541 }
5542 self.notify_error_listeners(source_error.into());
5545 }
5546
5547 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
5548 for error in errors {
5549 self.dispatch_token_source_error(error);
5550 }
5551 }
5552
5553 fn dispatch_generated_diagnostics(
5556 &self,
5557 parser_diagnostics: &[ParserDiagnostic],
5558 token_errors: &[TokenSourceError],
5559 ) {
5560 let mut token_iter = token_errors.iter().peekable();
5566 for diagnostic in parser_diagnostics {
5567 while let Some(error) = token_iter.peek() {
5568 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
5569 self.dispatch_token_source_error(error);
5570 token_iter.next();
5571 } else {
5572 break;
5573 }
5574 }
5575 self.dispatch_parser_diagnostic(diagnostic);
5576 }
5577 for error in token_iter {
5578 self.dispatch_token_source_error(error);
5579 }
5580 }
5581
5582 pub fn record_generated_ambiguity_diagnostic(
5585 &mut self,
5586 atn: &Atn,
5587 state_number: usize,
5588 start_index: usize,
5589 stop_index: usize,
5590 alts: &[usize],
5591 ) {
5592 if !self.report_diagnostic_errors || alts.len() < 2 {
5593 return;
5594 }
5595 let Some(decision) = atn
5596 .decision_to_state()
5597 .iter()
5598 .position(|candidate| candidate == state_number)
5599 else {
5600 return;
5601 };
5602 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5603 return;
5604 };
5605 let rule_name = self
5606 .rule_names()
5607 .get(rule_index)
5608 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5609 let input = display_input_text(&self.input.text(start_index, stop_index));
5610 let alts = alts
5611 .iter()
5612 .map(usize::to_string)
5613 .collect::<Vec<_>>()
5614 .join(", ");
5615 let key = (decision, start_index, format!("{alts}:{input}"));
5616 if !self.reported_prediction_diagnostics.insert(key) {
5617 return;
5618 }
5619 let start_diagnostic = diagnostic_for_token(
5620 self.token_at(start_index),
5621 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5622 );
5623 let stop_diagnostic = diagnostic_for_token(
5624 self.token_at(stop_index),
5625 format!(
5626 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5627 ),
5628 );
5629 self.generated_parser_diagnostics.push(start_diagnostic);
5630 self.generated_parser_diagnostics.push(stop_diagnostic);
5631 }
5632
5633 pub fn record_generated_prediction_diagnostic(
5636 &mut self,
5637 atn: &Atn,
5638 state_number: usize,
5639 prediction: &ParserAtnPrediction,
5640 ) {
5641 let Some(diagnostic) = &prediction.diagnostic else {
5642 return;
5643 };
5644 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5645 return;
5646 }
5647 let Some(decision) = atn
5648 .decision_to_state()
5649 .iter()
5650 .position(|candidate| candidate == state_number)
5651 else {
5652 return;
5653 };
5654 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5655 return;
5656 };
5657 let rule_name = self
5658 .rule_names()
5659 .get(rule_index)
5660 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5661 let attempt_input = display_input_text(
5662 &self
5663 .input
5664 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5665 );
5666 let result_input = display_input_text(
5667 &self
5668 .input
5669 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5670 );
5671 let alts = diagnostic
5672 .conflicting_alts
5673 .iter()
5674 .map(usize::to_string)
5675 .collect::<Vec<_>>()
5676 .join(", ");
5677 let key = (
5678 decision,
5679 diagnostic.start_index,
5680 format!(
5681 "{:?}:{alts}:{attempt_input}:{result_input}",
5682 diagnostic.kind
5683 ),
5684 );
5685 if !self.reported_prediction_diagnostics.insert(key) {
5686 return;
5687 }
5688 let attempt_diagnostic = diagnostic_for_token(
5689 self.token_at(diagnostic.sll_stop_index),
5690 format!(
5691 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5692 ),
5693 );
5694 self.generated_parser_diagnostics.push(attempt_diagnostic);
5695 let message = match diagnostic.kind {
5696 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5697 if !diagnostic.exact {
5702 return;
5703 }
5704 format!(
5705 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5706 )
5707 }
5708 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5709 format!(
5710 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5711 )
5712 }
5713 };
5714 let result_diagnostic =
5715 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5716 self.generated_parser_diagnostics.push(result_diagnostic);
5717 }
5718
5719 pub fn la(&self, offset: isize) -> i32 {
5720 self.input.la_token(offset)
5721 }
5722
5723 pub fn consume(&mut self) {
5724 IntStream::consume(&mut self.input);
5725 }
5726
5727 pub fn set_int_member(&mut self, member: usize, value: i64) {
5729 self.int_members.set_scalar(member, value);
5730 }
5731
5732 pub fn int_member(&self, member: usize) -> Option<i64> {
5734 self.int_members.scalar(member)
5735 }
5736
5737 pub fn push_stack_member(&mut self, member: usize, value: i64) {
5739 self.int_members.push_stack(member, value);
5740 }
5741
5742 pub fn pop_stack_member(&mut self, member: usize) -> Option<i64> {
5745 self.int_members.pop_stack(member)
5746 }
5747
5748 #[must_use]
5751 pub fn stack_member_top(&self, member: usize) -> Option<i64> {
5752 self.int_members.stack_top(member)
5753 }
5754
5755 #[must_use]
5757 pub fn stack_member_len(&self, member: usize) -> usize {
5758 self.int_members.stack_len(member)
5759 }
5760
5761 pub fn set_initial_members(&mut self, initial: impl IntoIterator<Item = (usize, i64)>) {
5768 self.int_members = MemberEnv::with_initial_scalars(initial);
5769 }
5770
5771 #[must_use]
5777 pub fn int_members_checkpoint(&self) -> MemberEnv {
5778 self.int_members.clone()
5779 }
5780
5781 pub fn restore_int_members(&mut self, members: MemberEnv) {
5783 self.int_members = members;
5784 }
5785
5786 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5788 self.int_members.add_scalar(member, delta)
5789 }
5790
5791 fn token_type_for_id(&self, id: TokenId) -> i32 {
5792 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5793 }
5794
5795 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5796 if self.build_parse_trees {
5797 self.tree.terminal(id)
5798 } else {
5799 NodeId::placeholder()
5800 }
5801 }
5802
5803 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5804 if self.build_parse_trees {
5805 self.tree.error(id)
5806 } else {
5807 NodeId::placeholder()
5808 }
5809 }
5810
5811 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5812 context.set_start_id(id);
5813 }
5814
5815 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5816 context.set_stop_id(id);
5817 }
5818
5819 fn insert_synthetic_token(
5820 &mut self,
5821 token_type: i32,
5822 text: String,
5823 line: usize,
5824 column: usize,
5825 ) -> Result<TokenId, AntlrError> {
5826 self.input
5827 .insert(
5828 TokenSpec::explicit(token_type, text)
5829 .with_span(usize::MAX, usize::MAX)
5830 .with_position(line, column),
5831 )
5832 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5833 }
5834
5835 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5842 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5843 line: 0,
5844 column: 0,
5845 message: "missing current token".to_owned(),
5846 offending: None,
5847 })?;
5848 let current_type = self.token_type_for_id(current);
5849 if current_type == token_type {
5850 self.reset_generated_recovery_state();
5851 self.consume();
5852 Ok(self.terminal_tree(current))
5853 } else {
5854 Err(AntlrError::MismatchedInput {
5855 expected: self.vocabulary().display_name(token_type),
5856 found: self.vocabulary().display_name(current_type),
5857 })
5858 }
5859 }
5860
5861 pub fn match_token_recovering(
5865 &mut self,
5866 token_type: i32,
5867 follow_state: usize,
5868 atn: &Atn,
5869 ) -> Result<GeneratedMatch, AntlrError> {
5870 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5871 line: 0,
5872 column: 0,
5873 message: "missing current token".to_owned(),
5874 offending: None,
5875 })?;
5876 let current_type = self.token_type_for_id(current);
5877 if current_type == token_type {
5878 self.generated_sync_expected = None;
5879 self.reset_generated_recovery_state();
5880 let consumed_eof = current_type == TOKEN_EOF;
5881 self.consume();
5882 return Ok(GeneratedMatch {
5883 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5884 consumed_eof,
5885 });
5886 }
5887 let mut expected_symbols = BTreeSet::new();
5888 expected_symbols.insert(token_type);
5889 self.recover_generated_match(
5890 current,
5891 GeneratedExpectedSymbols::Tree(&expected_symbols),
5892 follow_state,
5893 atn,
5894 |symbol| symbol == token_type,
5895 )
5896 }
5897
5898 pub fn match_set_recovering(
5899 &mut self,
5900 intervals: &[(i32, i32)],
5901 follow_state: usize,
5902 atn: &Atn,
5903 ) -> Result<GeneratedMatch, AntlrError> {
5904 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5905 line: 0,
5906 column: 0,
5907 message: "missing current token".to_owned(),
5908 offending: None,
5909 })?;
5910 let current_type = self.token_type_for_id(current);
5911 if interval_set_contains(intervals, current_type) {
5912 self.generated_sync_expected = None;
5913 self.reset_generated_recovery_state();
5914 let consumed_eof = current_type == TOKEN_EOF;
5915 self.consume();
5916 return Ok(GeneratedMatch {
5917 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5918 consumed_eof,
5919 });
5920 }
5921 let expected_symbols = interval_symbols(intervals);
5922 self.recover_generated_match(
5923 current,
5924 GeneratedExpectedSymbols::Tree(&expected_symbols),
5925 follow_state,
5926 atn,
5927 |symbol| interval_set_contains(intervals, symbol),
5928 )
5929 }
5930
5931 pub fn match_token_set_recovering(
5932 &mut self,
5933 set: ParserIntervalSet<'_>,
5934 follow_state: usize,
5935 atn: &Atn,
5936 ) -> Result<GeneratedMatch, AntlrError> {
5937 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5938 line: 0,
5939 column: 0,
5940 message: "missing current token".to_owned(),
5941 offending: None,
5942 })?;
5943 let current_type = self.token_type_for_id(current);
5944 if set.contains(current_type) {
5945 self.generated_sync_expected = None;
5946 self.reset_generated_recovery_state();
5947 let consumed_eof = current_type == TOKEN_EOF;
5948 self.consume();
5949 return Ok(GeneratedMatch {
5950 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5951 consumed_eof,
5952 });
5953 }
5954 self.recover_generated_match(
5955 current,
5956 GeneratedExpectedSymbols::TokenSet(set),
5957 follow_state,
5958 atn,
5959 |symbol| set.contains(symbol),
5960 )
5961 }
5962
5963 pub fn match_not_set_recovering(
5964 &mut self,
5965 intervals: &[(i32, i32)],
5966 min_vocabulary: i32,
5967 max_vocabulary: i32,
5968 follow_state: usize,
5969 atn: &Atn,
5970 ) -> Result<GeneratedMatch, AntlrError> {
5971 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5972 line: 0,
5973 column: 0,
5974 message: "missing current token".to_owned(),
5975 offending: None,
5976 })?;
5977 let current_type = self.token_type_for_id(current);
5978 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5979 && !interval_set_contains(intervals, current_type)
5980 {
5981 self.generated_sync_expected = None;
5982 self.reset_generated_recovery_state();
5983 let consumed_eof = current_type == TOKEN_EOF;
5984 self.consume();
5985 return Ok(GeneratedMatch {
5986 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5987 consumed_eof,
5988 });
5989 }
5990 let expected_symbols =
5991 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5992 self.recover_generated_match(
5993 current,
5994 GeneratedExpectedSymbols::Tree(&expected_symbols),
5995 follow_state,
5996 atn,
5997 |symbol| {
5998 (min_vocabulary..=max_vocabulary).contains(&symbol)
5999 && !interval_set_contains(intervals, symbol)
6000 },
6001 )
6002 }
6003
6004 pub fn match_not_token_set_recovering(
6005 &mut self,
6006 set: ParserIntervalSet<'_>,
6007 min_vocabulary: i32,
6008 max_vocabulary: i32,
6009 follow_state: usize,
6010 atn: &Atn,
6011 ) -> Result<GeneratedMatch, AntlrError> {
6012 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6013 line: 0,
6014 column: 0,
6015 message: "missing current token".to_owned(),
6016 offending: None,
6017 })?;
6018 let current_type = self.token_type_for_id(current);
6019 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
6020 {
6021 self.generated_sync_expected = None;
6022 self.reset_generated_recovery_state();
6023 let consumed_eof = current_type == TOKEN_EOF;
6024 self.consume();
6025 return Ok(GeneratedMatch {
6026 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
6027 consumed_eof,
6028 });
6029 }
6030 self.recover_generated_match(
6031 current,
6032 GeneratedExpectedSymbols::TokenSetComplement {
6033 set,
6034 min_vocabulary,
6035 max_vocabulary,
6036 },
6037 follow_state,
6038 atn,
6039 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
6040 )
6041 }
6042
6043 fn recover_generated_match(
6044 &mut self,
6045 current: TokenId,
6046 expected_symbols: GeneratedExpectedSymbols<'_>,
6047 follow_state: usize,
6048 atn: &Atn,
6049 matches: impl Fn(i32) -> bool,
6050 ) -> Result<GeneratedMatch, AntlrError> {
6051 let expected_display = expected_symbols.display(self.vocabulary());
6052 let (current_type, current_line, current_column, current_display) = {
6053 let token = self
6054 .input
6055 .token_view(current)
6056 .expect("current token ID should be valid");
6057 (
6058 token.token_type(),
6059 token.line(),
6060 token.column(),
6061 token_input_display(&token),
6062 )
6063 };
6064 if self.bail_on_error {
6065 return Err(AntlrError::ParserError {
6066 line: current_line,
6067 column: current_column,
6068 message: format!("mismatched input {current_display} expecting {expected_display}"),
6069 offending: Some(current),
6070 });
6071 }
6072 if current_type != TOKEN_EOF
6073 && let Some(next) = self.input.lt_id(2)
6074 && matches(self.token_type_for_id(next))
6075 {
6076 let message =
6077 format!("extraneous input {current_display} expecting {expected_display}");
6078 self.push_generated_parser_diagnostic(ParserDiagnostic {
6079 line: current_line,
6080 column: current_column,
6081 message,
6082 offending: Some(current),
6083 });
6084 self.record_syntax_errors(1);
6085 self.generated_sync_expected = None;
6086 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
6089 self.consume();
6090 self.consume();
6091 self.reset_generated_recovery_state();
6092 return Ok(GeneratedMatch {
6093 children: GeneratedMatchChildren::Many(vec![
6094 self.error_tree(current),
6095 self.terminal_tree(next),
6096 ]),
6097 consumed_eof,
6098 });
6099 }
6100 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
6101 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
6110 && self
6111 .cached_state_expected_symbols(atn, follow_state)
6112 .contains(&TOKEN_EOF);
6113 if follow_symbols.contains(¤t_type)
6114 && (current_type != TOKEN_EOF
6115 || self.rule_context_stack.len() > 1
6116 || expected_symbols.is_empty()
6117 || follow_explicitly_expects_eof)
6118 {
6119 let message = format!("missing {expected_display} at {current_display}");
6120 self.push_generated_parser_diagnostic(ParserDiagnostic {
6121 line: current_line,
6122 column: current_column,
6123 message,
6124 offending: Some(current),
6125 });
6126 self.record_syntax_errors(1);
6127 self.generated_sync_expected = None;
6128 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
6129 let missing_display = expected_symbol_display(token_type, self.vocabulary());
6130 let token = self.insert_synthetic_token(
6131 token_type,
6132 format!("<missing {missing_display}>"),
6133 current_line,
6134 current_column,
6135 )?;
6136 return Ok(GeneratedMatch {
6141 children: GeneratedMatchChildren::One(self.error_tree(token)),
6142 consumed_eof: false,
6143 });
6144 }
6145 let mismatch_expected_display = self
6146 .generated_sync_expected
6147 .take()
6148 .map_or(expected_display, |symbols| {
6149 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
6150 });
6151 Err(AntlrError::ParserError {
6152 line: current_line,
6153 column: current_column,
6154 message: format!(
6155 "mismatched input {current_display} expecting {mismatch_expected_display}"
6156 ),
6157 offending: Some(current),
6158 })
6159 }
6160
6161 fn generated_recovery_follow_symbols(
6162 &mut self,
6163 atn: &Atn,
6164 follow_state: usize,
6165 ) -> BTreeSet<i32> {
6166 let mut follow = self
6167 .cached_state_expected_symbols(atn, follow_state)
6168 .as_ref()
6169 .clone();
6170 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
6171 follow.extend(self.context_expected_symbols(atn));
6172 }
6173 follow
6174 }
6175
6176 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
6177 self.match_token(TOKEN_EOF)
6178 }
6179
6180 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
6181 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
6182 }
6183
6184 pub fn match_not_set(
6185 &mut self,
6186 intervals: &[(i32, i32)],
6187 min_vocabulary: i32,
6188 max_vocabulary: i32,
6189 ) -> Result<ParseTree, AntlrError> {
6190 self.match_interval_condition(intervals, |symbol| {
6191 (min_vocabulary..=max_vocabulary).contains(&symbol)
6192 && !interval_set_contains(intervals, symbol)
6193 })
6194 }
6195
6196 fn match_interval_condition(
6197 &mut self,
6198 intervals: &[(i32, i32)],
6199 matches: impl FnOnce(i32) -> bool,
6200 ) -> Result<ParseTree, AntlrError> {
6201 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6202 line: 0,
6203 column: 0,
6204 message: "missing current token".to_owned(),
6205 offending: None,
6206 })?;
6207 let current_type = self.token_type_for_id(current);
6208 if matches(current_type) {
6209 self.reset_generated_recovery_state();
6210 self.consume();
6211 Ok(self.terminal_tree(current))
6212 } else {
6213 Err(AntlrError::MismatchedInput {
6214 expected: self.interval_display(intervals),
6215 found: self.vocabulary().display_name(current_type),
6216 })
6217 }
6218 }
6219
6220 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
6221 let values = intervals
6222 .iter()
6223 .map(|(start, stop)| {
6224 if start == stop {
6225 self.vocabulary().display_name(*start)
6226 } else {
6227 format!(
6228 "{}..{}",
6229 self.vocabulary().display_name(*start),
6230 self.vocabulary().display_name(*stop)
6231 )
6232 }
6233 })
6234 .collect::<Vec<_>>()
6235 .join(", ");
6236 format!("{{{values}}}")
6237 }
6238
6239 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
6240 if self.build_parse_trees {
6241 self.tree.finish_rule(context)
6242 } else {
6243 NodeId::placeholder()
6244 }
6245 }
6246
6247 #[must_use]
6256 pub const fn generated_rule_stack_check_due(&self) -> bool {
6257 self.rule_context_stack
6258 .len()
6259 .is_multiple_of(GENERATED_RULE_STACK_CHECK_INTERVAL)
6260 }
6261
6262 #[inline]
6280 pub fn rule_depth_cap_violation(&mut self) -> Option<AntlrError> {
6281 let max = self.max_rule_depth?;
6282 if self.rule_depth_error.is_none()
6285 && self.rule_context_stack.len() + self.recursion_expansions < max
6286 {
6287 return None;
6288 }
6289 Some(self.rule_depth_cap_violation_cold(max))
6290 }
6291
6292 #[cold]
6293 fn rule_depth_cap_violation_cold(&mut self, max: usize) -> AntlrError {
6294 if let Some(error) = &self.rule_depth_error {
6295 return error.clone();
6296 }
6297 let current = self.input.lt(1);
6298 let (line, column) = current
6299 .as_ref()
6300 .map_or((0, 0), |token| (token.line(), token.column()));
6301 let error = AntlrError::ParserError {
6302 line,
6303 column,
6304 message: format!("rule nesting depth limit of {max} exceeded"),
6305 offending: current.as_ref().map(Token::token_id),
6306 };
6307 self.rule_depth_error = Some(error.clone());
6308 error
6309 }
6310
6311 pub const fn take_rule_depth_error(&mut self) -> Option<AntlrError> {
6318 self.rule_depth_error.take()
6319 }
6320
6321 #[must_use]
6328 pub const fn has_rule_depth_cap(&self) -> bool {
6329 self.max_rule_depth.is_some()
6330 }
6331
6332 pub fn add_parse_listener<L>(&mut self, listener: L)
6336 where
6337 L: ParseListener + 'static,
6338 {
6339 self.parse_listeners
6340 .push(ParseListenerSlot(Box::new(listener)));
6341 }
6342
6343 pub fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
6350 self.parse_listener_abort = None;
6351 self.parse_listeners.drain(..).map(|slot| slot.0).collect()
6352 }
6353
6354 #[must_use]
6360 pub const fn has_parse_listeners(&self) -> bool {
6361 !self.parse_listeners.is_empty()
6362 }
6363
6364 #[doc(hidden)]
6369 #[must_use]
6370 pub fn observes_parser_decisions(&self) -> bool {
6371 self.semantic_hooks.observes_parser_decisions()
6372 }
6373
6374 pub fn parse_listener_enter_rule(&mut self, rule_index: usize) -> Option<AntlrError> {
6385 if self.parse_listeners.is_empty() {
6386 return None;
6387 }
6388 self.parse_listener_enter_rule_dispatch(rule_index)
6389 }
6390
6391 fn parse_listener_enter_rule_dispatch(&mut self, rule_index: usize) -> Option<AntlrError> {
6392 if let Some(error) = &self.parse_listener_abort {
6393 return Some(error.clone());
6394 }
6395 let event = EnterRuleEvent {
6396 rule_index,
6397 current: self.input.lt(1),
6398 };
6399 let mut listeners = std::mem::take(&mut self.parse_listeners);
6403 let mut abort = None;
6404 for slot in &mut listeners {
6405 if let Err(error) = slot.0.enter_every_rule(&event) {
6406 abort = Some(error);
6407 break;
6408 }
6409 }
6410 self.parse_listeners = listeners;
6411 if let Some(error) = abort {
6412 self.parse_listener_abort = Some(error.clone());
6413 return Some(error);
6414 }
6415 None
6416 }
6417
6418 pub fn parse_listener_exit_rule(&mut self, rule_index: usize) {
6425 if self.parse_listeners.is_empty() {
6426 return;
6427 }
6428 for slot in self.parse_listeners.iter_mut().rev() {
6431 slot.0.exit_every_rule(rule_index);
6432 }
6433 }
6434
6435 pub const fn take_parse_listener_abort(&mut self) -> Option<AntlrError> {
6442 self.parse_listener_abort.take()
6443 }
6444
6445 pub fn take_parse_abort(&mut self) -> Option<AntlrError> {
6454 if let Some(error) = self.rule_depth_error.take() {
6455 self.parse_listener_abort = None;
6456 return Some(error);
6457 }
6458 self.parse_listener_abort.take()
6459 }
6460
6461 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
6464 self.set_state(state);
6465 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
6466 self.rule_context_stack.push(RuleContextFrame {
6467 rule_index,
6468 invoking_state,
6469 });
6470 self.advance_rule_context_version();
6471 let start_index = self.current_visible_index();
6472 let mut context = ParserRuleContext::new(rule_index, invoking_state);
6473 if let Some(token) = self.token_id_at(start_index) {
6474 self.set_context_start(&mut context, token);
6475 }
6476 context
6477 }
6478
6479 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
6486 let marker = self.pending_invoking_states.len();
6487 self.pending_invoking_states.push(invoking_state);
6488 marker
6489 }
6490
6491 pub fn discard_invoking_state(&mut self, marker: usize) {
6493 self.pending_invoking_states.truncate(marker);
6494 }
6495
6496 pub fn exit_rule(&mut self) {
6498 self.rule_context_stack.pop();
6499 self.advance_rule_context_version();
6500 }
6501
6502 pub fn prediction_context_return_states<'a>(
6505 &'a self,
6506 atn: &'a Atn,
6507 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
6508 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
6509 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
6510 return None;
6511 };
6512 let Some(Transition::Rule { follow_state, .. }) = atn
6513 .state(state_number)
6514 .and_then(|state| state.transitions().first())
6515 .map(ParserTransition::data)
6516 else {
6517 return None;
6518 };
6519 Some(follow_state)
6520 })
6521 }
6522
6523 pub const fn rule_context_version(&self) -> usize {
6528 self.rule_context_version
6529 }
6530
6531 const fn advance_rule_context_version(&mut self) {
6532 self.rule_context_version = self.rule_context_version.wrapping_add(1);
6533 }
6534
6535 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
6540 if self.build_parse_trees {
6541 self.tree.add_child(context, child);
6542 } else {
6543 context.note_matched_child();
6544 }
6545 }
6546
6547 fn release_tree_scratch_if_idle(&mut self) {
6548 if self.rule_context_stack.is_empty() {
6549 self.tree.release_scratch();
6550 }
6551 }
6552
6553 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
6555 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6556 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6557 self.set_context_stop(&mut context, token);
6558 }
6559 let node = self.rule_node(context);
6560 self.exit_rule();
6561 self.release_tree_scratch_if_idle();
6562 node
6563 }
6564
6565 pub fn recover_generated_rule(
6572 &mut self,
6573 context: &mut ParserRuleContext,
6574 atn: &Atn,
6575 error: AntlrError,
6576 ) {
6577 let diagnostic = self.generated_rule_error_diagnostic(error);
6578 self.push_generated_parser_diagnostic(diagnostic);
6579 self.generated_sync_expected = None;
6580 let error_index = self.input.index();
6581 let error_state = self.data.state();
6582 if self.generated_recovery_error_index == Some(error_index)
6587 && self.generated_recovery_error_states.contains(&error_state)
6588 && self.la(1) != TOKEN_EOF
6589 && let Some(token) = self.input.lt_id(1)
6590 {
6591 self.consume();
6592 let child = self.error_tree(token);
6593 self.add_parse_child(context, child);
6594 }
6595 let recovery_index = self.input.index();
6596 if self.generated_recovery_error_index != Some(recovery_index) {
6597 self.generated_recovery_error_index = Some(recovery_index);
6598 self.generated_recovery_error_states.clear();
6599 }
6600 self.generated_recovery_error_states.insert(error_state);
6601 let recovery_symbols = self.context_expected_symbols(atn);
6602 loop {
6603 let symbol = self.la(1);
6604 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
6605 break;
6606 }
6607 let Some(token) = self.input.lt_id(1) else {
6608 break;
6609 };
6610 self.consume();
6611 let child = self.error_tree(token);
6612 self.add_parse_child(context, child);
6613 }
6614 self.record_syntax_errors(1);
6615 }
6616
6617 fn reset_generated_recovery_state(&mut self) {
6618 if self.generated_recovery_error_index.is_some() {
6619 self.generated_recovery_error_index = None;
6620 self.generated_recovery_error_states.clear();
6621 }
6622 }
6623
6624 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
6625 if self
6626 .generated_parser_diagnostics
6627 .iter()
6628 .any(|existing| existing == &diagnostic)
6629 {
6630 return;
6631 }
6632 self.generated_parser_diagnostics.push(diagnostic);
6633 }
6634
6635 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
6636 match error {
6637 AntlrError::ParserError {
6641 line,
6642 column,
6643 message,
6644 offending,
6645 } => ParserDiagnostic {
6646 line,
6647 column,
6648 message,
6649 offending,
6650 },
6651 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
6652 self.input.lt(1),
6653 format!("mismatched input {found} expecting {expected}"),
6654 ),
6655 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
6656 self.input.lt(1),
6657 format!("no viable alternative at input {input}"),
6658 ),
6659 AntlrError::LexerError {
6660 line,
6661 column,
6662 message,
6663 } => ParserDiagnostic {
6664 line,
6665 column,
6666 message,
6667 offending: None,
6668 },
6669 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
6670 }
6671 }
6672
6673 pub fn finish_recursion_rule(
6675 &mut self,
6676 mut context: ParserRuleContext,
6677 consumed_eof: bool,
6678 ) -> ParseTree {
6679 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6680 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6681 self.set_context_stop(&mut context, token);
6682 }
6683 let node = self.rule_node(context);
6684 self.unroll_recursion_context();
6685 self.release_tree_scratch_if_idle();
6686 node
6687 }
6688
6689 pub fn enter_recursion_rule(
6691 &mut self,
6692 state: isize,
6693 rule_index: usize,
6694 precedence: i32,
6695 ) -> ParserRuleContext {
6696 self.precedence_stack.push(precedence);
6697 self.recursion_expansion_marks
6698 .push(self.recursion_expansions);
6699 self.enter_rule(state, rule_index)
6700 }
6701
6702 pub fn push_new_recursion_context(
6704 &mut self,
6705 state: isize,
6706 rule_index: usize,
6707 ) -> ParserRuleContext {
6708 self.set_state(state);
6709 self.recursion_expansions += 1;
6712 ParserRuleContext::new(rule_index, state)
6713 }
6714
6715 pub fn push_new_recursion_context_with_previous(
6718 &mut self,
6719 state: isize,
6720 rule_index: usize,
6721 current: &mut ParserRuleContext,
6722 ) {
6723 self.set_state(state);
6724 self.recursion_expansions += 1;
6730 if let Some(stop) = self
6731 .rule_stop_token_index(self.input.index(), false)
6732 .and_then(|index| self.token_id_at(index))
6733 {
6734 self.set_context_stop(current, stop);
6735 }
6736 let invoking_state = current.invoking_state();
6737 let start = current.start_id();
6738 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
6739 if start.is_some() {
6740 replacement.set_start_from_context(current);
6741 }
6742 let previous = std::mem::replace(current, replacement);
6743 if self.build_parse_trees {
6744 let previous = self.rule_node(previous);
6745 self.tree.add_child(current, previous);
6746 }
6747 }
6748
6749 pub fn unroll_recursion_context(&mut self) {
6751 if self.precedence_stack.len() > 1 {
6752 self.precedence_stack.pop();
6753 }
6754 if let Some(mark) = self.recursion_expansion_marks.pop() {
6760 self.recursion_expansions = mark;
6761 }
6762 self.exit_rule();
6763 }
6764
6765 pub fn left_recursive_loop_enter_prediction(
6779 &mut self,
6780 atn: &Atn,
6781 state_number: usize,
6782 precedence: i32,
6783 ) -> Option<bool> {
6784 let symbol = self.la(1);
6785 if symbol == TOKEN_EOF {
6786 return Some(false);
6787 }
6788 let operator_lookahead =
6789 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
6790 let can_single = operator_lookahead.single_token.contains(symbol);
6791 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
6792 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
6793 if !can_single && !can_multi && !can_predicate {
6794 return Some(false);
6795 }
6796 if can_predicate && !can_single {
6797 return None;
6798 }
6799 if !can_single && can_multi && precedence > 0 {
6803 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
6804 if baseline.single_token.contains(symbol) {
6805 return None;
6806 }
6807 }
6808 let atn_key = SharedAtnCacheKey::for_atn(atn);
6809 let cached_overlap = self
6810 .left_recursive_caller_overlap_cache
6811 .iter()
6812 .flatten()
6813 .find(|entry| {
6814 entry.atn_key == atn_key
6815 && entry.state_number == state_number
6816 && entry.symbol == symbol
6817 && entry.context_version == self.rule_context_version
6818 })
6819 .map(|entry| entry.overlaps);
6820 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
6821 let overlaps = caller_context_can_match_symbol_before_state(
6822 atn,
6823 self.prediction_context_return_states(atn),
6824 state_number,
6825 symbol,
6826 );
6827 if let Some(slot) = self
6828 .left_recursive_caller_overlap_cache
6829 .iter_mut()
6830 .find(|slot| slot.is_none())
6831 {
6832 *slot = Some(LeftRecursiveCallerOverlap {
6833 atn_key,
6834 state_number,
6835 symbol,
6836 context_version: self.rule_context_version,
6837 overlaps,
6838 });
6839 }
6840 overlaps
6841 });
6842 if caller_overlaps {
6843 return None;
6844 }
6845 Some(true)
6846 }
6847
6848 fn cached_left_recursive_operator_lookahead(
6849 atn: &Atn,
6850 state_number: usize,
6851 precedence: i32,
6852 ) -> Rc<LeftRecursiveOperatorLookahead> {
6853 with_shared_atn_caches(atn, |cache| {
6854 let key = (state_number, precedence);
6855 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
6856 return Rc::clone(cached);
6857 }
6858 let lookahead = Rc::new(left_recursive_operator_lookahead(
6859 atn,
6860 state_number,
6861 precedence,
6862 ));
6863 cache
6864 .left_recursive_operator_lookahead
6865 .insert(key, Rc::clone(&lookahead));
6866 lookahead
6867 })
6868 }
6869
6870 pub fn left_recursive_loop_enter_matches(
6873 &mut self,
6874 atn: &Atn,
6875 state_number: usize,
6876 precedence: i32,
6877 ) -> bool {
6878 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
6879 }
6880
6881 pub fn precpred(&self, precedence: i32) -> bool {
6883 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
6884 }
6885
6886 pub fn parser_semantic_predicate_matches(
6889 &mut self,
6890 predicates: &[(usize, usize, ParserPredicate)],
6891 rule_index: usize,
6892 pred_index: usize,
6893 ) -> bool {
6894 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
6895 }
6896
6897 pub fn parser_semantic_predicate_matches_with_local(
6900 &mut self,
6901 predicates: &[(usize, usize, ParserPredicate)],
6902 rule_index: usize,
6903 pred_index: usize,
6904 local_int_arg: i32,
6905 ) -> bool {
6906 self.parser_semantic_predicate_matches_inner(
6907 predicates,
6908 rule_index,
6909 pred_index,
6910 Some((rule_index, i64::from(local_int_arg))),
6911 )
6912 }
6913
6914 fn parser_semantic_predicate_matches_inner(
6915 &mut self,
6916 predicates: &[(usize, usize, ParserPredicate)],
6917 rule_index: usize,
6918 pred_index: usize,
6919 local_int_arg: Option<(usize, i64)>,
6920 ) -> bool {
6921 let index = self.input.index();
6922 let member_values = self.int_members.clone();
6923 self.parser_predicate_matches(PredicateEval {
6924 index,
6925 rule_index,
6926 pred_index,
6927 predicates,
6928 semantics: None,
6929 context: None,
6930 local_int_arg,
6931 member_values: &member_values,
6932 })
6933 }
6934
6935 pub fn parser_semantic_predicate_matches_with_context_and_local(
6938 &mut self,
6939 predicates: &[(usize, usize, ParserPredicate)],
6940 rule_index: usize,
6941 pred_index: usize,
6942 context: &ParserRuleContext,
6943 local_int_arg: i32,
6944 ) -> bool {
6945 let index = self.input.index();
6946 let member_values = self.int_members.clone();
6947 self.parser_predicate_matches(PredicateEval {
6948 index,
6949 rule_index,
6950 pred_index,
6951 predicates,
6952 semantics: None,
6953 context: Some(context),
6954 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6955 member_values: &member_values,
6956 })
6957 }
6958
6959 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6962 &mut self,
6963 semantics: &ParserSemantics,
6964 rule_index: usize,
6965 pred_index: usize,
6966 context: &ParserRuleContext,
6967 local_int_arg: i32,
6968 ) -> bool {
6969 let index = self.input.index();
6970 let member_values = self.int_members.clone();
6971 self.parser_predicate_matches(PredicateEval {
6972 index,
6973 rule_index,
6974 pred_index,
6975 predicates: &[],
6976 semantics: Some(semantics),
6977 context: Some(context),
6978 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6979 member_values: &member_values,
6980 })
6981 }
6982
6983 pub fn parser_semantic_predicate_failure_message(
6986 &self,
6987 rule_index: usize,
6988 pred_index: usize,
6989 predicates: &[(usize, usize, ParserPredicate)],
6990 ) -> Option<&'static str> {
6991 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6992 }
6993
6994 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6996 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6997 line: 0,
6998 column: 0,
6999 message: "missing current token".to_owned(),
7000 offending: None,
7001 })?;
7002 if self.token_type_for_id(current) == TOKEN_EOF {
7003 return Err(AntlrError::MismatchedInput {
7004 expected: "wildcard".to_owned(),
7005 found: self.vocabulary().display_name(TOKEN_EOF),
7006 });
7007 }
7008 self.reset_generated_recovery_state();
7009 self.consume();
7010 Ok(self.terminal_tree(current))
7011 }
7012
7013 #[allow(clippy::unnecessary_wraps)]
7017 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
7018 self.set_state(state);
7019 Ok(())
7020 }
7021
7022 pub fn sync_decision(
7030 &mut self,
7031 atn: &Atn,
7032 state_number: usize,
7033 _current_context_empty: bool,
7034 loop_back: bool,
7035 ) -> Result<Vec<ParseTree>, AntlrError> {
7036 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
7037 self.generated_sync_expected = None;
7038 let Some(state) = atn.state(state_number) else {
7039 return Ok(Vec::new());
7040 };
7041 let Some(rule_index) = state.rule_index() else {
7042 return Ok(Vec::new());
7043 };
7044 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
7045 return Ok(Vec::new());
7046 };
7047 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
7048 let symbol = self.la(1);
7049 let mut has_expected_symbols = false;
7050 let mut nullable = false;
7051 let mut explicit_eof_expected = false;
7059 for transition in &entry.transitions {
7060 if transition.symbols.contains(symbol) {
7061 return Ok(Vec::new());
7062 }
7063 has_expected_symbols |= !transition.symbols.is_empty();
7064 nullable |= transition.nullable;
7065 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
7066 }
7067 if nullable {
7074 if self.context_expected_contains(atn, symbol) {
7078 return Ok(Vec::new());
7079 }
7080 let mut expected = self.context_expected_token_set(atn);
7081 for transition in &entry.transitions {
7082 expected.extend_from(&transition.symbols);
7083 }
7084 self.generated_sync_expected = Some(expected);
7085 return Ok(Vec::new());
7086 }
7087 if !has_expected_symbols {
7088 return Ok(Vec::new());
7089 }
7090 let mut expected = TokenBitSet::default();
7091 for transition in &entry.transitions {
7092 expected.extend_from(&transition.symbols);
7093 }
7094 let loop_sync = loop_back;
7111 if symbol != TOKEN_EOF {
7112 let mut cursor = self.input.index();
7113 let mut skipped = Vec::new();
7114 loop {
7115 let current = self.token_type_at(cursor);
7116 if current == TOKEN_EOF {
7117 break;
7118 }
7119 skipped.push(cursor);
7120 let next = self.consume_index(cursor, current);
7121 if next == cursor {
7122 break;
7123 }
7124 let next_symbol = self.token_type_at(next);
7125 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
7133 explicit_eof_expected
7134 } else {
7135 expected.contains(next_symbol)
7136 };
7137 if next_is_expected_stop {
7138 let current_token = self.input.lt(1);
7139 let expected_symbols = expected.to_btree_set();
7140 let message = format!(
7141 "extraneous input {} expecting {}",
7142 current_token
7143 .as_ref()
7144 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7145 self.expected_symbols_display(&expected_symbols)
7146 );
7147 self.push_generated_parser_diagnostic(diagnostic_for_token(
7148 current_token,
7149 message,
7150 ));
7151 self.record_syntax_errors(1);
7152 let mut children = Vec::with_capacity(skipped.len());
7153 for index in skipped {
7154 if let Some(token) = self.token_id_at(index) {
7155 self.consume();
7156 children.push(self.error_tree(token));
7157 }
7158 }
7159 if !loop_sync {
7160 self.reset_generated_recovery_state();
7161 }
7162 return Ok(children);
7163 }
7164 if !loop_sync {
7168 break;
7169 }
7170 cursor = next;
7171 }
7172 }
7173 let current = self.input.lt(1);
7174 let expected_symbols = expected.to_btree_set();
7175 Err(AntlrError::ParserError {
7176 line: current.as_ref().map(Token::line).unwrap_or_default(),
7177 column: current.as_ref().map(Token::column).unwrap_or_default(),
7178 message: format!(
7179 "mismatched input {} expecting {}",
7180 current
7181 .as_ref()
7182 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7183 self.expected_symbols_display(&expected_symbols)
7184 ),
7185 offending: current.as_ref().map(Token::token_id),
7186 })
7187 }
7188
7189 pub fn ll1_decision_prediction(
7196 &mut self,
7197 atn: &Atn,
7198 state_number: usize,
7199 ) -> Option<ParserAtnPrediction> {
7200 let state = atn.state(state_number)?;
7201 if state.precedence_rule_decision() {
7202 return None;
7203 }
7204 let rule_stop = state
7205 .rule_index()
7206 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
7207 let symbol = self.la(1);
7208 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
7209 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
7210 alt: alt + 1,
7211 requires_full_context: false,
7212 has_semantic_context: false,
7213 diagnostic: None,
7214 })
7215 }
7216
7217 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
7218 let mut expected = BTreeSet::new();
7219 for index in (1..self.rule_context_stack.len()).rev() {
7220 let invoking_state = self.rule_context_stack[index].invoking_state;
7221 let Ok(state_number) = usize::try_from(invoking_state) else {
7222 continue;
7223 };
7224 let Some(Transition::Rule { follow_state, .. }) = atn
7225 .state(state_number)
7226 .and_then(|state| state.transitions().first())
7227 .map(ParserTransition::data)
7228 else {
7229 continue;
7230 };
7231 let return_state = follow_state;
7232 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
7233 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
7234 return expected;
7235 }
7236 }
7237 expected.insert(TOKEN_EOF);
7238 expected
7239 }
7240
7241 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
7242 let mut expected = TokenBitSet::default();
7243 for index in (1..self.rule_context_stack.len()).rev() {
7244 let invoking_state = self.rule_context_stack[index].invoking_state;
7245 let Ok(state_number) = usize::try_from(invoking_state) else {
7246 continue;
7247 };
7248 let Some(Transition::Rule { follow_state, .. }) = atn
7249 .state(state_number)
7250 .and_then(|state| state.transitions().first())
7251 .map(ParserTransition::data)
7252 else {
7253 continue;
7254 };
7255 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
7256 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7257 return expected;
7258 }
7259 }
7260 expected.insert(TOKEN_EOF);
7261 expected
7262 }
7263
7264 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
7271 for index in (1..self.rule_context_stack.len()).rev() {
7272 let invoking_state = self.rule_context_stack[index].invoking_state;
7273 let Ok(state_number) = usize::try_from(invoking_state) else {
7274 continue;
7275 };
7276 let Some(Transition::Rule { follow_state, .. }) = atn
7277 .state(state_number)
7278 .and_then(|state| state.transitions().first())
7279 .map(ParserTransition::data)
7280 else {
7281 continue;
7282 };
7283 if self
7284 .cached_state_expected_token_set(atn, follow_state)
7285 .contains(symbol)
7286 {
7287 return true;
7288 }
7289 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7290 return false;
7291 }
7292 }
7293 symbol == TOKEN_EOF
7294 }
7295
7296 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
7298 let error_index = self.input.index();
7299 self.no_viable_alternative_error_at(start_index, error_index)
7300 }
7301
7302 pub fn no_viable_alternative_error_at(
7307 &self,
7308 start_index: usize,
7309 error_index: usize,
7310 ) -> AntlrError {
7311 let diagnostic = self.no_viable_alternative(start_index, error_index);
7312 AntlrError::ParserError {
7313 line: diagnostic.line,
7314 column: diagnostic.column,
7315 message: diagnostic.message,
7316 offending: diagnostic.offending,
7317 }
7318 }
7319
7320 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
7322 let current = self.input.lt(1);
7323 AntlrError::ParserError {
7324 line: current.as_ref().map(Token::line).unwrap_or_default(),
7325 column: current.as_ref().map(Token::column).unwrap_or_default(),
7326 message: format!("rule failed predicate: {}", message.into()),
7327 offending: current.as_ref().map(Token::token_id),
7328 }
7329 }
7330
7331 pub fn failed_predicate_option_error(
7334 &self,
7335 rule_index: usize,
7336 message: impl Into<String>,
7337 ) -> AntlrError {
7338 let current = self.input.lt(1);
7339 let rule_name = self
7340 .rule_names()
7341 .get(rule_index)
7342 .map_or_else(|| rule_index.to_string(), Clone::clone);
7343 AntlrError::ParserError {
7344 line: current.as_ref().map(Token::line).unwrap_or_default(),
7345 column: current.as_ref().map(Token::column).unwrap_or_default(),
7346 message: format!("rule {rule_name} {}", message.into()),
7347 offending: current.as_ref().map(Token::token_id),
7348 }
7349 }
7350
7351 pub fn parser_action_at_current(
7353 &mut self,
7354 source_state: usize,
7355 rule_index: usize,
7356 start_index: usize,
7357 consumed_eof: bool,
7358 ) -> ParserAction {
7359 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7360 ParserAction::new(source_state, rule_index, start_index, stop_index)
7361 }
7362
7363 pub fn parser_action_at_current_indexed(
7365 &mut self,
7366 source_state: usize,
7367 rule_index: usize,
7368 action_index: usize,
7369 start_index: usize,
7370 consumed_eof: bool,
7371 ) -> ParserAction {
7372 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7373 ParserAction::new_indexed(
7374 source_state,
7375 rule_index,
7376 action_index,
7377 start_index,
7378 stop_index,
7379 )
7380 }
7381
7382 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
7387 self.parser_action_hook_inner(action, None, Some(tree), None, true)
7388 }
7389
7390 pub fn parser_action_hook_with_context(
7395 &mut self,
7396 action: ParserAction,
7397 context: &ParserRuleContext,
7398 ) -> bool {
7399 self.parser_action_hook_inner(action, Some(context), None, None, true)
7400 }
7401
7402 pub fn parser_action_hook_with_context_and_local(
7408 &mut self,
7409 action: ParserAction,
7410 context: &ParserRuleContext,
7411 local_int_arg: i32,
7412 ) -> bool {
7413 self.parser_action_hook_inner(
7414 action,
7415 Some(context),
7416 None,
7417 Some((action.rule_index(), i64::from(local_int_arg))),
7418 true,
7419 )
7420 }
7421
7422 fn parser_rule_init_hook_with_context(
7427 &mut self,
7428 action: ParserAction,
7429 context: &ParserRuleContext,
7430 local_int_arg: Option<(usize, i64)>,
7431 ) -> bool {
7432 debug_assert!(action.is_rule_init());
7433 self.parser_action_hook_inner(action, Some(context), None, local_int_arg, false)
7434 }
7435
7436 fn parser_action_hook_inner(
7437 &mut self,
7438 action: ParserAction,
7439 context: Option<&ParserRuleContext>,
7440 tree: Option<ParseTree>,
7441 local_int_arg: Option<(usize, i64)>,
7442 record_unhandled: bool,
7443 ) -> bool {
7444 let rule_index = action.rule_index();
7445 let rule_name = self.rule_names().get(rule_index).cloned();
7446 let input = &mut self.input;
7447 let semantic_hooks = &mut self.semantic_hooks;
7448 let member_values = &self.int_members;
7449 let mut ctx = ParserSemCtx {
7450 input,
7451 tree_storage: &self.tree,
7452 rule_index,
7453 coordinate_index: action.action_index().unwrap_or(usize::MAX),
7454 rule_name,
7455 context,
7456 tree,
7457 local_int_arg,
7458 member_values,
7459 action: Some(action),
7460 };
7461 let handled = semantic_hooks.action(&mut ctx, action);
7462 if record_unhandled
7468 && !handled
7469 && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error)
7470 {
7471 let coordinate = (rule_index, action.source_state());
7472 if !self.unhandled_action_hits.contains(&coordinate) {
7473 self.unhandled_action_hits.push(coordinate);
7474 }
7475 }
7476 handled
7477 }
7478
7479 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
7484 &mut self,
7485 atn: &'atn Atn,
7486 simulator: &mut ParserAtnSimulator<'atn>,
7487 rule_index: usize,
7488 ) -> Result<ParseTree, AntlrError> {
7489 let start_index = self.current_visible_index();
7490 self.clear_prediction_diagnostics();
7491 self.reset_per_parse_caches();
7492 self.reset_recognition_arena();
7493 let tree_checkpoint = self.tree.checkpoint();
7494 let mut decision_by_state = vec![None; atn.states().len()];
7495 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
7496 if let Some(slot) = decision_by_state.get_mut(state_number) {
7497 *slot = Some(decision);
7498 }
7499 }
7500
7501 let result = DirectAdaptiveParser {
7502 parser: self,
7503 atn,
7504 simulator,
7505 decision_by_state,
7506 steps: 0,
7507 }
7508 .parse_rule(rule_index, -1, 0);
7509
7510 match result {
7511 Ok(tree) => {
7512 self.report_token_source_errors();
7513 self.release_tree_scratch_if_idle();
7514 Ok(tree)
7515 }
7516 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
7517 let _ = reason;
7518 self.tree.rollback(tree_checkpoint);
7519 self.input.seek(start_index);
7520 self.parse_atn_rule(atn, rule_index)
7521 }
7522 }
7523 }
7524
7525 pub fn parse_atn_rule(
7535 &mut self,
7536 atn: &Atn,
7537 rule_index: usize,
7538 ) -> Result<ParseTree, AntlrError> {
7539 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
7540 }
7541
7542 pub fn parse_atn_rule_with_precedence(
7545 &mut self,
7546 atn: &Atn,
7547 rule_index: usize,
7548 precedence: i32,
7549 ) -> Result<ParseTree, AntlrError> {
7550 self.parse_atn_rule_with_precedence_inner(
7551 atn,
7552 rule_index,
7553 precedence,
7554 None,
7555 AltNumberTracking::default(),
7556 )
7557 }
7558
7559 fn parse_atn_rule_with_precedence_inner(
7560 &mut self,
7561 atn: &Atn,
7562 rule_index: usize,
7563 precedence: i32,
7564 predicate_context: Option<FastPredicateContext<'_>>,
7565 alt_tracking: AltNumberTracking,
7566 ) -> Result<ParseTree, AntlrError> {
7567 let report_unrecovered_error = self.is_top_level_entry();
7568 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7569 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7570 })?;
7571 let stop_state = atn
7572 .rule_to_stop_state()
7573 .get(rule_index)
7574 .filter(|state| *state != usize::MAX)
7575 .ok_or_else(|| {
7576 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7577 })?;
7578
7579 let start_index = self.current_visible_index();
7580 self.clear_prediction_diagnostics();
7581 self.reset_per_parse_caches();
7582 self.reset_recognition_arena();
7583 let caller_follow_state = self.pending_invoking_follow_state(atn);
7584 self.fast_recovery_enabled = false;
7585 self.fast_token_nodes_enabled = false;
7586 self.fast_track_alt_numbers = alt_tracking.any();
7587 let top_request = FastRecognizeTopRequest {
7588 start_state,
7589 stop_state,
7590 start_index,
7591 precedence,
7592 caller_follow_state,
7593 };
7594 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
7595 self.fast_token_nodes_enabled = self.build_parse_trees;
7596 let needs_tree_retry = matches!(
7597 &first_pass,
7598 Ok((outcome, _, _))
7599 if self.build_parse_trees
7600 && self
7601 .recognition_arena
7602 .sequence_has_left_recursive_boundary(outcome.nodes)
7603 );
7604 let needs_retry = match &first_pass {
7605 Err(_) => true,
7618 Ok((outcome, _, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
7619 };
7620 let (outcome, _expected, alt_number) = if needs_retry {
7621 self.fast_first_set_prefilter = false;
7622 self.fast_recovery_enabled = false;
7623 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7624 let clean_selected = if needs_tree_retry {
7625 match clean_retry {
7626 ok @ Ok(_) => ok,
7627 Err(_) => first_pass,
7628 }
7629 } else {
7630 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
7631 };
7632 let selected = if clean_selected.is_err()
7633 || matches!(&clean_selected, Ok((outcome, _, _)) if !outcome.diagnostics.is_empty())
7634 {
7635 self.fast_recovery_enabled = true;
7636 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7637 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
7638 } else {
7639 clean_selected
7640 };
7641 self.fast_first_set_prefilter = true;
7642 self.fast_recovery_enabled = true;
7643 selected.map_err(|expected| {
7644 if predicate_context.is_some()
7645 && let Some(error) = self.unknown_semantic_error()
7646 {
7647 self.report_token_source_errors();
7648 return error;
7649 }
7650 let error = self.recognition_error(rule_index, start_index, &expected);
7651 self.record_syntax_errors(1);
7652 self.report_token_source_errors();
7653 if report_unrecovered_error {
7654 self.report_unrecovered_parser_error(&error);
7655 }
7656 error
7657 })?
7658 } else {
7659 first_pass.expect("first_pass is Ok in the no-retry branch")
7660 };
7661 if predicate_context.is_some()
7662 && let Some(error) = self.unknown_semantic_error()
7663 {
7664 self.report_token_source_errors();
7665 return Err(error);
7666 }
7667 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7668 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7669 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7670 self.report_token_source_errors();
7671 let mut context = ParserRuleContext::with_child_capacity(
7672 rule_index,
7673 self.state(),
7674 if self.build_parse_trees {
7675 self.recognition_arena.sequence_len(outcome.nodes)
7676 } else {
7677 0
7678 },
7679 );
7680 if alt_tracking.public {
7681 context.set_alt_number(alt_number.max(1));
7682 }
7683 if alt_tracking.context {
7684 context.set_context_alt_number(alt_number);
7685 }
7686 if let Some(token) = self.token_id_at(start_index) {
7687 self.set_context_start(&mut context, token);
7688 }
7689 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
7690 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
7691 self.set_context_stop(&mut context, token);
7692 }
7693 let live_root = if self.build_parse_trees {
7694 self.recognition_arena
7695 .fold_left_recursive_boundaries(outcome.nodes)
7696 } else {
7697 outcome.nodes
7698 };
7699 if self.build_parse_trees {
7700 if self
7701 .recognition_arena
7702 .sequence_has_explicit_token(live_root)
7703 {
7704 let mut cursor = live_root;
7705 while let Some(link) = self.recognition_arena.link(cursor) {
7706 let child = self.arena_recognized_node_tree(
7707 link.head,
7708 alt_tracking.public,
7709 alt_tracking.context,
7710 )?;
7711 self.tree.add_child(&mut context, child);
7712 cursor = link.tail;
7713 }
7714 } else {
7715 self.add_arena_implicit_token_children(
7716 &mut context,
7717 start_index,
7718 stop_index,
7719 live_root,
7720 alt_tracking,
7721 )?;
7722 }
7723 }
7724 self.finish_recognition_arena(live_root, outcome.diagnostics);
7725 self.input.seek(outcome.index);
7726
7727 let tree = self.rule_node(context);
7728 self.release_tree_scratch_if_idle();
7729 Ok(tree)
7730 }
7731
7732 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
7733 let invoking_state = self.pending_invoking_states.last().copied()?;
7734 let state_number = usize::try_from(invoking_state).ok()?;
7735 match atn.state(state_number)?.transitions().first()?.data() {
7736 Transition::Rule { follow_state, .. } => Some(follow_state),
7737 _ => None,
7738 }
7739 }
7740
7741 #[cfg(test)]
7742 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
7743 caller_follow_token_info_for_stream(&mut self.input, index)
7744 }
7745
7746 fn fast_recognize_top(
7751 &mut self,
7752 atn: &Atn,
7753 request: FastRecognizeTopRequest,
7754 predicate_context: Option<FastPredicateContext<'_>>,
7755 ) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
7756 let FastRecognizeTopRequest {
7757 start_state,
7758 stop_state,
7759 start_index,
7760 precedence,
7761 caller_follow_state,
7762 } = request;
7763 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
7772 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
7773 recognize_scratch.prepare(memo_capacity);
7774 let mut expected = ExpectedTokens::default();
7775 let empty_recovery = self.empty_recovery_symbols();
7776 let outcomes = self.recognize_state_fast(
7777 atn,
7778 FastRecognizeRequest {
7779 state_number: start_state,
7780 stop_state,
7781 index: start_index,
7782 rule_start_index: start_index,
7783 decision_start_index: None,
7784 precedence,
7785 depth: 0,
7786 recovery_symbols: empty_recovery,
7787 recovery_state: None,
7788 },
7789 FastRecognizeScratch {
7790 predicate_context,
7791 visiting: &mut recognize_scratch.visiting,
7792 memo: &mut recognize_scratch.memo,
7793 expected: &mut expected,
7794 native_depth: 0,
7795 },
7796 );
7797 recognize_scratch.release_oversized_memo();
7798 self.fast_recognize_scratch = recognize_scratch;
7799 #[cfg(feature = "perf-counters")]
7800 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
7801 perf_counters::dump();
7802 perf_counters::reset();
7803 }
7804 let caller_follow =
7805 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
7806 let selected = {
7807 let arena = &self.recognition_arena;
7808 let input = &mut self.input;
7809 select_best_fast_outcome(
7810 outcomes.into_iter(),
7811 self.prediction_mode,
7812 caller_follow.as_deref(),
7813 |index| caller_follow_token_info_for_stream(input, index),
7814 arena,
7815 )
7816 };
7817 match selected {
7818 Some(mut outcome) => {
7819 let alt_number = if self.build_parse_trees || self.fast_track_alt_numbers {
7820 self.materialize_fast_outcome_nodes(&mut outcome)
7821 } else {
7822 0
7823 };
7824 Ok((outcome, expected, alt_number))
7825 }
7826 None => Err(expected),
7827 }
7828 }
7829
7830 fn arena_recognized_node_tree(
7832 &mut self,
7833 node_id: RecognizedNodeId,
7834 track_alt_numbers: bool,
7835 track_context_alt_numbers: bool,
7836 ) -> Result<ParseTree, AntlrError> {
7837 let node = self.recognition_arena.node(node_id);
7838 match node {
7839 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
7840 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
7841 ArenaRecognizedNode::MissingToken { extra } => {
7842 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
7843 RecognitionExtra::MissingToken {
7844 token_type,
7845 at_index,
7846 text,
7847 } => (*token_type, *at_index as usize, text.clone()),
7848 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
7849 unreachable!("missing-token node must reference missing-token extra")
7850 }
7851 };
7852 let (line, column) = self
7853 .token_at(at_index)
7854 .map_or((0, 0), |token| (token.line(), token.column()));
7855 let token = self.insert_synthetic_token(token_type, text, line, column)?;
7856 Ok(self.error_tree(token))
7857 }
7858 ArenaRecognizedNode::Rule {
7859 rule_index,
7860 invoking_state,
7861 alt_number,
7862 start_index,
7863 stop_index,
7864 return_values,
7865 children,
7866 } => {
7867 let mut context = ParserRuleContext::with_child_capacity(
7868 rule_index as usize,
7869 invoking_state as isize,
7870 self.recognition_arena.sequence_len(children),
7871 );
7872 if track_alt_numbers {
7873 context.set_alt_number((alt_number as usize).max(1));
7874 }
7875 if track_context_alt_numbers {
7876 context.set_context_alt_number(alt_number as usize);
7877 }
7878 if let Some(extra) = return_values {
7879 let RecognitionExtra::ReturnValues(values) =
7880 self.recognition_arena.extra(extra)
7881 else {
7882 unreachable!("rule node must reference return-values extra");
7883 };
7884 for (name, value) in values {
7885 context.set_int_return(name.clone(), *value);
7886 }
7887 }
7888 if let Some(token) = self.token_id_at(start_index as usize) {
7889 self.set_context_start(&mut context, token);
7890 }
7891 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7892 self.set_context_stop(&mut context, token);
7893 }
7894 let mut cursor = self
7895 .recognition_arena
7896 .fold_left_recursive_boundaries(children);
7897 while let Some(link) = self.recognition_arena.link(cursor) {
7898 let child = self.arena_recognized_node_tree(
7899 link.head,
7900 track_alt_numbers,
7901 track_context_alt_numbers,
7902 )?;
7903 self.tree.add_child(&mut context, child);
7904 cursor = link.tail;
7905 }
7906 Ok(self.rule_node(context))
7907 }
7908 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
7909 Err(AntlrError::Unsupported(format!(
7910 "unfolded left-recursive boundary for rule {rule_index}"
7911 )))
7912 }
7913 }
7914 }
7915
7916 fn arena_recognized_node_tree_with_implicit_tokens(
7917 &mut self,
7918 node_id: RecognizedNodeId,
7919 alt_tracking: AltNumberTracking,
7920 ) -> Result<ParseTree, AntlrError> {
7921 let node = self.recognition_arena.node(node_id);
7922 match node {
7923 ArenaRecognizedNode::Rule {
7924 rule_index,
7925 invoking_state,
7926 alt_number,
7927 start_index,
7928 stop_index,
7929 children,
7930 ..
7931 } => {
7932 let mut context = ParserRuleContext::with_child_capacity(
7933 rule_index as usize,
7934 invoking_state as isize,
7935 self.recognition_arena.sequence_len(children),
7936 );
7937 if alt_tracking.public {
7938 context.set_alt_number((alt_number as usize).max(1));
7939 }
7940 if alt_tracking.context {
7941 context.set_context_alt_number(alt_number as usize);
7942 }
7943 if let Some(token) = self.token_id_at(start_index as usize) {
7944 self.set_context_start(&mut context, token);
7945 }
7946 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7947 self.set_context_stop(&mut context, token);
7948 }
7949 let children = self
7950 .recognition_arena
7951 .fold_left_recursive_boundaries(children);
7952 self.add_arena_implicit_token_children(
7953 &mut context,
7954 start_index as usize,
7955 stop_index.map(|index| index as usize),
7956 children,
7957 alt_tracking,
7958 )?;
7959 Ok(self.rule_node(context))
7960 }
7961 _ => {
7962 self.arena_recognized_node_tree(node_id, alt_tracking.public, alt_tracking.context)
7963 }
7964 }
7965 }
7966
7967 fn add_arena_implicit_token_children(
7968 &mut self,
7969 context: &mut ParserRuleContext,
7970 start_index: usize,
7971 stop_index: Option<usize>,
7972 mut children: NodeSeqId,
7973 alt_tracking: AltNumberTracking,
7974 ) -> Result<(), AntlrError> {
7975 let mut cursor = Some(start_index);
7976 while let Some(link) = self.recognition_arena.link(children) {
7977 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
7978 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
7979 let child =
7980 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7981 self.tree.add_child(context, child);
7982 if let Some(child_stop) = child_stop {
7983 let next = self.next_visible_after_token(child_stop);
7984 cursor = match (cursor, next) {
7985 (None, _) | (_, None) => None,
7986 (Some(current), Some(next)) => Some(current.max(next)),
7987 };
7988 }
7989 } else {
7990 let child =
7991 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7992 self.tree.add_child(context, child);
7993 }
7994 children = link.tail;
7995 }
7996 if let Some(stop) = stop_index {
7997 self.add_visible_terminals_through(context, cursor, stop)?;
7998 }
7999 Ok(())
8000 }
8001
8002 fn add_visible_terminals_before(
8003 &mut self,
8004 context: &mut ParserRuleContext,
8005 cursor: &mut Option<usize>,
8006 before: usize,
8007 ) -> Result<(), AntlrError> {
8008 let Some(stop) = before.checked_sub(1) else {
8009 return Ok(());
8010 };
8011 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
8012 *cursor = next;
8013 Ok(())
8014 }
8015
8016 fn add_visible_terminals_through(
8017 &mut self,
8018 context: &mut ParserRuleContext,
8019 mut cursor: Option<usize>,
8020 stop: usize,
8021 ) -> Result<Option<usize>, AntlrError> {
8022 while let Some(index) = cursor {
8023 if index > stop {
8024 return Ok(Some(index));
8025 }
8026 let token = self
8027 .input
8028 .get_id(index)
8029 .ok_or_else(|| AntlrError::ParserError {
8030 line: 0,
8031 column: 0,
8032 message: format!("missing token at index {index}"),
8033 offending: None,
8034 })?;
8035 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
8036 let child = self.terminal_tree(token);
8037 self.tree.add_child(context, child);
8038 if is_eof {
8039 return Ok(None);
8040 }
8041 cursor = self.next_visible_after_token(index);
8042 }
8043 Ok(None)
8044 }
8045
8046 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
8047 let next = self.input.next_visible_after(index);
8048 (next != index).then_some(next)
8049 }
8050
8051 pub fn parse_atn_rule_with_actions(
8058 &mut self,
8059 atn: &Atn,
8060 rule_index: usize,
8061 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8062 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
8063 }
8064
8065 pub fn parse_atn_rule_with_action_inits(
8073 &mut self,
8074 atn: &Atn,
8075 rule_index: usize,
8076 init_action_rules: &[usize],
8077 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8078 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
8079 }
8080
8081 pub fn parse_atn_rule_with_action_options(
8087 &mut self,
8088 atn: &Atn,
8089 rule_index: usize,
8090 init_action_rules: &[usize],
8091 track_alt_numbers: bool,
8092 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8093 self.parse_atn_rule_with_runtime_options(
8094 atn,
8095 rule_index,
8096 ParserRuntimeOptions {
8097 init_action_rules,
8098 track_alt_numbers,
8099 ..ParserRuntimeOptions::default()
8100 },
8101 )
8102 }
8103
8104 pub fn parse_atn_rule_with_runtime_options(
8111 &mut self,
8112 atn: &Atn,
8113 rule_index: usize,
8114 options: ParserRuntimeOptions<'_>,
8115 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8116 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
8117 }
8118
8119 fn parse_atn_rule_committed_with_runtime_options(
8120 &mut self,
8121 atn: &Atn,
8122 rule_index: usize,
8123 precedence: i32,
8124 options: ParserRuntimeOptions<'_>,
8125 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8126 let top_level_entry = self.is_top_level_entry();
8127 self.unknown_predicate_policy = options.unknown_predicate_policy;
8128 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8129 let prior_unhandled_action_hits = std::mem::take(&mut self.unhandled_action_hits);
8130 self.clear_prediction_diagnostics();
8131 self.reset_per_parse_caches();
8132 self.reset_recognition_arena();
8133
8134 let mut decision_by_state = vec![None; atn.states().len()];
8135 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
8136 if let Some(slot) = decision_by_state.get_mut(state_number) {
8137 *slot = Some(decision);
8138 }
8139 }
8140 let mut action_index_by_state = FxHashMap::default();
8141 for &(state, index) in options.action_indices {
8142 action_index_by_state.entry(state).or_insert(index);
8143 }
8144 let mut simulator = ParserAtnSimulator::new(atn);
8145 simulator.set_track_prediction_rule_calls(!options.rule_args.is_empty());
8146 let (result, deferred_actions) = {
8147 let mut committed = CommittedAtnParser {
8148 parser: self,
8149 atn,
8150 simulator,
8151 options,
8152 decision_by_state,
8153 action_index_by_state,
8154 deferred_actions: Vec::new(),
8155 };
8156 let result = committed.parse_rule(rule_index, precedence, None, None);
8157 (result, committed.deferred_actions)
8158 };
8159
8160 if top_level_entry {
8161 self.report_generated_parser_diagnostics();
8162 }
8163 let semantic_error = self.unknown_semantic_error();
8164 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8165 self.restore_prior_unhandled_action_hits(prior_unhandled_action_hits);
8166 if top_level_entry && let Some(error) = self.take_parse_abort() {
8167 self.reset_unknown_semantic_hits();
8168 return Err(error);
8169 }
8170 if let Some(error) = semantic_error {
8171 if top_level_entry {
8172 self.reset_unknown_semantic_hits();
8173 }
8174 return Err(error);
8175 }
8176 let result = result.map(|outcome| (outcome.tree, deferred_actions));
8177 if top_level_entry && let Err(error) = &result {
8178 self.report_unrecovered_parser_error(error);
8179 }
8180 result
8181 }
8182
8183 pub fn parse_atn_rule_with_runtime_options_and_precedence(
8186 &mut self,
8187 atn: &Atn,
8188 rule_index: usize,
8189 precedence: i32,
8190 options: ParserRuntimeOptions<'_>,
8191 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8192 if !options.action_indices.is_empty() {
8193 return self.parse_atn_rule_committed_with_runtime_options(
8194 atn, rule_index, precedence, options,
8195 );
8196 }
8197 let report_unrecovered_error = self.is_top_level_entry();
8198 let ParserRuntimeOptions {
8199 init_action_rules,
8200 track_alt_numbers,
8201 track_context_alt_numbers,
8202 predicates,
8203 semantics,
8204 rule_args,
8205 member_actions,
8206 return_actions,
8207 unknown_predicate_policy,
8208 ..
8209 } = options;
8210 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
8211 if init_action_rules.is_empty()
8212 && !capture_alt_numbers
8213 && predicates.is_empty()
8214 && semantics.is_none()
8215 && rule_args.is_empty()
8216 && member_actions.is_empty()
8217 && return_actions.is_empty()
8218 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
8219 && !atn_has_observable_action_transitions(atn)
8220 && !self.semantic_hooks.observes_parser_decisions()
8221 && (!self.semantic_hooks.observes_parser_predicates()
8222 || !atn_has_predicate_transitions(atn))
8223 {
8224 return self
8225 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
8226 .map(|tree| (tree, Vec::new()));
8227 }
8228 if !self.semantic_hooks.observes_parser_decisions()
8229 && can_use_fast_predicate_recognizer(atn, &options)
8230 {
8231 self.unknown_predicate_policy = unknown_predicate_policy;
8232 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8233 let member_values = self.int_members.clone();
8234 let result = self
8235 .parse_atn_rule_with_precedence_inner(
8236 atn,
8237 rule_index,
8238 precedence,
8239 Some(FastPredicateContext {
8240 predicates,
8241 semantics,
8242 member_values: &member_values,
8243 }),
8244 AltNumberTracking {
8245 public: track_alt_numbers,
8246 context: track_context_alt_numbers,
8247 },
8248 )
8249 .map(|tree| (tree, Vec::new()));
8250 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
8251 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8252 }
8253 return result;
8254 }
8255 self.unknown_predicate_policy = unknown_predicate_policy;
8256 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8263 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
8264 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
8265 })?;
8266 let stop_state = atn
8267 .rule_to_stop_state()
8268 .get(rule_index)
8269 .filter(|state| *state != usize::MAX)
8270 .ok_or_else(|| {
8271 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
8272 })?;
8273
8274 let start_index = self.current_visible_index();
8275 self.clear_prediction_diagnostics();
8276 self.reset_per_parse_caches();
8277 self.reset_recognition_arena();
8278 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
8279 let invoking_state = self.pending_invoking_states.pop();
8280 let local_int_arg = invoking_state
8281 .and_then(|state| usize::try_from(state).ok())
8282 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
8283 let mut visiting = BTreeSet::new();
8284 let mut memo = BTreeMap::new();
8285 let mut expected = ExpectedTokens::default();
8286 let member_values = self.int_members.clone();
8287 let return_values = BTreeMap::new();
8288 let outcomes = self.recognize_state(
8289 atn,
8290 RecognizeRequest {
8291 state_number: start_state,
8292 stop_state,
8293 index: start_index,
8294 rule_start_index: start_index,
8295 decision_start_index: None,
8296 init_action_rules: &init_action_rules,
8297 predicates,
8298 semantics,
8299 rule_args,
8300 member_actions,
8301 return_actions,
8302 local_int_arg,
8303 member_values,
8304 return_values,
8305 rule_alt_number: 0,
8306 track_alt_numbers: capture_alt_numbers,
8307 consumed_eof: false,
8308 committed_decision: false,
8309 precedence,
8310 depth: 0,
8311 recovery_symbols: BTreeSet::new(),
8312 recovery_state: None,
8313 },
8314 &mut visiting,
8315 &mut memo,
8316 &mut expected,
8317 );
8318 if let Some(error) = self.unknown_semantic_error() {
8319 self.report_token_source_errors();
8320 return Err(error);
8327 }
8328 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8331 let Some(outcome) = select_best_outcome(
8332 outcomes.into_iter(),
8333 self.prediction_mode,
8334 &self.recognition_arena,
8335 ) else {
8336 let error = self.recognition_error(rule_index, start_index, &expected);
8337 self.record_syntax_errors(1);
8338 self.report_token_source_errors();
8339 if report_unrecovered_error {
8340 self.report_unrecovered_parser_error(&error);
8341 }
8342 return Err(error);
8343 };
8344
8345 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
8346 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
8347 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
8348 self.report_token_source_errors();
8349 let mut actions = outcome.actions;
8350 if init_action_rules.contains(&rule_index) {
8351 actions.insert(
8352 0,
8353 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
8354 );
8355 }
8356 let mut context =
8357 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
8358 if track_alt_numbers {
8359 context.set_alt_number(outcome.alt_number.max(1));
8360 }
8361 if track_context_alt_numbers {
8362 context.set_context_alt_number(outcome.alt_number);
8363 }
8364 for (name, value) in outcome.return_values {
8365 context.set_int_return(name, value);
8366 }
8367 if let Some(token) = self.token_id_at(start_index) {
8368 self.set_context_start(&mut context, token);
8369 }
8370 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
8371 self.set_context_stop(&mut context, token);
8372 }
8373 let live_root = if self.build_parse_trees {
8374 self.recognition_arena
8375 .fold_left_recursive_boundaries(outcome.nodes)
8376 } else {
8377 outcome.nodes
8378 };
8379 if self.build_parse_trees {
8380 let mut nodes = live_root;
8381 while let Some(link) = self.recognition_arena.link(nodes) {
8382 let child = self.arena_recognized_node_tree(
8383 link.head,
8384 track_alt_numbers,
8385 track_context_alt_numbers,
8386 )?;
8387 self.tree.add_child(&mut context, child);
8388 nodes = link.tail;
8389 }
8390 }
8391 self.finish_recognition_arena(live_root, outcome.diagnostics);
8392 self.input.seek(outcome.index);
8393
8394 let tree = self.rule_node(context);
8395 self.release_tree_scratch_if_idle();
8396 Ok((tree, actions))
8397 }
8398
8399 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
8406 let mut context = ParserRuleContext::new(rule_index, self.state());
8407 while self.la(1) != TOKEN_EOF {
8408 let token_type = self.la(1);
8409 let child = self.match_token(token_type)?;
8410 if self.build_parse_trees {
8411 self.tree.add_child(&mut context, child);
8412 }
8413 }
8414 if self.build_parse_trees {
8415 let child = self.match_eof()?;
8416 self.tree.add_child(&mut context, child);
8417 }
8418 let tree = self.rule_node(context);
8419 self.release_tree_scratch_if_idle();
8420 Ok(tree)
8421 }
8422
8423 fn recognition_error(
8426 &mut self,
8427 rule_index: usize,
8428 start_index: usize,
8429 expected: &ExpectedTokens,
8430 ) -> AntlrError {
8431 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
8432 self.input.seek(index);
8433 let current = self.input.lt(1);
8434 let line = current.as_ref().map(Token::line).unwrap_or_default();
8435 let column = current.as_ref().map(Token::column).unwrap_or_default();
8436 AntlrError::ParserError {
8437 line,
8438 column,
8439 message,
8440 offending: current.as_ref().map(Token::token_id),
8441 }
8442 }
8443
8444 fn expected_error_message(
8446 &mut self,
8447 rule_index: usize,
8448 start_index: usize,
8449 expected: &ExpectedTokens,
8450 ) -> (usize, String) {
8451 let index = expected
8452 .index
8453 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
8454 .unwrap_or_else(|| self.input.index());
8455 self.input.seek(index);
8456 let current = self.input.lt(1);
8457 let message = if expected
8458 .no_viable
8459 .as_ref()
8460 .is_some_and(|no_viable| no_viable.error_index == index)
8461 {
8462 let start = expected
8463 .no_viable
8464 .as_ref()
8465 .map_or(start_index, |no_viable| no_viable.start_index);
8466 let text = display_input_text(&self.input.text(start, index));
8467 format!("no viable alternative at input '{text}'")
8468 } else if expected.symbols.is_empty() {
8469 if expected.index.is_some() {
8470 let found = current
8471 .as_ref()
8472 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
8473 if current
8474 .as_ref()
8475 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8476 {
8477 format!(
8478 "missing {} at {found}",
8479 self.expected_symbols_display(&expected.symbols)
8480 )
8481 } else {
8482 format!("mismatched input {found}")
8483 }
8484 } else {
8485 format!("no viable alternative while parsing rule {rule_index}")
8486 }
8487 } else {
8488 format!(
8489 "mismatched input {} expecting {}",
8490 current
8491 .as_ref()
8492 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8493 self.expected_symbols_display(&expected.symbols)
8494 )
8495 };
8496 (index, message)
8497 }
8498
8499 fn child_rule_failure_recovery(
8502 &mut self,
8503 rule_index: usize,
8504 start_index: usize,
8505 sync_symbols: &BTreeSet<i32>,
8506 member_values: MemberEnv,
8507 expected: &ExpectedTokens,
8508 ) -> Option<RecognizeOutcome> {
8509 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8510 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8511 let mut next_index = error_index;
8512 loop {
8513 let symbol = self.token_type_at(next_index);
8514 if sync_symbols.contains(&symbol) {
8515 if next_index == error_index {
8516 return None;
8517 }
8518 break;
8519 }
8520 if symbol == TOKEN_EOF {
8521 break;
8522 }
8523 let after = self.consume_index(next_index, symbol);
8524 if after == next_index {
8525 break;
8526 }
8527 next_index = after;
8528 }
8529 let mut nodes = NodeSeqId::EMPTY;
8530 let error = self.arena_token_node(error_index, true);
8531 self.arena_prepend(&mut nodes, error);
8532 let diagnostics = self
8533 .recognition_arena
8534 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8535 Some(RecognizeOutcome {
8536 index: next_index,
8537 consumed_eof: false,
8538 alt_number: 0,
8539 member_values,
8540 return_values: BTreeMap::new(),
8541 diagnostics,
8542 decisions: Vec::new(),
8543 actions: Vec::new(),
8544 nodes,
8545 })
8546 }
8547
8548 fn child_rule_failure_recovery_outcomes(
8551 &mut self,
8552 request: ChildRuleFailureRecovery<'_>,
8553 ) -> Vec<RecognizeOutcome> {
8554 let sync_symbols =
8555 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
8556 self.child_rule_failure_recovery(
8557 request.rule_index,
8558 request.start_index,
8559 &sync_symbols,
8560 request.member_values,
8561 request.expected,
8562 )
8563 .into_iter()
8564 .collect()
8565 }
8566
8567 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
8569 expected_symbols_display(symbols, self.vocabulary())
8570 }
8571
8572 fn single_token_deletion(
8575 &mut self,
8576 transition: ParserTransition<'_>,
8577 index: usize,
8578 max_token_type: i32,
8579 expected_symbols: &BTreeSet<i32>,
8580 ) -> Option<(ParserDiagnostic, usize, i32)> {
8581 let current_symbol = self.token_type_at(index);
8582 if current_symbol == TOKEN_EOF {
8583 return None;
8584 }
8585 let next_index = self.consume_index(index, current_symbol);
8586 if next_index == index {
8587 return None;
8588 }
8589 let next_symbol = self.token_type_at(next_index);
8590 if !transition.matches(next_symbol, 1, max_token_type) {
8591 return None;
8592 }
8593 let transition_expected = transition_expected_symbols(transition, max_token_type);
8594 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8595 &transition_expected
8596 } else {
8597 expected_symbols
8598 });
8599 let current = self.token_at(index);
8600 let message = format!(
8601 "extraneous input {} expecting {expected_display}",
8602 current
8603 .as_ref()
8604 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8605 );
8606 Some((
8607 diagnostic_for_token(current, message),
8608 next_index,
8609 next_symbol,
8610 ))
8611 }
8612
8613 fn current_token_deletion(
8616 &mut self,
8617 index: usize,
8618 expected_symbols: &BTreeSet<i32>,
8619 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
8620 if expected_symbols.is_empty() {
8621 return None;
8622 }
8623 let current_symbol = self.token_type_at(index);
8624 if current_symbol == TOKEN_EOF {
8625 return None;
8626 }
8627 let current = self.token_at(index);
8628 let message = format!(
8629 "extraneous input {} expecting {}",
8630 current
8631 .as_ref()
8632 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8633 self.expected_symbols_display(expected_symbols)
8634 );
8635 let diagnostic = diagnostic_for_token(current, message);
8636 let mut skipped = Vec::new();
8637 let mut cursor = index;
8638 loop {
8639 let symbol = self.token_type_at(cursor);
8640 if symbol == TOKEN_EOF {
8641 return None;
8642 }
8643 skipped.push(cursor);
8644 let next_index = self.consume_index(cursor, symbol);
8645 if next_index == cursor {
8646 return None;
8647 }
8648 let next_symbol = self.token_type_at(next_index);
8649 if expected_symbols.contains(&next_symbol) {
8650 return Some((diagnostic, next_index, skipped));
8651 }
8652 cursor = next_index;
8653 }
8654 }
8655
8656 fn single_token_insertion(
8660 &mut self,
8661 transition: ParserTransition<'_>,
8662 index: usize,
8663 max_token_type: i32,
8664 expected_symbols: &BTreeSet<i32>,
8665 follow_symbols: &BTreeSet<i32>,
8666 ) -> Option<(ParserDiagnostic, i32, String)> {
8667 let current_symbol = self.token_type_at(index);
8668 if !follow_symbols.contains(¤t_symbol) {
8669 return None;
8670 }
8671 let transition_expected = transition_expected_symbols(transition, max_token_type);
8672 let token_type = transition_expected.iter().next().copied()?;
8673 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8674 &transition_expected
8675 } else {
8676 expected_symbols
8677 });
8678 let mut token_symbols = BTreeSet::new();
8679 token_symbols.insert(token_type);
8680 let missing_token_display = self.expected_symbols_display(&token_symbols);
8681 let current = self.token_at(index);
8682 let message = format!(
8683 "missing {expected_display} at {}",
8684 current
8685 .as_ref()
8686 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8687 );
8688 let text = format!("<missing {missing_token_display}>");
8689 Some((
8690 diagnostic_for_token(current.as_ref(), message),
8691 token_type,
8692 text,
8693 ))
8694 }
8695
8696 fn fast_single_token_deletion_recovery(
8700 &mut self,
8701 recovery: FastRecoveryRequest<'_, '_>,
8702 predicate_context: Option<FastPredicateContext<'_>>,
8703 ) -> Vec<FastRecognizeOutcome> {
8704 let FastRecoveryRequest {
8705 atn,
8706 transition,
8707 expected_symbols,
8708 target,
8709 request,
8710 visiting,
8711 memo,
8712 expected,
8713 } = recovery;
8714 let FastRecognizeRequest {
8715 stop_state,
8716 index,
8717 rule_start_index,
8718 decision_start_index,
8719 precedence,
8720 depth,
8721 ..
8722 } = request;
8723 let Some((diagnostic, next_index, next_symbol)) =
8724 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8725 else {
8726 return Vec::new();
8727 };
8728 let after_next = self.consume_index(next_index, next_symbol);
8729 let empty_recovery = self.empty_recovery_symbols();
8730 self.recognize_state_fast(
8731 atn,
8732 FastRecognizeRequest {
8733 state_number: target,
8734 stop_state,
8735 index: after_next,
8736 rule_start_index,
8737 decision_start_index,
8738 precedence,
8739 depth: depth + 1,
8740 recovery_symbols: empty_recovery,
8741 recovery_state: None,
8742 },
8743 FastRecognizeScratch {
8744 predicate_context,
8745 visiting,
8746 memo,
8747 expected,
8748 native_depth: 0,
8749 },
8750 )
8751 .into_iter()
8752 .map(|mut outcome| {
8753 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
8754 outcome.diagnostics = self
8755 .recognition_arena
8756 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8757 if self.fast_token_nodes_enabled {
8758 let token = self.arena_token_node(next_index, false);
8759 self.defer_fast_outcome_node(&mut outcome, token);
8760 let error = self.arena_token_node(index, true);
8761 self.defer_fast_outcome_node(&mut outcome, error);
8762 }
8763 outcome
8764 })
8765 .collect()
8766 }
8767
8768 fn fast_single_token_insertion_recovery(
8772 &mut self,
8773 recovery: FastRecoveryRequest<'_, '_>,
8774 predicate_context: Option<FastPredicateContext<'_>>,
8775 ) -> Vec<FastRecognizeOutcome> {
8776 let FastRecoveryRequest {
8777 atn,
8778 transition,
8779 expected_symbols,
8780 target,
8781 request,
8782 visiting,
8783 memo,
8784 expected,
8785 } = recovery;
8786 let FastRecognizeRequest {
8787 stop_state,
8788 index,
8789 rule_start_index,
8790 decision_start_index,
8791 precedence,
8792 depth,
8793 ..
8794 } = request;
8795 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
8796 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
8797 transition,
8798 index,
8799 atn.max_token_type(),
8800 &expected_symbols,
8801 &follow_symbols,
8802 ) else {
8803 return Vec::new();
8804 };
8805 let empty_recovery = self.empty_recovery_symbols();
8806 self.recognize_state_fast(
8807 atn,
8808 FastRecognizeRequest {
8809 state_number: target,
8810 stop_state,
8811 index,
8812 rule_start_index,
8813 decision_start_index,
8814 precedence,
8815 depth: depth + 1,
8816 recovery_symbols: empty_recovery,
8817 recovery_state: None,
8818 },
8819 FastRecognizeScratch {
8820 predicate_context,
8821 visiting,
8822 memo,
8823 expected,
8824 native_depth: 0,
8825 },
8826 )
8827 .into_iter()
8828 .map(|mut outcome| {
8829 outcome.diagnostics = self
8830 .recognition_arena
8831 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8832 let missing = self.arena_missing_token_node(token_type, index, text.clone());
8833 self.defer_fast_outcome_node(&mut outcome, missing);
8834 outcome
8835 })
8836 .collect()
8837 }
8838
8839 fn fast_current_token_deletion_recovery(
8842 &mut self,
8843 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
8844 predicate_context: Option<FastPredicateContext<'_>>,
8845 ) -> Vec<FastRecognizeOutcome> {
8846 let FastCurrentTokenDeletionRequest {
8847 atn,
8848 expected_symbols,
8849 mut request,
8850 visiting,
8851 memo,
8852 expected,
8853 } = recovery;
8854 if request.index == request.rule_start_index {
8855 return Vec::new();
8856 }
8857 let Some((diagnostic, next_index, skipped)) =
8858 self.current_token_deletion(request.index, &expected_symbols)
8859 else {
8860 return Vec::new();
8861 };
8862 request.state_number = request.recovery_state.unwrap_or(request.state_number);
8863 request.index = next_index;
8864 request.depth += 1;
8865 request.recovery_state = None;
8866 self.recognize_state_fast(
8867 atn,
8868 request,
8869 FastRecognizeScratch {
8870 predicate_context,
8871 visiting,
8872 memo,
8873 expected,
8874 native_depth: 0,
8875 },
8876 )
8877 .into_iter()
8878 .map(|mut outcome| {
8879 outcome.diagnostics = self
8880 .recognition_arena
8881 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8882 for index in skipped.iter().rev() {
8883 let error = self.arena_token_node(*index, true);
8884 self.defer_fast_outcome_node(&mut outcome, error);
8885 }
8886 outcome
8887 })
8888 .collect()
8889 }
8890
8891 fn fast_child_rule_failure_recovery(
8894 &mut self,
8895 rule_index: usize,
8896 start_index: usize,
8897 sync_symbols: &BTreeSet<i32>,
8898 expected: &ExpectedTokens,
8899 ) -> Option<FastRecognizeOutcome> {
8900 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8901 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8902 let mut next_index = error_index;
8903 loop {
8904 let symbol = self.token_type_at(next_index);
8905 if sync_symbols.contains(&symbol) {
8906 if next_index == error_index {
8907 return None;
8908 }
8909 break;
8910 }
8911 if symbol == TOKEN_EOF {
8912 break;
8913 }
8914 let after = self.consume_index(next_index, symbol);
8915 if after == next_index {
8916 break;
8917 }
8918 next_index = after;
8919 }
8920 let diagnostics = self
8921 .recognition_arena
8922 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8923 let mut nodes = NodeSeqId::EMPTY;
8924 if self.fast_token_nodes_enabled {
8925 let error = self.arena_token_node(error_index, true);
8926 self.arena_prepend(&mut nodes, error);
8927 }
8928 Some(FastRecognizeOutcome {
8929 index: next_index,
8930 consumed_eof: false,
8931 diagnostics,
8932 deferred_nodes: FastDeferredNodeId::EMPTY,
8933 nodes,
8934 })
8935 }
8936
8937 fn fast_child_rule_failure_recovery_outcomes(
8940 &mut self,
8941 request: FastChildRuleFailureRecoveryRequest<'_>,
8942 ) -> Vec<FastRecognizeOutcome> {
8943 let FastChildRuleFailureRecoveryRequest {
8944 atn,
8945 rule_index,
8946 start_index,
8947 follow_state,
8948 stop_state,
8949 expected,
8950 } = request;
8951 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
8952 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
8953 .into_iter()
8954 .collect()
8955 }
8956
8957 fn defer_fast_outcome_node(
8958 &mut self,
8959 outcome: &mut FastRecognizeOutcome,
8960 node: RecognizedNodeId,
8961 ) {
8962 if outcome.deferred_nodes.is_empty() {
8963 self.arena_prepend(&mut outcome.nodes, node);
8964 return;
8965 }
8966 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
8967 let fragment = self.recognition_arena.deferred_fragment(fragment);
8968 outcome.deferred_nodes = self
8969 .recognition_arena
8970 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
8971 }
8972
8973 fn defer_fast_outcome_alternative(
8974 &mut self,
8975 outcome: &mut FastRecognizeOutcome,
8976 alt_number: usize,
8977 ) {
8978 let alternative = self.recognition_arena.deferred_alternative(alt_number);
8979 outcome.deferred_nodes = self
8980 .recognition_arena
8981 .concat_deferred_nodes(alternative, outcome.deferred_nodes);
8982 }
8983
8984 fn defer_fast_outcome_boundary(
8985 &mut self,
8986 outcome: &mut FastRecognizeOutcome,
8987 rule_index: usize,
8988 ) {
8989 let boundary = self
8990 .recognition_arena
8991 .deferred_left_recursive_boundary(rule_index);
8992 outcome.deferred_nodes = self
8993 .recognition_arena
8994 .concat_deferred_nodes(boundary, outcome.deferred_nodes);
8995 }
8996
8997 fn materialize_fast_deferred_nodes(
8998 &mut self,
8999 root: FastDeferredNodeId,
9000 initial_suffix: NodeSeqId,
9001 ) -> (NodeSeqId, usize) {
9002 if root.is_empty() {
9003 return (initial_suffix, 0);
9004 }
9005
9006 enum Frame {
9007 Visit(FastDeferredNodeId),
9008 ContinuePrefix(FastDeferredNodeId),
9009 FinishRule {
9010 rule: FastDeferredRule,
9011 parent_suffix: NodeSeqId,
9012 parent_alt_number: u32,
9013 parent_pending_boundary: Option<RecognizedNodeId>,
9014 },
9015 }
9016
9017 let mut result = initial_suffix;
9018 let mut alt_number = 0;
9022 let mut pending_boundary = None;
9023 let mut pending = Vec::with_capacity(16);
9024 pending.push(Frame::Visit(root));
9025 let mut fragment_nodes = Vec::new();
9026 while let Some(frame) = pending.pop() {
9027 match frame {
9028 Frame::Visit(deferred) => {
9029 if deferred.is_empty() {
9030 continue;
9031 }
9032
9033 match self.recognition_arena.deferred_node(deferred) {
9034 FastDeferredNode::Fragment(sequence) => {
9035 fragment_nodes.clear();
9036 fragment_nodes.extend(self.recognition_arena.iter(sequence));
9037 while let Some(node) = fragment_nodes.pop() {
9038 self.arena_prepend(&mut result, node);
9039 }
9040 }
9041 FastDeferredNode::Rule(rule) => {
9042 let rule = self.recognition_arena.deferred_rule(rule);
9043 let parent_suffix = result;
9044 let parent_alt_number = alt_number;
9045 let parent_pending_boundary = pending_boundary;
9046 result = rule.children;
9047 alt_number = 0;
9048 pending_boundary = None;
9049 pending.push(Frame::FinishRule {
9050 rule,
9051 parent_suffix,
9052 parent_alt_number,
9053 parent_pending_boundary,
9054 });
9055 pending.push(Frame::Visit(rule.deferred_children));
9056 }
9057 FastDeferredNode::Alternative(selected) => {
9058 if let Some(boundary) = pending_boundary {
9059 self.recognition_arena
9060 .set_boundary_alt_number(boundary, selected);
9061 } else {
9062 alt_number = selected;
9063 }
9064 }
9065 FastDeferredNode::LeftRecursiveBoundary { rule_index } => {
9066 let boundary = self.arena_boundary_node(rule_index as usize, 0);
9067 self.arena_prepend(&mut result, boundary);
9068 pending_boundary = Some(boundary);
9069 }
9070 FastDeferredNode::Concat {
9071 prefix,
9072 suffix: deferred_suffix,
9073 } => {
9074 pending.push(Frame::ContinuePrefix(prefix));
9075 pending.push(Frame::Visit(deferred_suffix));
9076 }
9077 }
9078 }
9079 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
9080 Frame::FinishRule {
9081 rule,
9082 parent_suffix,
9083 parent_alt_number,
9084 parent_pending_boundary,
9085 } => {
9086 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
9087 rule_index: rule.rule_index,
9088 invoking_state: rule.invoking_state,
9089 alt_number,
9090 start_index: rule.start_index,
9091 stop_index: rule.stop_index,
9092 return_values: None,
9093 children: result,
9094 });
9095 result = parent_suffix;
9096 self.arena_prepend(&mut result, node);
9097 alt_number = parent_alt_number;
9098 pending_boundary = parent_pending_boundary;
9099 }
9100 }
9101 }
9102 (result, alt_number as usize)
9103 }
9104
9105 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) -> usize {
9106 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
9107 let (nodes, alt_number) =
9108 self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
9109 outcome.nodes = nodes;
9110 alt_number
9111 }
9112
9113 fn recognize_repetition_fast(
9116 &mut self,
9117 atn: &Atn,
9118 request: &FastRecognizeRequest,
9119 shape: FastRepetitionShape,
9120 scratch: FastRecognizeScratch<'_, '_>,
9121 ) -> Vec<FastRecognizeOutcome> {
9122 let FastRecognizeScratch {
9123 predicate_context,
9124 visiting,
9125 memo,
9126 expected,
9127 native_depth,
9128 } = scratch;
9129 let lookahead = if self.fast_first_set_prefilter {
9130 atn.state(request.state_number).and_then(|state| {
9131 state
9132 .rule_index()
9133 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9134 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
9135 })
9136 } else {
9137 None
9138 };
9139 let (enter_alt_number, exit_alt_number) = if self.fast_track_alt_numbers {
9140 let state = atn
9141 .state(request.state_number)
9142 .expect("repetition request state must exist");
9143 (
9144 next_alt_number(state, 2, shape.enter_transition_index, 0, true),
9145 next_alt_number(state, 2, shape.exit_transition_index, 0, true),
9146 )
9147 } else {
9148 (0, 0)
9149 };
9150 let mut work = Vec::with_capacity(2);
9151 push_fast_repetition_work(
9152 &mut work,
9153 shape,
9154 FastRepetitionPath {
9155 index: request.index,
9156 deferred_nodes: FastDeferredNodeId::EMPTY,
9157 diagnostics: DiagnosticSeqId::EMPTY,
9158 consumed_eof: false,
9159 },
9160 lookahead.as_deref(),
9161 self.token_type_at(request.index),
9162 );
9163 let mut coordinates = FastRepetitionCoordinates::new(request.index);
9164 let mut outcomes = Vec::new();
9165 while let Some(item) = work.pop() {
9166 match item {
9167 FastRepetitionWork::Enter(path) => {
9168 if !coordinates.insert_entered(path) {
9169 continue;
9170 }
9171 let path_nodes = if enter_alt_number == 0 {
9172 path.deferred_nodes
9173 } else {
9174 let alternative = self
9175 .recognition_arena
9176 .deferred_alternative(enter_alt_number);
9177 self.recognition_arena
9178 .concat_deferred_nodes(path.deferred_nodes, alternative)
9179 };
9180 let body_outcomes = self.recognize_state_fast(
9181 atn,
9182 FastRecognizeRequest {
9183 state_number: shape.enter_target,
9184 stop_state: shape.body_stop_state,
9185 index: path.index,
9186 rule_start_index: request.rule_start_index,
9187 decision_start_index: request.decision_start_index,
9188 precedence: request.precedence,
9189 depth: request.depth.saturating_add(1),
9190 recovery_symbols: Rc::clone(&request.recovery_symbols),
9191 recovery_state: request.recovery_state,
9192 },
9193 FastRecognizeScratch {
9194 predicate_context,
9195 visiting: &mut *visiting,
9196 memo: &mut *memo,
9197 expected: &mut *expected,
9198 native_depth: native_depth + 1,
9199 },
9200 );
9201 for body in body_outcomes.into_iter().rev() {
9202 if body.index <= path.index {
9206 continue;
9207 }
9208 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
9209 let body_nodes = self
9210 .recognition_arena
9211 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
9212 let deferred_nodes = self
9213 .recognition_arena
9214 .concat_deferred_nodes(path_nodes, body_nodes);
9215 let next_path = FastRepetitionPath {
9216 index: body.index,
9217 deferred_nodes,
9218 diagnostics: self
9219 .recognition_arena
9220 .concat_diagnostics(path.diagnostics, body.diagnostics),
9221 consumed_eof: path.consumed_eof || body.consumed_eof,
9222 };
9223 let symbol = self.token_type_at(next_path.index);
9224 push_fast_repetition_work(
9225 &mut work,
9226 shape,
9227 next_path,
9228 lookahead.as_deref(),
9229 symbol,
9230 );
9231 }
9232 }
9233 FastRepetitionWork::Exit(path) => {
9234 if !coordinates.insert_exited(path) {
9235 continue;
9236 }
9237 let path_nodes = if exit_alt_number == 0 {
9238 path.deferred_nodes
9239 } else {
9240 let alternative =
9241 self.recognition_arena.deferred_alternative(exit_alt_number);
9242 self.recognition_arena
9243 .concat_deferred_nodes(path.deferred_nodes, alternative)
9244 };
9245 let suffixes = self.recognize_state_fast(
9246 atn,
9247 FastRecognizeRequest {
9248 state_number: shape.exit_target,
9249 stop_state: request.stop_state,
9250 index: path.index,
9251 rule_start_index: request.rule_start_index,
9252 decision_start_index: request.decision_start_index,
9253 precedence: request.precedence,
9254 depth: request.depth.saturating_add(1),
9255 recovery_symbols: Rc::clone(&request.recovery_symbols),
9256 recovery_state: request.recovery_state,
9257 },
9258 FastRecognizeScratch {
9259 predicate_context,
9260 visiting: &mut *visiting,
9261 memo: &mut *memo,
9262 expected: &mut *expected,
9263 native_depth: native_depth + 1,
9264 },
9265 );
9266 for mut outcome in suffixes {
9267 outcome.deferred_nodes = self
9268 .recognition_arena
9269 .concat_deferred_nodes(path_nodes, outcome.deferred_nodes);
9270 outcome.diagnostics = self
9271 .recognition_arena
9272 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
9273 outcome.consumed_eof |= path.consumed_eof;
9274 outcomes.push(outcome);
9275 }
9276 }
9277 }
9278 }
9279 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9280 outcomes
9281 }
9282
9283 fn recognize_state_fast(
9286 &mut self,
9287 atn: &Atn,
9288 request: FastRecognizeRequest,
9289 scratch: FastRecognizeScratch<'_, '_>,
9290 ) -> Vec<FastRecognizeOutcome> {
9291 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
9292 return self.recognize_state_fast_inner(atn, request, scratch);
9293 }
9294 self.recognize_state_fast_checked(atn, request, scratch)
9295 }
9296
9297 #[inline(never)]
9298 fn recognize_state_fast_checked(
9299 &mut self,
9300 atn: &Atn,
9301 request: FastRecognizeRequest,
9302 mut scratch: FastRecognizeScratch<'_, '_>,
9303 ) -> Vec<FastRecognizeOutcome> {
9304 scratch.native_depth = 1;
9305 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
9306 self.recognize_state_fast_inner(atn, request, scratch)
9307 })
9308 }
9309
9310 #[allow(clippy::too_many_lines)]
9311 fn recognize_state_fast_inner(
9312 &mut self,
9313 atn: &Atn,
9314 request: FastRecognizeRequest,
9315 scratch: FastRecognizeScratch<'_, '_>,
9316 ) -> Vec<FastRecognizeOutcome> {
9317 #[cfg(feature = "perf-counters")]
9318 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
9319 let FastRecognizeScratch {
9320 predicate_context,
9321 visiting,
9322 memo,
9323 expected,
9324 native_depth,
9325 } = scratch;
9326 let FastRecognizeRequest {
9327 mut state_number,
9328 stop_state,
9329 mut index,
9330 rule_start_index,
9331 decision_start_index,
9332 precedence,
9333 mut depth,
9334 recovery_symbols,
9335 recovery_state,
9336 } = request;
9337 let max_token_type = atn.max_token_type();
9338 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
9357 let mut inline_consumed_eof = false;
9358 loop {
9359 if depth > RECOGNITION_DEPTH_LIMIT {
9360 return Vec::new();
9361 }
9362 if state_number == stop_state {
9363 let mut nodes = NodeSeqId::EMPTY;
9364 if self.fast_token_nodes_enabled {
9365 for token_index in inline_consumed_tokens.iter().rev() {
9366 let token = self.arena_token_node(*token_index, false);
9367 self.arena_prepend(&mut nodes, token);
9368 }
9369 }
9370 return vec![FastRecognizeOutcome {
9371 index,
9372 consumed_eof: inline_consumed_eof,
9373 diagnostics: DiagnosticSeqId::EMPTY,
9374 deferred_nodes: FastDeferredNodeId::EMPTY,
9375 nodes,
9376 }];
9377 }
9378 let Some(state) = atn.state(state_number) else {
9379 return Vec::new();
9380 };
9381 let transitions = state.transitions();
9382 if transitions.len() == 1 && !state.precedence_rule_decision() {
9383 let transition = transitions
9384 .first()
9385 .expect("single transition checked above");
9386 let transition_kind = transition.kind();
9387 let target = transition.target();
9388 match transition_kind {
9389 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
9390 if left_recursive_boundary(atn, state, target).is_none() =>
9391 {
9392 #[cfg(feature = "perf-counters")]
9393 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9394 state_number = target;
9395 depth += 1;
9396 continue;
9397 }
9398 ParserTransitionKind::Predicate
9399 if left_recursive_boundary(atn, state, target).is_none() =>
9400 {
9401 #[cfg(feature = "perf-counters")]
9402 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9403 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
9404 {
9405 record_predicate_no_viable(expected, decision_start_index, index);
9406 return Vec::new();
9407 }
9408 state_number = target;
9409 depth += 1;
9410 continue;
9411 }
9412 ParserTransitionKind::Precedence
9413 if packed_i32(transition.arg0()) >= precedence
9414 && left_recursive_boundary(atn, state, target).is_none() =>
9415 {
9416 #[cfg(feature = "perf-counters")]
9417 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9418 state_number = target;
9419 depth += 1;
9420 continue;
9421 }
9422 ParserTransitionKind::Atom
9432 | ParserTransitionKind::Range
9433 | ParserTransitionKind::Set
9434 | ParserTransitionKind::NotSet
9435 | ParserTransitionKind::Wildcard
9436 if !self.fast_recovery_enabled =>
9437 {
9438 let symbol = self.token_type_at(index);
9439 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9440 #[cfg(feature = "perf-counters")]
9441 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9442 if self.fast_token_nodes_enabled {
9443 inline_consumed_tokens.push(index);
9444 }
9445 inline_consumed_eof |= symbol == TOKEN_EOF;
9446 index = self.consume_index(index, symbol);
9447 state_number = target;
9448 depth += 1;
9449 continue;
9450 }
9451 }
9454 _ => {}
9455 }
9456 }
9457 break;
9458 }
9459 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
9463 let Some(state) = atn.state(state_number) else {
9464 return Vec::new();
9465 };
9466 let transitions = state.transitions();
9467 let transition_count = transitions.len();
9468 if !self.fast_recovery_enabled
9469 && let Some(shape) = fast_repetition_shape(atn, state)
9470 {
9471 let mut outcomes = self.recognize_repetition_fast(
9472 atn,
9473 &FastRecognizeRequest {
9474 state_number,
9475 stop_state,
9476 index,
9477 rule_start_index,
9478 decision_start_index,
9479 precedence,
9480 depth,
9481 recovery_symbols: Rc::clone(&recovery_symbols),
9482 recovery_state,
9483 },
9484 shape,
9485 FastRecognizeScratch {
9486 predicate_context,
9487 visiting: &mut *visiting,
9488 memo: &mut *memo,
9489 expected: &mut *expected,
9490 native_depth: native_depth + 1,
9491 },
9492 );
9493 if inline_pending {
9494 for outcome in &mut outcomes {
9495 outcome.consumed_eof |= inline_consumed_eof;
9496 if self.fast_token_nodes_enabled {
9497 for token_index in inline_consumed_tokens.iter().rev() {
9498 let token = self.arena_token_node(*token_index, false);
9499 self.defer_fast_outcome_node(outcome, token);
9500 }
9501 }
9502 }
9503 }
9504 return outcomes;
9505 }
9506 let key = if self.fast_recovery_enabled {
9516 FastRecognizeKey {
9517 state_number,
9518 stop_state,
9519 index,
9520 rule_start_index,
9521 decision_start_index,
9522 precedence,
9523 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
9524 recovery_state,
9525 }
9526 } else {
9527 FastRecognizeKey {
9528 state_number,
9529 stop_state,
9530 index,
9531 rule_start_index: 0,
9532 decision_start_index: None,
9533 precedence,
9534 recovery_symbols_id: 0,
9535 recovery_state: None,
9536 }
9537 };
9538 let memo_lookup_enabled = self.fast_recovery_enabled
9543 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
9544 if memo_lookup_enabled {
9545 if let Some(outcomes) = memo.get(&key) {
9546 #[cfg(feature = "perf-counters")]
9547 {
9548 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
9549 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
9550 }
9551 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
9555 let inline_eof = inline_consumed_eof;
9556 let inline_tokens = &inline_consumed_tokens;
9557 return outcomes
9558 .iter()
9559 .copied()
9560 .map(|mut outcome| {
9561 if inline_eof {
9562 outcome.consumed_eof = true;
9563 }
9564 if self.fast_token_nodes_enabled {
9565 for token_index in inline_tokens.iter().rev() {
9566 let token = self.arena_token_node(*token_index, false);
9567 self.defer_fast_outcome_node(&mut outcome, token);
9568 }
9569 }
9570 outcome
9571 })
9572 .collect();
9573 }
9574 return outcomes.to_vec();
9575 }
9576 #[cfg(feature = "perf-counters")]
9577 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
9578 }
9579
9580 let needs_cycle_guard = if self.fast_recovery_enabled {
9585 transitions.iter().any(ParserTransition::is_epsilon)
9586 } else {
9587 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
9588 };
9589 #[cfg(feature = "perf-counters")]
9590 if needs_cycle_guard {
9591 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
9592 } else {
9593 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
9594 match state
9595 .transitions()
9596 .first()
9597 .expect("single-transition path requires one transition")
9598 .data()
9599 {
9600 Transition::Rule { .. } => {
9601 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
9602 }
9603 Transition::Atom { .. }
9604 | Transition::Range { .. }
9605 | Transition::Set { .. }
9606 | Transition::NotSet { .. }
9607 | Transition::Wildcard { .. } => {
9608 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
9609 }
9610 _ => {
9611 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
9612 }
9613 }
9614 }
9615 let has_inserted_cycle_guard = if needs_cycle_guard {
9616 if !visiting.insert(key.clone()) {
9617 #[cfg(feature = "perf-counters")]
9618 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
9619 return Vec::new();
9620 }
9621 true
9622 } else {
9623 false
9624 };
9625 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9626 Some(index)
9627 } else {
9628 decision_start_index
9629 };
9630 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
9631 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
9632 } else {
9633 (Rc::clone(&recovery_symbols), recovery_state)
9634 };
9635
9636 let lookahead_filter = if transition_count > 1
9655 && self.fast_first_set_prefilter
9656 && !state.precedence_rule_decision()
9657 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
9658 {
9659 state
9660 .rule_index()
9661 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9662 .map(|rule_stop| {
9663 let symbol = self.token_type_at(index);
9664 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
9665 (symbol, entry)
9666 })
9667 } else {
9668 None
9669 };
9670 let ll1_only_alt: Option<usize> = if transition_count > 1
9679 && let Some((symbol, entry)) = lookahead_filter.as_ref()
9680 {
9681 let key = (state.state_number(), *symbol);
9682 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
9683 cached
9684 } else {
9685 let result = ll1_unique_alt(entry, *symbol);
9686 self.ll1_decision_cache.insert(key, result);
9687 result
9688 }
9689 } else {
9690 None
9691 };
9692 let lookahead_filter = lookahead_filter.as_ref();
9693 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
9699 for (transition_index, transition) in transitions.iter().enumerate() {
9700 if let Some(alt) = ll1_only_alt {
9701 if alt != transition_index {
9703 continue;
9704 }
9705 }
9706 let transition_kind = transition.kind();
9707 if ll1_only_alt.is_none()
9708 && should_skip_via_lookahead(
9709 transition_kind,
9710 transition_index,
9711 lookahead_filter,
9712 index,
9713 self.fast_recovery_enabled,
9714 expected,
9715 )
9716 {
9717 continue;
9718 }
9719 let target = transition.target();
9720 let outcomes_before_transition = outcomes.len();
9721 let left_recursive_boundary = match transition_kind {
9722 ParserTransitionKind::Epsilon
9723 | ParserTransitionKind::Action
9724 | ParserTransitionKind::Predicate
9725 | ParserTransitionKind::Precedence => left_recursive_boundary(atn, state, target),
9726 ParserTransitionKind::Atom
9727 | ParserTransitionKind::Range
9728 | ParserTransitionKind::Set
9729 | ParserTransitionKind::NotSet
9730 | ParserTransitionKind::Wildcard
9731 | ParserTransitionKind::Rule => None,
9732 };
9733 match transition_kind {
9734 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
9735 #[cfg(feature = "perf-counters")]
9736 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9737 outcomes.extend(self.recognize_state_fast(
9738 atn,
9739 FastRecognizeRequest {
9740 state_number: target,
9741 stop_state,
9742 index,
9743 rule_start_index,
9744 decision_start_index: next_decision_start_index,
9745 precedence,
9746 depth: depth + 1,
9747 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9748 recovery_state: epsilon_recovery_state,
9749 },
9750 FastRecognizeScratch {
9751 predicate_context,
9752 visiting,
9753 memo,
9754 expected,
9755 native_depth: native_depth + 1,
9756 },
9757 ));
9758 }
9759 ParserTransitionKind::Predicate => {
9760 #[cfg(feature = "perf-counters")]
9761 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9762 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
9763 outcomes.extend(self.recognize_state_fast(
9764 atn,
9765 FastRecognizeRequest {
9766 state_number: target,
9767 stop_state,
9768 index,
9769 rule_start_index,
9770 decision_start_index: next_decision_start_index,
9771 precedence,
9772 depth: depth + 1,
9773 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9774 recovery_state: epsilon_recovery_state,
9775 },
9776 FastRecognizeScratch {
9777 predicate_context,
9778 visiting,
9779 memo,
9780 expected,
9781 native_depth: native_depth + 1,
9782 },
9783 ));
9784 } else {
9785 record_predicate_no_viable(expected, next_decision_start_index, index);
9786 }
9787 }
9788 ParserTransitionKind::Precedence => {
9789 let transition_precedence = packed_i32(transition.arg0());
9790 if transition_precedence >= precedence {
9791 outcomes.extend(self.recognize_state_fast(
9792 atn,
9793 FastRecognizeRequest {
9794 state_number: target,
9795 stop_state,
9796 index,
9797 rule_start_index,
9798 decision_start_index: next_decision_start_index,
9799 precedence,
9800 depth: depth + 1,
9801 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9802 recovery_state: epsilon_recovery_state,
9803 },
9804 FastRecognizeScratch {
9805 predicate_context,
9806 visiting,
9807 memo,
9808 expected,
9809 native_depth: native_depth + 1,
9810 },
9811 ));
9812 }
9813 }
9814 ParserTransitionKind::Rule => {
9815 let rule_index = transition.arg0() as usize;
9816 let follow_state = transition.arg1() as usize;
9817 let rule_precedence = packed_i32(transition.arg2());
9818 #[cfg(feature = "perf-counters")]
9819 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
9820 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
9821 continue;
9822 };
9823 let symbol = self.token_type_at(index);
9835 if self.fast_first_set_prefilter {
9836 let first = self.cached_rule_first_set(atn, target, child_stop);
9849 if should_skip_rule_via_first_set(
9850 &first,
9851 symbol,
9852 self.fast_recovery_enabled,
9853 index,
9854 expected,
9855 ) {
9856 continue;
9857 }
9858 }
9859 let expected_before_child =
9860 self.fast_recovery_enabled.then(|| expected.clone());
9861 let mut children = self.recognize_state_fast(
9862 atn,
9863 FastRecognizeRequest {
9864 state_number: target,
9865 stop_state: child_stop,
9866 index,
9867 rule_start_index: index,
9868 decision_start_index: None,
9869 precedence: rule_precedence,
9870 depth: depth + 1,
9871 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9872 recovery_state: epsilon_recovery_state,
9873 },
9874 FastRecognizeScratch {
9875 predicate_context,
9876 visiting,
9877 memo,
9878 expected,
9879 native_depth: native_depth + 1,
9880 },
9881 );
9882 if children.is_empty() && self.fast_recovery_enabled {
9883 children = self.fast_child_rule_failure_recovery_outcomes(
9884 FastChildRuleFailureRecoveryRequest {
9885 atn,
9886 rule_index,
9887 start_index: index,
9888 follow_state,
9889 stop_state,
9890 expected,
9891 },
9892 );
9893 }
9894 if let Some(expected_before_child) = expected_before_child {
9895 if children
9896 .iter()
9897 .any(|child| child.diagnostics.is_empty() && child.index > index)
9898 {
9899 *expected = expected_before_child;
9900 }
9901 }
9902 for child in children {
9903 let child_index = child.index;
9904 let child_consumed_eof = child.consumed_eof;
9905 let child_diagnostics = child.diagnostics;
9906 let empty_recovery = self.empty_recovery_symbols();
9907 let follow_outcomes = self.recognize_state_fast(
9908 atn,
9909 FastRecognizeRequest {
9910 state_number: follow_state,
9911 stop_state,
9912 index: child_index,
9913 rule_start_index,
9914 decision_start_index: next_decision_start_index,
9915 precedence,
9916 depth: depth + 1,
9917 recovery_symbols: empty_recovery,
9918 recovery_state: None,
9919 },
9920 FastRecognizeScratch {
9921 predicate_context,
9922 visiting,
9923 memo,
9924 expected,
9925 native_depth: native_depth + 1,
9926 },
9927 );
9928 if follow_outcomes.is_empty() {
9929 continue;
9930 }
9931 let child_stop_index =
9932 self.rule_stop_token_index(child_index, child_consumed_eof);
9933 let child_node = self.build_parse_trees.then(|| {
9934 self.recognition_arena.deferred_rule_node(FastDeferredRule {
9935 rule_index: u32::try_from(rule_index)
9936 .expect("rule index fits in u32"),
9937 invoking_state: i32::try_from(invoking_state_number(state_number))
9938 .expect("invoking state fits in i32"),
9939 start_index: u32::try_from(index)
9940 .expect("rule start index fits in u32"),
9941 stop_index: child_stop_index.map(|stop_index| {
9942 u32::try_from(stop_index).expect("rule stop index fits in u32")
9943 }),
9944 deferred_children: child.deferred_nodes,
9945 children: child.nodes,
9946 })
9947 });
9948 let child_diags_empty = child_diagnostics.is_empty();
9949 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
9950 outcome.consumed_eof |= child_consumed_eof;
9951 if !child_diags_empty {
9954 outcome.diagnostics = self
9955 .recognition_arena
9956 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
9957 }
9958 if let Some(child_node) = child_node {
9959 outcome.deferred_nodes = self
9960 .recognition_arena
9961 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
9962 }
9963 outcome
9964 }));
9965 }
9966 }
9967 ParserTransitionKind::Atom
9968 | ParserTransitionKind::Range
9969 | ParserTransitionKind::Set
9970 | ParserTransitionKind::NotSet
9971 | ParserTransitionKind::Wildcard => {
9972 #[cfg(feature = "perf-counters")]
9973 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9974 let symbol = self.token_type_at(index);
9975 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9976 let next_index = self.consume_index(index, symbol);
9977 let empty_recovery = self.empty_recovery_symbols();
9978 outcomes.extend(
9979 self.recognize_state_fast(
9980 atn,
9981 FastRecognizeRequest {
9982 state_number: target,
9983 stop_state,
9984 index: next_index,
9985 rule_start_index,
9986 decision_start_index: next_decision_start_index,
9987 precedence,
9988 depth: depth + 1,
9989 recovery_symbols: empty_recovery,
9990 recovery_state: None,
9991 },
9992 FastRecognizeScratch {
9993 predicate_context,
9994 visiting,
9995 memo,
9996 expected,
9997 native_depth: native_depth + 1,
9998 },
9999 )
10000 .into_iter()
10001 .map(|mut outcome| {
10002 outcome.consumed_eof |= symbol == TOKEN_EOF;
10003 if self.fast_token_nodes_enabled {
10004 let token = self.arena_token_node(index, false);
10005 self.defer_fast_outcome_node(&mut outcome, token);
10006 }
10007 outcome
10008 }),
10009 );
10010 } else {
10011 if !self.fast_recovery_enabled {
10012 continue;
10020 }
10021 let expected_symbols = fast_recovery_expected_symbols(
10022 self,
10023 atn,
10024 state.state_number(),
10025 &recovery_symbols,
10026 );
10027 if expected_symbols.contains(&symbol) {
10028 continue;
10029 }
10030 {
10031 expected.record_transition(index, transition, max_token_type);
10032 record_no_viable_if_ambiguous(
10033 expected,
10034 next_decision_start_index,
10035 index,
10036 );
10037 outcomes.extend(self.fast_single_token_deletion_recovery(
10038 FastRecoveryRequest {
10039 atn,
10040 transition,
10041 expected_symbols: Rc::clone(&expected_symbols),
10042 target,
10043 request: FastRecognizeRequest {
10044 state_number,
10045 stop_state,
10046 index,
10047 rule_start_index,
10048 decision_start_index,
10049 precedence,
10050 depth,
10051 recovery_symbols: Rc::clone(&recovery_symbols),
10052 recovery_state,
10053 },
10054 visiting,
10055 memo,
10056 expected,
10057 },
10058 predicate_context,
10059 ));
10060 if !state_is_left_recursive_rule(atn, state) {
10061 outcomes.extend(self.fast_single_token_insertion_recovery(
10062 FastRecoveryRequest {
10063 atn,
10064 transition,
10065 expected_symbols: Rc::clone(&expected_symbols),
10066 target,
10067 request: FastRecognizeRequest {
10068 state_number,
10069 stop_state,
10070 index,
10071 rule_start_index,
10072 decision_start_index,
10073 precedence,
10074 depth,
10075 recovery_symbols: Rc::clone(&recovery_symbols),
10076 recovery_state,
10077 },
10078 visiting,
10079 memo,
10080 expected,
10081 },
10082 predicate_context,
10083 ));
10084 }
10085 outcomes.extend(self.fast_current_token_deletion_recovery(
10086 FastCurrentTokenDeletionRequest {
10087 atn,
10088 expected_symbols,
10089 request: FastRecognizeRequest {
10090 state_number,
10091 stop_state,
10092 index,
10093 rule_start_index,
10094 decision_start_index,
10095 precedence,
10096 depth,
10097 recovery_symbols: Rc::clone(&recovery_symbols),
10098 recovery_state,
10099 },
10100 visiting,
10101 memo,
10102 expected,
10103 },
10104 predicate_context,
10105 ));
10106 }
10107 }
10108 }
10109 }
10110 let alt_number = next_alt_number(
10111 state,
10112 transition_count,
10113 transition_index,
10114 0,
10115 self.fast_track_alt_numbers,
10116 );
10117 if alt_number != 0 || left_recursive_boundary.is_some() {
10118 for outcome in &mut outcomes[outcomes_before_transition..] {
10119 if alt_number != 0 {
10120 self.defer_fast_outcome_alternative(outcome, alt_number);
10121 }
10122 if let Some(rule_index) = left_recursive_boundary {
10123 self.defer_fast_outcome_boundary(outcome, rule_index);
10124 }
10125 }
10126 }
10127 }
10128
10129 if has_inserted_cycle_guard {
10130 visiting.remove(&key);
10131 }
10132 if matches!(
10133 self.prediction_mode,
10134 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
10135 ) && self.fast_recovery_enabled
10136 {
10137 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
10141 }
10142 if self.fast_recovery_enabled {
10143 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
10144 } else {
10145 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
10146 }
10147 let should_memoize = self.fast_recovery_enabled
10157 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
10158 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
10162 if inline_consumed_eof {
10163 outcome.consumed_eof = true;
10164 }
10165 if !inline_consumed_tokens.is_empty() {
10166 for token_index in inline_consumed_tokens.iter().rev() {
10167 let token = self.arena_token_node(*token_index, false);
10168 self.defer_fast_outcome_node(&mut outcome, token);
10169 }
10170 }
10171 outcome
10172 };
10173 if should_memoize {
10174 #[cfg(feature = "perf-counters")]
10175 {
10176 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
10177 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
10178 match outcomes.len() {
10179 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
10180 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
10181 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
10182 }
10183 }
10184 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
10189 memo.insert(key, Rc::clone(&stored));
10190 if inline_pending {
10191 return stored
10192 .iter()
10193 .copied()
10194 .map(&mut apply_inline_pending)
10195 .collect();
10196 }
10197 return stored.to_vec();
10198 }
10199 #[cfg(feature = "perf-counters")]
10200 match outcomes.len() {
10201 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
10202 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
10203 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
10204 }
10205 if inline_pending {
10206 return outcomes.into_iter().map(apply_inline_pending).collect();
10207 }
10208 outcomes
10209 }
10210
10211 fn single_token_deletion_recovery(
10214 &mut self,
10215 recovery: RecoveryRequest<'_, '_>,
10216 ) -> Vec<RecognizeOutcome> {
10217 let RecoveryRequest {
10218 atn,
10219 transition,
10220 expected_symbols,
10221 target,
10222 request,
10223 visiting,
10224 memo,
10225 expected,
10226 } = recovery;
10227 let RecognizeRequest {
10228 stop_state,
10229 index,
10230 rule_start_index,
10231 decision_start_index,
10232 init_action_rules,
10233 predicates,
10234 semantics,
10235 rule_args,
10236 member_actions,
10237 return_actions,
10238 local_int_arg,
10239 member_values,
10240 return_values,
10241 rule_alt_number,
10242 track_alt_numbers,
10243 consumed_eof,
10244 precedence,
10245 depth,
10246 ..
10247 } = request;
10248 let Some((diagnostic, next_index, next_symbol)) =
10249 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
10250 else {
10251 return Vec::new();
10252 };
10253 let after_next = self.consume_index(next_index, next_symbol);
10254 self.recognize_state(
10255 atn,
10256 RecognizeRequest {
10257 state_number: target,
10258 stop_state,
10259 index: after_next,
10260 rule_start_index,
10261 decision_start_index,
10262 init_action_rules,
10263 predicates,
10264 semantics,
10265 rule_args,
10266 member_actions,
10267 return_actions,
10268 local_int_arg,
10269 member_values,
10270 return_values,
10271 rule_alt_number,
10272 track_alt_numbers,
10273 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
10274 committed_decision: false,
10275 precedence,
10276 depth: depth + 1,
10277 recovery_symbols: BTreeSet::new(),
10278 recovery_state: None,
10279 },
10280 visiting,
10281 memo,
10282 expected,
10283 )
10284 .into_iter()
10285 .map(|mut outcome| {
10286 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
10287 outcome.diagnostics = self
10288 .recognition_arena
10289 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10290 let token = self.arena_token_node(next_index, false);
10291 self.arena_prepend(&mut outcome.nodes, token);
10292 let error = self.arena_token_node(index, true);
10293 self.arena_prepend(&mut outcome.nodes, error);
10294 outcome
10295 })
10296 .collect()
10297 }
10298
10299 fn current_token_deletion_recovery(
10302 &mut self,
10303 recovery: CurrentTokenDeletionRequest<'_, '_>,
10304 ) -> Vec<RecognizeOutcome> {
10305 let CurrentTokenDeletionRequest {
10306 atn,
10307 expected_symbols,
10308 mut request,
10309 visiting,
10310 memo,
10311 expected,
10312 } = recovery;
10313 let error_index = request.index;
10314 if error_index == request.rule_start_index {
10315 return Vec::new();
10316 }
10317 let Some((diagnostic, next_index, skipped)) =
10318 self.current_token_deletion(error_index, &expected_symbols)
10319 else {
10320 return Vec::new();
10321 };
10322 request.state_number = request.recovery_state.unwrap_or(request.state_number);
10323 request.index = next_index;
10324 request.committed_decision = false;
10325 request.depth += 1;
10326 request.recovery_state = None;
10327 self.recognize_state(atn, request, visiting, memo, expected)
10328 .into_iter()
10329 .map(|mut outcome| {
10330 outcome.diagnostics = self
10331 .recognition_arena
10332 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10333 for index in skipped.iter().rev() {
10334 let error = self.arena_token_node(*index, true);
10335 self.arena_prepend(&mut outcome.nodes, error);
10336 }
10337 outcome
10338 })
10339 .collect()
10340 }
10341
10342 fn consuming_failure_fallback(
10345 &mut self,
10346 fallback: ConsumingFailureFallback<'_>,
10347 visiting: &mut BTreeSet<RecognizeKey>,
10348 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10349 expected: &mut ExpectedTokens,
10350 ) -> Vec<RecognizeOutcome> {
10351 if fallback.expected_symbols.is_empty() {
10352 return Vec::new();
10353 }
10354 if fallback.symbol == TOKEN_EOF {
10355 return self.eof_consuming_failure_fallback(fallback, expected);
10356 }
10357 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
10358 }
10359
10360 fn non_eof_consuming_failure_fallback(
10363 &mut self,
10364 fallback: ConsumingFailureFallback<'_>,
10365 visiting: &mut BTreeSet<RecognizeKey>,
10366 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10367 expected: &mut ExpectedTokens,
10368 ) -> Vec<RecognizeOutcome> {
10369 let ConsumingFailureFallback {
10370 atn,
10371 target,
10372 request,
10373 symbol,
10374 expected_symbols,
10375 decision_start_index,
10376 decision,
10377 } = fallback;
10378 let error_index = request.index;
10379 let diagnostic =
10380 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
10381 let next_index = self.consume_index(error_index, symbol);
10382 self.recognize_state(
10383 atn,
10384 RecognizeRequest {
10385 state_number: target,
10386 stop_state: request.stop_state,
10387 index: next_index,
10388 rule_start_index: request.rule_start_index,
10389 decision_start_index,
10390 init_action_rules: request.init_action_rules,
10391 predicates: request.predicates,
10392 semantics: request.semantics,
10393 rule_args: request.rule_args,
10394 member_actions: request.member_actions,
10395 return_actions: request.return_actions,
10396 local_int_arg: request.local_int_arg,
10397 member_values: request.member_values,
10398 return_values: request.return_values,
10399 rule_alt_number: request.rule_alt_number,
10400 track_alt_numbers: request.track_alt_numbers,
10401 consumed_eof: request.consumed_eof,
10402 committed_decision: false,
10403 precedence: request.precedence,
10404 depth: request.depth + 1,
10405 recovery_symbols: BTreeSet::new(),
10406 recovery_state: None,
10407 },
10408 visiting,
10409 memo,
10410 expected,
10411 )
10412 .into_iter()
10413 .map(|mut outcome| {
10414 prepend_decision(&mut outcome, decision);
10415 outcome.diagnostics = self
10416 .recognition_arena
10417 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10418 let error = self.arena_token_node(error_index, true);
10419 self.arena_prepend(&mut outcome.nodes, error);
10420 outcome
10421 })
10422 .collect()
10423 }
10424
10425 fn eof_consuming_failure_fallback(
10428 &mut self,
10429 fallback: ConsumingFailureFallback<'_>,
10430 expected: &ExpectedTokens,
10431 ) -> Vec<RecognizeOutcome> {
10432 let request = fallback.request;
10433 if request.index == request.rule_start_index {
10434 return Vec::new();
10435 }
10436 let diagnostic =
10437 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
10438 let diagnostics = self
10439 .recognition_arena
10440 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10441 vec![RecognizeOutcome {
10442 index: request.index,
10443 consumed_eof: request.consumed_eof,
10444 alt_number: request.rule_alt_number,
10445 member_values: request.member_values,
10446 return_values: request.return_values,
10447 diagnostics,
10448 decisions: Vec::new(),
10449 actions: Vec::new(),
10450 nodes: NodeSeqId::EMPTY,
10451 }]
10452 }
10453
10454 fn single_token_insertion_recovery(
10457 &mut self,
10458 recovery: RecoveryRequest<'_, '_>,
10459 ) -> Vec<RecognizeOutcome> {
10460 let RecoveryRequest {
10461 atn,
10462 transition,
10463 expected_symbols,
10464 target,
10465 request,
10466 visiting,
10467 memo,
10468 expected,
10469 } = recovery;
10470 let RecognizeRequest {
10471 stop_state,
10472 index,
10473 rule_start_index,
10474 decision_start_index,
10475 init_action_rules,
10476 predicates,
10477 semantics,
10478 rule_args,
10479 member_actions,
10480 return_actions,
10481 local_int_arg,
10482 member_values,
10483 return_values,
10484 rule_alt_number,
10485 track_alt_numbers,
10486 consumed_eof,
10487 precedence,
10488 depth,
10489 ..
10490 } = request;
10491 let follow_symbols = state_expected_symbols(atn, transition.target());
10492 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
10493 transition,
10494 index,
10495 atn.max_token_type(),
10496 &expected_symbols,
10497 &follow_symbols,
10498 ) else {
10499 return Vec::new();
10500 };
10501 self.recognize_state(
10502 atn,
10503 RecognizeRequest {
10504 state_number: target,
10505 stop_state,
10506 index,
10507 rule_start_index,
10508 decision_start_index,
10509 init_action_rules,
10510 predicates,
10511 semantics,
10512 rule_args,
10513 member_actions,
10514 return_actions,
10515 local_int_arg,
10516 member_values,
10517 return_values,
10518 rule_alt_number,
10519 track_alt_numbers,
10520 consumed_eof,
10521 committed_decision: false,
10522 precedence,
10523 depth: depth + 1,
10524 recovery_symbols: BTreeSet::new(),
10525 recovery_state: None,
10526 },
10527 visiting,
10528 memo,
10529 expected,
10530 )
10531 .into_iter()
10532 .map(|mut outcome| {
10533 outcome.diagnostics = self
10534 .recognition_arena
10535 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10536 let missing = self.arena_missing_token_node(token_type, index, text.clone());
10537 self.arena_prepend(&mut outcome.nodes, missing);
10538 outcome
10539 })
10540 .collect()
10541 }
10542
10543 #[allow(clippy::too_many_lines)]
10546 fn recognize_state(
10547 &mut self,
10548 atn: &Atn,
10549 request: RecognizeRequest<'_>,
10550 visiting: &mut BTreeSet<RecognizeKey>,
10551 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10552 expected: &mut ExpectedTokens,
10553 ) -> Vec<RecognizeOutcome> {
10554 let request_template = request.clone();
10555 let RecognizeRequest {
10556 state_number,
10557 stop_state,
10558 index,
10559 rule_start_index,
10560 decision_start_index,
10561 init_action_rules,
10562 predicates,
10563 semantics,
10564 rule_args,
10565 member_actions,
10566 return_actions,
10567 local_int_arg,
10568 member_values,
10569 return_values,
10570 rule_alt_number,
10571 track_alt_numbers,
10572 consumed_eof,
10573 committed_decision,
10574 precedence,
10575 depth,
10576 recovery_symbols,
10577 recovery_state,
10578 } = request;
10579 if depth > RECOGNITION_DEPTH_LIMIT {
10580 return Vec::new();
10581 }
10582 if state_number == stop_state {
10583 return stop_outcome(
10584 index,
10585 consumed_eof,
10586 rule_alt_number,
10587 member_values,
10588 return_values,
10589 );
10590 }
10591 let key = RecognizeKey {
10592 state_number,
10593 stop_state,
10594 index,
10595 rule_start_index,
10596 decision_start_index,
10597 local_int_arg,
10598 member_values: member_values.clone(),
10599 return_values: return_values.clone(),
10600 rule_alt_number,
10601 track_alt_numbers,
10602 consumed_eof,
10603 committed_decision,
10604 precedence,
10605 recovery_symbols: recovery_symbols.clone(),
10606 recovery_state,
10607 };
10608 if let Some(outcomes) = memo.get(&key) {
10609 return outcomes.clone();
10610 }
10611
10612 let visit_key = key.clone();
10613 if !visiting.insert(visit_key.clone()) {
10614 return Vec::new();
10615 }
10616
10617 let Some(state) = atn.state(state_number) else {
10618 visiting.remove(&visit_key);
10619 return Vec::new();
10620 };
10621 let decision_override_generation = self.decision_override_generation;
10622 let transitions = state.transitions();
10623 let transition_count = transitions.len();
10624 let overridden_transition = if transition_count > 1
10625 && self.semantic_hooks.observes_parser_decisions()
10626 {
10627 atn.decision_to_state()
10628 .iter()
10629 .position(|candidate| candidate == state_number)
10630 .and_then(|decision| {
10631 self.semantic_hooks
10632 .parser_decision_override(decision, index, transition_count)
10633 })
10634 .and_then(|alternative| alternative.checked_sub(1))
10635 .filter(|alternative| *alternative < transition_count)
10636 } else {
10637 None
10638 };
10639 if overridden_transition.is_some() {
10640 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
10641 }
10642 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
10643 Some(index)
10644 } else {
10645 decision_start_index
10646 };
10647 let (epsilon_recovery_symbols, epsilon_recovery_state) =
10648 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
10649 let mut outcomes = Vec::new();
10650 for (transition_index, transition) in transitions.iter().enumerate() {
10651 if overridden_transition.is_some_and(|forced| forced != transition_index) {
10652 continue;
10653 }
10654 let transition_committed =
10655 committed_decision || overridden_transition == Some(transition_index);
10656 let mut transition_request = request_template.clone();
10657 transition_request.committed_decision = transition_committed;
10658 let decision =
10659 transition_decision(atn, state, transition_count, transition_index, predicates);
10660 let next_alt_number = next_alt_number(
10661 state,
10662 transition_count,
10663 transition_index,
10664 rule_alt_number,
10665 track_alt_numbers,
10666 );
10667 let transition_data = transition.data();
10668 match &transition_data {
10669 Transition::Epsilon { target } | Transition::Action { target, .. } => {
10670 let (action_rule_index, action_index) = match &transition_data {
10671 Transition::Action {
10672 rule_index,
10673 action_index,
10674 ..
10675 } => (Some(*rule_index), *action_index),
10676 _ => (None, None),
10677 };
10678 outcomes.extend(self.recognize_epsilon_or_action_step(
10679 atn,
10680 &transition_request,
10681 EpsilonActionStep {
10682 source_state: state_number,
10683 target: *target,
10684 action_rule_index,
10685 action_index,
10686 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
10687 decision,
10688 decision_start_index: next_decision_start_index,
10689 alt_number: next_alt_number,
10690 recovery_symbols: epsilon_recovery_symbols.clone(),
10691 recovery_state: epsilon_recovery_state,
10692 },
10693 RecognizeScratch {
10694 visiting,
10695 memo,
10696 expected,
10697 },
10698 ));
10699 }
10700 Transition::Predicate {
10701 target,
10702 rule_index,
10703 pred_index,
10704 ..
10705 } => {
10706 let predicate = PredicateEval {
10707 index,
10708 rule_index: *rule_index,
10709 pred_index: *pred_index,
10710 predicates,
10711 semantics,
10712 context: None,
10713 local_int_arg,
10714 member_values: &member_values,
10715 };
10716 if self.parser_predicate_matches(predicate) {
10717 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
10718 outcomes.extend(
10719 self.recognize_state(
10720 atn,
10721 RecognizeRequest {
10722 state_number: *target,
10723 stop_state,
10724 index,
10725 rule_start_index,
10726 decision_start_index: next_decision_start_index,
10727 init_action_rules,
10728 predicates,
10729 semantics,
10730 rule_args,
10731 member_actions,
10732 return_actions,
10733 local_int_arg,
10734 member_values: member_values.clone(),
10735 return_values: return_values.clone(),
10736 rule_alt_number: next_alt_number,
10737 track_alt_numbers,
10738 consumed_eof,
10739 committed_decision: transition_committed,
10740 precedence,
10741 depth: depth + 1,
10742 recovery_symbols: epsilon_recovery_symbols.clone(),
10743 recovery_state: epsilon_recovery_state,
10744 },
10745 visiting,
10746 memo,
10747 expected,
10748 )
10749 .into_iter()
10750 .map(|mut outcome| {
10751 prepend_decision(&mut outcome, decision);
10752 if let Some(rule_index) = left_recursive_boundary {
10753 let boundary =
10754 self.arena_boundary_node(rule_index, next_alt_number);
10755 self.arena_prepend(&mut outcome.nodes, boundary);
10756 }
10757 outcome
10758 }),
10759 );
10760 } else if let Some(message) = semantics
10761 .and_then(|semantics| {
10762 self.parser_semantic_ir_predicate_failure_message(
10763 *rule_index,
10764 *pred_index,
10765 semantics,
10766 )
10767 })
10768 .or_else(|| {
10769 self.parser_predicate_failure_message(
10770 *rule_index,
10771 *pred_index,
10772 predicates,
10773 )
10774 })
10775 {
10776 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
10777 rule_index: *rule_index,
10778 index,
10779 message,
10780 member_values: member_values.clone(),
10781 return_values: return_values.clone(),
10782 rule_alt_number,
10783 }));
10784 } else {
10785 record_predicate_no_viable(expected, next_decision_start_index, index);
10786 }
10787 }
10788 Transition::Precedence {
10789 target,
10790 precedence: transition_precedence,
10791 } => {
10792 if *transition_precedence >= precedence {
10793 outcomes.extend(
10794 self.recognize_state(
10795 atn,
10796 RecognizeRequest {
10797 state_number: *target,
10798 stop_state,
10799 index,
10800 rule_start_index,
10801 decision_start_index: next_decision_start_index,
10802 init_action_rules,
10803 predicates,
10804 semantics,
10805 rule_args,
10806 member_actions,
10807 return_actions,
10808 local_int_arg,
10809 member_values: member_values.clone(),
10810 return_values: return_values.clone(),
10811 rule_alt_number: next_alt_number,
10812 track_alt_numbers,
10813 consumed_eof,
10814 committed_decision: transition_committed,
10815 precedence,
10816 depth: depth + 1,
10817 recovery_symbols: epsilon_recovery_symbols.clone(),
10818 recovery_state: epsilon_recovery_state,
10819 },
10820 visiting,
10821 memo,
10822 expected,
10823 )
10824 .into_iter()
10825 .map(|mut outcome| {
10826 prepend_decision(&mut outcome, decision);
10827 outcome
10828 }),
10829 );
10830 }
10831 }
10832 Transition::Rule {
10833 target,
10834 rule_index,
10835 follow_state,
10836 precedence: rule_precedence,
10837 ..
10838 } => {
10839 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
10840 continue;
10841 };
10842 let child_local_int_arg =
10843 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
10844 let expected_before_child = expected.clone();
10845 let children = self.recognize_state(
10846 atn,
10847 RecognizeRequest {
10848 state_number: *target,
10849 stop_state: child_stop,
10850 index,
10851 rule_start_index: index,
10852 decision_start_index: None,
10853 init_action_rules,
10854 predicates,
10855 semantics,
10856 rule_args,
10857 member_actions,
10858 return_actions,
10859 local_int_arg: child_local_int_arg,
10860 member_values: member_values.clone(),
10861 return_values: BTreeMap::new(),
10862 rule_alt_number: 0,
10863 track_alt_numbers,
10864 consumed_eof: false,
10865 committed_decision: transition_committed,
10866 precedence: *rule_precedence,
10867 depth: depth + 1,
10868 recovery_symbols: epsilon_recovery_symbols.clone(),
10869 recovery_state: epsilon_recovery_state,
10870 },
10871 visiting,
10872 memo,
10873 expected,
10874 );
10875 let children = if children.is_empty() {
10876 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
10877 atn,
10878 rule_index: *rule_index,
10879 start_index: index,
10880 follow_state: *follow_state,
10881 stop_state,
10882 member_values: member_values.clone(),
10883 expected,
10884 })
10885 } else {
10886 children
10887 };
10888 let preserve_child_expected =
10889 self.child_expected_reaches_clean_eof(&children, expected);
10890 restore_expected(
10891 &children,
10892 index,
10893 expected,
10894 expected_before_child,
10895 preserve_child_expected,
10896 );
10897 for child in children {
10898 let child_stop_index =
10899 self.rule_stop_token_index(child.index, child.consumed_eof);
10900 let child_nodes = self
10901 .recognition_arena
10902 .fold_left_recursive_boundaries(child.nodes);
10903 let child_node = self.arena_rule_node(ArenaRuleSpec {
10904 rule_index: *rule_index,
10905 invoking_state: invoking_state_number(state_number),
10906 alt_number: child.alt_number,
10907 start_index: index,
10908 stop_index: child_stop_index,
10909 return_values: child.return_values.clone(),
10910 children: child_nodes,
10911 });
10912 outcomes.extend(
10913 self.recognize_state(
10914 atn,
10915 RecognizeRequest {
10916 state_number: *follow_state,
10917 stop_state,
10918 index: child.index,
10919 rule_start_index,
10920 decision_start_index: next_decision_start_index,
10921 init_action_rules,
10922 predicates,
10923 semantics,
10924 rule_args,
10925 member_actions,
10926 return_actions,
10927 local_int_arg,
10928 member_values: child.member_values.clone(),
10929 return_values: return_values.clone(),
10930 rule_alt_number,
10931 track_alt_numbers,
10932 consumed_eof: consumed_eof || child.consumed_eof,
10933 committed_decision: transition_committed
10934 && child.index == index,
10935 precedence,
10936 depth: depth + 1,
10937 recovery_symbols: BTreeSet::new(),
10938 recovery_state: None,
10939 },
10940 visiting,
10941 memo,
10942 expected,
10943 )
10944 .into_iter()
10945 .map(|mut outcome| {
10946 outcome.consumed_eof |= child.consumed_eof;
10947 outcome.diagnostics = self
10948 .recognition_arena
10949 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
10950 let mut decisions = child.decisions.clone();
10951 decisions.append(&mut outcome.decisions);
10952 outcome.decisions = decisions;
10953 prepend_decision(&mut outcome, decision);
10954 let mut actions = child.actions.clone();
10955 if init_action_rules.contains(rule_index) {
10956 actions.insert(
10957 0,
10958 ParserAction::new_rule_init(
10959 *rule_index,
10960 index,
10961 Some(*follow_state),
10962 ),
10963 );
10964 }
10965 actions.append(&mut outcome.actions);
10966 outcome.actions = actions;
10967 self.arena_prepend(&mut outcome.nodes, child_node);
10968 outcome
10969 }),
10970 );
10971 }
10972 }
10973 Transition::Atom { target, .. }
10974 | Transition::Range { target, .. }
10975 | Transition::Set { target, .. }
10976 | Transition::NotSet { target, .. }
10977 | Transition::Wildcard { target, .. } => {
10978 let symbol = self.token_type_at(index);
10979 if transition_data.matches(symbol, 1, atn.max_token_type()) {
10980 let next_index = self.consume_index(index, symbol);
10981 outcomes.extend(
10982 self.recognize_state(
10983 atn,
10984 RecognizeRequest {
10985 state_number: *target,
10986 stop_state,
10987 index: next_index,
10988 rule_start_index,
10989 decision_start_index: next_decision_start_index,
10990 init_action_rules,
10991 predicates,
10992 semantics,
10993 rule_args,
10994 member_actions,
10995 return_actions,
10996 local_int_arg,
10997 member_values: member_values.clone(),
10998 return_values: return_values.clone(),
10999 rule_alt_number: next_alt_number,
11000 track_alt_numbers,
11001 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
11002 committed_decision: false,
11003 precedence,
11004 depth: depth + 1,
11005 recovery_symbols: BTreeSet::new(),
11006 recovery_state: None,
11007 },
11008 visiting,
11009 memo,
11010 expected,
11011 )
11012 .into_iter()
11013 .map(|mut outcome| {
11014 prepend_decision(&mut outcome, decision);
11015 outcome.consumed_eof |= symbol == TOKEN_EOF;
11016 let token = self.arena_token_node(index, false);
11017 self.arena_prepend(&mut outcome.nodes, token);
11018 outcome
11019 }),
11020 );
11021 } else {
11022 let expected_symbols =
11023 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
11024 if expected_symbols.contains(&symbol) && !transition_committed {
11025 continue;
11026 }
11027 expected.record_transition(index, transition, atn.max_token_type());
11028 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
11029 let before_recovery = outcomes.len();
11030 let recovery_request = transition_request.clone();
11031 if transition_committed {
11032 outcomes.extend(self.consuming_failure_fallback(
11033 ConsumingFailureFallback {
11034 atn,
11035 target: *target,
11036 request: recovery_request,
11037 symbol,
11038 expected_symbols,
11039 decision_start_index: next_decision_start_index,
11040 decision,
11041 },
11042 visiting,
11043 memo,
11044 expected,
11045 ));
11046 break;
11047 }
11048 outcomes.extend(
11049 self.single_token_deletion_recovery(RecoveryRequest {
11050 atn,
11051 transition,
11052 expected_symbols: expected_symbols.clone(),
11053 target: *target,
11054 request: recovery_request.clone(),
11055 visiting,
11056 memo,
11057 expected,
11058 })
11059 .into_iter()
11060 .map(|mut outcome| {
11061 prepend_decision(&mut outcome, decision);
11062 outcome
11063 }),
11064 );
11065 if !state_is_left_recursive_rule(atn, state) {
11066 outcomes.extend(
11067 self.single_token_insertion_recovery(RecoveryRequest {
11068 atn,
11069 transition,
11070 expected_symbols: expected_symbols.clone(),
11071 target: *target,
11072 request: recovery_request.clone(),
11073 visiting,
11074 memo,
11075 expected,
11076 })
11077 .into_iter()
11078 .map(|mut outcome| {
11079 prepend_decision(&mut outcome, decision);
11080 outcome
11081 }),
11082 );
11083 }
11084 outcomes.extend(self.current_token_deletion_recovery(
11085 CurrentTokenDeletionRequest {
11086 atn,
11087 expected_symbols: expected_symbols.clone(),
11088 request: recovery_request.clone(),
11089 visiting,
11090 memo,
11091 expected,
11092 },
11093 ));
11094 if outcomes.len() == before_recovery {
11095 outcomes.extend(self.consuming_failure_fallback(
11096 ConsumingFailureFallback {
11097 atn,
11098 target: *target,
11099 request: recovery_request,
11100 symbol,
11101 expected_symbols,
11102 decision_start_index: next_decision_start_index,
11103 decision,
11104 },
11105 visiting,
11106 memo,
11107 expected,
11108 ));
11109 }
11110 }
11111 }
11112 }
11113 if self.decision_override_generation != decision_override_generation {
11114 break;
11115 }
11116 }
11117
11118 visiting.remove(&visit_key);
11119 self.record_prediction_diagnostics(atn, state, index, &outcomes);
11120 if matches!(
11121 self.prediction_mode,
11122 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11123 ) {
11124 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
11125 }
11126 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
11127 memo.insert(key, outcomes.clone());
11128 outcomes
11129 }
11130
11131 fn recognize_epsilon_or_action_step(
11134 &mut self,
11135 atn: &Atn,
11136 request: &RecognizeRequest<'_>,
11137 step: EpsilonActionStep,
11138 scratch: RecognizeScratch<'_>,
11139 ) -> Vec<RecognizeOutcome> {
11140 let RecognizeScratch {
11141 visiting,
11142 memo,
11143 expected,
11144 } = scratch;
11145 let action = step.action_rule_index.map(|rule_index| {
11146 let stop_index = self.rule_stop_token_index(request.index, request.consumed_eof);
11147 step.action_index.map_or_else(
11148 || {
11149 ParserAction::new(
11150 step.source_state,
11151 rule_index,
11152 request.rule_start_index,
11153 stop_index,
11154 )
11155 },
11156 |action_index| {
11157 ParserAction::new_indexed(
11158 step.source_state,
11159 rule_index,
11160 action_index,
11161 request.rule_start_index,
11162 stop_index,
11163 )
11164 },
11165 )
11166 });
11167 let next_member_values = if action.is_some() {
11168 member_values_after_action(
11169 step.source_state,
11170 request.member_actions,
11171 request.semantics,
11172 &request.member_values,
11173 )
11174 } else {
11175 request.member_values.clone()
11176 };
11177 let next_return_values = action.map_or_else(
11178 || request.return_values.clone(),
11179 |action| {
11180 return_values_after_action(
11181 step.source_state,
11182 action.rule_index(),
11183 request.return_actions,
11184 request.semantics,
11185 &request.return_values,
11186 )
11187 },
11188 );
11189
11190 self.recognize_state(
11191 atn,
11192 RecognizeRequest {
11193 state_number: step.target,
11194 stop_state: request.stop_state,
11195 index: request.index,
11196 rule_start_index: request.rule_start_index,
11197 decision_start_index: step.decision_start_index,
11198 init_action_rules: request.init_action_rules,
11199 predicates: request.predicates,
11200 semantics: request.semantics,
11201 rule_args: request.rule_args,
11202 member_actions: request.member_actions,
11203 return_actions: request.return_actions,
11204 local_int_arg: request.local_int_arg,
11205 member_values: next_member_values,
11206 return_values: next_return_values,
11207 rule_alt_number: if step.left_recursive_boundary.is_some() {
11208 0
11209 } else {
11210 step.alt_number
11211 },
11212 track_alt_numbers: request.track_alt_numbers,
11213 consumed_eof: request.consumed_eof,
11214 committed_decision: request.committed_decision,
11215 precedence: request.precedence,
11216 depth: request.depth + 1,
11217 recovery_symbols: step.recovery_symbols,
11218 recovery_state: step.recovery_state,
11219 },
11220 visiting,
11221 memo,
11222 expected,
11223 )
11224 .into_iter()
11225 .map(|mut outcome| {
11226 prepend_decision(&mut outcome, step.decision);
11227 if let Some(rule_index) = step.left_recursive_boundary {
11228 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
11229 self.arena_prepend(&mut outcome.nodes, boundary);
11230 }
11231 if let Some(action) = action {
11232 outcome.actions.insert(0, action);
11233 }
11234 outcome
11235 })
11236 .collect()
11237 }
11238
11239 fn token_type_at(&mut self, index: usize) -> i32 {
11244 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
11245 self.input.fill();
11246 }
11247 self.input.token_type_at_index(index)
11248 }
11249
11250 fn cached_state_expected_symbols(
11262 &mut self,
11263 atn: &Atn,
11264 state_number: usize,
11265 ) -> Rc<BTreeSet<i32>> {
11266 if let Some(cached) = self.state_expected_cache.get(&state_number) {
11267 return Rc::clone(cached);
11268 }
11269 let symbols = state_expected_symbols(atn, state_number);
11270 let entry = self.intern_recovery_symbols(symbols);
11271 self.state_expected_cache
11272 .insert(state_number, Rc::clone(&entry));
11273 entry
11274 }
11275
11276 fn cached_state_expected_token_set(
11277 &mut self,
11278 atn: &Atn,
11279 state_number: usize,
11280 ) -> Rc<TokenBitSet> {
11281 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
11282 return Rc::clone(cached);
11283 }
11284 let symbols = with_shared_atn_caches(atn, |cache| {
11288 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
11289 return Rc::clone(cached);
11290 }
11291 let symbols = Rc::new(state_expected_token_set(atn, state_number));
11292 cache
11293 .state_expected_tokens
11294 .insert(state_number, Rc::clone(&symbols));
11295 symbols
11296 });
11297 self.state_expected_token_cache
11298 .insert(state_number, Rc::clone(&symbols));
11299 symbols
11300 }
11301
11302 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
11303 if self.rule_stop_reach_cache.len() <= state_number {
11304 self.rule_stop_reach_cache
11305 .resize_with(atn.states().len().max(state_number + 1), || None);
11306 }
11307 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
11308 return reaches;
11309 }
11310 let reaches = with_shared_atn_caches(atn, |cache| {
11311 *cache
11312 .rule_stop_reach
11313 .entry(state_number)
11314 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
11315 });
11316 self.rule_stop_reach_cache[state_number] = Some(reaches);
11317 reaches
11318 }
11319
11320 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
11323 Rc::clone(&self.empty_recovery_symbols)
11324 }
11325
11326 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
11335 if set.is_empty() {
11336 return Rc::clone(&self.empty_recovery_symbols);
11337 }
11338 let candidate = Rc::new(set);
11339 match self.recovery_symbols_intern.get(&candidate) {
11340 Some(existing) => Rc::clone(existing),
11341 None => {
11342 self.recovery_symbols_intern
11343 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
11344 candidate
11345 }
11346 }
11347 }
11348
11349 fn cached_decision_lookahead(
11354 &mut self,
11355 atn: &Atn,
11356 state: AtnState<'_>,
11357 rule_stop_state: usize,
11358 ) -> Rc<DecisionLookahead> {
11359 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
11366 return Rc::clone(cached);
11367 }
11368 let entry = with_shared_atn_caches(atn, |cache| {
11369 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
11370 return Rc::clone(cached);
11371 }
11372 let mut entry = DecisionLookahead {
11373 transitions: Vec::with_capacity(state.transitions().len()),
11374 };
11375 for transition in &state.transitions() {
11376 entry.transitions.push(transition_first_set(
11377 atn,
11378 transition,
11379 rule_stop_state,
11380 &mut cache.first_set,
11381 ));
11382 }
11383 let entry = Rc::new(entry);
11384 cache
11385 .decision_lookahead
11386 .insert(state.state_number(), Rc::clone(&entry));
11387 entry
11388 });
11389 self.decision_lookahead_cache
11390 .insert(state.state_number(), Rc::clone(&entry));
11391 entry
11392 }
11393
11394 fn cached_rule_first_set(
11395 &mut self,
11396 atn: &Atn,
11397 target: usize,
11398 child_stop: usize,
11399 ) -> Rc<FirstSet> {
11400 if self.rule_first_set_cache.len() <= target {
11401 self.rule_first_set_cache
11402 .resize_with(atn.states().len().max(target + 1), || None);
11403 }
11404 if let Some(cached) = self
11405 .rule_first_set_cache
11406 .get(target)
11407 .and_then(Option::as_ref)
11408 {
11409 return Rc::clone(cached);
11410 }
11411 let first = with_shared_first_set_cache(atn, |cache| {
11412 rule_first_set(atn, target, child_stop, cache)
11413 });
11414 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
11415 first
11416 }
11417
11418 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
11419 let atn_key = SharedAtnCacheKey::for_atn(atn);
11420 if self.empty_cycle_cache_atn != Some(atn_key) {
11421 self.empty_cycle_cache.clear();
11422 self.empty_cycle_cache_atn = Some(atn_key);
11423 }
11424 if self.empty_cycle_cache.len() <= state_number {
11425 self.empty_cycle_cache
11426 .resize_with(atn.state_count().max(state_number + 1), || None);
11427 }
11428 if let Some(cached) = self.empty_cycle_cache[state_number] {
11429 return cached;
11430 }
11431 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
11432 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
11433 self.empty_cycle_cache[state_number] = Some(result);
11434 result
11435 }
11436
11437 fn empty_path_reaches_state(
11438 &mut self,
11439 atn: &Atn,
11440 state_number: usize,
11441 target_state: usize,
11442 visited: &mut FxHashSet<usize>,
11443 ) -> bool {
11444 enum Work {
11445 Visit(usize),
11446 RuleFollow {
11447 target: usize,
11448 rule_index: usize,
11449 follow_state: usize,
11450 },
11451 }
11452
11453 let mut work = vec![Work::Visit(state_number)];
11454 while let Some(item) = work.pop() {
11455 match item {
11456 Work::Visit(state_number) => {
11457 if !visited.insert(state_number) {
11458 continue;
11459 }
11460 let Some(state) = atn.state(state_number) else {
11461 continue;
11462 };
11463 let transitions = state.transitions();
11464 for transition_index in (0..transitions.len()).rev() {
11465 let transition = transitions
11466 .get(transition_index)
11467 .expect("in-bounds parser transition");
11468 let kind = transition.kind();
11469 let target = transition.target();
11470 match kind {
11471 ParserTransitionKind::Atom
11472 | ParserTransitionKind::Range
11473 | ParserTransitionKind::Set
11474 | ParserTransitionKind::NotSet
11475 | ParserTransitionKind::Wildcard => {}
11476 ParserTransitionKind::Rule => {
11477 if target == target_state {
11478 return true;
11479 }
11480 work.push(Work::RuleFollow {
11481 target,
11482 rule_index: transition.arg0() as usize,
11483 follow_state: transition.arg1() as usize,
11484 });
11485 work.push(Work::Visit(target));
11486 }
11487 ParserTransitionKind::Epsilon
11488 | ParserTransitionKind::Predicate
11489 | ParserTransitionKind::Action
11490 | ParserTransitionKind::Precedence => {
11491 if target == target_state {
11492 return true;
11493 }
11494 work.push(Work::Visit(target));
11495 }
11496 }
11497 }
11498 }
11499 Work::RuleFollow {
11500 target,
11501 rule_index,
11502 follow_state,
11503 } => {
11504 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
11505 continue;
11506 };
11507 if self.cached_rule_first_set(atn, target, child_stop).nullable {
11508 if follow_state == target_state {
11509 return true;
11510 }
11511 work.push(Work::Visit(follow_state));
11512 }
11513 }
11514 }
11515 }
11516 false
11517 }
11518
11519 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
11522 match self.clean_memo_mode {
11523 CleanMemoMode::Promote => true,
11524 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
11525 CleanMemoMode::Sparse => {
11526 self.clean_memo_sparse_samples += 1;
11527 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
11528 return false;
11529 }
11530 self.clean_memo_sparse_samples = 0;
11531 self.clean_memo_mode = CleanMemoMode::Probe;
11532 self.clean_memo_probe_samples = 0;
11533 self.clean_memo_probe_repeats = 0;
11534 self.clean_memo_probe_seen.clear();
11535 self.observe_clean_memo_probe(key)
11536 }
11537 }
11538 }
11539
11540 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
11541 self.clean_memo_probe_samples += 1;
11542 if !self.clean_memo_probe_seen.insert(key.clone()) {
11543 self.clean_memo_probe_repeats += 1;
11544 }
11545 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
11546 self.clean_memo_mode = CleanMemoMode::Promote;
11547 self.clean_memo_probe_seen.clear();
11548 return true;
11549 }
11550 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
11551 self.clean_memo_mode = CleanMemoMode::Sparse;
11552 self.clean_memo_sparse_samples = 0;
11553 self.clean_memo_probe_seen.clear();
11554 return false;
11555 }
11556 true
11557 }
11558
11559 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
11561 self.input.get(index)
11562 }
11563
11564 fn token_id_at(&self, index: usize) -> Option<TokenId> {
11566 self.input.get_id(index)
11567 }
11568
11569 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
11570 let token = self
11571 .token_id_at(index)
11572 .expect("recognized token index must exist in the token store");
11573 let node = if error {
11574 ArenaRecognizedNode::ErrorToken { token }
11575 } else {
11576 ArenaRecognizedNode::Token { token }
11577 };
11578 self.recognition_arena.push_node(node)
11579 }
11580
11581 fn arena_missing_token_node(
11582 &mut self,
11583 token_type: i32,
11584 at_index: usize,
11585 text: String,
11586 ) -> RecognizedNodeId {
11587 let extra = self
11588 .recognition_arena
11589 .push_extra(RecognitionExtra::MissingToken {
11590 token_type,
11591 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
11592 text,
11593 });
11594 self.recognition_arena
11595 .push_node(ArenaRecognizedNode::MissingToken { extra })
11596 }
11597
11598 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
11599 let ArenaRuleSpec {
11600 rule_index,
11601 invoking_state,
11602 alt_number,
11603 start_index,
11604 stop_index,
11605 return_values,
11606 children,
11607 } = spec;
11608 let return_values = (!return_values.is_empty()).then(|| {
11609 self.recognition_arena
11610 .push_extra(RecognitionExtra::ReturnValues(return_values))
11611 });
11612 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
11613 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11614 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
11615 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11616 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
11617 stop_index: stop_index
11618 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
11619 return_values,
11620 children,
11621 })
11622 }
11623
11624 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
11625 self.recognition_arena
11626 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
11627 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11628 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11629 })
11630 }
11631
11632 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
11633 *sequence = self.recognition_arena.prepend(*sequence, node);
11634 }
11635
11636 #[allow(clippy::missing_const_for_fn)]
11639 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
11640 self.last_recognition_arena_root = root;
11641 self.last_recognition_arena_diagnostics = diagnostics;
11642 #[cfg(feature = "perf-counters")]
11643 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
11644 let stats = self.recognition_arena_stats();
11645 #[allow(clippy::print_stderr)]
11646 {
11647 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
11648 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
11649 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
11650 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
11651 eprintln!("perf recognition_links_total={}", stats.total_links);
11652 eprintln!("perf recognition_links_live={}", stats.live_links);
11653 eprintln!("perf recognition_links_dead={}", stats.dead_links);
11654 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
11655 eprintln!("perf recognition_extras_total={}", stats.total_extras);
11656 eprintln!("perf recognition_extras_live={}", stats.live_extras);
11657 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
11658 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
11659 }
11660 }
11661 }
11662
11663 fn reset_recognition_arena(&mut self) {
11664 self.recognition_arena.reset();
11665 self.last_recognition_arena_root = NodeSeqId::EMPTY;
11666 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
11667 }
11668
11669 fn current_visible_index(&mut self) -> usize {
11672 let index = self.input.index();
11673 self.input.seek(index);
11674 self.input.index()
11675 }
11676
11677 fn child_expected_reaches_clean_eof(
11680 &mut self,
11681 children: &[RecognizeOutcome],
11682 expected: &ExpectedTokens,
11683 ) -> bool {
11684 let Some(index) = expected.index else {
11685 return false;
11686 };
11687 self.token_type_at(index) == TOKEN_EOF
11688 && children
11689 .iter()
11690 .any(|child| child.diagnostics.is_empty() && child.index == index)
11691 }
11692
11693 fn previous_token_index(&self, index: usize) -> Option<usize> {
11700 self.input.previous_visible_token_index(index)
11701 }
11702
11703 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
11708 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
11709 Some(index)
11710 } else {
11711 self.previous_token_index(index)
11712 }
11713 }
11714
11715 #[must_use]
11732 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
11733 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
11734 self.rule_stop_token_index(current_index, consumed_eof)
11735 }
11736
11737 #[must_use]
11746 pub fn after_action_stop_index_for_tree(
11747 &mut self,
11748 tree: ParseTree,
11749 current_index: usize,
11750 ) -> Option<usize> {
11751 if let Some(stop) = self
11752 .node(tree)
11753 .as_rule()
11754 .and_then(crate::tree::RuleNodeView::stop_id)
11755 {
11756 return Some(stop.index());
11757 }
11758 self.after_action_stop_index(current_index)
11759 }
11760
11761 #[must_use]
11771 pub fn after_action_start_index_for_tree(
11772 &self,
11773 tree: ParseTree,
11774 fallback_index: usize,
11775 ) -> usize {
11776 if let Some(start) = self
11777 .node(tree)
11778 .as_rule()
11779 .and_then(crate::tree::RuleNodeView::start_id)
11780 {
11781 return start.index();
11782 }
11783 fallback_index
11784 }
11785
11786 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
11791 self.rule_stop_token_index(index, consumed_eof)
11792 .and_then(|token_index| self.token_id_at(token_index))
11793 }
11794
11795 fn predicate_failure_recovery(
11802 &mut self,
11803 request: PredicateFailureRecovery<'_>,
11804 ) -> RecognizeOutcome {
11805 let PredicateFailureRecovery {
11806 rule_index,
11807 index,
11808 message,
11809 member_values,
11810 return_values,
11811 rule_alt_number,
11812 } = request;
11813 let rule_name = self
11814 .rule_names()
11815 .get(rule_index)
11816 .map_or_else(|| rule_index.to_string(), Clone::clone);
11817 let diagnostic = diagnostic_for_token(
11818 self.token_at(index).as_ref(),
11819 format!("rule {rule_name} {message}"),
11820 );
11821 let mut reversed_nodes = NodeSeqId::EMPTY;
11822 let mut next_index = index;
11823 loop {
11824 let symbol = self.token_type_at(next_index);
11825 if symbol == TOKEN_EOF {
11826 break;
11827 }
11828 let error = self.arena_token_node(next_index, true);
11829 self.arena_prepend(&mut reversed_nodes, error);
11830 let after = self.consume_index(next_index, symbol);
11831 if after == next_index {
11832 break;
11833 }
11834 next_index = after;
11835 }
11836 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
11837 let diagnostics = self
11838 .recognition_arena
11839 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
11840 RecognizeOutcome {
11841 index: next_index,
11842 consumed_eof: false,
11843 alt_number: rule_alt_number,
11844 member_values,
11845 return_values,
11846 diagnostics,
11847 decisions: Vec::new(),
11848 actions: Vec::new(),
11849 nodes,
11850 }
11851 }
11852
11853 fn parser_semantic_hook_result(
11856 &mut self,
11857 request: ParserSemanticHookRequest<'_>,
11858 ) -> Option<bool> {
11859 let ParserSemanticHookRequest {
11860 index,
11861 rule_index,
11862 pred_index,
11863 context,
11864 local_int_arg,
11865 member_values,
11866 } = request;
11867 let rule_name = self.rule_names().get(rule_index).cloned();
11868 self.input.seek(index);
11869 let input = &mut self.input;
11870 let semantic_hooks = &mut self.semantic_hooks;
11871 let mut ctx = ParserSemCtx {
11872 input,
11873 tree_storage: &self.tree,
11874 rule_index,
11875 coordinate_index: pred_index,
11876 rule_name,
11877 context,
11878 tree: None,
11879 local_int_arg,
11880 member_values,
11881 action: None,
11882 };
11883 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
11884 }
11885
11886 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
11891 if prior.is_empty() {
11892 return;
11893 }
11894 let mut merged = prior;
11895 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
11896 if !merged.contains(&coordinate) {
11897 merged.push(coordinate);
11898 }
11899 }
11900 self.unknown_predicate_hits = merged;
11901 }
11902
11903 fn restore_prior_unhandled_action_hits(&mut self, prior: Vec<(usize, usize)>) {
11906 if prior.is_empty() {
11907 return;
11908 }
11909 let mut merged = prior;
11910 for coordinate in std::mem::take(&mut self.unhandled_action_hits) {
11911 if !merged.contains(&coordinate) {
11912 merged.push(coordinate);
11913 }
11914 }
11915 self.unhandled_action_hits = merged;
11916 }
11917
11918 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
11927 apply_unknown_predicate_policy(
11928 self.unknown_predicate_policy,
11929 rule_index,
11930 pred_index,
11931 &mut self.unknown_predicate_hits,
11932 )
11933 }
11934
11935 fn unknown_semantic_error(&self) -> Option<AntlrError> {
11938 use std::fmt::Write as _;
11939 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
11940 return None;
11941 }
11942 let mut message = String::new();
11943 for (rule_index, pred_index) in &self.unknown_predicate_hits {
11944 if !message.is_empty() {
11945 message.push_str("; ");
11946 }
11947 let _ = match self.rule_names().get(*rule_index) {
11948 Some(rule_name) => write!(
11949 message,
11950 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
11951 ),
11952 None => write!(
11953 message,
11954 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
11955 ),
11956 };
11957 }
11958 for (rule_index, source_state) in &self.unhandled_action_hits {
11959 if !message.is_empty() {
11960 message.push_str("; ");
11961 }
11962 let _ = match self.rule_names().get(*rule_index) {
11963 Some(rule_name) => write!(
11964 message,
11965 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
11966 ),
11967 None => write!(
11968 message,
11969 "unhandled semantic action: rule_index={rule_index} state={source_state}"
11970 ),
11971 };
11972 }
11973 Some(AntlrError::Unsupported(message))
11974 }
11975
11976 fn parser_semir_predicate_matches(
11984 &mut self,
11985 semantics: &ParserSemantics,
11986 predicate: &ParserSemanticPredicate,
11987 request: ParserSemanticHookRequest<'_>,
11988 ) -> bool {
11989 self.input.seek(request.index);
11990 let rule_name = self
11991 .data
11992 .rule_names()
11993 .get(request.rule_index)
11994 .map(String::as_str);
11995 let unknown_predicate_policy = self.unknown_predicate_policy;
11996 let mut ctx = ParserSemIrCtx {
11997 input: &mut self.input,
11998 tree_storage: &self.tree,
11999 semantic_hooks: &mut self.semantic_hooks,
12000 rule_index: request.rule_index,
12001 coordinate_index: request.pred_index,
12002 rule_name,
12003 context: request.context,
12004 local_int_arg: request.local_int_arg,
12005 member_values: request.member_values,
12006 invoked_predicates: &mut self.invoked_predicates,
12007 unknown_predicate_policy,
12008 unknown_predicate_hits: &mut self.unknown_predicate_hits,
12009 };
12010 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
12011 }
12012
12013 fn fast_parser_predicate_matches(
12014 &mut self,
12015 context: Option<FastPredicateContext<'_>>,
12016 transition: ParserTransition<'_>,
12017 index: usize,
12018 ) -> bool {
12019 let Some(context) = context else {
12020 return true;
12021 };
12022 let rule_index = transition.arg0() as usize;
12023 let pred_index = transition.arg1() as usize;
12024 let key = (index, rule_index, pred_index);
12025 if let Some(result) = self.fast_predicate_cache.get(&key) {
12026 return *result;
12027 }
12028 let result = self.parser_predicate_matches(PredicateEval {
12029 index,
12030 rule_index,
12031 pred_index,
12032 predicates: context.predicates,
12033 semantics: context.semantics,
12034 context: None,
12035 local_int_arg: None,
12036 member_values: context.member_values,
12037 });
12038 self.fast_predicate_cache.insert(key, result);
12039 result
12040 }
12041
12042 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
12043 let PredicateEval {
12044 index,
12045 rule_index,
12046 pred_index,
12047 predicates,
12048 semantics,
12049 context,
12050 local_int_arg,
12051 member_values,
12052 } = eval;
12053 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
12054 semantics
12055 .predicates
12056 .iter()
12057 .find(|predicate| {
12058 predicate.rule_index == rule_index && predicate.pred_index == pred_index
12059 })
12060 .map(|predicate| (semantics, predicate))
12061 }) {
12062 return self.parser_semir_predicate_matches(
12063 semantics,
12064 predicate,
12065 ParserSemanticHookRequest {
12066 index,
12067 rule_index,
12068 pred_index,
12069 context,
12070 local_int_arg,
12071 member_values,
12072 },
12073 );
12074 }
12075 let Some((_, _, predicate)) = predicates
12076 .iter()
12077 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
12078 else {
12079 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
12080 index,
12081 rule_index,
12082 pred_index,
12083 context,
12084 local_int_arg,
12085 member_values,
12086 }) {
12087 return result;
12088 }
12089 return self.unknown_predicate_result(rule_index, pred_index);
12090 };
12091 self.input.seek(index);
12092 match predicate {
12093 ParserPredicate::True => true,
12094 ParserPredicate::False => false,
12095 ParserPredicate::FalseWithMessage { .. } => false,
12096 ParserPredicate::Invoke { value } => {
12097 let key = (rule_index, pred_index);
12098 if !self.invoked_predicates.contains(&key) {
12099 self.invoked_predicates.push(key);
12100 use std::io::Write as _;
12101 let mut stdout = std::io::stdout().lock();
12102 let _ = writeln!(stdout, "eval={value}");
12103 }
12104 *value
12105 }
12106 ParserPredicate::LookaheadTextEquals { offset, text } => self
12107 .input
12108 .lt(*offset)
12109 .is_some_and(|token| Token::text(&token) == Some(*text)),
12110 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
12111 self.la(*offset) != *token_type
12112 }
12113 ParserPredicate::TokenPairAdjacent => {
12114 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
12115 return false;
12116 };
12117 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
12118 return false;
12119 };
12120 first + 1 == second
12121 }
12122 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
12123 .and_then(|context| {
12124 context
12125 .child_rules(&self.tree, self.input.token_store(), *rule_index)
12126 .next()
12127 .map(crate::tree::RuleNodeView::text)
12128 })
12129 .is_none_or(|actual| actual != *text),
12130 ParserPredicate::LocalIntEquals { value } => {
12131 local_int_arg.is_none_or(|(_, actual)| actual == *value)
12132 }
12133 ParserPredicate::LocalIntLessOrEqual { value } => {
12134 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
12135 }
12136 ParserPredicate::MemberModuloEquals {
12137 member,
12138 modulus,
12139 value,
12140 equals,
12141 } => {
12142 if *modulus == 0 {
12143 return false;
12144 }
12145 let actual = member_values.scalar(*member).unwrap_or_default() % *modulus;
12146 (actual == *value) == *equals
12147 }
12148 ParserPredicate::MemberEquals {
12149 member,
12150 value,
12151 equals,
12152 } => {
12153 let actual = member_values.scalar(*member).unwrap_or_default();
12154 (actual == *value) == *equals
12155 }
12156 }
12157 }
12158
12159 fn parser_predicate_failure_message(
12161 &self,
12162 rule_index: usize,
12163 pred_index: usize,
12164 predicates: &[(usize, usize, ParserPredicate)],
12165 ) -> Option<&'static str> {
12166 predicates
12167 .iter()
12168 .find_map(|(rule, pred, predicate)| match predicate {
12169 ParserPredicate::FalseWithMessage { message }
12170 if *rule == rule_index && *pred == pred_index =>
12171 {
12172 Some(*message)
12173 }
12174 _ => None,
12175 })
12176 }
12177
12178 pub fn parser_semantic_ir_predicate_failure_message(
12181 &self,
12182 rule_index: usize,
12183 pred_index: usize,
12184 semantics: &ParserSemantics,
12185 ) -> Option<&'static str> {
12186 semantics
12187 .predicates
12188 .iter()
12189 .find(|predicate| {
12190 predicate.rule_index == rule_index && predicate.pred_index == pred_index
12191 })
12192 .and_then(|predicate| predicate.failure_message)
12193 }
12194
12195 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
12204 if symbol == TOKEN_EOF {
12205 return index;
12206 }
12207 self.input.next_visible_after(index)
12208 }
12209
12210 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
12213 let text = display_input_text(&self.input.text(start_index, error_index));
12214 diagnostic_for_token(
12215 self.token_at(error_index).as_ref(),
12216 format!("no viable alternative at input '{text}'"),
12217 )
12218 }
12219
12220 fn recovery_failure_diagnostic(
12223 &self,
12224 index: usize,
12225 decision_start_index: Option<usize>,
12226 expected_symbols: &BTreeSet<i32>,
12227 ) -> ParserDiagnostic {
12228 if expected_symbols.len() > 1 {
12229 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
12230 return self.no_viable_alternative(decision_start, index);
12231 }
12232 }
12233 diagnostic_for_token(
12234 self.token_at(index).as_ref(),
12235 format!(
12236 "mismatched input {} expecting {}",
12237 self.token_at(index)
12238 .as_ref()
12239 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
12240 self.expected_symbols_display(expected_symbols)
12241 ),
12242 )
12243 }
12244
12245 fn eof_rule_recovery_diagnostic(
12248 &self,
12249 index: usize,
12250 expected_symbols: &BTreeSet<i32>,
12251 expected: &ExpectedTokens,
12252 ) -> ParserDiagnostic {
12253 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
12254 &expected.symbols
12255 } else {
12256 expected_symbols
12257 };
12258 diagnostic_for_token(
12259 self.token_at(index).as_ref(),
12260 format!(
12261 "mismatched input {} expecting {}",
12262 self.token_at(index)
12263 .as_ref()
12264 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
12265 self.expected_symbols_display(symbols)
12266 ),
12267 )
12268 }
12269
12270 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
12276 let Some(stop) = stop else {
12277 return String::new();
12278 };
12279 let stop = if self
12280 .token_at(stop)
12281 .is_some_and(|token| token.token_type() == TOKEN_EOF)
12282 {
12283 let Some(previous) = self.previous_token_index(stop) else {
12284 return String::new();
12285 };
12286 previous
12287 } else {
12288 stop
12289 };
12290 self.input.text(start, stop)
12291 }
12292
12293 fn clear_prediction_diagnostics(&mut self) {
12296 self.prediction_diagnostics.clear();
12297 self.reported_prediction_diagnostics.clear();
12298 }
12299
12300 fn reset_per_parse_caches(&mut self) {
12324 self.rule_first_set_cache.clear();
12325 self.decision_lookahead_cache.clear();
12326 self.ll1_decision_cache.clear();
12327 self.fast_predicate_cache.clear();
12328 self.rule_stop_reach_cache.clear();
12329 self.clean_memo_mode = CleanMemoMode::Probe;
12330 self.clean_memo_probe_seen.clear();
12331 self.clean_memo_probe_samples = 0;
12332 self.clean_memo_probe_repeats = 0;
12333 self.clean_memo_sparse_samples = 0;
12334 self.recovery_symbols_intern.clear();
12335 self.state_expected_cache.clear();
12336 self.state_expected_token_cache.clear();
12337 }
12338
12339 fn record_prediction_diagnostics(
12342 &mut self,
12343 atn: &Atn,
12344 state: AtnState<'_>,
12345 start_index: usize,
12346 outcomes: &[RecognizeOutcome],
12347 ) {
12348 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
12349 return;
12350 }
12351 let Some(decision) = atn
12352 .decision_to_state()
12353 .iter()
12354 .position(|state_number| state_number == state.state_number())
12355 else {
12356 return;
12357 };
12358 let Some(rule_index) = state.rule_index() else {
12359 return;
12360 };
12361 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
12362 for outcome in outcomes
12363 .iter()
12364 .filter(|outcome| outcome.diagnostics.is_empty())
12365 {
12366 let Some(alt) = outcome.decisions.first() else {
12367 continue;
12368 };
12369 alts_by_end
12370 .entry(outcome.index)
12371 .or_default()
12372 .insert(alt + 1);
12373 }
12374 let Some((&end_index, ambig_alts)) = alts_by_end
12375 .iter()
12376 .filter(|(_, alts)| alts.len() > 1)
12377 .max_by_key(|(end, _)| *end)
12378 else {
12379 return;
12380 };
12381 let rule_name = self
12382 .rule_names()
12383 .get(rule_index)
12384 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
12385 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
12386 let input = display_input_text(&self.input.text(start_index, stop_index));
12387 let alts = ambig_alts
12388 .iter()
12389 .map(usize::to_string)
12390 .collect::<Vec<_>>()
12391 .join(", ");
12392 let key = (decision, start_index, format!("{alts}:{input}"));
12393 if !self.reported_prediction_diagnostics.insert(key) {
12394 return;
12395 }
12396 let start_diagnostic = diagnostic_for_token(
12397 self.token_at(start_index),
12398 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
12399 );
12400 let stop_diagnostic = diagnostic_for_token(
12401 self.token_at(stop_index),
12402 format!(
12403 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
12404 ),
12405 );
12406 self.prediction_diagnostics.push(start_diagnostic);
12407 self.prediction_diagnostics.push(stop_diagnostic);
12408 }
12409
12410 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
12412 expected_symbols_display(
12413 &state_expected_symbols(atn, state_number),
12414 self.vocabulary(),
12415 )
12416 }
12417
12418 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
12423 let state = usize::try_from(self.data().state()).unwrap_or(0);
12424 ExpectedTokenSet {
12425 symbols: state_expected_symbols(atn, state),
12426 }
12427 }
12428
12429 pub const fn set_bail_on_error(&mut self, bail: bool) {
12432 self.bail_on_error = bail;
12433 }
12434
12435 #[must_use]
12437 pub const fn bail_on_error(&self) -> bool {
12438 self.bail_on_error
12439 }
12440
12441 pub fn rule_invocation_stack(&self) -> Vec<String> {
12444 self.rule_context_stack
12445 .iter()
12446 .rev()
12447 .map(|frame| {
12448 self.data()
12449 .rule_names()
12450 .get(frame.rule_index)
12451 .cloned()
12452 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
12453 })
12454 .collect()
12455 }
12456
12457 pub fn active_invocation_states(&self) -> Vec<isize> {
12461 self.rule_context_stack
12462 .iter()
12463 .skip(1)
12464 .rev()
12465 .map(|frame| frame.invoking_state)
12466 .collect()
12467 }
12468
12469 pub fn token_display_at(&self, index: usize) -> Option<String> {
12471 self.token_at(index).map(|token| format!("{token}"))
12472 }
12473}
12474
12475impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
12476where
12477 S: TokenSource,
12478 H: SemanticHooks,
12479{
12480 fn parse_rule(
12481 &mut self,
12482 rule_index: usize,
12483 invoking_state: isize,
12484 precedence: i32,
12485 ) -> DirectAdaptiveParseResult<ParseTree> {
12486 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
12487 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
12488 )?;
12489 let stop_state = self
12490 .atn
12491 .rule_to_stop_state()
12492 .get(rule_index)
12493 .filter(|state| *state != usize::MAX)
12494 .ok_or(DirectAdaptiveParseControl::Fallback(
12495 DirectAdaptiveFallback::MissingAtn,
12496 ))?;
12497 let start_index = self.parser.current_visible_index();
12498 let mut context = ParserRuleContext::new(rule_index, invoking_state);
12499 if let Some(token) = self.parser.token_id_at(start_index) {
12500 self.parser.set_context_start(&mut context, token);
12501 }
12502 let mut state_number = start_state;
12503 let mut consumed_eof = false;
12504 while state_number != stop_state {
12505 self.step()?;
12506 let (transition, boundary) = self.next_transition(state_number, precedence)?;
12507 if boundary.is_some() {
12508 return Err(DirectAdaptiveParseControl::Fallback(
12509 DirectAdaptiveFallback::LeftRecursiveBoundary,
12510 ));
12511 }
12512 match transition.data() {
12513 Transition::Epsilon { target } => {
12514 state_number = target;
12515 }
12516 Transition::Precedence {
12517 target,
12518 precedence: transition_precedence,
12519 } => {
12520 if transition_precedence < precedence {
12521 return Err(DirectAdaptiveParseControl::Fallback(
12522 DirectAdaptiveFallback::Precedence,
12523 ));
12524 }
12525 state_number = target;
12526 }
12527 Transition::Rule {
12528 rule_index,
12529 follow_state,
12530 precedence: rule_precedence,
12531 ..
12532 } => {
12533 let child = self.parse_rule(
12534 rule_index,
12535 invoking_state_number(state_number),
12536 rule_precedence,
12537 )?;
12538 if self.parser.build_parse_trees {
12539 self.parser.tree.add_child(&mut context, child);
12540 }
12541 state_number = follow_state;
12542 }
12543 Transition::Atom { .. }
12544 | Transition::Range { .. }
12545 | Transition::Set { .. }
12546 | Transition::NotSet { .. }
12547 | Transition::Wildcard { .. } => {
12548 let (matched_eof, child) = self.consume_transition(transition)?;
12549 consumed_eof |= matched_eof;
12550 if let Some(child) = child {
12551 self.parser.tree.add_child(&mut context, child);
12552 }
12553 state_number = transition.target();
12554 }
12555 Transition::Predicate { .. } => {
12556 return Err(DirectAdaptiveParseControl::Fallback(
12557 DirectAdaptiveFallback::Predicate,
12558 ));
12559 }
12560 Transition::Action { .. } => {
12561 return Err(DirectAdaptiveParseControl::Fallback(
12562 DirectAdaptiveFallback::Action,
12563 ));
12564 }
12565 }
12566 }
12567
12568 let stop_index = self
12569 .parser
12570 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
12571 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
12572 self.parser.set_context_stop(&mut context, token);
12573 }
12574 Ok(self.parser.rule_node(context))
12575 }
12576
12577 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
12578 self.steps += 1;
12579 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
12580 return Err(DirectAdaptiveParseControl::Fallback(
12581 DirectAdaptiveFallback::StepLimit,
12582 ));
12583 }
12584 Ok(())
12585 }
12586
12587 fn next_transition(
12588 &mut self,
12589 state_number: usize,
12590 precedence: i32,
12591 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
12592 let state = self
12593 .atn
12594 .state(state_number)
12595 .ok_or(DirectAdaptiveParseControl::Fallback(
12596 DirectAdaptiveFallback::MissingAtn,
12597 ))?;
12598 if state.is_rule_stop() {
12599 return Err(DirectAdaptiveParseControl::Fallback(
12600 DirectAdaptiveFallback::RuleStop,
12601 ));
12602 }
12603 let transition_index =
12604 self.transition_index(state_number, state.transitions().len(), precedence)?;
12605 let transition = state.transitions().get(transition_index).ok_or(
12606 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
12607 )?;
12608 let boundary = match &transition.data() {
12609 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
12610 left_recursive_boundary(self.atn, state, *target)
12611 }
12612 _ => None,
12613 };
12614 Ok((transition, boundary))
12615 }
12616
12617 fn transition_index(
12618 &mut self,
12619 state_number: usize,
12620 transition_count: usize,
12621 precedence: i32,
12622 ) -> DirectAdaptiveParseResult<usize> {
12623 match transition_count {
12624 0 => Err(DirectAdaptiveParseControl::Fallback(
12625 DirectAdaptiveFallback::NoTransition,
12626 )),
12627 1 => Ok(0),
12628 _ => {
12629 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
12630 return Ok(alt);
12631 }
12632 let decision = self
12633 .decision_by_state
12634 .get(state_number)
12635 .and_then(|decision| *decision)
12636 .ok_or(DirectAdaptiveParseControl::Fallback(
12637 DirectAdaptiveFallback::UnknownDecision,
12638 ))?;
12639 let prediction = self
12640 .simulator
12641 .adaptive_predict_stream_info_with_precedence(
12642 decision,
12643 direct_precedence(precedence),
12644 &mut self.parser.input,
12645 )
12646 .map_err(|_| {
12647 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
12648 })?;
12649 if prediction.has_semantic_context {
12650 return Err(DirectAdaptiveParseControl::Fallback(
12651 DirectAdaptiveFallback::SemanticContext,
12652 ));
12653 }
12654 prediction
12655 .alt
12656 .checked_sub(1)
12657 .filter(|index| *index < transition_count)
12658 .ok_or(DirectAdaptiveParseControl::Fallback(
12659 DirectAdaptiveFallback::InvalidAlt,
12660 ))
12661 }
12662 }
12663 }
12664
12665 fn ll1_transition_index(
12666 &mut self,
12667 state_number: usize,
12668 transition_count: usize,
12669 ) -> DirectAdaptiveParseResult<Option<usize>> {
12670 let state = self
12671 .atn
12672 .state(state_number)
12673 .ok_or(DirectAdaptiveParseControl::Fallback(
12674 DirectAdaptiveFallback::MissingAtn,
12675 ))?;
12676 if state.precedence_rule_decision() {
12677 return Ok(None);
12678 }
12679 let Some(rule_stop) = state
12680 .rule_index()
12681 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
12682 else {
12683 return Ok(None);
12684 };
12685 let symbol = self.parser.input.la_token(1);
12686 let entry = self
12687 .parser
12688 .cached_decision_lookahead(self.atn, state, rule_stop);
12689 Ok(
12690 ll1_greedy_alt(&entry, symbol, state.non_greedy())
12691 .filter(|alt| *alt < transition_count),
12692 )
12693 }
12694
12695 fn consume_transition(
12696 &mut self,
12697 transition: ParserTransition<'_>,
12698 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
12699 let symbol = self.parser.input.la_token(1);
12700 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
12701 return Err(DirectAdaptiveParseControl::Fallback(
12702 DirectAdaptiveFallback::TokenMismatch,
12703 ));
12704 }
12705 let token = self
12706 .parser
12707 .input
12708 .lt_id(1)
12709 .ok_or(DirectAdaptiveParseControl::Fallback(
12710 DirectAdaptiveFallback::TokenMismatch,
12711 ))?;
12712 let matched_eof = symbol == TOKEN_EOF;
12713 if !matched_eof {
12714 self.parser.consume();
12715 }
12716 let child = self
12717 .parser
12718 .build_parse_trees
12719 .then(|| self.parser.terminal_tree(token));
12720 Ok((matched_eof, child))
12721 }
12722}
12723
12724impl<S, H> CommittedAtnParser<'_, '_, '_, S, H>
12725where
12726 S: TokenSource,
12727 H: SemanticHooks,
12728{
12729 fn parse_rule(
12730 &mut self,
12731 rule_index: usize,
12732 precedence: i32,
12733 inherited_local_int_arg: Option<(usize, i64)>,
12734 init_expected_state: Option<usize>,
12735 ) -> Result<CommittedRuleOutcome, AntlrError> {
12736 let start_state = self
12737 .atn
12738 .rule_to_start_state()
12739 .get(rule_index)
12740 .ok_or_else(|| {
12741 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
12742 })?;
12743 let stop_state = self
12744 .atn
12745 .rule_to_stop_state()
12746 .get(rule_index)
12747 .filter(|state| *state != usize::MAX)
12748 .ok_or_else(|| {
12749 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
12750 })?;
12751 let left_recursive = self
12752 .atn
12753 .state(start_state)
12754 .is_some_and(AtnState::left_recursive_rule);
12755 if let Some(error) = self.parser.rule_depth_cap_violation() {
12756 return Err(error);
12757 }
12758 if let Some(error) = self.parser.parse_listener_enter_rule(rule_index) {
12759 return Err(error);
12760 }
12761 let mut context = if left_recursive {
12762 self.parser.enter_recursion_rule(
12763 invoking_state_number(start_state),
12764 rule_index,
12765 precedence,
12766 )
12767 } else {
12768 self.parser
12769 .enter_rule(invoking_state_number(start_state), rule_index)
12770 };
12771 let rule_start_index = self.parser.current_visible_index();
12772 let local_int_arg =
12773 usize::try_from(context.invoking_state())
12774 .ok()
12775 .and_then(|source_state| {
12776 rule_local_int_arg(
12777 self.options.rule_args,
12778 source_state,
12779 rule_index,
12780 inherited_local_int_arg,
12781 )
12782 });
12783 if self.options.init_action_rules.contains(&rule_index) {
12784 let action = ParserAction::new_rule_init(
12785 rule_index,
12786 rule_start_index,
12787 init_expected_state.or(Some(start_state)),
12788 );
12789 if !self
12790 .parser
12791 .parser_rule_init_hook_with_context(action, &context, local_int_arg)
12792 {
12793 self.deferred_actions.push(action);
12794 }
12795 }
12796 let mut consumed_eof = false;
12797 let result = self.walk_rule(
12798 rule_index,
12799 start_state,
12800 stop_state,
12801 precedence,
12802 rule_start_index,
12803 local_int_arg,
12804 left_recursive,
12805 &mut context,
12806 &mut consumed_eof,
12807 );
12808
12809 let result = match result {
12810 Ok(()) => Ok(if left_recursive {
12811 self.parser.finish_recursion_rule(context, consumed_eof)
12812 } else {
12813 self.parser.finish_rule(context, consumed_eof)
12814 }),
12815 Err(error) if self.parser.bail_on_error() => {
12816 if left_recursive {
12817 self.parser.unroll_recursion_context();
12818 } else {
12819 self.parser.exit_rule();
12820 }
12821 Err(error)
12822 }
12823 Err(error) => {
12824 self.parser
12825 .recover_generated_rule(&mut context, self.atn, error);
12826 Ok(if left_recursive {
12827 self.parser.finish_recursion_rule(context, consumed_eof)
12828 } else {
12829 self.parser.finish_rule(context, consumed_eof)
12830 })
12831 }
12832 };
12833 self.parser.parse_listener_exit_rule(rule_index);
12834 result.map(|tree| CommittedRuleOutcome { tree, consumed_eof })
12835 }
12836
12837 #[allow(clippy::too_many_arguments)]
12838 fn walk_rule(
12839 &mut self,
12840 rule_index: usize,
12841 mut state_number: usize,
12842 stop_state: usize,
12843 precedence: i32,
12844 rule_start_index: usize,
12845 local_int_arg: Option<(usize, i64)>,
12846 left_recursive: bool,
12847 context: &mut ParserRuleContext,
12848 consumed_eof: &mut bool,
12849 ) -> Result<(), AntlrError> {
12850 let mut entered_loops = BTreeSet::new();
12851 let mut visited_coordinates = FxHashSet::default();
12852 let mut guarded_input_index = self.parser.input.index();
12853 while state_number != stop_state {
12854 let input_index = self.parser.input.index();
12855 if input_index != guarded_input_index {
12856 visited_coordinates.clear();
12857 guarded_input_index = input_index;
12858 }
12859 if !visited_coordinates.insert((state_number, input_index)) {
12860 return Err(AntlrError::Unsupported(format!(
12861 "committed parser encountered a non-consuming ATN cycle at state \
12862 {state_number}"
12863 )));
12864 }
12865 let state = self.atn.state(state_number).ok_or_else(|| {
12866 AntlrError::Unsupported(format!("missing parser ATN state {state_number}"))
12867 })?;
12868 if state.is_rule_stop() {
12869 return Err(AntlrError::Unsupported(format!(
12870 "rule {rule_index} reached unexpected stop state {state_number}"
12871 )));
12872 }
12873 let transition_index = {
12874 let mut decision_context = CommittedDecisionContext {
12875 precedence,
12876 local_int_arg,
12877 context,
12878 entered_loops: &mut entered_loops,
12879 };
12880 self.transition_index(state, &mut decision_context)?
12881 };
12882 let transition = state.transitions().get(transition_index).ok_or_else(|| {
12883 AntlrError::Unsupported(format!(
12884 "missing transition {transition_index} from parser ATN state {state_number}"
12885 ))
12886 })?;
12887
12888 let next_alt = next_alt_number(
12889 state,
12890 state.transitions().len(),
12891 transition_index,
12892 context.alt_number(),
12893 self.options.track_alt_numbers,
12894 );
12895 if self.options.track_alt_numbers && context.alt_number() == 0 && next_alt != 0 {
12896 context.set_alt_number(next_alt);
12897 }
12898 let next_context_alt = next_alt_number(
12899 state,
12900 state.transitions().len(),
12901 transition_index,
12902 context.context_alt_number(),
12903 self.options.track_context_alt_numbers,
12904 );
12905 if self.options.track_context_alt_numbers
12906 && context.context_alt_number() == 0
12907 && next_context_alt != 0
12908 {
12909 context.set_context_alt_number(next_context_alt);
12910 }
12911
12912 if left_recursive
12913 && left_recursive_boundary(self.atn, state, transition.target()).is_some()
12914 {
12915 if let Some(error) = self.parser.rule_depth_cap_violation() {
12916 return Err(error);
12917 }
12918 self.parser.parse_listener_exit_rule(rule_index);
12919 self.parser.push_new_recursion_context_with_previous(
12920 invoking_state_number(
12921 self.atn
12922 .rule_to_start_state()
12923 .get(rule_index)
12924 .unwrap_or(state_number),
12925 ),
12926 rule_index,
12927 context,
12928 );
12929 if let Some(error) = self.parser.parse_listener_enter_rule(rule_index) {
12930 return Err(error);
12931 }
12932 }
12933 state_number = self.apply_transition(
12934 state_number,
12935 transition,
12936 precedence,
12937 rule_start_index,
12938 local_int_arg,
12939 context,
12940 consumed_eof,
12941 )?;
12942 }
12943 Ok(())
12944 }
12945
12946 fn transition_index(
12947 &mut self,
12948 state: AtnState<'_>,
12949 decision_context: &mut CommittedDecisionContext<'_>,
12950 ) -> Result<usize, AntlrError> {
12951 let transition_count = state.transitions().len();
12952 if transition_count == 1 {
12953 return Ok(0);
12954 }
12955 let Some(decision) = self
12956 .decision_by_state
12957 .get(state.state_number())
12958 .copied()
12959 .flatten()
12960 else {
12961 return Err(AntlrError::Unsupported(format!(
12962 "parser ATN state {} has {transition_count} transitions but is not a decision",
12963 state.state_number()
12964 )));
12965 };
12966
12967 let decision_start = self.parser.input.index();
12968 let overridden_transition = if self.parser.semantic_hooks.observes_parser_decisions() {
12969 self.parser
12970 .semantic_hooks
12971 .parser_decision_override(decision, decision_start, transition_count)
12972 .and_then(|alternative| alternative.checked_sub(1))
12973 .filter(|alternative| *alternative < transition_count)
12974 } else {
12975 None
12976 };
12977 if let Some(selected) = overridden_transition {
12978 self.update_loop_selection(state, selected, decision_context);
12979 return Ok(selected);
12980 }
12981
12982 if !state.precedence_rule_decision() {
12983 let loop_back = match state.kind() {
12984 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack => true,
12985 AtnStateKind::StarLoopEntry => decision_context
12986 .entered_loops
12987 .contains(&state.state_number()),
12988 _ => false,
12989 };
12990 let children = self.parser.sync_decision(
12991 self.atn,
12992 state.state_number(),
12993 !decision_context.context.has_matched_child(),
12994 loop_back,
12995 )?;
12996 for child in children {
12997 self.parser.add_parse_child(decision_context.context, child);
12998 }
12999 }
13000
13001 let prediction_precedence = if state.precedence_rule_decision() {
13002 usize::try_from(decision_context.precedence.max(0)).unwrap_or_default()
13003 } else {
13004 0
13005 };
13006 let prediction_context = {
13007 let return_states = self
13008 .parser
13009 .prediction_context_return_states(self.atn)
13010 .collect::<Vec<_>>();
13011 self.simulator
13012 .intern_prediction_context(self.parser.rule_context_version(), return_states)
13013 };
13014 self.simulator.set_exact_ambig_detection(
13015 self.parser.prediction_mode() == PredictionMode::LlExactAmbigDetection,
13016 );
13017 let prediction_mode = self.parser.prediction_mode();
13018 let prediction = match self.simulator.adaptive_predict_stream_info_sll_probe(
13019 decision,
13020 prediction_precedence,
13021 &mut self.parser.input,
13022 ) {
13023 Ok(prediction)
13024 if prediction.requires_full_context && prediction_mode != PredictionMode::Sll =>
13025 {
13026 self.simulator.adaptive_predict_stream_info_with_context(
13027 decision,
13028 prediction_precedence,
13029 &mut self.parser.input,
13030 prediction_context,
13031 )
13032 }
13033 prediction => prediction,
13034 };
13035 let mut prediction = match prediction {
13036 Ok(prediction) => prediction,
13037 Err(ParserAtnSimulatorError::NoViableAlt { index, .. })
13038 if state.precedence_rule_decision() =>
13039 {
13040 let enter_alt = state.transitions().iter().position(|transition| {
13041 self.atn
13042 .state(transition.target())
13043 .is_some_and(|target| target.kind() != AtnStateKind::LoopEnd)
13044 });
13045 let exit_alt = state.transitions().iter().position(|transition| {
13046 self.atn
13047 .state(transition.target())
13048 .is_some_and(|target| target.kind() == AtnStateKind::LoopEnd)
13049 });
13050 let selected = if self.parser.left_recursive_loop_enter_matches(
13051 self.atn,
13052 state.state_number(),
13053 decision_context.precedence,
13054 ) {
13055 enter_alt
13056 } else {
13057 exit_alt
13058 };
13059 let Some(selected) = selected else {
13060 return Err(self
13061 .parser
13062 .no_viable_alternative_error_at(decision_start, index));
13063 };
13064 ParserAtnPrediction {
13065 alt: selected + 1,
13066 requires_full_context: true,
13067 has_semantic_context: true,
13068 diagnostic: None,
13069 }
13070 }
13071 Err(ParserAtnSimulatorError::NoViableAlt { index, .. }) => {
13072 return Err(self
13073 .parser
13074 .no_viable_alternative_error_at(decision_start, index));
13075 }
13076 Err(ParserAtnSimulatorError::PredictionRequiresMoreLookahead) => {
13077 return Err(self.parser.no_viable_alternative_error(decision_start));
13078 }
13079 Err(error) => {
13080 return Err(AntlrError::Unsupported(format!(
13081 "committed parser prediction failed at decision {decision}: {error:?}"
13082 )));
13083 }
13084 };
13085 let mut selected = prediction
13086 .alt
13087 .checked_sub(1)
13088 .filter(|index| *index < transition_count)
13089 .ok_or_else(|| self.parser.no_viable_alternative_error(decision_start))?;
13090
13091 let semantic_candidates = self.simulator.prediction_semantic_candidates();
13092 if !semantic_candidates.is_empty() {
13093 let predicted_alt = prediction.alt;
13094 let mut semantic_results = BTreeMap::new();
13095 let selected_alt = selected + 1;
13096 let selected_matches = self.semantic_alternative_matches(
13097 selected_alt,
13098 decision_context,
13099 &semantic_candidates,
13100 );
13101 semantic_results.insert(selected_alt, selected_matches);
13102 if !selected_matches {
13103 let alternatives = semantic_candidates
13104 .iter()
13105 .map(|candidate| candidate.alt)
13106 .filter(|alternative| *alternative != 0 && *alternative <= transition_count)
13107 .collect::<BTreeSet<_>>();
13108 selected = alternatives
13109 .into_iter()
13110 .find(|alternative| {
13111 let matches = self.semantic_alternative_matches(
13112 *alternative,
13113 decision_context,
13114 &semantic_candidates,
13115 );
13116 semantic_results.insert(*alternative, matches);
13117 matches
13118 })
13119 .and_then(|alternative| alternative.checked_sub(1))
13120 .ok_or_else(|| self.parser.no_viable_alternative_error(decision_start))?;
13121 }
13122 if self.parser.report_diagnostic_errors
13123 && let Some(diagnostic) = prediction.diagnostic.as_ref()
13124 {
13125 for alternative in diagnostic.conflicting_alts.clone() {
13126 if semantic_results.contains_key(&alternative)
13127 || !semantic_candidates
13128 .iter()
13129 .any(|candidate| candidate.alt == alternative)
13130 {
13131 continue;
13132 }
13133 let matches = self.semantic_alternative_matches(
13134 alternative,
13135 decision_context,
13136 &semantic_candidates,
13137 );
13138 semantic_results.insert(alternative, matches);
13139 }
13140 }
13141 Self::filter_prediction_diagnostic(
13142 &mut prediction,
13143 predicted_alt,
13144 selected + 1,
13145 &semantic_results,
13146 );
13147 }
13148 self.parser.record_generated_prediction_diagnostic(
13149 self.atn,
13150 state.state_number(),
13151 &prediction,
13152 );
13153
13154 self.update_loop_selection(state, selected, decision_context);
13155 Ok(selected)
13156 }
13157
13158 fn semantic_alternative_matches(
13159 &mut self,
13160 alternative: usize,
13161 decision_context: &CommittedDecisionContext<'_>,
13162 candidates: &[ParserSemanticCandidate],
13163 ) -> bool {
13164 candidates
13165 .iter()
13166 .filter(|candidate| candidate.alt == alternative)
13167 .any(|candidate| {
13168 self.semantic_context_matches(&candidate.context, decision_context, candidate)
13169 })
13170 }
13171
13172 fn filter_prediction_diagnostic(
13173 prediction: &mut ParserAtnPrediction,
13174 predicted_alt: usize,
13175 selected_alt: usize,
13176 semantic_results: &BTreeMap<usize, bool>,
13177 ) {
13178 prediction.alt = selected_alt;
13179 if selected_alt != predicted_alt {
13180 prediction.diagnostic = None;
13181 return;
13182 }
13183 if let Some(diagnostic) = prediction.diagnostic.as_mut() {
13184 diagnostic
13185 .conflicting_alts
13186 .retain(|alternative| semantic_results.get(alternative).copied().unwrap_or(true));
13187 if diagnostic.conflicting_alts.len() < 2 {
13188 prediction.diagnostic = None;
13189 }
13190 }
13191 }
13192
13193 fn semantic_context_matches(
13194 &mut self,
13195 semantic_context: &SemanticContext,
13196 decision_context: &CommittedDecisionContext<'_>,
13197 candidate: &ParserSemanticCandidate,
13198 ) -> bool {
13199 match semantic_context {
13200 SemanticContext::None => true,
13201 SemanticContext::Predicate {
13202 rule_index,
13203 pred_index,
13204 ..
13205 } => {
13206 let mut matched_provenance = false;
13207 for predicate_call in candidate
13208 .predicate_calls
13209 .iter()
13210 .filter(|call| call.rule_index == *rule_index && call.pred_index == *pred_index)
13211 {
13212 matched_provenance = true;
13213 let mut local_int_arg = decision_context.local_int_arg;
13214 for rule_call in &predicate_call.rule_calls {
13215 local_int_arg = rule_local_int_arg(
13216 self.options.rule_args,
13217 rule_call.source_state,
13218 rule_call.rule_index,
13219 local_int_arg,
13220 );
13221 }
13222 if !self.semantic_predicate_matches(
13223 *rule_index,
13224 *pred_index,
13225 decision_context,
13226 local_int_arg,
13227 ) {
13228 return false;
13229 }
13230 }
13231 if matched_provenance {
13232 true
13233 } else {
13234 self.semantic_predicate_matches(
13235 *rule_index,
13236 *pred_index,
13237 decision_context,
13238 decision_context.local_int_arg,
13239 )
13240 }
13241 }
13242 SemanticContext::Precedence { precedence } => {
13243 *precedence >= decision_context.precedence
13244 }
13245 SemanticContext::And(children) => {
13246 for child in children {
13247 if !self.semantic_context_matches(child, decision_context, candidate) {
13248 return false;
13249 }
13250 }
13251 true
13252 }
13253 SemanticContext::Or(children) => {
13254 for child in children {
13255 if self.semantic_context_matches(child, decision_context, candidate) {
13256 return true;
13257 }
13258 }
13259 false
13260 }
13261 }
13262 }
13263
13264 fn semantic_predicate_matches(
13265 &mut self,
13266 rule_index: usize,
13267 pred_index: usize,
13268 decision_context: &CommittedDecisionContext<'_>,
13269 local_int_arg: Option<(usize, i64)>,
13270 ) -> bool {
13271 let member_values = self.parser.int_members.clone();
13272 self.parser.parser_predicate_matches(PredicateEval {
13273 index: self.parser.input.index(),
13274 rule_index,
13275 pred_index,
13276 predicates: self.options.predicates,
13277 semantics: self.options.semantics,
13278 context: Some(&*decision_context.context),
13279 local_int_arg,
13280 member_values: &member_values,
13281 })
13282 }
13283
13284 fn update_loop_selection(
13285 &self,
13286 state: AtnState<'_>,
13287 selected: usize,
13288 decision_context: &mut CommittedDecisionContext<'_>,
13289 ) {
13290 if state.kind() == AtnStateKind::StarLoopEntry {
13291 let enters = self
13292 .atn
13293 .state(
13294 state
13295 .transitions()
13296 .get(selected)
13297 .expect("selected transition is in bounds")
13298 .target(),
13299 )
13300 .is_some_and(|target| target.kind() != AtnStateKind::LoopEnd);
13301 if enters {
13302 decision_context.entered_loops.insert(state.state_number());
13303 } else {
13304 decision_context.entered_loops.remove(&state.state_number());
13305 }
13306 }
13307 }
13308
13309 #[allow(clippy::too_many_arguments)]
13310 fn apply_transition(
13311 &mut self,
13312 source_state: usize,
13313 transition: ParserTransition<'_>,
13314 precedence: i32,
13315 rule_start_index: usize,
13316 local_int_arg: Option<(usize, i64)>,
13317 context: &mut ParserRuleContext,
13318 consumed_eof: &mut bool,
13319 ) -> Result<usize, AntlrError> {
13320 self.parser.set_state(invoking_state_number(source_state));
13321 match transition.data() {
13322 Transition::Epsilon { target } => Ok(target),
13323 Transition::Atom { target, label } => {
13324 let matched = self
13325 .parser
13326 .match_token_recovering(label, target, self.atn)?;
13327 *consumed_eof |= matched.consumed_eof();
13328 for child in matched.into_child_iter() {
13329 self.parser.add_parse_child(context, child);
13330 }
13331 Ok(target)
13332 }
13333 Transition::Range {
13334 target,
13335 start,
13336 stop,
13337 } => {
13338 let matched =
13339 self.parser
13340 .match_set_recovering(&[(start, stop)], target, self.atn)?;
13341 *consumed_eof |= matched.consumed_eof();
13342 for child in matched.into_child_iter() {
13343 self.parser.add_parse_child(context, child);
13344 }
13345 Ok(target)
13346 }
13347 Transition::Set { target, set } => {
13348 let matched = self
13349 .parser
13350 .match_token_set_recovering(set, target, self.atn)?;
13351 *consumed_eof |= matched.consumed_eof();
13352 for child in matched.into_child_iter() {
13353 self.parser.add_parse_child(context, child);
13354 }
13355 Ok(target)
13356 }
13357 Transition::NotSet { target, set } => {
13358 let matched = self.parser.match_not_token_set_recovering(
13359 set,
13360 1,
13361 self.atn.max_token_type(),
13362 target,
13363 self.atn,
13364 )?;
13365 *consumed_eof |= matched.consumed_eof();
13366 for child in matched.into_child_iter() {
13367 self.parser.add_parse_child(context, child);
13368 }
13369 Ok(target)
13370 }
13371 Transition::Wildcard { target } => {
13372 let matched = self.parser.match_not_set_recovering(
13373 &[],
13374 1,
13375 self.atn.max_token_type(),
13376 target,
13377 self.atn,
13378 )?;
13379 *consumed_eof |= matched.consumed_eof();
13380 for child in matched.into_child_iter() {
13381 self.parser.add_parse_child(context, child);
13382 }
13383 Ok(target)
13384 }
13385 Transition::Rule {
13386 rule_index,
13387 follow_state,
13388 precedence: rule_precedence,
13389 ..
13390 } => {
13391 let marker = self
13392 .parser
13393 .push_invoking_state(invoking_state_number(source_state));
13394 let child = if self.parser.generated_rule_stack_check_due() {
13395 grow_generated_rule_stack(|| {
13396 self.parse_rule(
13397 rule_index,
13398 rule_precedence,
13399 local_int_arg,
13400 Some(follow_state),
13401 )
13402 })
13403 } else {
13404 self.parse_rule(
13405 rule_index,
13406 rule_precedence,
13407 local_int_arg,
13408 Some(follow_state),
13409 )
13410 };
13411 self.parser.discard_invoking_state(marker);
13412 let child = child?;
13413 *consumed_eof |= child.consumed_eof;
13414 self.parser.add_parse_child(context, child.tree);
13415 Ok(follow_state)
13416 }
13417 Transition::Predicate {
13418 target,
13419 rule_index,
13420 pred_index,
13421 ..
13422 } => {
13423 let member_values = self.parser.int_members.clone();
13424 if self.parser.parser_predicate_matches(PredicateEval {
13425 index: self.parser.input.index(),
13426 rule_index,
13427 pred_index,
13428 predicates: self.options.predicates,
13429 semantics: self.options.semantics,
13430 context: Some(context),
13431 local_int_arg,
13432 member_values: &member_values,
13433 }) {
13434 return Ok(target);
13435 }
13436 if let Some(message) = self
13437 .options
13438 .semantics
13439 .and_then(|semantics| {
13440 self.parser.parser_semantic_ir_predicate_failure_message(
13441 rule_index, pred_index, semantics,
13442 )
13443 })
13444 .or_else(|| {
13445 self.parser.parser_predicate_failure_message(
13446 rule_index,
13447 pred_index,
13448 self.options.predicates,
13449 )
13450 })
13451 {
13452 return Err(self
13453 .parser
13454 .failed_predicate_option_error(rule_index, message));
13455 }
13456 Err(self.parser.failed_predicate_error("semantic predicate"))
13457 }
13458 Transition::Action {
13459 target, rule_index, ..
13460 } => {
13461 self.apply_translated_actions(source_state, rule_index, context);
13462 if let Some(action_index) = self.action_index(source_state) {
13463 let action = self.parser.parser_action_at_current_indexed(
13464 source_state,
13465 rule_index,
13466 action_index,
13467 rule_start_index,
13468 *consumed_eof,
13469 );
13470 let _ = self.parser.parser_action_hook_inner(
13471 action,
13472 Some(context),
13473 None,
13474 local_int_arg,
13475 true,
13476 );
13477 }
13478 Ok(target)
13479 }
13480 Transition::Precedence {
13481 target,
13482 precedence: transition_precedence,
13483 } => {
13484 if transition_precedence >= precedence {
13485 Ok(target)
13486 } else {
13487 Err(self
13488 .parser
13489 .failed_predicate_error(format!("precpred(_ctx, {transition_precedence})")))
13490 }
13491 }
13492 }
13493 }
13494
13495 fn apply_translated_actions(
13496 &mut self,
13497 source_state: usize,
13498 rule_index: usize,
13499 context: &mut ParserRuleContext,
13500 ) {
13501 apply_member_actions(
13502 source_state,
13503 self.options.member_actions,
13504 self.options.semantics,
13505 &mut self.parser.int_members,
13506 );
13507 let return_values = return_values_after_action(
13508 source_state,
13509 rule_index,
13510 self.options.return_actions,
13511 self.options.semantics,
13512 &BTreeMap::new(),
13513 );
13514 for (name, value) in return_values {
13515 context.set_int_return(name, value);
13516 }
13517 }
13518
13519 fn action_index(&self, source_state: usize) -> Option<usize> {
13520 self.action_index_by_state.get(&source_state).copied()
13521 }
13522}
13523
13524fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
13527 if !state.precedence_rule_decision() {
13528 return None;
13529 }
13530 let target_state = atn.state(target)?;
13531 if target_state.kind() == AtnStateKind::LoopEnd {
13532 return None;
13533 }
13534 state.rule_index()
13535}
13536
13537fn next_alt_number(
13544 state: AtnState<'_>,
13545 transition_count: usize,
13546 transition_index: usize,
13547 current_alt_number: usize,
13548 track_alt_numbers: bool,
13549) -> usize {
13550 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
13551 return current_alt_number;
13552 }
13553 if matches!(
13554 state.kind(),
13555 AtnStateKind::Basic
13556 | AtnStateKind::BlockStart
13557 | AtnStateKind::PlusBlockStart
13558 | AtnStateKind::StarBlockStart
13559 | AtnStateKind::StarLoopEntry
13560 ) && !state.precedence_rule_decision()
13561 {
13562 return transition_index + 1;
13563 }
13564 current_alt_number
13565}
13566
13567fn invoking_state_number(state_number: usize) -> isize {
13570 isize::try_from(state_number).unwrap_or(isize::MAX)
13571}
13572
13573const fn packed_i32(value: u32) -> i32 {
13574 i32::from_le_bytes(value.to_le_bytes())
13575}
13576
13577fn direct_precedence(precedence: i32) -> usize {
13578 usize::try_from(precedence.max(0)).unwrap_or_default()
13579}
13580
13581fn token_input_display(token: &impl Token) -> String {
13582 format!("'{}'", token.text().unwrap_or("<EOF>"))
13583}
13584
13585fn display_input_text(text: &str) -> String {
13586 let mut out = String::new();
13587 for ch in text.chars() {
13588 match ch {
13589 '\n' => out.push_str("\\n"),
13590 '\r' => out.push_str("\\r"),
13591 '\t' => out.push_str("\\t"),
13592 other => out.push(other),
13593 }
13594 }
13595 out
13596}
13597
13598fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
13599 let (line, column, offending) = token.map_or((0, 0, None), |token| {
13600 (token.line(), token.column(), Some(token.token_id()))
13601 });
13602 ParserDiagnostic {
13603 line,
13604 column,
13605 message,
13606 offending,
13607 }
13608}
13609
13610fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
13611 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
13612}
13613
13614fn expected_symbols_display_iter(
13615 symbols: impl IntoIterator<Item = i32>,
13616 vocabulary: &Vocabulary,
13617) -> String {
13618 let items = symbols
13619 .into_iter()
13620 .map(|symbol| expected_symbol_display(symbol, vocabulary))
13621 .collect::<Vec<_>>();
13622 if let [single] = items.as_slice() {
13623 return single.clone();
13624 }
13625 format!("{{{}}}", items.join(", "))
13626}
13627
13628fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
13629 if symbol == TOKEN_EOF {
13630 return "<EOF>".to_owned();
13631 }
13632 vocabulary.display_name(symbol)
13633}
13634
13635fn caller_follow_token_info_for_stream<S: TokenSource>(
13636 input: &mut CommonTokenStream<S>,
13637 index: usize,
13638) -> (i32, bool, bool) {
13639 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
13642 input.fill();
13643 }
13644 let token_type = input.token_type_at_index(index);
13645 let visible_channel = input.channel();
13646 let token = input.get(index);
13647 let is_boundary = token
13648 .as_ref()
13649 .and_then(Token::text)
13650 .is_some_and(is_caller_follow_boundary_text);
13651 let is_boundary_gap = token.as_ref().is_some_and(|token| {
13652 token.channel() != visible_channel
13653 || is_caller_follow_boundary_gap_text(token.text_or_empty())
13654 });
13655 (token_type, is_boundary, is_boundary_gap)
13656}
13657
13658fn is_caller_follow_boundary_text(text: &str) -> bool {
13659 text.chars().any(|ch| ch == ';' || ch == '\n')
13660 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
13661}
13662
13663fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
13664 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
13665}
13666
13667fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
13671 let Some(rule_index) = state.rule_index() else {
13672 return false;
13673 };
13674 atn.rule_to_start_state()
13675 .get(rule_index)
13676 .and_then(|state_number| atn.state(state_number))
13677 .is_some_and(AtnState::left_recursive_rule)
13678}
13679
13680fn select_better_top_outcome(
13687 first: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
13688 second: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
13689 arena: &RecognitionArena,
13690) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
13691 match (first, second) {
13692 (Ok(first), Ok(second)) => {
13693 if arena.diagnostics(first.0.diagnostics).next().is_none() {
13694 Ok(first)
13695 } else {
13696 Ok(second)
13697 }
13698 }
13699 (Ok(first), Err(_)) => Ok(first),
13700 (Err(_), Ok(second)) => Ok(second),
13701 (Err(_), Err(second_expected)) => Err(second_expected),
13702 }
13703}
13704
13705fn select_best_fast_outcome(
13711 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
13712 prediction_mode: PredictionMode,
13713 caller_follow: Option<&TokenBitSet>,
13714 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
13715 arena: &RecognitionArena,
13716) -> Option<FastRecognizeOutcome> {
13717 let mut best = None;
13718 let mut best_caller_follow = None;
13719 for outcome in outcomes {
13720 if matches!(
13721 prediction_mode,
13722 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
13723 ) && outcome.diagnostics.is_empty()
13724 && let Some(follow) = caller_follow
13725 {
13726 let (token_type, is_boundary, _) = token_info_at(outcome.index);
13727 if is_boundary && follow.contains(token_type) {
13728 let replace =
13729 best_caller_follow
13730 .as_ref()
13731 .is_none_or(|existing: &FastRecognizeOutcome| {
13732 (outcome.index, outcome.consumed_eof)
13733 < (existing.index, existing.consumed_eof)
13734 });
13735 if replace {
13736 best_caller_follow = Some(outcome);
13737 }
13738 }
13739 }
13740 let Some(existing) = best else {
13741 best = Some(outcome);
13742 continue;
13743 };
13744 let outcome_position = (outcome.index, outcome.consumed_eof);
13745 let best_position = (existing.index, existing.consumed_eof);
13746 let better = match prediction_mode {
13747 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
13748 outcome_position,
13749 outcome.diagnostics,
13750 best_position,
13751 existing.diagnostics,
13752 arena,
13753 ),
13754 PredictionMode::Sll => outcome.index > existing.index,
13755 };
13756 best = Some(if better { outcome } else { existing });
13757 }
13758 let should_use_caller_follow =
13759 best_caller_follow
13760 .as_ref()
13761 .zip(best.as_ref())
13762 .is_some_and(|(candidate, selected)| {
13763 if !selected.diagnostics.is_empty() {
13764 return true;
13765 }
13766 candidate.index < selected.index
13767 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
13768 });
13769 if should_use_caller_follow {
13770 best_caller_follow
13771 } else {
13772 best
13773 }
13774}
13775
13776fn select_best_outcome(
13777 outcomes: impl Iterator<Item = RecognizeOutcome>,
13778 prediction_mode: PredictionMode,
13779 arena: &RecognitionArena,
13780) -> Option<RecognizeOutcome> {
13781 let outcomes = outcomes.collect::<Vec<_>>();
13782 let prefer_first_tie = outcomes
13783 .iter()
13784 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
13785 outcomes.into_iter().reduce(|best, outcome| {
13786 let outcome_position = (outcome.index, outcome.consumed_eof);
13787 let best_position = (best.index, best.consumed_eof);
13788 let better = match prediction_mode {
13789 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
13790 outcome_is_better(
13791 outcome_position,
13792 outcome.diagnostics,
13793 best_position,
13794 best.diagnostics,
13795 arena,
13796 ) || (outcome_position == best_position
13797 && arena.diagnostics_len(outcome.diagnostics)
13798 == arena.diagnostics_len(best.diagnostics)
13799 && arena.diagnostics_recovery_rank(outcome.diagnostics)
13800 == arena.diagnostics_recovery_rank(best.diagnostics)
13801 && (outcome.decisions < best.decisions
13802 || (!prefer_first_tie
13803 && outcome.decisions == best.decisions
13804 && outcome.actions > best.actions)))
13805 }
13806 PredictionMode::Sll => {
13807 outcome_position > best_position
13808 || (outcome_position == best_position
13809 && !prefer_first_tie
13810 && (outcome.decisions < best.decisions
13811 || (outcome.decisions == best.decisions
13812 && outcome_is_better(
13813 outcome_position,
13814 outcome.diagnostics,
13815 best_position,
13816 best.diagnostics,
13817 arena,
13818 ))))
13819 }
13820 };
13821 if better {
13822 return outcome;
13823 }
13824 best
13825 })
13826}
13827
13828fn transition_decision(
13835 atn: &Atn,
13836 state: AtnState<'_>,
13837 transition_count: usize,
13838 transition_index: usize,
13839 predicates: &[(usize, usize, ParserPredicate)],
13840) -> Option<usize> {
13841 if transition_count <= 1 || decision_reaches_unsupported_predicate(atn, state, predicates) {
13842 return None;
13843 }
13844 Some(transition_index)
13845}
13846
13847fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
13853 transition_count > 1
13854 && !matches!(
13855 state.kind(),
13856 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
13857 )
13858}
13859
13860fn record_no_viable_if_ambiguous(
13863 expected: &mut ExpectedTokens,
13864 decision_start_index: Option<usize>,
13865 index: usize,
13866) {
13867 if expected.index == Some(index) && expected.symbols.len() > 1 {
13868 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
13869 expected.record_no_viable(decision_start, index);
13870 }
13871 }
13872}
13873
13874const fn record_predicate_no_viable(
13877 expected: &mut ExpectedTokens,
13878 decision_start_index: Option<usize>,
13879 index: usize,
13880) {
13881 if let Some(decision_start) = decision_start_index {
13882 expected.record_no_viable(decision_start, index);
13883 }
13884}
13885
13886const fn no_viable_decision_start(
13888 decision_start_index: Option<usize>,
13889 index: usize,
13890) -> Option<usize> {
13891 match decision_start_index {
13892 Some(start) if index > start => Some(start),
13893 _ => None,
13894 }
13895}
13896
13897fn restore_expected(
13901 children: &[RecognizeOutcome],
13902 child_start_index: usize,
13903 expected: &mut ExpectedTokens,
13904 snapshot: ExpectedTokens,
13905 preserve_child_expected: bool,
13906) {
13907 if preserve_child_expected {
13908 return;
13909 }
13910 if children
13911 .iter()
13912 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
13913 {
13914 *expected = snapshot;
13915 }
13916}
13917
13918fn decision_reaches_unsupported_predicate(
13921 atn: &Atn,
13922 state: AtnState<'_>,
13923 predicates: &[(usize, usize, ParserPredicate)],
13924) -> bool {
13925 state.transitions().iter().any(|transition| {
13926 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
13927 })
13928}
13929
13930fn transition_reaches_unsupported_predicate(
13932 atn: &Atn,
13933 transition: ParserTransition<'_>,
13934 predicates: &[(usize, usize, ParserPredicate)],
13935 visited: &mut BTreeSet<usize>,
13936) -> bool {
13937 match &transition.data() {
13938 Transition::Predicate {
13939 rule_index,
13940 pred_index,
13941 ..
13942 } => !predicates
13943 .iter()
13944 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
13945 Transition::Epsilon { target }
13946 | Transition::Action { target, .. }
13947 | Transition::Rule { target, .. } => {
13948 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
13949 }
13950 Transition::Precedence { .. }
13951 | Transition::Atom { .. }
13952 | Transition::Range { .. }
13953 | Transition::Set { .. }
13954 | Transition::NotSet { .. }
13955 | Transition::Wildcard { .. } => false,
13956 }
13957}
13958
13959fn state_reaches_unsupported_predicate(
13961 atn: &Atn,
13962 state_number: usize,
13963 predicates: &[(usize, usize, ParserPredicate)],
13964 visited: &mut BTreeSet<usize>,
13965) -> bool {
13966 if !visited.insert(state_number) {
13967 return false;
13968 }
13969 let Some(state) = atn.state(state_number) else {
13970 return false;
13971 };
13972 state.transitions().iter().any(|transition| {
13973 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
13974 })
13975}
13976
13977fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
13979 if let Some(decision) = decision {
13980 outcome.decisions.insert(0, decision);
13981 }
13982}
13983
13984fn outcome_is_better(
13985 outcome_position: (usize, bool),
13986 outcome_diagnostics: DiagnosticSeqId,
13987 best_position: (usize, bool),
13988 best_diagnostics: DiagnosticSeqId,
13989 arena: &RecognitionArena,
13990) -> bool {
13991 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
13992 let best_len = arena.diagnostics_len(best_diagnostics);
13993 outcome_position > best_position
13994 || (outcome_position == best_position
13995 && (outcome_len < best_len
13996 || (outcome_len == best_len
13997 && arena.diagnostics_recovery_rank(outcome_diagnostics)
13998 < arena.diagnostics_recovery_rank(best_diagnostics))))
13999}
14000
14001fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
14002 if outcomes
14003 .iter()
14004 .any(|outcome| outcome.diagnostics.is_empty())
14005 {
14006 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
14007 }
14008}
14009
14010fn discard_recovered_outcomes_if_clean_path_exists(
14011 outcomes: &mut Vec<RecognizeOutcome>,
14012 arena: &RecognitionArena,
14013) {
14014 if outcomes
14015 .iter()
14016 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
14017 {
14018 return;
14019 }
14020 if outcomes
14021 .iter()
14022 .any(|outcome| outcome.diagnostics.is_empty())
14023 {
14024 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
14025 }
14026}
14027
14028fn outcome_has_rule_failure_diagnostic(
14031 outcome: &RecognizeOutcome,
14032 arena: &RecognitionArena,
14033) -> bool {
14034 arena
14035 .diagnostics(outcome.diagnostics)
14036 .any(|diagnostic| diagnostic.message.starts_with("rule "))
14037}
14038
14039fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
14053 if outcomes.len() < 2 {
14054 return;
14055 }
14056 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
14057 outcomes.retain(|outcome| {
14058 seen.insert((
14059 outcome.index,
14060 outcome.consumed_eof,
14061 arena.diagnostics_len(outcome.diagnostics),
14062 arena.diagnostics_recovery_rank(outcome.diagnostics),
14063 ))
14064 });
14065}
14066
14067const FAST_OUTCOME_INLINE_KEYS: usize = 8;
14068const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
14069const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
14070const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
14071
14072#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14073enum FastOutcomeDedupStrategy {
14074 Inline,
14075 Dense,
14076 Sparse,
14077}
14078
14079impl FastOutcomeDedupScratch {
14080 fn prepare_dense(&mut self, word_count: usize) {
14081 while let Some(word_index) = self.touched_dense_words.pop() {
14082 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
14083 }
14084 if self.dense_words.len() < word_count {
14085 self.dense_words.resize(word_count, 0);
14086 }
14087 }
14088}
14089
14090fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
14091 let first_index = outcomes.first()?.index;
14092 let (min_index, max_index) = outcomes[1..].iter().fold(
14093 (first_index, first_index),
14094 |(min_index, max_index), outcome| {
14095 (min_index.min(outcome.index), max_index.max(outcome.index))
14096 },
14097 );
14098 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
14099 let bit_count = index_span.checked_mul(2)?;
14100 let word_count =
14101 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
14102 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
14103 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
14104 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
14105 .then_some((min_index, word_count))
14106}
14107
14108#[cfg(feature = "perf-counters")]
14109fn record_clean_fast_outcome_dedup(
14110 strategy: FastOutcomeDedupStrategy,
14111 input_len: usize,
14112 output_len: usize,
14113 dense_words: usize,
14114) {
14115 let counter = match strategy {
14116 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
14117 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
14118 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
14119 };
14120 perf_counters::inc(
14121 &perf_counters::OUTCOME_DEDUPE_INPUTS,
14122 u64::try_from(input_len).unwrap_or(u64::MAX),
14123 );
14124 perf_counters::inc(
14125 &perf_counters::OUTCOME_DEDUPE_REMOVED,
14126 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
14127 );
14128 perf_counters::inc(counter, 1);
14129 perf_counters::inc(
14130 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
14131 u64::try_from(dense_words).unwrap_or(u64::MAX),
14132 );
14133}
14134
14135fn dedupe_clean_fast_outcomes(
14139 outcomes: &mut Vec<FastRecognizeOutcome>,
14140 scratch: &mut FastOutcomeDedupScratch,
14141) -> FastOutcomeDedupStrategy {
14142 #[cfg(feature = "perf-counters")]
14143 let input_len = outcomes.len();
14144 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
14145 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
14146 let mut inline_len = 0_usize;
14147 outcomes.retain(|outcome| {
14148 let key = (outcome.index, outcome.consumed_eof);
14149 if inline_keys[..inline_len].contains(&key) {
14150 return false;
14151 }
14152 inline_keys[inline_len] = key;
14153 inline_len += 1;
14154 true
14155 });
14156 #[cfg(feature = "perf-counters")]
14157 record_clean_fast_outcome_dedup(
14158 FastOutcomeDedupStrategy::Inline,
14159 input_len,
14160 outcomes.len(),
14161 0,
14162 );
14163 return FastOutcomeDedupStrategy::Inline;
14164 }
14165
14166 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
14167 scratch.prepare_dense(word_count);
14168 outcomes.retain(|outcome| {
14169 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
14170 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
14171 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
14172 let word = &mut scratch.dense_words[word_index];
14173 if *word & bit != 0 {
14174 return false;
14175 }
14176 if *word == 0 {
14177 scratch
14178 .touched_dense_words
14179 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
14180 }
14181 *word |= bit;
14182 true
14183 });
14184 #[cfg(feature = "perf-counters")]
14185 record_clean_fast_outcome_dedup(
14186 FastOutcomeDedupStrategy::Dense,
14187 input_len,
14188 outcomes.len(),
14189 word_count,
14190 );
14191 return FastOutcomeDedupStrategy::Dense;
14192 }
14193
14194 scratch.sparse_keys.clear();
14195 scratch.sparse_keys.reserve(outcomes.len());
14196 outcomes.retain(|outcome| {
14197 scratch
14198 .sparse_keys
14199 .insert((outcome.index, outcome.consumed_eof))
14200 });
14201 #[cfg(feature = "perf-counters")]
14202 record_clean_fast_outcome_dedup(
14203 FastOutcomeDedupStrategy::Sparse,
14204 input_len,
14205 outcomes.len(),
14206 0,
14207 );
14208 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
14209 scratch.sparse_keys = FxHashSet::default();
14210 }
14211 FastOutcomeDedupStrategy::Sparse
14212}
14213
14214fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
14217 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
14218 outcomes
14219 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
14220}
14221
14222fn compare_recognize_outcomes(
14223 left: &RecognizeOutcome,
14224 right: &RecognizeOutcome,
14225 arena: &RecognitionArena,
14226) -> Ordering {
14227 left.index
14228 .cmp(&right.index)
14229 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
14230 .then_with(|| left.alt_number.cmp(&right.alt_number))
14231 .then_with(|| left.member_values.cmp(&right.member_values))
14232 .then_with(|| left.return_values.cmp(&right.return_values))
14233 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
14234 .then_with(|| left.decisions.cmp(&right.decisions))
14235 .then_with(|| left.actions.cmp(&right.actions))
14236 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
14237}
14238
14239impl<S, H> Recognizer for BaseParser<S, H>
14240where
14241 S: TokenSource,
14242 H: SemanticHooks,
14243{
14244 fn data(&self) -> &RecognizerData {
14245 &self.data
14246 }
14247
14248 fn data_mut(&mut self) -> &mut RecognizerData {
14249 &mut self.data
14250 }
14251}
14252
14253impl<S, H> Parser for BaseParser<S, H>
14254where
14255 S: TokenSource,
14256 H: SemanticHooks,
14257{
14258 fn build_parse_trees(&self) -> bool {
14259 self.build_parse_trees
14260 }
14261
14262 fn set_build_parse_trees(&mut self, build: bool) {
14263 self.build_parse_trees = build;
14264 }
14265
14266 fn number_of_syntax_errors(&self) -> usize {
14267 Self::number_of_syntax_errors(self)
14268 }
14269
14270 fn report_diagnostic_errors(&self) -> bool {
14271 self.report_diagnostic_errors
14272 }
14273
14274 fn set_report_diagnostic_errors(&mut self, report: bool) {
14275 self.report_diagnostic_errors = report;
14276 }
14277
14278 fn prediction_mode(&self) -> PredictionMode {
14279 self.prediction_mode
14280 }
14281
14282 fn set_prediction_mode(&mut self, mode: PredictionMode) {
14283 self.prediction_mode = mode;
14284 }
14285
14286 fn max_rule_depth(&self) -> Option<usize> {
14287 self.max_rule_depth
14288 }
14289
14290 fn set_max_rule_depth(&mut self, depth: Option<usize>) {
14291 self.max_rule_depth = depth;
14292 }
14293
14294 fn add_parse_listener(&mut self, listener: Box<dyn ParseListener>) {
14295 self.parse_listeners.push(ParseListenerSlot(listener));
14296 }
14297
14298 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
14299 Self::remove_parse_listeners(self)
14300 }
14301}
14302
14303#[cfg(test)]
14304#[allow(clippy::disallowed_methods)] mod tests {
14306 use super::*;
14307 use crate::atn::parser::{
14308 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
14309 };
14310 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
14311 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
14312 use crate::token_stream::CommonTokenStream;
14313 use crate::tree::{NodeKind, ParseTreeStats};
14314 use crate::vocabulary::Vocabulary;
14315 use std::cell::RefCell;
14316 use std::mem::size_of;
14317 use std::rc::Rc;
14318 use std::sync::{Arc, Mutex};
14319
14320 #[test]
14321 fn fx_hasher_write_matches_typed_methods_for_full_words() {
14322 let value: u64 = 0x0102_0304_0506_0708;
14329 let mut typed = FxHasher::default();
14330 typed.write_u64(value);
14331 let mut bytewise = FxHasher::default();
14332 bytewise.write(&value.to_le_bytes());
14333 assert_eq!(typed.finish(), bytewise.finish());
14334 }
14335
14336 #[derive(Clone, Debug)]
14337 struct TestToken {
14338 spec: TokenSpec,
14339 id: TokenId,
14340 source_name: String,
14341 }
14342
14343 impl TestToken {
14344 fn new(token_type: i32) -> Self {
14345 Self {
14346 spec: TokenSpec::explicit(token_type, ""),
14347 id: TokenId::try_from(0).expect("zero token ID"),
14348 source_name: String::new(),
14349 }
14350 }
14351
14352 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
14353 Self {
14354 spec: TokenSpec::eof(index, index, line, column),
14355 id: TokenId::try_from(0).expect("zero token ID"),
14356 source_name: source_name.to_owned(),
14357 }
14358 }
14359
14360 fn with_text(mut self, text: impl Into<String>) -> Self {
14361 self.spec.text = Some(text.into());
14362 self
14363 }
14364
14365 const fn with_channel(mut self, channel: i32) -> Self {
14366 self.spec.channel = channel;
14367 self
14368 }
14369
14370 fn with_span(mut self, start: usize, stop: usize) -> Self {
14371 self.spec = self.spec.with_span(start, stop);
14372 self
14373 }
14374
14375 fn with_byte_span(mut self, start: usize, stop: usize) -> Self {
14376 self.spec = self.spec.with_byte_span(start, stop);
14377 self
14378 }
14379
14380 const fn with_position(mut self, line: usize, column: usize) -> Self {
14381 self.spec.line = line;
14382 self.spec.column = column;
14383 self
14384 }
14385
14386 fn set_token_index(&mut self, index: isize) {
14387 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
14388 }
14389 }
14390
14391 impl Token for TestToken {
14392 fn token_id(&self) -> TokenId {
14393 self.id
14394 }
14395
14396 fn token_type(&self) -> i32 {
14397 self.spec.token_type
14398 }
14399
14400 fn channel(&self) -> i32 {
14401 self.spec.channel
14402 }
14403
14404 fn start(&self) -> usize {
14405 self.spec.start
14406 }
14407
14408 fn stop(&self) -> usize {
14409 self.spec.stop
14410 }
14411
14412 fn line(&self) -> usize {
14413 self.spec.line
14414 }
14415
14416 fn column(&self) -> usize {
14417 self.spec.column
14418 }
14419
14420 fn text(&self) -> Option<&str> {
14421 self.spec.text.as_deref()
14422 }
14423
14424 fn source_name(&self) -> &str {
14425 &self.source_name
14426 }
14427
14428 fn start_byte(&self) -> Option<usize> {
14429 (self.spec.start_byte != usize::MAX).then_some(self.spec.start_byte)
14430 }
14431
14432 fn stop_byte(&self) -> Option<usize> {
14433 (self.spec.stop_byte != usize::MAX).then_some(self.spec.stop_byte)
14434 }
14435 }
14436
14437 #[derive(Debug)]
14438 struct Source {
14439 tokens: Vec<TestToken>,
14440 index: usize,
14441 }
14442
14443 impl TokenSource for Source {
14444 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
14445 let token = self
14446 .tokens
14447 .get(self.index)
14448 .cloned()
14449 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
14450 self.index += 1;
14451 sink.push(token.spec)
14452 }
14453
14454 fn line(&self) -> usize {
14455 1
14456 }
14457
14458 fn column(&self) -> usize {
14459 self.index
14460 }
14461
14462 fn source_name(&self) -> &'static str {
14463 "parser-test"
14464 }
14465 }
14466
14467 #[derive(Clone, Debug, Eq, PartialEq)]
14468 struct RecordedDiagnostic {
14469 grammar_file_name: String,
14470 offending_text: Option<String>,
14471 line: usize,
14472 column: usize,
14473 span: Option<std::ops::Range<usize>>,
14474 message: String,
14475 error: Option<AntlrError>,
14476 }
14477
14478 #[derive(Clone, Debug)]
14479 struct RecordingErrorListener {
14480 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
14481 }
14482
14483 impl<R> crate::ErrorListener<R> for RecordingErrorListener
14484 where
14485 R: Recognizer + ?Sized,
14486 {
14487 fn syntax_error(&mut self, recognizer: &R, event: &SyntaxErrorEvent<'_>) {
14488 self.diagnostics
14489 .lock()
14490 .expect("recorded diagnostics lock")
14491 .push(RecordedDiagnostic {
14492 grammar_file_name: recognizer.grammar_file_name().to_owned(),
14493 offending_text: event
14494 .offending
14495 .and_then(|token| token.text().map(str::to_owned)),
14496 line: event.line,
14497 column: event.column,
14498 span: event.span.clone(),
14499 message: event.message.to_owned(),
14500 error: event.error.cloned(),
14501 });
14502 }
14503 }
14504
14505 #[derive(Debug)]
14506 struct ReportingSource {
14507 source: Source,
14508 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
14509 }
14510
14511 impl TokenSource for ReportingSource {
14512 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
14513 self.source.next_token(sink)
14514 }
14515
14516 fn line(&self) -> usize {
14517 self.source.line()
14518 }
14519
14520 fn column(&self) -> usize {
14521 self.source.column()
14522 }
14523
14524 fn source_name(&self) -> &str {
14525 self.source.source_name()
14526 }
14527
14528 fn report_error(&self, error: &TokenSourceError) -> bool {
14529 self.diagnostics.borrow_mut().push(error.clone());
14530 true
14531 }
14532 }
14533
14534 fn mini_parser_data() -> RecognizerData {
14535 RecognizerData::new(
14536 "Mini.g4",
14537 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14538 )
14539 .with_rule_names(["s"])
14540 }
14541
14542 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
14543 let data = mini_parser_data();
14544 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
14545 }
14546
14547 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
14548 where
14549 H: SemanticHooks,
14550 {
14551 BaseParser::with_semantic_hooks(
14552 CommonTokenStream::new(Source { tokens, index: 0 }),
14553 mini_parser_data(),
14554 hooks,
14555 )
14556 }
14557
14558 #[test]
14559 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
14560 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
14561 parser.remove_error_listeners();
14562 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14563 parser.add_error_listener(RecordingErrorListener {
14564 diagnostics: Arc::clone(&diagnostics),
14565 });
14566 let parser_diagnostics = [ParserDiagnostic {
14567 line: 1,
14568 column: 2,
14569 message: "missing 'x' at 'y'".to_owned(),
14570 offending: None,
14571 }];
14572 let token_errors = [
14573 TokenSourceError::new(1, 1, "token recognition error at: '@'").with_span(1..2),
14574 TokenSourceError::new(1, 3, "token recognition error at: '#'").with_span(3..4),
14575 ];
14576
14577 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
14578
14579 insta::assert_debug_snapshot!(
14582 "parser_dispatches_recovery_diagnostics_through_registered_listeners",
14583 *diagnostics.lock().expect("recorded diagnostics lock")
14584 );
14585
14586 parser.remove_error_listeners();
14587 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
14588 assert_eq!(
14589 diagnostics.lock().expect("recorded diagnostics lock").len(),
14590 3
14591 );
14592 }
14593
14594 #[test]
14595 fn recovery_diagnostics_expose_the_offending_token_to_listeners() {
14596 let mut parser = mini_parser(vec![
14597 TestToken::new(7)
14598 .with_text("oops")
14599 .with_span(0, 3)
14600 .with_byte_span(0, 4)
14601 .with_position(1, 2),
14602 TestToken::eof("parser-test", 4, 1, 6),
14603 ]);
14604 parser.remove_error_listeners();
14605 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14606 parser.add_error_listener(RecordingErrorListener {
14607 diagnostics: Arc::clone(&diagnostics),
14608 });
14609 let offending = parser.input.lt_id(1);
14610 assert!(offending.is_some(), "current token should be buffered");
14611 let parser_diagnostics = [ParserDiagnostic {
14612 line: 1,
14613 column: 2,
14614 message: "extraneous input 'oops'".to_owned(),
14615 offending,
14616 }];
14617
14618 parser.dispatch_generated_diagnostics(&parser_diagnostics, &[]);
14619
14620 let recorded = diagnostics
14624 .lock()
14625 .expect("recorded diagnostics lock")
14626 .clone();
14627 insta::assert_debug_snapshot!(
14628 "recovery_diagnostics_expose_the_offending_token_to_listeners",
14629 recorded
14630 );
14631 }
14632
14633 #[test]
14634 fn recovery_diagnostics_preserve_unknown_custom_token_span() {
14635 let mut parser = mini_parser(vec![
14636 TestToken::new(7)
14637 .with_text("oops")
14638 .with_span(0, 3)
14639 .with_position(1, 2),
14640 TestToken::eof("parser-test", 4, 1, 6),
14641 ]);
14642 parser.remove_error_listeners();
14643 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14644 parser.add_error_listener(RecordingErrorListener {
14645 diagnostics: Arc::clone(&diagnostics),
14646 });
14647 let offending = parser.input.lt_id(1);
14648 assert!(offending.is_some(), "current token should be buffered");
14649
14650 parser.dispatch_parser_diagnostic(&ParserDiagnostic {
14651 line: 1,
14652 column: 2,
14653 message: "extraneous input 'oops'".to_owned(),
14654 offending,
14655 });
14656
14657 let span = {
14658 let diagnostics = diagnostics.lock().expect("recorded diagnostics lock");
14659 assert_eq!(diagnostics.len(), 1);
14660 diagnostics[0].span.clone()
14661 };
14662 assert_eq!(span, None);
14663 }
14664
14665 #[test]
14666 fn parser_leaves_token_errors_to_source_owned_listeners() {
14667 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
14668 let source = ReportingSource {
14669 source: Source {
14670 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
14671 index: 0,
14672 },
14673 diagnostics: Rc::clone(&source_diagnostics),
14674 };
14675 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
14676 parser.remove_error_listeners();
14677 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
14678 parser.add_error_listener(RecordingErrorListener {
14679 diagnostics: Arc::clone(&parser_diagnostics),
14680 });
14681 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
14682
14683 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
14684
14685 assert_eq!(*source_diagnostics.borrow(), [source_error]);
14686 assert!(
14687 parser_diagnostics
14688 .lock()
14689 .expect("recorded diagnostics lock")
14690 .is_empty()
14691 );
14692 }
14693
14694 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
14695 builder.finish().expect("valid packed parser ATN")
14696 }
14697
14698 fn nested_rule_chain_atn(depth: usize) -> Atn {
14699 nested_rule_graph_atn(depth, false, false)
14700 }
14701
14702 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
14703 assert!(depth > 0);
14704 let mut atn = ParserAtnBuilder::new(2);
14705 let mut starts = Vec::with_capacity(depth);
14706 let mut stops = Vec::with_capacity(depth);
14707 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
14708 for rule_index in 0..depth {
14709 starts.push(
14710 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
14711 .expect("rule start")
14712 .index(),
14713 );
14714 }
14715 for rule_index in 0..depth {
14716 stops.push(
14717 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
14718 .expect("rule stop")
14719 .index(),
14720 );
14721 }
14722 if consuming_follows {
14723 for rule_index in 0..depth - 1 {
14724 follows.push(
14725 atn.add_state(AtnStateKind::Basic, Some(rule_index))
14726 .expect("rule follow")
14727 .index(),
14728 );
14729 }
14730 }
14731 atn.set_rule_to_start_state(starts.clone())
14732 .expect("rule start states");
14733 atn.set_rule_to_stop_state(stops.clone())
14734 .expect("rule stop states");
14735 for rule_index in 0..depth - 1 {
14736 let follow_state = if consuming_follows {
14737 follows[rule_index]
14738 } else {
14739 stops[rule_index]
14740 };
14741 atn.add_transition(
14742 starts[rule_index],
14743 ParserTransitionSpec::Rule {
14744 target: starts[rule_index + 1],
14745 rule_index: rule_index + 1,
14746 follow_state,
14747 precedence: 0,
14748 },
14749 )
14750 .expect("nested rule transition");
14751 if branching {
14752 atn.add_transition(
14753 starts[rule_index],
14754 ParserTransitionSpec::Atom {
14755 target: stops[rule_index],
14756 label: 2,
14757 },
14758 )
14759 .expect("dead branch transition");
14760 }
14761 if consuming_follows {
14762 atn.add_transition(
14763 follow_state,
14764 ParserTransitionSpec::Atom {
14765 target: stops[rule_index],
14766 label: 1,
14767 },
14768 )
14769 .expect("consuming follow transition");
14770 }
14771 }
14772 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
14773 atn.add_transition(
14774 starts[depth - 1],
14775 ParserTransitionSpec::Set {
14776 target: stops[depth - 1],
14777 set: token_set,
14778 },
14779 )
14780 .expect("terminal set transition");
14781 if branching {
14782 atn.add_transition(
14783 starts[depth - 1],
14784 ParserTransitionSpec::Atom {
14785 target: stops[depth - 1],
14786 label: 2,
14787 },
14788 )
14789 .expect("dead leaf branch transition");
14790 }
14791 finish_atn(atn)
14792 }
14793
14794 fn ordinary_star_loop_atn() -> Atn {
14795 let mut atn = ParserAtnBuilder::new(2);
14796 for (state_number, kind, rule_index) in [
14797 (0, AtnStateKind::RuleStart, 0),
14798 (1, AtnStateKind::StarLoopEntry, 0),
14799 (2, AtnStateKind::Basic, 0),
14800 (3, AtnStateKind::StarLoopBack, 0),
14801 (4, AtnStateKind::LoopEnd, 0),
14802 (5, AtnStateKind::Basic, 0),
14803 (6, AtnStateKind::RuleStop, 0),
14804 (7, AtnStateKind::RuleStart, 1),
14805 (8, AtnStateKind::Basic, 1),
14806 (9, AtnStateKind::RuleStop, 1),
14807 ] {
14808 assert_eq!(
14809 atn.add_state(kind, Some(rule_index))
14810 .expect("state")
14811 .index(),
14812 state_number
14813 );
14814 }
14815 atn.set_rule_to_start_state(vec![0, 7])
14816 .expect("rule start states");
14817 atn.set_rule_to_stop_state(vec![6, 9])
14818 .expect("rule stop states");
14819 atn.add_decision_state(1).expect("decision state");
14820 atn.set_loop_back_state(4, 3).expect("loop back state");
14821 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14822 .expect("transition");
14823 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14824 .expect("transition");
14825 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
14826 .expect("transition");
14827 atn.add_transition(
14828 2,
14829 ParserTransitionSpec::Rule {
14830 target: 7,
14831 rule_index: 1,
14832 follow_state: 3,
14833 precedence: 0,
14834 },
14835 )
14836 .expect("transition");
14837 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
14838 .expect("transition");
14839 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14840 .expect("transition");
14841 atn.add_transition(
14842 5,
14843 ParserTransitionSpec::Atom {
14844 target: 6,
14845 label: TOKEN_EOF,
14846 },
14847 )
14848 .expect("transition");
14849 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
14850 .expect("transition");
14851 atn.add_transition(
14852 8,
14853 ParserTransitionSpec::Atom {
14854 target: 9,
14855 label: 1,
14856 },
14857 )
14858 .expect("transition");
14859 finish_atn(atn)
14860 }
14861
14862 fn ambiguous_ordinary_star_loop_atn() -> Atn {
14864 let mut atn = ParserAtnBuilder::new(1);
14865 for (state_number, kind) in [
14866 (0, AtnStateKind::RuleStart),
14867 (1, AtnStateKind::StarLoopEntry),
14868 (2, AtnStateKind::StarBlockStart),
14869 (3, AtnStateKind::Basic),
14870 (4, AtnStateKind::BlockEnd),
14871 (5, AtnStateKind::StarLoopBack),
14872 (6, AtnStateKind::LoopEnd),
14873 (7, AtnStateKind::Basic),
14874 (8, AtnStateKind::RuleStop),
14875 ] {
14876 assert_eq!(
14877 atn.add_state(kind, Some(0)).expect("state").index(),
14878 state_number
14879 );
14880 }
14881 atn.set_rule_to_start_state(vec![0])
14882 .expect("rule start states");
14883 atn.set_rule_to_stop_state(vec![8])
14884 .expect("rule stop states");
14885 atn.set_end_state(2, 4).expect("block end state");
14886 atn.set_loop_back_state(6, 5).expect("loop back state");
14887 atn.add_decision_state(1).expect("decision state");
14888 atn.add_decision_state(2).expect("decision state");
14889 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14890 .expect("transition");
14891 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14892 .expect("transition");
14893 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
14894 .expect("transition");
14895 atn.add_transition(
14896 2,
14897 ParserTransitionSpec::Atom {
14898 target: 4,
14899 label: 1,
14900 },
14901 )
14902 .expect("transition");
14903 atn.add_transition(
14904 2,
14905 ParserTransitionSpec::Atom {
14906 target: 3,
14907 label: 1,
14908 },
14909 )
14910 .expect("transition");
14911 atn.add_transition(
14912 3,
14913 ParserTransitionSpec::Atom {
14914 target: 4,
14915 label: 1,
14916 },
14917 )
14918 .expect("transition");
14919 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14920 .expect("transition");
14921 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
14922 .expect("transition");
14923 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
14924 .expect("transition");
14925 atn.add_transition(
14926 7,
14927 ParserTransitionSpec::Atom {
14928 target: 8,
14929 label: TOKEN_EOF,
14930 },
14931 )
14932 .expect("transition");
14933 finish_atn(atn)
14934 }
14935
14936 fn ordinary_plus_loop_atn() -> Atn {
14937 let mut atn = ParserAtnBuilder::new(2);
14938 for (state_number, kind, rule_index) in [
14939 (0, AtnStateKind::RuleStart, 0),
14940 (1, AtnStateKind::Basic, 0),
14941 (2, AtnStateKind::PlusLoopBack, 0),
14942 (3, AtnStateKind::LoopEnd, 0),
14943 (4, AtnStateKind::Basic, 0),
14944 (5, AtnStateKind::RuleStop, 0),
14945 (6, AtnStateKind::RuleStart, 1),
14946 (7, AtnStateKind::Basic, 1),
14947 (8, AtnStateKind::RuleStop, 1),
14948 ] {
14949 assert_eq!(
14950 atn.add_state(kind, Some(rule_index))
14951 .expect("state")
14952 .index(),
14953 state_number
14954 );
14955 }
14956 atn.set_rule_to_start_state(vec![0, 6])
14957 .expect("rule start states");
14958 atn.set_rule_to_stop_state(vec![5, 8])
14959 .expect("rule stop states");
14960 atn.add_decision_state(2).expect("decision state");
14961 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14962 .expect("transition");
14963 atn.add_transition(
14964 1,
14965 ParserTransitionSpec::Rule {
14966 target: 6,
14967 rule_index: 1,
14968 follow_state: 2,
14969 precedence: 0,
14970 },
14971 )
14972 .expect("transition");
14973 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
14974 .expect("transition");
14975 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
14976 .expect("transition");
14977 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14978 .expect("transition");
14979 atn.add_transition(
14980 4,
14981 ParserTransitionSpec::Atom {
14982 target: 5,
14983 label: TOKEN_EOF,
14984 },
14985 )
14986 .expect("transition");
14987 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
14988 .expect("transition");
14989 atn.add_transition(
14990 7,
14991 ParserTransitionSpec::Atom {
14992 target: 8,
14993 label: 1,
14994 },
14995 )
14996 .expect("transition");
14997 finish_atn(atn)
14998 }
14999
15000 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
15001 let mut tokens = (0..count)
15002 .map(|_| TestToken::new(1).with_text("x"))
15003 .collect::<Vec<_>>();
15004 tokens.push(TestToken::eof("parser-test", count, 1, count));
15005 tokens
15006 }
15007
15008 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
15009 let mut atn = ParserAtnBuilder::new(2);
15010 assert_eq!(
15011 atn.add_state(AtnStateKind::RuleStart, Some(0))
15012 .expect("state")
15013 .index(),
15014 0
15015 );
15016 assert_eq!(
15017 atn.add_state(AtnStateKind::Basic, Some(0))
15018 .expect("state")
15019 .index(),
15020 1
15021 );
15022 assert_eq!(
15023 atn.add_state(AtnStateKind::Basic, Some(0))
15024 .expect("state")
15025 .index(),
15026 2
15027 );
15028 assert_eq!(
15029 atn.add_state(AtnStateKind::RuleStart, Some(1))
15030 .expect("state")
15031 .index(),
15032 3
15033 );
15034 atn.set_left_recursive_rule(3)
15035 .expect("left-recursive rule start");
15036 assert_eq!(
15037 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
15038 .expect("state")
15039 .index(),
15040 4
15041 );
15042 atn.set_precedence_rule_decision(4)
15043 .expect("precedence decision");
15044 assert_eq!(
15045 atn.add_state(AtnStateKind::Basic, Some(1))
15046 .expect("state")
15047 .index(),
15048 5
15049 );
15050 assert_eq!(
15051 atn.add_state(AtnStateKind::Basic, Some(1))
15052 .expect("state")
15053 .index(),
15054 6
15055 );
15056 assert_eq!(
15057 atn.add_state(AtnStateKind::LoopEnd, Some(1))
15058 .expect("state")
15059 .index(),
15060 7
15061 );
15062 assert_eq!(
15063 atn.add_state(AtnStateKind::RuleStop, Some(1))
15064 .expect("state")
15065 .index(),
15066 8
15067 );
15068 assert_eq!(
15069 atn.add_state(AtnStateKind::RuleStop, Some(0))
15070 .expect("state")
15071 .index(),
15072 9
15073 );
15074 atn.set_rule_to_start_state(vec![0, 3])
15075 .expect("rule start states");
15076 atn.set_rule_to_stop_state(vec![9, 8])
15077 .expect("rule stop states");
15078 atn.add_transition(
15079 1,
15080 ParserTransitionSpec::Rule {
15081 target: 3,
15082 rule_index: 1,
15083 follow_state: 2,
15084 precedence: 0,
15085 },
15086 )
15087 .expect("transition");
15088 atn.add_transition(
15089 2,
15090 ParserTransitionSpec::Atom {
15091 target: 9,
15092 label: caller_symbol,
15093 },
15094 )
15095 .expect("transition");
15096 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15097 .expect("transition");
15098 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
15099 .expect("transition");
15100 atn.add_transition(
15101 5,
15102 ParserTransitionSpec::Precedence {
15103 target: 6,
15104 precedence: 1,
15105 },
15106 )
15107 .expect("transition");
15108 atn.add_transition(
15109 6,
15110 ParserTransitionSpec::Atom {
15111 target: 4,
15112 label: 1,
15113 },
15114 )
15115 .expect("transition");
15116 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
15117 .expect("transition");
15118 finish_atn(atn)
15119 }
15120
15121 fn labeled_left_recursive_operator_atn() -> Atn {
15122 let mut atn = ParserAtnBuilder::new(4);
15123 for (state, kind) in [
15124 (0, AtnStateKind::RuleStart),
15125 (1, AtnStateKind::BlockStart),
15126 (2, AtnStateKind::StarLoopEntry),
15127 (3, AtnStateKind::StarBlockStart),
15128 (4, AtnStateKind::Basic),
15129 (5, AtnStateKind::Basic),
15130 (6, AtnStateKind::Basic),
15131 (7, AtnStateKind::StarLoopBack),
15132 (8, AtnStateKind::LoopEnd),
15133 (9, AtnStateKind::RuleStop),
15134 ] {
15135 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15136 }
15137 atn.set_left_recursive_rule(0)
15138 .expect("left-recursive rule start");
15139 atn.set_precedence_rule_decision(2)
15140 .expect("precedence decision");
15141 atn.set_loop_back_state(8, 7).expect("loop-back state");
15142 atn.set_rule_to_start_state(vec![0])
15143 .expect("rule start states");
15144 atn.set_rule_to_stop_state(vec![9])
15145 .expect("rule stop states");
15146 for state in [1, 2, 3] {
15147 atn.add_decision_state(state).expect("decision state");
15148 }
15149 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
15150 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
15151 .expect("epsilon transition");
15152 }
15153 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3), (6, 7, 1)] {
15154 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
15155 .expect("token transition");
15156 }
15157 for (target, precedence) in [(4, 2), (5, 1)] {
15158 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
15159 .expect("operator precedence");
15160 }
15161 finish_atn(atn)
15162 }
15163
15164 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
15165 let mut parser = mini_parser(vec![
15166 TestToken::new(symbol).with_text("lookahead"),
15167 TestToken::eof("parser-test", 1, 1, 1),
15168 ]);
15169 parser.rule_context_stack = vec![
15170 RuleContextFrame {
15171 rule_index: 0,
15172 invoking_state: -1,
15173 },
15174 RuleContextFrame {
15175 rule_index: 1,
15176 invoking_state: 1,
15177 },
15178 ];
15179 parser
15180 }
15181
15182 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
15183 let mut atn = ParserAtnBuilder::new(1);
15187 for (state, kind, rule) in [
15188 (0, AtnStateKind::RuleStart, 0),
15189 (1, AtnStateKind::StarLoopEntry, 0),
15190 (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),
15197 (9, AtnStateKind::RuleStop, 0),
15198 ] {
15199 assert_eq!(
15200 atn.add_state(kind, Some(rule)).expect("state").index(),
15201 state
15202 );
15203 if state == 0 {
15204 atn.set_left_recursive_rule(state)
15205 .expect("left-recursive rule start");
15206 } else if state == 1 {
15207 atn.set_precedence_rule_decision(state)
15208 .expect("precedence decision");
15209 }
15210 }
15211 atn.set_rule_to_start_state(vec![0])
15212 .expect("rule start states");
15213 atn.set_rule_to_stop_state(vec![9])
15214 .expect("rule stop states");
15215 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15216 .expect("ops");
15217 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
15218 .expect("exit");
15219 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15220 .expect("to shift");
15221 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15222 .expect("to rel");
15223 atn.add_transition(
15224 3,
15225 ParserTransitionSpec::Precedence {
15226 target: 4,
15227 precedence: 2,
15228 },
15229 )
15230 .expect("shift prec");
15231 atn.add_transition(
15232 4,
15233 ParserTransitionSpec::Atom {
15234 target: 5,
15235 label: 1,
15236 },
15237 )
15238 .expect("shift first >");
15239 atn.add_transition(
15240 5,
15241 ParserTransitionSpec::Atom {
15242 target: 1,
15243 label: 1,
15244 },
15245 )
15246 .expect("shift second >");
15247 atn.add_transition(
15248 6,
15249 ParserTransitionSpec::Precedence {
15250 target: 7,
15251 precedence: 1,
15252 },
15253 )
15254 .expect("rel prec");
15255 atn.add_transition(
15256 7,
15257 ParserTransitionSpec::Atom {
15258 target: 1,
15259 label: 1,
15260 },
15261 )
15262 .expect("rel >");
15263 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15264 .expect("loop end");
15265 finish_atn(atn)
15266 }
15267
15268 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
15269 let mut atn = ParserAtnBuilder::new(2);
15270 for (state, kind, rule) in [
15271 (0, AtnStateKind::RuleStart, 0),
15272 (1, AtnStateKind::StarLoopEntry, 0),
15273 (2, AtnStateKind::Basic, 0),
15274 (3, AtnStateKind::Basic, 0),
15275 (4, AtnStateKind::Basic, 0),
15276 (5, AtnStateKind::Basic, 0),
15277 (6, AtnStateKind::Basic, 0),
15278 (7, AtnStateKind::Basic, 0),
15279 (8, AtnStateKind::LoopEnd, 0),
15280 (9, AtnStateKind::RuleStop, 0),
15281 (10, AtnStateKind::RuleStart, 1),
15282 (11, AtnStateKind::Basic, 1),
15283 (12, AtnStateKind::RuleStop, 1),
15284 ] {
15285 assert_eq!(
15286 atn.add_state(kind, Some(rule)).expect("state").index(),
15287 state
15288 );
15289 if state == 0 {
15290 atn.set_left_recursive_rule(state)
15291 .expect("left-recursive rule start");
15292 } else if state == 1 {
15293 atn.set_precedence_rule_decision(state)
15294 .expect("precedence decision");
15295 }
15296 }
15297 atn.set_rule_to_start_state(vec![0, 10])
15298 .expect("rule start states");
15299 atn.set_rule_to_stop_state(vec![9, 12])
15300 .expect("rule stop states");
15301 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15302 .expect("ops");
15303 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
15304 .expect("exit");
15305 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15306 .expect("to shift");
15307 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15308 .expect("to relational");
15309 atn.add_transition(
15310 3,
15311 ParserTransitionSpec::Precedence {
15312 target: 4,
15313 precedence: 2,
15314 },
15315 )
15316 .expect("shift precedence");
15317 atn.add_transition(
15318 4,
15319 ParserTransitionSpec::Rule {
15320 target: 10,
15321 rule_index: 1,
15322 follow_state: 5,
15323 precedence: 0,
15324 },
15325 )
15326 .expect("first shift token helper");
15327 atn.add_transition(
15328 5,
15329 ParserTransitionSpec::Atom {
15330 target: 1,
15331 label: 1,
15332 },
15333 )
15334 .expect("second shift token");
15335 atn.add_transition(
15336 6,
15337 ParserTransitionSpec::Precedence {
15338 target: 7,
15339 precedence: 1,
15340 },
15341 )
15342 .expect("relational precedence");
15343 atn.add_transition(
15344 7,
15345 ParserTransitionSpec::Atom {
15346 target: 1,
15347 label: 1,
15348 },
15349 )
15350 .expect("relational token");
15351 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15352 .expect("loop end");
15353 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
15354 .expect("helper entry");
15355 atn.add_transition(
15356 11,
15357 ParserTransitionSpec::Atom {
15358 target: 12,
15359 label: 1,
15360 },
15361 )
15362 .expect("first shift token");
15363 finish_atn(atn)
15364 }
15365
15366 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
15367 let mut atn = ParserAtnBuilder::new(1);
15368 for (state, kind) in [
15369 (0, AtnStateKind::RuleStart),
15370 (1, AtnStateKind::StarLoopEntry),
15371 (2, AtnStateKind::Basic),
15372 (3, AtnStateKind::Basic),
15373 (4, AtnStateKind::Basic),
15374 (5, AtnStateKind::Basic),
15375 (6, AtnStateKind::Basic),
15376 (7, AtnStateKind::Basic),
15377 (8, AtnStateKind::Basic),
15378 (9, AtnStateKind::LoopEnd),
15379 (10, AtnStateKind::RuleStop),
15380 ] {
15381 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15382 if state == 0 {
15383 atn.set_left_recursive_rule(state)
15384 .expect("left-recursive rule start");
15385 } else if state == 1 {
15386 atn.set_precedence_rule_decision(state)
15387 .expect("precedence decision");
15388 }
15389 }
15390 atn.set_rule_to_start_state(vec![0])
15391 .expect("rule start states");
15392 atn.set_rule_to_stop_state(vec![10])
15393 .expect("rule stop states");
15394 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15395 .expect("ops");
15396 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
15397 .expect("exit");
15398 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15399 .expect("to multi-token operator");
15400 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15401 .expect("to predicate operator");
15402 atn.add_transition(
15403 3,
15404 ParserTransitionSpec::Precedence {
15405 target: 4,
15406 precedence: 2,
15407 },
15408 )
15409 .expect("multi-token precedence");
15410 atn.add_transition(
15411 4,
15412 ParserTransitionSpec::Atom {
15413 target: 5,
15414 label: 1,
15415 },
15416 )
15417 .expect("multi-token first");
15418 atn.add_transition(
15419 5,
15420 ParserTransitionSpec::Atom {
15421 target: 1,
15422 label: 1,
15423 },
15424 )
15425 .expect("multi-token second");
15426 atn.add_transition(
15427 6,
15428 ParserTransitionSpec::Precedence {
15429 target: 7,
15430 precedence: 2,
15431 },
15432 )
15433 .expect("predicate precedence");
15434 atn.add_transition(
15435 7,
15436 ParserTransitionSpec::Predicate {
15437 target: 8,
15438 rule_index: 0,
15439 pred_index: 0,
15440 context_dependent: false,
15441 },
15442 )
15443 .expect("operator predicate");
15444 atn.add_transition(
15445 8,
15446 ParserTransitionSpec::Atom {
15447 target: 1,
15448 label: 1,
15449 },
15450 )
15451 .expect("predicate single token");
15452 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15453 .expect("loop end");
15454 finish_atn(atn)
15455 }
15456
15457 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
15458 let mut atn = ParserAtnBuilder::new(2);
15459 for (state, kind, rule) in [
15460 (0, AtnStateKind::RuleStart, 0),
15461 (1, AtnStateKind::StarLoopEntry, 0),
15462 (2, AtnStateKind::Basic, 0),
15463 (3, AtnStateKind::Basic, 0),
15464 (4, AtnStateKind::Basic, 0),
15465 (5, AtnStateKind::LoopEnd, 0),
15466 (6, AtnStateKind::RuleStop, 0),
15467 (7, AtnStateKind::RuleStart, 1),
15468 (8, AtnStateKind::RuleStop, 1),
15469 (9, AtnStateKind::Basic, 1),
15470 ] {
15471 assert_eq!(
15472 atn.add_state(kind, Some(rule)).expect("state").index(),
15473 state
15474 );
15475 if state == 0 {
15476 atn.set_left_recursive_rule(state)
15477 .expect("left-recursive rule start");
15478 } else if state == 1 {
15479 atn.set_precedence_rule_decision(state)
15480 .expect("precedence decision");
15481 }
15482 }
15483 atn.set_rule_to_start_state(vec![0, 7])
15484 .expect("rule start states");
15485 atn.set_rule_to_stop_state(vec![6, 8])
15486 .expect("rule stop states");
15487 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15488 .expect("transition");
15489 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
15490 .expect("transition");
15491 atn.add_transition(
15492 2,
15493 ParserTransitionSpec::Precedence {
15494 target: 3,
15495 precedence: 3,
15496 },
15497 )
15498 .expect("transition");
15499 atn.add_transition(
15500 3,
15501 ParserTransitionSpec::Rule {
15502 target: 7,
15503 rule_index: 1,
15504 follow_state: 4,
15505 precedence: 0,
15506 },
15507 )
15508 .expect("transition");
15509 atn.add_transition(
15510 4,
15511 ParserTransitionSpec::Atom {
15512 target: 1,
15513 label: 1,
15514 },
15515 )
15516 .expect("transition");
15517 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15518 .expect("transition");
15519 atn.add_transition(
15520 7,
15521 ParserTransitionSpec::Precedence {
15522 target: 9,
15523 precedence: 1,
15524 },
15525 )
15526 .expect("transition");
15527 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
15528 .expect("transition");
15529 finish_atn(atn)
15530 }
15531
15532 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
15533 let mut atn = ParserAtnBuilder::new(2);
15534 for (state, kind) in [
15535 (0, AtnStateKind::RuleStart),
15536 (1, AtnStateKind::StarLoopEntry),
15537 (2, AtnStateKind::Basic),
15538 (3, AtnStateKind::Basic),
15539 (4, AtnStateKind::Basic),
15540 (5, AtnStateKind::LoopEnd),
15541 (6, AtnStateKind::RuleStop),
15542 ] {
15543 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15544 if state == 0 {
15545 atn.set_left_recursive_rule(state)
15546 .expect("left-recursive rule start");
15547 } else if state == 1 {
15548 atn.set_precedence_rule_decision(state)
15549 .expect("precedence decision");
15550 }
15551 }
15552 atn.set_rule_to_start_state(vec![0])
15553 .expect("rule start states");
15554 atn.set_rule_to_stop_state(vec![6])
15555 .expect("rule stop states");
15556 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15557 .expect("transition");
15558 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
15559 .expect("transition");
15560 atn.add_transition(
15561 2,
15562 ParserTransitionSpec::Precedence {
15563 target: 3,
15564 precedence: 1,
15565 },
15566 )
15567 .expect("transition");
15568 atn.add_transition(
15569 3,
15570 ParserTransitionSpec::Predicate {
15571 target: 4,
15572 rule_index: 0,
15573 pred_index: 0,
15574 context_dependent: false,
15575 },
15576 )
15577 .expect("transition");
15578 atn.add_transition(
15579 4,
15580 ParserTransitionSpec::Atom {
15581 target: 1,
15582 label: 1,
15583 },
15584 )
15585 .expect("transition");
15586 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15587 .expect("transition");
15588 finish_atn(atn)
15589 }
15590
15591 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
15592 let mut atn = ParserAtnBuilder::new(2);
15593 for (state, kind, rule) in [
15594 (0, AtnStateKind::RuleStart, 0),
15595 (1, AtnStateKind::Basic, 0),
15596 (2, AtnStateKind::Basic, 0),
15597 (3, AtnStateKind::Basic, 0),
15598 (4, AtnStateKind::RuleStop, 0),
15599 (5, AtnStateKind::RuleStart, 1),
15600 (6, AtnStateKind::StarLoopEntry, 1),
15601 (7, AtnStateKind::Basic, 1),
15602 (8, AtnStateKind::Basic, 1),
15603 (9, AtnStateKind::LoopEnd, 1),
15604 (10, AtnStateKind::RuleStop, 1),
15605 (11, AtnStateKind::RuleStart, 2),
15606 (12, AtnStateKind::RuleStop, 2),
15607 ] {
15608 assert_eq!(
15609 atn.add_state(kind, Some(rule)).expect("state").index(),
15610 state
15611 );
15612 if state == 5 {
15613 atn.set_left_recursive_rule(state)
15614 .expect("left-recursive rule start");
15615 } else if state == 6 {
15616 atn.set_precedence_rule_decision(state)
15617 .expect("precedence decision");
15618 }
15619 }
15620 atn.set_rule_to_start_state(vec![0, 5, 11])
15621 .expect("rule start states");
15622 atn.set_rule_to_stop_state(vec![4, 10, 12])
15623 .expect("rule stop states");
15624 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15625 .expect("transition");
15626 atn.add_transition(
15627 1,
15628 ParserTransitionSpec::Rule {
15629 target: 5,
15630 rule_index: 1,
15631 follow_state: 2,
15632 precedence: 0,
15633 },
15634 )
15635 .expect("transition");
15636 atn.add_transition(
15637 2,
15638 ParserTransitionSpec::Rule {
15639 target: 11,
15640 rule_index: 2,
15641 follow_state: 3,
15642 precedence: 0,
15643 },
15644 )
15645 .expect("transition");
15646 atn.add_transition(
15647 3,
15648 ParserTransitionSpec::Atom {
15649 target: 4,
15650 label: caller_symbol,
15651 },
15652 )
15653 .expect("transition");
15654 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15655 .expect("transition");
15656 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
15657 .expect("transition");
15658 atn.add_transition(
15659 7,
15660 ParserTransitionSpec::Precedence {
15661 target: 8,
15662 precedence: 1,
15663 },
15664 )
15665 .expect("transition");
15666 atn.add_transition(
15667 8,
15668 ParserTransitionSpec::Atom {
15669 target: 6,
15670 label: 1,
15671 },
15672 )
15673 .expect("transition");
15674 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15675 .expect("transition");
15676 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
15677 .expect("transition");
15678 finish_atn(atn)
15679 }
15680
15681 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
15682 let mut atn = ParserAtnBuilder::new(2);
15683 for (state, kind, rule) in [
15684 (0, AtnStateKind::RuleStart, 0),
15685 (1, AtnStateKind::Basic, 0),
15686 (2, AtnStateKind::Basic, 0),
15687 (3, AtnStateKind::RuleStop, 0),
15688 (4, AtnStateKind::RuleStart, 1),
15689 (5, AtnStateKind::Basic, 1),
15690 (6, AtnStateKind::Basic, 1),
15691 (7, AtnStateKind::RuleStop, 1),
15692 (8, AtnStateKind::RuleStart, 2),
15693 (9, AtnStateKind::StarLoopEntry, 2),
15694 (10, AtnStateKind::Basic, 2),
15695 (11, AtnStateKind::Basic, 2),
15696 (12, AtnStateKind::LoopEnd, 2),
15697 (13, AtnStateKind::RuleStop, 2),
15698 ] {
15699 assert_eq!(
15700 atn.add_state(kind, Some(rule)).expect("state").index(),
15701 state
15702 );
15703 if state == 8 {
15704 atn.set_left_recursive_rule(state)
15705 .expect("left-recursive rule start");
15706 } else if state == 9 {
15707 atn.set_precedence_rule_decision(state)
15708 .expect("precedence decision");
15709 }
15710 }
15711 atn.set_rule_to_start_state(vec![0, 4, 8])
15712 .expect("rule start states");
15713 atn.set_rule_to_stop_state(vec![3, 7, 13])
15714 .expect("rule stop states");
15715 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15716 .expect("transition");
15717 atn.add_transition(
15718 1,
15719 ParserTransitionSpec::Rule {
15720 target: 4,
15721 rule_index: 1,
15722 follow_state: 2,
15723 precedence: 0,
15724 },
15725 )
15726 .expect("transition");
15727 atn.add_transition(
15728 2,
15729 ParserTransitionSpec::Atom {
15730 target: 3,
15731 label: caller_symbol,
15732 },
15733 )
15734 .expect("transition");
15735 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15736 .expect("transition");
15737 atn.add_transition(
15738 5,
15739 ParserTransitionSpec::Rule {
15740 target: 8,
15741 rule_index: 2,
15742 follow_state: 6,
15743 precedence: 0,
15744 },
15745 )
15746 .expect("transition");
15747 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15748 .expect("transition");
15749 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15750 .expect("transition");
15751 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
15752 .expect("transition");
15753 atn.add_transition(
15754 10,
15755 ParserTransitionSpec::Precedence {
15756 target: 11,
15757 precedence: 1,
15758 },
15759 )
15760 .expect("transition");
15761 atn.add_transition(
15762 11,
15763 ParserTransitionSpec::Atom {
15764 target: 9,
15765 label: 1,
15766 },
15767 )
15768 .expect("transition");
15769 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
15770 .expect("transition");
15771 finish_atn(atn)
15772 }
15773
15774 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
15775 let mut atn = ParserAtnBuilder::new(2);
15776 for (state, kind, rule) in [
15777 (0, AtnStateKind::RuleStart, 0),
15778 (1, AtnStateKind::Basic, 0),
15779 (2, AtnStateKind::Basic, 0),
15780 (3, AtnStateKind::RuleStop, 0),
15781 (4, AtnStateKind::RuleStart, 1),
15782 (5, AtnStateKind::StarLoopEntry, 1),
15783 (6, AtnStateKind::Basic, 1),
15784 (7, AtnStateKind::Basic, 1),
15785 (8, AtnStateKind::Basic, 1),
15786 (9, AtnStateKind::Basic, 1),
15787 (10, AtnStateKind::LoopEnd, 1),
15788 (11, AtnStateKind::RuleStop, 1),
15789 ] {
15790 assert_eq!(
15791 atn.add_state(kind, Some(rule)).expect("state").index(),
15792 state
15793 );
15794 if state == 4 {
15795 atn.set_left_recursive_rule(state)
15796 .expect("left-recursive rule start");
15797 } else if state == 5 {
15798 atn.set_precedence_rule_decision(state)
15799 .expect("precedence decision");
15800 }
15801 }
15802 atn.set_rule_to_start_state(vec![0, 4])
15803 .expect("rule start states");
15804 atn.set_rule_to_stop_state(vec![3, 11])
15805 .expect("rule stop states");
15806 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15807 .expect("transition");
15808 atn.add_transition(
15809 1,
15810 ParserTransitionSpec::Rule {
15811 target: 4,
15812 rule_index: 1,
15813 follow_state: 2,
15814 precedence: 0,
15815 },
15816 )
15817 .expect("transition");
15818 atn.add_transition(
15819 2,
15820 ParserTransitionSpec::Atom {
15821 target: 3,
15822 label: caller_symbol,
15823 },
15824 )
15825 .expect("transition");
15826 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15827 .expect("transition");
15828 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
15829 .expect("transition");
15830 atn.add_transition(
15831 6,
15832 ParserTransitionSpec::Precedence {
15833 target: 7,
15834 precedence: 1,
15835 },
15836 )
15837 .expect("transition");
15838 atn.add_transition(
15839 7,
15840 ParserTransitionSpec::Atom {
15841 target: 8,
15842 label: 1,
15843 },
15844 )
15845 .expect("transition");
15846 atn.add_transition(
15847 8,
15848 ParserTransitionSpec::Rule {
15849 target: 4,
15850 rule_index: 1,
15851 follow_state: 9,
15852 precedence: 2,
15853 },
15854 )
15855 .expect("transition");
15856 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
15857 .expect("transition");
15858 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
15859 .expect("transition");
15860 finish_atn(atn)
15861 }
15862
15863 #[test]
15864 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
15865 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
15866 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
15867
15868 let mut overlapping = parser_inside_left_recursive_callee(1);
15869 assert_eq!(
15870 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
15871 None
15872 );
15873
15874 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
15875 assert_eq!(
15876 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
15877 Some(true)
15878 );
15879
15880 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
15881 assert_eq!(
15882 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
15883 Some(false)
15884 );
15885
15886 assert_eq!(
15887 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
15888 Some(true),
15889 "overlap results must not leak across ATNs"
15890 );
15891 }
15892
15893 #[test]
15894 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
15895 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
15896 let mut parser = mini_parser(vec![
15897 TestToken::new(1).with_text("operator"),
15898 TestToken::eof("parser-test", 1, 1, 1),
15899 ]);
15900 parser.rule_context_stack = vec![RuleContextFrame {
15901 rule_index: 0,
15902 invoking_state: -1,
15903 }];
15904
15905 assert_eq!(
15906 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
15907 Some(true)
15908 );
15909 assert_eq!(
15910 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
15911 Some(true),
15912 "cached operator lookahead must preserve the nullable prefix return path"
15913 );
15914 assert_eq!(
15915 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
15916 Some(true),
15917 "the nullable child must use its rule-call precedence, not the caller precedence"
15918 );
15919 }
15920
15921 #[test]
15922 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
15923 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
15928 let mut parser = mini_parser(vec![
15929 TestToken::new(1).with_text(">"),
15930 TestToken::new(2).with_text("id"),
15931 TestToken::eof("parser-test", 1, 1, 1),
15932 ]);
15933 parser.rule_context_stack = vec![RuleContextFrame {
15934 rule_index: 0,
15935 invoking_state: -1,
15936 }];
15937
15938 assert_eq!(
15939 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
15940 Some(true),
15941 "at low precedence relational `>` is a single-token operator"
15942 );
15943 assert_eq!(
15944 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
15945 Some(true),
15946 "relational remains single-token at its own precedence"
15947 );
15948 assert_eq!(
15949 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
15950 None,
15951 "at shift precedence, bare `>` must not force enter"
15952 );
15953 }
15954
15955 #[test]
15956 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
15957 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
15958 let mut parser = mini_parser(vec![
15959 TestToken::new(1).with_text(">"),
15960 TestToken::new(2).with_text("id"),
15961 TestToken::eof("parser-test", 1, 1, 1),
15962 ]);
15963 parser.rule_context_stack = vec![RuleContextFrame {
15964 rule_index: 0,
15965 invoking_state: -1,
15966 }];
15967
15968 assert_eq!(
15969 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
15970 Some(true),
15971 "the direct relational alternative remains a one-token operator"
15972 );
15973 assert_eq!(
15974 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
15975 None,
15976 "a token matched in the helper rule must return to the second shift token"
15977 );
15978 }
15979
15980 #[test]
15981 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
15982 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
15983 let mut parser = mini_parser(vec![
15984 TestToken::new(1).with_text(">"),
15985 TestToken::new(2).with_text("id"),
15986 TestToken::eof("parser-test", 1, 1, 1),
15987 ]);
15988 parser.rule_context_stack = vec![RuleContextFrame {
15989 rule_index: 0,
15990 invoking_state: -1,
15991 }];
15992
15993 assert_eq!(
15994 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
15995 None,
15996 "a predicate-gated single-token path must not be hidden by a multi-token path"
15997 );
15998 }
15999
16000 #[test]
16001 fn left_recursive_loop_defers_predicate_guarded_operator() {
16002 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
16003 let mut parser = mini_parser_with_hooks(
16004 vec![
16005 TestToken::new(1).with_text("operator"),
16006 TestToken::eof("parser-test", 1, 1, 1),
16007 ],
16008 RejectingPredicateHooks::default(),
16009 );
16010 parser.rule_context_stack = vec![RuleContextFrame {
16011 rule_index: 0,
16012 invoking_state: -1,
16013 }];
16014
16015 assert_eq!(
16016 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16017 None,
16018 "a false predicate must be evaluated before entering the operator alternative"
16019 );
16020 assert_eq!(
16021 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16022 None,
16023 "cached predicate-dependent lookahead must keep deferring"
16024 );
16025 }
16026
16027 #[test]
16028 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
16029 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
16030 let mut parser = parser_inside_left_recursive_callee(1);
16031
16032 assert_eq!(
16033 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
16034 None
16035 );
16036 assert_eq!(
16037 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
16038 None,
16039 "the cached overlap must preserve the nullable child return path"
16040 );
16041 }
16042
16043 #[test]
16044 fn left_recursive_loop_defers_through_nullable_parent_return() {
16045 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
16046 let mut parser = mini_parser(vec![
16047 TestToken::new(1).with_text("lookahead"),
16048 TestToken::eof("parser-test", 1, 1, 1),
16049 ]);
16050 parser.rule_context_stack = vec![
16051 RuleContextFrame {
16052 rule_index: 0,
16053 invoking_state: -1,
16054 },
16055 RuleContextFrame {
16056 rule_index: 1,
16057 invoking_state: 1,
16058 },
16059 RuleContextFrame {
16060 rule_index: 2,
16061 invoking_state: 5,
16062 },
16063 ];
16064
16065 assert_eq!(
16066 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
16067 None,
16068 "a nullable caller must unwind to its parent's consuming follow path"
16069 );
16070 assert_eq!(
16071 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
16072 None,
16073 "the caller-overlap cache must not retain a false negative"
16074 );
16075 }
16076
16077 #[test]
16078 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
16079 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
16080 let mut parser = mini_parser(vec![
16081 TestToken::new(1).with_text("lookahead"),
16082 TestToken::eof("parser-test", 1, 1, 1),
16083 ]);
16084 parser.rule_context_stack = vec![
16085 RuleContextFrame {
16086 rule_index: 0,
16087 invoking_state: -1,
16088 },
16089 RuleContextFrame {
16090 rule_index: 1,
16091 invoking_state: 1,
16092 },
16093 RuleContextFrame {
16094 rule_index: 1,
16095 invoking_state: 8,
16096 },
16097 ];
16098
16099 assert_eq!(
16100 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
16101 None,
16102 "a recursive operand return must preserve its parent caller context"
16103 );
16104 assert_eq!(
16105 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
16106 None,
16107 "the caller-overlap cache must preserve the loop-boundary return"
16108 );
16109 }
16110
16111 fn token_then_eof_atn() -> Atn {
16112 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16113 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, ]))
16129 .deserialize_parser()
16130 .expect("artificial parser ATN should deserialize")
16131 }
16132
16133 fn epsilon_cycle_atn() -> Atn {
16134 let mut atn = ParserAtnBuilder::new(1);
16135 for (state_number, kind) in [
16136 (0, AtnStateKind::RuleStart),
16137 (1, AtnStateKind::Basic),
16138 (2, AtnStateKind::RuleStop),
16139 ] {
16140 assert_eq!(
16141 atn.add_state(kind, Some(0)).expect("state").index(),
16142 state_number
16143 );
16144 }
16145 atn.set_rule_to_start_state(vec![0])
16146 .expect("rule start states");
16147 atn.set_rule_to_stop_state(vec![2])
16148 .expect("rule stop states");
16149 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16150 .expect("transition");
16151 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
16152 .expect("self-cycle transition");
16153 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16154 .expect("exit transition");
16155 finish_atn(atn)
16156 }
16157
16158 fn committed_non_consuming_cycle_atn() -> Atn {
16159 let mut atn = ParserAtnBuilder::new(1);
16160 for (state_number, kind) in [
16161 (0, AtnStateKind::RuleStart),
16162 (1, AtnStateKind::Basic),
16163 (2, AtnStateKind::RuleStop),
16164 ] {
16165 assert_eq!(
16166 atn.add_state(kind, Some(0)).expect("state").index(),
16167 state_number
16168 );
16169 }
16170 atn.set_rule_to_start_state(vec![0])
16171 .expect("rule start states");
16172 atn.set_rule_to_stop_state(vec![2])
16173 .expect("rule stop states");
16174 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16175 .expect("cycle entry");
16176 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
16177 .expect("self-cycle transition");
16178 finish_atn(atn)
16179 }
16180
16181 fn eof_then_action_atn() -> Atn {
16182 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16183 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, ]))
16199 .deserialize_parser()
16200 .expect("artificial parser ATN should deserialize")
16201 }
16202
16203 fn noop_action_then_token_then_eof_atn() -> Atn {
16204 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16205 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, ]))
16223 .deserialize_parser()
16224 .expect("artificial no-op action ATN should deserialize")
16225 }
16226
16227 fn committed_action_then_predicate_atn() -> Atn {
16228 let mut atn = ParserAtnBuilder::new(1);
16229 for (state_number, kind) in [
16230 (0, AtnStateKind::RuleStart),
16231 (1, AtnStateKind::Basic),
16232 (2, AtnStateKind::Basic),
16233 (3, AtnStateKind::Basic),
16234 (4, AtnStateKind::RuleStop),
16235 ] {
16236 assert_eq!(
16237 atn.add_state(kind, Some(0)).expect("state").index(),
16238 state_number
16239 );
16240 }
16241 atn.set_rule_to_start_state(vec![0])
16242 .expect("rule start states");
16243 atn.set_rule_to_stop_state(vec![4])
16244 .expect("rule stop states");
16245 atn.add_transition(
16246 0,
16247 ParserTransitionSpec::Action {
16248 target: 1,
16249 rule_index: 0,
16250 action_index: None,
16251 context_dependent: false,
16252 },
16253 )
16254 .expect("action transition");
16255 atn.add_transition(
16256 1,
16257 ParserTransitionSpec::Predicate {
16258 target: 2,
16259 rule_index: 0,
16260 pred_index: 0,
16261 context_dependent: false,
16262 },
16263 )
16264 .expect("predicate transition");
16265 atn.add_transition(
16266 2,
16267 ParserTransitionSpec::Atom {
16268 target: 3,
16269 label: 1,
16270 },
16271 )
16272 .expect("token transition");
16273 atn.add_transition(
16274 3,
16275 ParserTransitionSpec::Atom {
16276 target: 4,
16277 label: TOKEN_EOF,
16278 },
16279 )
16280 .expect("EOF transition");
16281 finish_atn(atn)
16282 }
16283
16284 fn parameterized_child_action_eof_atn() -> Atn {
16286 let mut atn = ParserAtnBuilder::new(1);
16287 for (state_number, kind, rule_index) in [
16288 (0, AtnStateKind::RuleStart, 0),
16289 (1, AtnStateKind::Basic, 0),
16290 (2, AtnStateKind::Basic, 0),
16291 (3, AtnStateKind::RuleStop, 0),
16292 (4, AtnStateKind::RuleStart, 1),
16293 (5, AtnStateKind::Basic, 1),
16294 (6, AtnStateKind::RuleStop, 1),
16295 ] {
16296 assert_eq!(
16297 atn.add_state(kind, Some(rule_index))
16298 .expect("state")
16299 .index(),
16300 state_number
16301 );
16302 }
16303 atn.set_rule_to_start_state(vec![0, 4])
16304 .expect("rule start states");
16305 atn.set_rule_to_stop_state(vec![3, 6])
16306 .expect("rule stop states");
16307 atn.add_transition(
16308 0,
16309 ParserTransitionSpec::Rule {
16310 target: 4,
16311 rule_index: 1,
16312 follow_state: 1,
16313 precedence: 0,
16314 },
16315 )
16316 .expect("parameterized child call");
16317 atn.add_transition(
16318 1,
16319 ParserTransitionSpec::Action {
16320 target: 2,
16321 rule_index: 0,
16322 action_index: None,
16323 context_dependent: false,
16324 },
16325 )
16326 .expect("parent action");
16327 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
16328 .expect("parent stop");
16329 atn.add_transition(
16330 4,
16331 ParserTransitionSpec::Action {
16332 target: 5,
16333 rule_index: 1,
16334 action_index: None,
16335 context_dependent: false,
16336 },
16337 )
16338 .expect("child action");
16339 atn.add_transition(
16340 5,
16341 ParserTransitionSpec::Atom {
16342 target: 6,
16343 label: TOKEN_EOF,
16344 },
16345 )
16346 .expect("child EOF");
16347 finish_atn(atn)
16348 }
16349
16350 fn action_then_nested_rule_atn() -> Atn {
16351 let mut atn = ParserAtnBuilder::new(1);
16352 for (state_number, kind, rule_index) in [
16353 (0, AtnStateKind::RuleStart, 0),
16354 (1, AtnStateKind::Basic, 0),
16355 (2, AtnStateKind::Basic, 0),
16356 (3, AtnStateKind::RuleStop, 0),
16357 (4, AtnStateKind::RuleStart, 1),
16358 (5, AtnStateKind::RuleStop, 1),
16359 ] {
16360 assert_eq!(
16361 atn.add_state(kind, Some(rule_index))
16362 .expect("state")
16363 .index(),
16364 state_number
16365 );
16366 }
16367 atn.set_rule_to_start_state(vec![0, 4])
16368 .expect("rule start states");
16369 atn.set_rule_to_stop_state(vec![3, 5])
16370 .expect("rule stop states");
16371 atn.add_transition(
16372 0,
16373 ParserTransitionSpec::Action {
16374 target: 1,
16375 rule_index: 0,
16376 action_index: None,
16377 context_dependent: false,
16378 },
16379 )
16380 .expect("parent action");
16381 atn.add_transition(
16382 1,
16383 ParserTransitionSpec::Rule {
16384 target: 4,
16385 rule_index: 1,
16386 follow_state: 2,
16387 precedence: 0,
16388 },
16389 )
16390 .expect("nested rule call");
16391 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
16392 .expect("parent stop");
16393 atn.add_transition(
16394 4,
16395 ParserTransitionSpec::Atom {
16396 target: 5,
16397 label: TOKEN_EOF,
16398 },
16399 )
16400 .expect("child EOF");
16401 finish_atn(atn)
16402 }
16403
16404 fn losing_alternative_action_atn() -> Atn {
16405 let mut atn = ParserAtnBuilder::new(2);
16406 for (state_number, kind) in [
16407 (0, AtnStateKind::RuleStart),
16408 (1, AtnStateKind::BlockStart),
16409 (2, AtnStateKind::Basic),
16410 (3, AtnStateKind::Basic),
16411 (4, AtnStateKind::BlockEnd),
16412 (5, AtnStateKind::RuleStop),
16413 ] {
16414 assert_eq!(
16415 atn.add_state(kind, Some(0)).expect("state").index(),
16416 state_number
16417 );
16418 }
16419 atn.set_rule_to_start_state(vec![0])
16420 .expect("rule start states");
16421 atn.set_rule_to_stop_state(vec![5])
16422 .expect("rule stop states");
16423 atn.set_end_state(1, 4).expect("block end state");
16424 atn.add_decision_state(1).expect("decision state");
16425 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16426 .expect("entry transition");
16427 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16428 .expect("first alternative");
16429 atn.add_transition(
16430 1,
16431 ParserTransitionSpec::Atom {
16432 target: 4,
16433 label: 2,
16434 },
16435 )
16436 .expect("second alternative");
16437 atn.add_transition(
16438 2,
16439 ParserTransitionSpec::Action {
16440 target: 3,
16441 rule_index: 0,
16442 action_index: None,
16443 context_dependent: false,
16444 },
16445 )
16446 .expect("losing action");
16447 atn.add_transition(
16448 3,
16449 ParserTransitionSpec::Atom {
16450 target: 4,
16451 label: 1,
16452 },
16453 )
16454 .expect("first alternative token");
16455 atn.add_transition(
16456 4,
16457 ParserTransitionSpec::Atom {
16458 target: 5,
16459 label: TOKEN_EOF,
16460 },
16461 )
16462 .expect("EOF transition");
16463 finish_atn(atn)
16464 }
16465
16466 fn committed_action_star_loop_atn() -> Atn {
16467 let mut atn = ParserAtnBuilder::new(1);
16468 for (state_number, kind) in [
16469 (0, AtnStateKind::RuleStart),
16470 (1, AtnStateKind::StarLoopEntry),
16471 (2, AtnStateKind::Basic),
16472 (3, AtnStateKind::Basic),
16473 (4, AtnStateKind::StarLoopBack),
16474 (5, AtnStateKind::LoopEnd),
16475 (6, AtnStateKind::RuleStop),
16476 ] {
16477 assert_eq!(
16478 atn.add_state(kind, Some(0)).expect("state").index(),
16479 state_number
16480 );
16481 }
16482 atn.set_rule_to_start_state(vec![0])
16483 .expect("rule start states");
16484 atn.set_rule_to_stop_state(vec![6])
16485 .expect("rule stop states");
16486 atn.add_decision_state(1).expect("decision state");
16487 atn.set_loop_back_state(5, 4).expect("loop back state");
16488 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16489 .expect("entry transition");
16490 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16491 .expect("loop body");
16492 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
16493 .expect("loop exit");
16494 atn.add_transition(
16495 2,
16496 ParserTransitionSpec::Action {
16497 target: 3,
16498 rule_index: 0,
16499 action_index: None,
16500 context_dependent: false,
16501 },
16502 )
16503 .expect("loop action");
16504 atn.add_transition(
16505 3,
16506 ParserTransitionSpec::Atom {
16507 target: 4,
16508 label: 1,
16509 },
16510 )
16511 .expect("loop token");
16512 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
16513 .expect("loop back");
16514 atn.add_transition(
16515 5,
16516 ParserTransitionSpec::Atom {
16517 target: 6,
16518 label: TOKEN_EOF,
16519 },
16520 )
16521 .expect("EOF transition");
16522 finish_atn(atn)
16523 }
16524
16525 fn committed_action_left_recursive_atn() -> Atn {
16526 let mut atn = ParserAtnBuilder::new(4);
16527 for (state, kind) in [
16528 (0, AtnStateKind::RuleStart),
16529 (1, AtnStateKind::BlockStart),
16530 (2, AtnStateKind::StarLoopEntry),
16531 (3, AtnStateKind::StarBlockStart),
16532 (4, AtnStateKind::Basic),
16533 (5, AtnStateKind::Basic),
16534 (6, AtnStateKind::Basic),
16535 (7, AtnStateKind::StarLoopBack),
16536 (8, AtnStateKind::LoopEnd),
16537 (9, AtnStateKind::RuleStop),
16538 (10, AtnStateKind::Basic),
16539 ] {
16540 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
16541 }
16542 atn.set_left_recursive_rule(0)
16543 .expect("left-recursive rule start");
16544 atn.set_precedence_rule_decision(2)
16545 .expect("precedence decision");
16546 atn.set_loop_back_state(8, 7).expect("loop-back state");
16547 atn.set_rule_to_start_state(vec![0])
16548 .expect("rule start states");
16549 atn.set_rule_to_stop_state(vec![9])
16550 .expect("rule stop states");
16551 for state in [1, 2, 3] {
16552 atn.add_decision_state(state).expect("decision state");
16553 }
16554 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
16555 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
16556 .expect("epsilon transition");
16557 }
16558 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3)] {
16559 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
16560 .expect("token transition");
16561 }
16562 for (target, precedence) in [(4, 2), (5, 1)] {
16563 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
16564 .expect("operator precedence");
16565 }
16566 atn.add_transition(
16567 6,
16568 ParserTransitionSpec::Action {
16569 target: 10,
16570 rule_index: 0,
16571 action_index: None,
16572 context_dependent: false,
16573 },
16574 )
16575 .expect("operator action");
16576 atn.add_transition(
16577 10,
16578 ParserTransitionSpec::Atom {
16579 target: 7,
16580 label: 1,
16581 },
16582 )
16583 .expect("right operand");
16584 finish_atn(atn)
16585 }
16586
16587 fn two_alt_decision_atn() -> Atn {
16588 let mut atn = ParserAtnBuilder::new(2);
16589 assert_eq!(
16590 atn.add_state(AtnStateKind::RuleStart, Some(0))
16591 .expect("state")
16592 .index(),
16593 0
16594 );
16595 assert_eq!(
16596 atn.add_state(AtnStateKind::BlockStart, Some(0))
16597 .expect("state")
16598 .index(),
16599 1
16600 );
16601 assert_eq!(
16602 atn.add_state(AtnStateKind::Basic, Some(0))
16603 .expect("state")
16604 .index(),
16605 2
16606 );
16607 assert_eq!(
16608 atn.add_state(AtnStateKind::Basic, Some(0))
16609 .expect("state")
16610 .index(),
16611 3
16612 );
16613 assert_eq!(
16614 atn.add_state(AtnStateKind::BlockEnd, Some(0))
16615 .expect("state")
16616 .index(),
16617 4
16618 );
16619 assert_eq!(
16620 atn.add_state(AtnStateKind::RuleStop, Some(0))
16621 .expect("state")
16622 .index(),
16623 5
16624 );
16625 atn.set_rule_to_start_state(vec![0])
16626 .expect("rule start states");
16627 atn.set_rule_to_stop_state(vec![5])
16628 .expect("rule stop states");
16629 atn.add_decision_state(1).expect("decision state");
16630 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16631 .expect("transition");
16632 atn.add_transition(
16633 1,
16634 ParserTransitionSpec::Atom {
16635 target: 2,
16636 label: 1,
16637 },
16638 )
16639 .expect("transition");
16640 atn.add_transition(
16641 1,
16642 ParserTransitionSpec::Atom {
16643 target: 3,
16644 label: 2,
16645 },
16646 )
16647 .expect("transition");
16648 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
16649 .expect("transition");
16650 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
16651 .expect("transition");
16652 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
16653 .expect("transition");
16654 finish_atn(atn)
16655 }
16656
16657 fn optional_then_b_eof_atn() -> Atn {
16660 let mut atn = ParserAtnBuilder::new(3);
16661 assert_eq!(
16662 atn.add_state(AtnStateKind::RuleStart, Some(0))
16663 .expect("state")
16664 .index(),
16665 0
16666 );
16667 assert_eq!(
16668 atn.add_state(AtnStateKind::BlockStart, Some(0))
16669 .expect("state")
16670 .index(),
16671 1
16672 );
16673 assert_eq!(
16674 atn.add_state(AtnStateKind::Basic, Some(0))
16675 .expect("state")
16676 .index(),
16677 2
16678 );
16679 assert_eq!(
16680 atn.add_state(AtnStateKind::Basic, Some(0))
16681 .expect("state")
16682 .index(),
16683 3
16684 );
16685 assert_eq!(
16686 atn.add_state(AtnStateKind::Basic, Some(0))
16687 .expect("state")
16688 .index(),
16689 4
16690 );
16691 assert_eq!(
16692 atn.add_state(AtnStateKind::RuleStop, Some(0))
16693 .expect("state")
16694 .index(),
16695 5
16696 );
16697 atn.set_rule_to_start_state(vec![0])
16698 .expect("rule start states");
16699 atn.set_rule_to_stop_state(vec![5])
16700 .expect("rule stop states");
16701 atn.add_decision_state(1).expect("decision state");
16702 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16703 .expect("transition");
16704 atn.add_transition(
16706 1,
16707 ParserTransitionSpec::Atom {
16708 target: 3,
16709 label: 1,
16710 },
16711 )
16712 .expect("transition");
16713 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
16714 .expect("transition");
16715 atn.add_transition(
16717 3,
16718 ParserTransitionSpec::Atom {
16719 target: 4,
16720 label: 2,
16721 },
16722 )
16723 .expect("transition");
16724 atn.add_transition(
16725 4,
16726 ParserTransitionSpec::Atom {
16727 target: 5,
16728 label: TOKEN_EOF,
16729 },
16730 )
16731 .expect("transition");
16732 finish_atn(atn)
16733 }
16734
16735 #[test]
16736 fn sync_decision_deletes_only_a_single_token() {
16737 let atn = optional_then_b_eof_atn();
16745
16746 let mut single = mini_parser(vec![
16747 TestToken::new(3).with_text("c"),
16748 TestToken::new(2).with_text("b"),
16749 TestToken::eof("parser-test", 1, 2, 2),
16750 ]);
16751 single.rule_context_stack = vec![RuleContextFrame {
16752 rule_index: 0,
16753 invoking_state: 0,
16754 }];
16755 let children = single
16756 .sync_decision(&atn, 1, true, false)
16757 .expect("single extraneous token recovers");
16758 assert_eq!(children.len(), 1);
16759 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
16760 assert_eq!(single.number_of_syntax_errors(), 1);
16761 assert_eq!(single.la(1), 2);
16763
16764 let mut double = mini_parser(vec![
16765 TestToken::new(3).with_text("c"),
16766 TestToken::new(3).with_text("c"),
16767 TestToken::new(2).with_text("b"),
16768 TestToken::eof("parser-test", 1, 3, 3),
16769 ]);
16770 double.rule_context_stack = vec![RuleContextFrame {
16771 rule_index: 0,
16772 invoking_state: 0,
16773 }];
16774 let result = double.sync_decision(&atn, 1, true, false);
16775 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
16780 match error {
16781 AntlrError::ParserError { message, .. } => {
16782 assert!(message.starts_with("mismatched input"), "got: {message}");
16783 }
16784 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
16785 }
16786 assert_eq!(double.la(1), 3);
16787 }
16788
16789 fn star_loop_then_eof_atn() -> Atn {
16793 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16794 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,
16795 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,
16796 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,
16797 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
16798 ]))
16799 .deserialize_parser()
16800 .expect("star-loop-then-EOF ATN should deserialize")
16801 }
16802
16803 fn nested_star_rule_atn() -> Atn {
16807 let mut atn = ParserAtnBuilder::new(2);
16808 for (state_number, kind, rule_index) in [
16809 (0, AtnStateKind::RuleStart, 0),
16810 (1, AtnStateKind::Basic, 0),
16811 (2, AtnStateKind::Basic, 0),
16812 (3, AtnStateKind::RuleStop, 0),
16813 (4, AtnStateKind::RuleStart, 1),
16814 (5, AtnStateKind::StarLoopEntry, 1),
16815 (6, AtnStateKind::Basic, 1),
16816 (7, AtnStateKind::StarLoopBack, 1),
16817 (8, AtnStateKind::LoopEnd, 1),
16818 (9, AtnStateKind::RuleStop, 1),
16819 ] {
16820 assert_eq!(
16821 atn.add_state(kind, Some(rule_index))
16822 .expect("state")
16823 .index(),
16824 state_number
16825 );
16826 }
16827 atn.set_rule_to_start_state(vec![0, 4])
16828 .expect("rule start states");
16829 atn.set_rule_to_stop_state(vec![3, 9])
16830 .expect("rule stop states");
16831 atn.add_decision_state(5).expect("decision state");
16832 atn.set_loop_back_state(8, 7).expect("loop back state");
16833 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16834 .expect("transition");
16835 atn.add_transition(
16836 1,
16837 ParserTransitionSpec::Rule {
16838 target: 4,
16839 rule_index: 1,
16840 follow_state: 2,
16841 precedence: 0,
16842 },
16843 )
16844 .expect("transition");
16845 atn.add_transition(
16846 2,
16847 ParserTransitionSpec::Atom {
16848 target: 3,
16849 label: TOKEN_EOF,
16850 },
16851 )
16852 .expect("transition");
16853 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
16854 .expect("transition");
16855 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
16856 .expect("transition");
16857 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 8 })
16858 .expect("transition");
16859 atn.add_transition(
16860 6,
16861 ParserTransitionSpec::Atom {
16862 target: 7,
16863 label: 1,
16864 },
16865 )
16866 .expect("transition");
16867 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 5 })
16868 .expect("transition");
16869 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
16870 .expect("transition");
16871 finish_atn(atn)
16872 }
16873
16874 fn plus_loop_with_recovering_body_atn() -> Atn {
16880 let mut atn = ParserAtnBuilder::new(2);
16881 assert_eq!(
16882 atn.add_state(AtnStateKind::RuleStart, Some(0))
16883 .expect("state")
16884 .index(),
16885 0
16886 );
16887 assert_eq!(
16888 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
16889 .expect("state")
16890 .index(),
16891 1
16892 );
16893 assert_eq!(
16894 atn.add_state(AtnStateKind::Basic, Some(0))
16895 .expect("state")
16896 .index(),
16897 2
16898 );
16899 assert_eq!(
16900 atn.add_state(AtnStateKind::BlockEnd, Some(0))
16901 .expect("state")
16902 .index(),
16903 3
16904 );
16905 assert_eq!(
16906 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
16907 .expect("state")
16908 .index(),
16909 4
16910 );
16911 assert_eq!(
16912 atn.add_state(AtnStateKind::LoopEnd, Some(0))
16913 .expect("state")
16914 .index(),
16915 5
16916 );
16917 assert_eq!(
16918 atn.add_state(AtnStateKind::RuleStop, Some(0))
16919 .expect("state")
16920 .index(),
16921 6
16922 );
16923 assert_eq!(
16924 atn.add_state(AtnStateKind::RuleStart, Some(1))
16925 .expect("state")
16926 .index(),
16927 7
16928 );
16929 assert_eq!(
16930 atn.add_state(AtnStateKind::Basic, Some(1))
16931 .expect("state")
16932 .index(),
16933 8
16934 );
16935 assert_eq!(
16936 atn.add_state(AtnStateKind::RuleStop, Some(1))
16937 .expect("state")
16938 .index(),
16939 9
16940 );
16941 atn.set_rule_to_start_state(vec![0, 7])
16942 .expect("rule start states");
16943 atn.set_rule_to_stop_state(vec![6, 9])
16944 .expect("rule stop states");
16945 atn.set_end_state(1, 3).expect("block end state");
16946 atn.set_loop_back_state(5, 4).expect("loop back state");
16947 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16948 .expect("transition");
16949 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16950 .expect("transition");
16951 atn.add_transition(
16952 2,
16953 ParserTransitionSpec::Rule {
16954 target: 7,
16955 rule_index: 1,
16956 follow_state: 3,
16957 precedence: 0,
16958 },
16959 )
16960 .expect("transition");
16961 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
16962 .expect("transition");
16963 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
16964 .expect("transition");
16965 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
16966 .expect("transition");
16967 atn.add_transition(
16968 5,
16969 ParserTransitionSpec::Atom {
16970 target: 6,
16971 label: 2,
16972 },
16973 )
16974 .expect("transition");
16975 atn.add_transition(
16976 7,
16977 ParserTransitionSpec::Atom {
16978 target: 8,
16979 label: 1,
16980 },
16981 )
16982 .expect("transition");
16983 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
16984 .expect("transition");
16985 finish_atn(atn)
16986 }
16987
16988 #[test]
16989 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
16990 let atn = plus_loop_with_recovering_body_atn();
16991 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16992
16993 let error = parser
16994 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16995 .expect_err("EOF recovery should report a bounded mismatch");
16996
16997 let AntlrError::ParserError { message, .. } = error else {
16998 panic!("expected ParserError, got {error:?}");
16999 };
17000 insta::assert_snapshot!(message, @"mismatched input '<EOF>' expecting {'x', 2}");
17001 assert_eq!(parser.number_of_syntax_errors(), 1);
17002 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
17003 }
17004
17005 #[test]
17006 fn sync_decision_deletes_token_before_eof_at_loop_back() {
17007 let atn = star_loop_then_eof_atn();
17013 let mut parser = mini_parser(vec![
17014 TestToken::new(2).with_text("c"),
17015 TestToken::eof("parser-test", 1, 1, 1),
17016 ]);
17017 parser.rule_context_stack = vec![RuleContextFrame {
17018 rule_index: 0,
17019 invoking_state: 0,
17020 }];
17021 let children = parser
17022 .sync_decision(&atn, 5, true, false)
17023 .expect("single token before EOF recovers");
17024 assert_eq!(children.len(), 1);
17025 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
17026 assert_eq!(parser.number_of_syntax_errors(), 1);
17027 assert_eq!(
17028 parser.la(1),
17029 TOKEN_EOF,
17030 "EOF is left for the rule's EOF match"
17031 );
17032 }
17033
17034 #[test]
17035 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
17036 let atn = star_loop_then_eof_atn();
17041 let mut parser = mini_parser(vec![
17042 TestToken::new(2).with_text("c"),
17043 TestToken::new(2).with_text("c"),
17044 TestToken::eof("parser-test", 1, 2, 2),
17045 ]);
17046 parser.rule_context_stack = vec![RuleContextFrame {
17047 rule_index: 0,
17048 invoking_state: 0,
17049 }];
17050 let error = parser
17051 .sync_decision(&atn, 5, true, false)
17052 .expect_err("two tokens at the loop entry must not be deleted");
17053 match error {
17054 AntlrError::ParserError { message, .. } => {
17055 assert!(message.starts_with("mismatched input"), "got: {message}");
17056 }
17057 other => panic!("expected mismatched-input ParserError, got {other:?}"),
17058 }
17059 assert_eq!(
17060 parser.la(1),
17061 2,
17062 "nothing consumed; cursor still on first `c`"
17063 );
17064 }
17065
17066 #[test]
17067 fn sync_decision_consumes_until_eof_at_loop_back() {
17068 let atn = star_loop_then_eof_atn();
17074 let mut parser = mini_parser(vec![
17075 TestToken::new(2).with_text("c"),
17076 TestToken::new(2).with_text("c"),
17077 TestToken::eof("parser-test", 1, 2, 2),
17078 ]);
17079 parser.rule_context_stack = vec![RuleContextFrame {
17080 rule_index: 0,
17081 invoking_state: 0,
17082 }];
17083 let children = parser
17084 .sync_decision(&atn, 5, false, true)
17085 .expect("loop-back multi-token deletion recovers onto EOF");
17086 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
17087 assert!(
17088 children
17089 .iter()
17090 .all(|child| parser.node(*child).kind() == NodeKind::Error)
17091 );
17092 assert_eq!(parser.number_of_syntax_errors(), 1);
17093 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
17094 }
17095
17096 #[test]
17097 fn sync_decision_returns_before_recovery_for_nullable_exit() {
17098 let atn = nested_star_rule_atn();
17099 for (current_context_empty, loop_back) in [(true, false), (false, true)] {
17100 let mut parser = mini_parser(vec![
17101 TestToken::new(2).with_text("c"),
17102 TestToken::new(1).with_text("a"),
17103 TestToken::eof("parser-test", 1, 2, 2),
17104 ]);
17105 parser.rule_context_stack = vec![
17106 RuleContextFrame {
17107 rule_index: 0,
17108 invoking_state: 0,
17109 },
17110 RuleContextFrame {
17111 rule_index: 1,
17112 invoking_state: 1,
17113 },
17114 ];
17115
17116 let children = parser
17117 .sync_decision(&atn, 5, current_context_empty, loop_back)
17118 .expect("nullable synchronization is a no-op");
17119
17120 assert!(children.is_empty());
17121 assert_eq!(parser.la(1), 2, "the caller must receive the current token");
17122 assert_eq!(parser.number_of_syntax_errors(), 0);
17123 assert_eq!(
17124 parser
17125 .generated_sync_expected
17126 .as_ref()
17127 .expect("nullable sync preserves expected symbols")
17128 .to_btree_set(),
17129 BTreeSet::from([TOKEN_EOF, 1])
17130 );
17131 }
17132 }
17133
17134 fn predicate_after_token_atn() -> Atn {
17135 let mut atn = ParserAtnBuilder::new(2);
17136 assert_eq!(
17137 atn.add_state(AtnStateKind::RuleStart, Some(0))
17138 .expect("state")
17139 .index(),
17140 0
17141 );
17142 assert_eq!(
17143 atn.add_state(AtnStateKind::Basic, Some(0))
17144 .expect("state")
17145 .index(),
17146 1
17147 );
17148 assert_eq!(
17149 atn.add_state(AtnStateKind::Basic, Some(0))
17150 .expect("state")
17151 .index(),
17152 2
17153 );
17154 assert_eq!(
17155 atn.add_state(AtnStateKind::Basic, Some(0))
17156 .expect("state")
17157 .index(),
17158 3
17159 );
17160 assert_eq!(
17161 atn.add_state(AtnStateKind::RuleStop, Some(0))
17162 .expect("state")
17163 .index(),
17164 4
17165 );
17166 atn.set_rule_to_start_state(vec![0])
17167 .expect("rule start states");
17168 atn.set_rule_to_stop_state(vec![4])
17169 .expect("rule stop states");
17170 atn.add_transition(
17171 0,
17172 ParserTransitionSpec::Atom {
17173 target: 1,
17174 label: 1,
17175 },
17176 )
17177 .expect("transition");
17178 atn.add_transition(
17179 1,
17180 ParserTransitionSpec::Predicate {
17181 target: 2,
17182 rule_index: 0,
17183 pred_index: 0,
17184 context_dependent: false,
17185 },
17186 )
17187 .expect("transition");
17188 atn.add_transition(
17189 2,
17190 ParserTransitionSpec::Atom {
17191 target: 3,
17192 label: 2,
17193 },
17194 )
17195 .expect("transition");
17196 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
17197 .expect("transition");
17198 finish_atn(atn)
17199 }
17200
17201 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
17202 let mut atn = ParserAtnBuilder::new(1);
17203 for (state_number, kind) in [
17204 (0, AtnStateKind::RuleStart),
17205 (1, AtnStateKind::BlockStart),
17206 (2, AtnStateKind::Basic),
17207 (3, AtnStateKind::Basic),
17208 (4, AtnStateKind::Basic),
17209 (5, AtnStateKind::Basic),
17210 (6, AtnStateKind::BlockEnd),
17211 (7, AtnStateKind::RuleStop),
17212 ] {
17213 assert_eq!(
17214 atn.add_state(kind, Some(0)).expect("state").index(),
17215 state_number
17216 );
17217 }
17218 atn.set_rule_to_start_state(vec![0])
17219 .expect("rule start states");
17220 atn.set_rule_to_stop_state(vec![7])
17221 .expect("rule stop states");
17222 atn.add_decision_state(1).expect("decision state");
17223 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17224 .expect("transition");
17225 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17226 .expect("transition");
17227 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17228 .expect("transition");
17229 atn.add_transition(
17230 2,
17231 ParserTransitionSpec::Predicate {
17232 target: 4,
17233 rule_index: 0,
17234 pred_index: pred_indexes[0],
17235 context_dependent: false,
17236 },
17237 )
17238 .expect("transition");
17239 atn.add_transition(
17240 3,
17241 ParserTransitionSpec::Predicate {
17242 target: 5,
17243 rule_index: 0,
17244 pred_index: pred_indexes[1],
17245 context_dependent: false,
17246 },
17247 )
17248 .expect("transition");
17249 atn.add_transition(
17250 4,
17251 ParserTransitionSpec::Atom {
17252 target: 6,
17253 label: 1,
17254 },
17255 )
17256 .expect("transition");
17257 atn.add_transition(
17258 5,
17259 ParserTransitionSpec::Atom {
17260 target: 6,
17261 label: 1,
17262 },
17263 )
17264 .expect("transition");
17265 atn.add_transition(
17266 6,
17267 ParserTransitionSpec::Atom {
17268 target: 7,
17269 label: TOKEN_EOF,
17270 },
17271 )
17272 .expect("transition");
17273 finish_atn(atn)
17274 }
17275
17276 fn semantic_fallback_viability_atn() -> Atn {
17278 let mut atn = ParserAtnBuilder::new(3);
17279 for (state_number, kind) in [
17280 (0, AtnStateKind::RuleStart),
17281 (1, AtnStateKind::BlockStart),
17282 (2, AtnStateKind::Basic),
17283 (3, AtnStateKind::Basic),
17284 (4, AtnStateKind::Basic),
17285 (5, AtnStateKind::Basic),
17286 (6, AtnStateKind::Basic),
17287 (7, AtnStateKind::Basic),
17288 (8, AtnStateKind::Basic),
17289 (9, AtnStateKind::BlockEnd),
17290 (10, AtnStateKind::RuleStop),
17291 ] {
17292 assert_eq!(
17293 atn.add_state(kind, Some(0)).expect("state").index(),
17294 state_number
17295 );
17296 }
17297 atn.set_rule_to_start_state(vec![0])
17298 .expect("rule start states");
17299 atn.set_rule_to_stop_state(vec![10])
17300 .expect("rule stop states");
17301 atn.set_end_state(1, 9).expect("block end state");
17302 atn.add_decision_state(1).expect("decision state");
17303 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17304 .expect("entry transition");
17305 atn.add_transition(
17306 1,
17307 ParserTransitionSpec::Atom {
17308 target: 2,
17309 label: 1,
17310 },
17311 )
17312 .expect("first alternative");
17313 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17314 .expect("second alternative");
17315 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
17316 .expect("third alternative");
17317 atn.add_transition(
17318 2,
17319 ParserTransitionSpec::Atom {
17320 target: 9,
17321 label: 2,
17322 },
17323 )
17324 .expect("first alternative suffix");
17325 for (source, target, pred_index) in [(3, 4, 0), (6, 7, 1)] {
17326 atn.add_transition(
17327 source,
17328 ParserTransitionSpec::Predicate {
17329 target,
17330 rule_index: 0,
17331 pred_index,
17332 context_dependent: false,
17333 },
17334 )
17335 .expect("predicate transition");
17336 }
17337 for (source, target, label) in [(4, 5, 1), (5, 9, 3), (7, 8, 1), (8, 9, 3)] {
17338 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
17339 .expect("predicate alternative token");
17340 }
17341 atn.add_transition(
17342 9,
17343 ParserTransitionSpec::Atom {
17344 target: 10,
17345 label: TOKEN_EOF,
17346 },
17347 )
17348 .expect("EOF transition");
17349 finish_atn(atn)
17350 }
17351
17352 fn rule_call_predicate_decision_atn() -> Atn {
17354 let mut atn = ParserAtnBuilder::new(1);
17355 for (state_number, kind, rule_index) in [
17356 (0, AtnStateKind::RuleStart, 0),
17357 (1, AtnStateKind::BlockStart, 0),
17358 (2, AtnStateKind::Basic, 0),
17359 (3, AtnStateKind::Basic, 0),
17360 (4, AtnStateKind::BlockEnd, 0),
17361 (5, AtnStateKind::RuleStop, 0),
17362 (6, AtnStateKind::RuleStart, 1),
17363 (7, AtnStateKind::Basic, 1),
17364 (8, AtnStateKind::RuleStop, 1),
17365 ] {
17366 assert_eq!(
17367 atn.add_state(kind, Some(rule_index))
17368 .expect("state")
17369 .index(),
17370 state_number
17371 );
17372 }
17373 atn.set_rule_to_start_state(vec![0, 6])
17374 .expect("rule start states");
17375 atn.set_rule_to_stop_state(vec![5, 8])
17376 .expect("rule stop states");
17377 atn.set_end_state(1, 4).expect("block end state");
17378 atn.add_decision_state(1).expect("decision state");
17379 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17380 .expect("entry transition");
17381 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17382 .expect("gated alternative entry");
17383 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17384 .expect("direct alternative entry");
17385 atn.add_transition(
17386 2,
17387 ParserTransitionSpec::Rule {
17388 target: 6,
17389 rule_index: 1,
17390 follow_state: 4,
17391 precedence: 0,
17392 },
17393 )
17394 .expect("gated alternative");
17395 atn.add_transition(
17396 3,
17397 ParserTransitionSpec::Atom {
17398 target: 4,
17399 label: 1,
17400 },
17401 )
17402 .expect("direct alternative");
17403 atn.add_transition(
17404 4,
17405 ParserTransitionSpec::Atom {
17406 target: 5,
17407 label: TOKEN_EOF,
17408 },
17409 )
17410 .expect("EOF transition");
17411 atn.add_transition(
17412 6,
17413 ParserTransitionSpec::Predicate {
17414 target: 7,
17415 rule_index: 1,
17416 pred_index: 0,
17417 context_dependent: false,
17418 },
17419 )
17420 .expect("callee predicate");
17421 atn.add_transition(
17422 7,
17423 ParserTransitionSpec::Atom {
17424 target: 8,
17425 label: 1,
17426 },
17427 )
17428 .expect("callee token");
17429 finish_atn(atn)
17430 }
17431
17432 fn predicate_gated_star_loop_atn() -> Atn {
17434 let mut atn = ParserAtnBuilder::new(2);
17435 for (state_number, kind) in [
17436 (0, AtnStateKind::RuleStart),
17437 (1, AtnStateKind::StarLoopEntry),
17438 (2, AtnStateKind::Basic),
17439 (3, AtnStateKind::Basic),
17440 (4, AtnStateKind::StarLoopBack),
17441 (5, AtnStateKind::LoopEnd),
17442 (6, AtnStateKind::RuleStop),
17443 ] {
17444 assert_eq!(
17445 atn.add_state(kind, Some(0)).expect("state").index(),
17446 state_number
17447 );
17448 }
17449 atn.set_rule_to_start_state(vec![0])
17450 .expect("rule start states");
17451 atn.set_rule_to_stop_state(vec![6])
17452 .expect("rule stop states");
17453 atn.add_decision_state(1).expect("decision state");
17454 atn.set_loop_back_state(5, 4).expect("loop back state");
17455 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17456 .expect("entry transition");
17457 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17458 .expect("loop enter");
17459 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
17460 .expect("loop exit");
17461 atn.add_transition(
17462 2,
17463 ParserTransitionSpec::Predicate {
17464 target: 3,
17465 rule_index: 0,
17466 pred_index: 0,
17467 context_dependent: false,
17468 },
17469 )
17470 .expect("loop predicate");
17471 atn.add_transition(
17472 3,
17473 ParserTransitionSpec::Atom {
17474 target: 4,
17475 label: 1,
17476 },
17477 )
17478 .expect("loop token");
17479 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
17480 .expect("loop back");
17481 atn.add_transition(
17482 5,
17483 ParserTransitionSpec::Atom {
17484 target: 6,
17485 label: TOKEN_EOF,
17486 },
17487 )
17488 .expect("EOF transition");
17489 finish_atn(atn)
17490 }
17491
17492 fn nested_nullable_context_atn() -> Atn {
17493 let mut atn = ParserAtnBuilder::new(1);
17494 for state_number in 0..=20 {
17495 let kind = match state_number {
17496 0 | 10 | 16 => AtnStateKind::RuleStart,
17497 9 | 15 | 20 => AtnStateKind::RuleStop,
17498 _ => AtnStateKind::Basic,
17499 };
17500 let rule_index = match state_number {
17501 0..=9 => 0,
17502 10..=15 => 1,
17503 _ => 2,
17504 };
17505 assert_eq!(
17506 atn.add_state(kind, Some(rule_index))
17507 .expect("state")
17508 .index(),
17509 state_number
17510 );
17511 }
17512 atn.set_rule_to_start_state(vec![0, 10, 16])
17513 .expect("rule start states");
17514 atn.set_rule_to_stop_state(vec![9, 15, 20])
17515 .expect("rule stop states");
17516 atn.add_transition(
17517 1,
17518 ParserTransitionSpec::Rule {
17519 target: 10,
17520 rule_index: 1,
17521 follow_state: 8,
17522 precedence: 0,
17523 },
17524 )
17525 .expect("transition");
17526 atn.add_transition(
17527 8,
17528 ParserTransitionSpec::Atom {
17529 target: 9,
17530 label: 1,
17531 },
17532 )
17533 .expect("transition");
17534 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17535 .expect("transition");
17536 atn.add_transition(
17537 2,
17538 ParserTransitionSpec::Rule {
17539 target: 16,
17540 rule_index: 2,
17541 follow_state: 14,
17542 precedence: 0,
17543 },
17544 )
17545 .expect("transition");
17546 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
17547 .expect("transition");
17548 finish_atn(atn)
17549 }
17550
17551 fn generated_match_recovery_atn() -> Atn {
17552 let mut atn = ParserAtnBuilder::new(2);
17553 assert_eq!(
17554 atn.add_state(AtnStateKind::RuleStart, Some(0))
17555 .expect("state")
17556 .index(),
17557 0
17558 );
17559 assert_eq!(
17560 atn.add_state(AtnStateKind::Basic, Some(0))
17561 .expect("state")
17562 .index(),
17563 1
17564 );
17565 assert_eq!(
17566 atn.add_state(AtnStateKind::Basic, Some(0))
17567 .expect("state")
17568 .index(),
17569 2
17570 );
17571 assert_eq!(
17572 atn.add_state(AtnStateKind::RuleStop, Some(0))
17573 .expect("state")
17574 .index(),
17575 3
17576 );
17577 assert_eq!(
17578 atn.add_state(AtnStateKind::RuleStart, Some(1))
17579 .expect("state")
17580 .index(),
17581 4
17582 );
17583 assert_eq!(
17584 atn.add_state(AtnStateKind::RuleStop, Some(1))
17585 .expect("state")
17586 .index(),
17587 5
17588 );
17589 atn.set_rule_to_start_state(vec![0, 4])
17590 .expect("rule start states");
17591 atn.set_rule_to_stop_state(vec![3, 5])
17592 .expect("rule stop states");
17593 atn.add_transition(
17594 1,
17595 ParserTransitionSpec::Rule {
17596 target: 4,
17597 rule_index: 1,
17598 follow_state: 2,
17599 precedence: 0,
17600 },
17601 )
17602 .expect("transition");
17603 atn.add_transition(
17604 2,
17605 ParserTransitionSpec::Atom {
17606 target: 3,
17607 label: TOKEN_EOF,
17608 },
17609 )
17610 .expect("transition");
17611 finish_atn(atn)
17612 }
17613
17614 fn complement_set_atn() -> Atn {
17615 let mut atn = ParserAtnBuilder::new(1);
17616 assert_eq!(
17617 atn.add_state(AtnStateKind::RuleStart, Some(0))
17618 .expect("state")
17619 .index(),
17620 0
17621 );
17622 assert_eq!(
17623 atn.add_state(AtnStateKind::RuleStop, Some(0))
17624 .expect("state")
17625 .index(),
17626 1
17627 );
17628 atn.set_rule_to_start_state(vec![0])
17629 .expect("rule start states");
17630 atn.set_rule_to_stop_state(vec![1])
17631 .expect("rule stop states");
17632 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
17633 atn.add_transition(
17634 0,
17635 ParserTransitionSpec::NotSet {
17636 target: 1,
17637 set: excluded,
17638 },
17639 )
17640 .expect("transition");
17641 finish_atn(atn)
17642 }
17643
17644 fn wildcard_then_eof_atn() -> Atn {
17647 let mut atn = ParserAtnBuilder::new(1);
17648 assert_eq!(
17649 atn.add_state(AtnStateKind::RuleStart, Some(0))
17650 .expect("state")
17651 .index(),
17652 0
17653 );
17654 assert_eq!(
17655 atn.add_state(AtnStateKind::RuleStop, Some(0))
17656 .expect("state")
17657 .index(),
17658 1
17659 );
17660 assert_eq!(
17661 atn.add_state(AtnStateKind::Basic, Some(0))
17662 .expect("state")
17663 .index(),
17664 2
17665 );
17666 atn.set_rule_to_start_state(vec![0])
17667 .expect("rule start states");
17668 atn.set_rule_to_stop_state(vec![1])
17669 .expect("rule stop states");
17670 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
17671 .expect("transition");
17672 atn.add_transition(
17673 2,
17674 ParserTransitionSpec::Atom {
17675 target: 1,
17676 label: TOKEN_EOF,
17677 },
17678 )
17679 .expect("transition");
17680 finish_atn(atn)
17681 }
17682
17683 #[test]
17684 fn parser_matches_token_and_reports_mismatch() {
17685 let source = Source {
17686 tokens: vec![
17687 TestToken::new(1).with_text("x"),
17688 TestToken::eof("parser-test", 1, 1, 1),
17689 ],
17690 index: 0,
17691 };
17692 let data = RecognizerData::new(
17693 "Mini.g4",
17694 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17695 );
17696 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17697 let matched = parser.match_token(1).expect("token 1 should match");
17698 assert_eq!(parser.node(matched).text(), "x");
17699 assert!(parser.match_token(1).is_err());
17700 }
17701
17702 #[test]
17703 fn parser_matches_token_sets() {
17704 let mut parser = mini_parser(vec![
17705 TestToken::new(1).with_text("x"),
17706 TestToken::eof("parser-test", 1, 1, 1),
17707 ]);
17708
17709 let matched = parser
17710 .match_set(&[(1, 1), (3, 4)])
17711 .expect("token set should match");
17712 assert_eq!(parser.node(matched).text(), "x");
17713 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
17714 }
17715
17716 #[test]
17717 fn generated_rule_api_tracks_state_and_precedence() {
17718 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17719
17720 let context = parser.enter_rule(7, 2);
17721 assert_eq!(context.rule_index(), 2);
17722 assert_eq!(parser.state(), 7);
17723 assert_eq!(
17724 parser.rule_context_stack,
17725 vec![RuleContextFrame {
17726 rule_index: 2,
17727 invoking_state: 7
17728 }]
17729 );
17730
17731 let recursive = parser.enter_recursion_rule(11, 3, 4);
17732 assert_eq!(recursive.rule_index(), 3);
17733 assert!(parser.precpred(4));
17734 assert!(parser.precpred(5));
17735 assert!(!parser.precpred(3));
17736
17737 let next = parser.push_new_recursion_context(13, 3);
17738 assert_eq!(next.invoking_state(), 13);
17739 parser.unroll_recursion_context();
17740 assert_eq!(parser.precedence_stack, vec![0]);
17741 assert_eq!(
17742 parser.rule_context_stack,
17743 vec![RuleContextFrame {
17744 rule_index: 2,
17745 invoking_state: 7
17746 }]
17747 );
17748
17749 parser.exit_rule();
17750 assert!(parser.rule_context_stack.is_empty());
17751 }
17752
17753 #[test]
17754 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
17755 let mut parser = mini_parser(vec![
17756 TestToken::new(1).with_text("x"),
17757 TestToken::eof("parser-test", 1, 1, 1),
17758 ]);
17759 let matched = parser.match_token(1).expect("token should match");
17760 assert_eq!(parser.node(matched).text(), "x");
17761 parser.record_generated_syntax_error();
17762 parser.set_int_member(7, 11);
17763 parser.set_build_parse_trees(false);
17764 parser.set_report_diagnostic_errors(true);
17765 parser.set_prediction_mode(PredictionMode::Sll);
17766 parser.set_bail_on_error(true);
17767 let _context = parser.enter_recursion_rule(9, 0, 4);
17768 parser.pending_invoking_states.push(5);
17769 parser.unknown_predicate_hits.push((0, 1));
17770 parser.unhandled_action_hits.push((0, 2));
17771
17772 parser.reset();
17773
17774 assert_eq!(parser.input.index(), 0);
17775 assert_eq!(parser.la(1), 1);
17776 assert_eq!(parser.state(), -1);
17777 assert_eq!(parser.number_of_syntax_errors(), 0);
17778 assert_eq!(parser.parse_tree_storage().node_count(), 0);
17779 assert!(parser.rule_context_stack.is_empty());
17780 assert!(parser.pending_invoking_states.is_empty());
17781 assert_eq!(parser.precedence_stack, [0]);
17782 assert!(parser.unknown_predicate_hits.is_empty());
17783 assert!(parser.unhandled_action_hits.is_empty());
17784 assert_eq!(parser.int_member(7), Some(11));
17785 assert!(!parser.build_parse_trees());
17786 assert!(parser.report_diagnostic_errors());
17787 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
17788 assert!(parser.bail_on_error());
17789 }
17790
17791 #[test]
17792 fn set_token_stream_replaces_input_and_resets_parser() {
17793 let mut parser = mini_parser(vec![
17794 TestToken::new(1).with_text("old"),
17795 TestToken::eof("parser-test", 1, 1, 1),
17796 ]);
17797 parser.consume();
17798 parser.record_generated_syntax_error();
17799 let replacement = CommonTokenStream::new(Source {
17800 tokens: vec![
17801 TestToken::new(2).with_text("new"),
17802 TestToken::eof("parser-test", 1, 1, 1),
17803 ],
17804 index: 0,
17805 });
17806
17807 parser.set_token_stream(replacement);
17808
17809 assert_eq!(parser.input.index(), 0);
17810 assert_eq!(parser.la(1), 2);
17811 assert_eq!(parser.input.text_all(), "new");
17812 assert_eq!(parser.number_of_syntax_errors(), 0);
17813 }
17814
17815 #[test]
17816 fn active_invocation_states_exclude_the_root_frame() {
17817 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17818
17819 let _root = parser.enter_rule(0, 0);
17820 assert!(parser.active_invocation_states().is_empty());
17821
17822 let marker = parser.push_invoking_state(6);
17823 let _child = parser.enter_rule(2, 1);
17824 parser.discard_invoking_state(marker);
17825 assert_eq!(parser.active_invocation_states(), [6]);
17826
17827 let marker = parser.push_invoking_state(13);
17828 let _grandchild = parser.enter_rule(4, 2);
17829 parser.discard_invoking_state(marker);
17830 assert_eq!(parser.active_invocation_states(), [13, 6]);
17831
17832 parser.exit_rule();
17833 parser.exit_rule();
17834 parser.exit_rule();
17835 }
17836
17837 #[test]
17838 fn parser_predicates_support_token_adjacency() {
17839 let mut parser = mini_parser(vec![
17840 TestToken::new(1).with_text("=").with_span(0, 0),
17841 TestToken::new(1).with_text(">").with_span(1, 1),
17842 TestToken::eof("parser-test", 2, 1, 2),
17843 ]);
17844 parser.consume();
17845 parser.consume();
17846
17847 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
17848
17849 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
17850
17851 let mut parser = mini_parser(vec![
17852 TestToken::new(1).with_text("=").with_span(0, 0),
17853 TestToken::new(1)
17854 .with_text(" ")
17855 .with_channel(HIDDEN_CHANNEL)
17856 .with_span(1, 1),
17857 TestToken::new(1).with_text(">").with_span(2, 2),
17858 TestToken::eof("parser-test", 3, 1, 3),
17859 ]);
17860 parser.consume();
17861 parser.consume();
17862
17863 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
17864 }
17865
17866 #[test]
17867 fn parser_predicates_support_context_child_text_checks() {
17868 let mut parser = mini_parser(vec![
17869 TestToken::new(1).with_text("var"),
17870 TestToken::eof("parser-test", 1, 1, 1),
17871 ]);
17872 let mut context = ParserRuleContext::new(1, 0);
17873 let mut child_context = ParserRuleContext::new(2, 0);
17874 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
17875 parser.tree.add_child(&mut child_context, terminal);
17876 let child = parser.rule_node(child_context);
17877 parser.tree.add_child(&mut context, child);
17878 let predicates = [(
17879 1,
17880 0,
17881 ParserPredicate::ContextChildRuleTextNotEquals {
17882 rule_index: 2,
17883 text: "var",
17884 },
17885 )];
17886
17887 assert!(
17888 !parser.parser_semantic_predicate_matches_with_context_and_local(
17889 &predicates,
17890 1,
17891 0,
17892 &context,
17893 0,
17894 )
17895 );
17896 }
17897
17898 #[test]
17899 fn context_expected_symbols_walks_nullable_parent_contexts() {
17900 let atn = nested_nullable_context_atn();
17901 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17902 parser.rule_context_stack = vec![
17903 RuleContextFrame {
17904 rule_index: 0,
17905 invoking_state: 0,
17906 },
17907 RuleContextFrame {
17908 rule_index: 1,
17909 invoking_state: 1,
17910 },
17911 RuleContextFrame {
17912 rule_index: 2,
17913 invoking_state: 2,
17914 },
17915 ];
17916
17917 let expected = parser.context_expected_symbols(&atn);
17918
17919 assert!(expected.contains(&1));
17920 assert!(expected.contains(&TOKEN_EOF));
17921 }
17922
17923 #[test]
17924 fn prediction_context_return_states_track_rule_stack_changes() {
17925 let atn = nested_nullable_context_atn();
17926 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17927 parser.rule_context_stack = vec![
17928 RuleContextFrame {
17929 rule_index: 0,
17930 invoking_state: 0,
17931 },
17932 RuleContextFrame {
17933 rule_index: 1,
17934 invoking_state: 1,
17935 },
17936 RuleContextFrame {
17937 rule_index: 2,
17938 invoking_state: 2,
17939 },
17940 ];
17941
17942 let initial_version = parser.rule_context_version();
17943 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
17944 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
17945 assert_eq!(first, second);
17946 assert_eq!(parser.rule_context_version(), initial_version);
17947
17948 parser.exit_rule();
17949 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
17950 assert_ne!(first, after_pop);
17951 assert_ne!(parser.rule_context_version(), initial_version);
17952 }
17953
17954 #[test]
17955 fn generated_match_token_recovers_missing_token_from_context_follow() {
17956 let atn = generated_match_recovery_atn();
17957 let data = RecognizerData::new(
17958 "Mini.g4",
17959 Vocabulary::new(
17960 [None, Some("'X'"), Some("'Y'")],
17961 [None, Some("X"), Some("Y")],
17962 [None::<&str>, None, None],
17963 ),
17964 );
17965 let mut parser = BaseParser::new(
17966 CommonTokenStream::new(Source {
17967 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
17968 index: 0,
17969 }),
17970 data,
17971 );
17972 parser.rule_context_stack = vec![
17973 RuleContextFrame {
17974 rule_index: 0,
17975 invoking_state: 0,
17976 },
17977 RuleContextFrame {
17978 rule_index: 1,
17979 invoking_state: 1,
17980 },
17981 ];
17982 assert_eq!(parser.number_of_syntax_errors(), 0);
17983
17984 let node = parser
17985 .match_token_recovering(2, 5, &atn)
17986 .expect("generated match should insert missing token");
17987
17988 assert_eq!(node.children().len(), 1);
17989 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
17990 assert_eq!(
17991 node.clone()
17992 .into_child_iter()
17993 .map(|child| parser.node(child).text())
17994 .collect::<Vec<_>>(),
17995 ["<missing 'Y'>"]
17996 );
17997 assert!(!node.consumed_eof());
18000 assert_eq!(parser.la(1), TOKEN_EOF);
18001 assert_eq!(parser.number_of_syntax_errors(), 1);
18002 assert_eq!(
18003 parser.generated_parser_diagnostics,
18004 [ParserDiagnostic {
18005 line: 1,
18006 column: 3,
18007 message: "missing 'Y' at '<EOF>'".to_owned(),
18008 offending: parser.input.lt_id(1),
18009 }]
18010 );
18011 }
18012
18013 #[test]
18014 fn generated_match_token_counts_single_token_deletion_recovery() {
18015 let atn = generated_match_recovery_atn();
18016 let data = RecognizerData::new(
18017 "Mini.g4",
18018 Vocabulary::new(
18019 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
18020 [None, Some("X"), Some("Y"), Some("Z")],
18021 [None::<&str>, None, None, None],
18022 ),
18023 );
18024 let mut parser = BaseParser::new(
18025 CommonTokenStream::new(Source {
18026 tokens: vec![
18027 TestToken::new(3).with_text("z"),
18028 TestToken::new(2).with_text("y"),
18029 TestToken::eof("parser-test", 3, 1, 3),
18030 ],
18031 index: 0,
18032 }),
18033 data,
18034 );
18035
18036 let node = parser
18037 .match_token_recovering(2, 5, &atn)
18038 .expect("generated match should delete the extraneous token");
18039
18040 assert_eq!(node.children().len(), 2);
18041 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
18042 assert_eq!(parser.node(node.children()[0]).text(), "z");
18043 assert_eq!(parser.node(node.children()[1]).text(), "y");
18044 assert_eq!(
18045 node.into_child_iter()
18046 .map(|child| parser.node(child).text())
18047 .collect::<Vec<_>>(),
18048 ["z", "y"]
18049 );
18050 assert_eq!(parser.number_of_syntax_errors(), 1);
18051 }
18052
18053 #[test]
18054 fn generated_match_token_iterates_single_success_without_a_children_vec() {
18055 let atn = generated_match_recovery_atn();
18056 let data = RecognizerData::new(
18057 "Mini.g4",
18058 Vocabulary::new(
18059 [None, Some("'X'"), Some("'Y'")],
18060 [None, Some("X"), Some("Y")],
18061 [None::<&str>, None, None],
18062 ),
18063 );
18064 let mut parser = BaseParser::new(
18065 CommonTokenStream::new(Source {
18066 tokens: vec![
18067 TestToken::new(2).with_text("y"),
18068 TestToken::eof("parser-test", 1, 1, 1),
18069 ],
18070 index: 0,
18071 }),
18072 data,
18073 );
18074
18075 let node = parser
18076 .match_token_recovering(2, 5, &atn)
18077 .expect("generated match should consume the expected token");
18078
18079 assert_eq!(
18080 node.into_child_iter()
18081 .map(|child| parser.node(child).text())
18082 .collect::<Vec<_>>(),
18083 ["y"]
18084 );
18085 assert_eq!(parser.number_of_syntax_errors(), 0);
18086 }
18087
18088 #[test]
18089 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
18090 let atn = generated_match_recovery_atn();
18091 let data = RecognizerData::new(
18092 "Mini.g4",
18093 Vocabulary::new(
18094 [None, Some("'X'"), Some("'Y'")],
18095 [None, Some("X"), Some("Y")],
18096 [None::<&str>, None, None],
18097 ),
18098 );
18099 let mut parser = BaseParser::new(
18100 CommonTokenStream::new(Source {
18101 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
18102 index: 0,
18103 }),
18104 data,
18105 );
18106 parser.rule_context_stack = vec![
18107 RuleContextFrame {
18108 rule_index: 0,
18109 invoking_state: 0,
18110 },
18111 RuleContextFrame {
18112 rule_index: 1,
18113 invoking_state: 1,
18114 },
18115 ];
18116 let marker = parser.generated_diagnostics_checkpoint();
18117
18118 let _ = parser
18119 .match_token_recovering(2, 5, &atn)
18120 .expect("generated match should insert missing token");
18121 assert_eq!(parser.number_of_syntax_errors(), 1);
18122
18123 parser.restore_generated_diagnostics(marker);
18124
18125 assert_eq!(parser.number_of_syntax_errors(), 0);
18126 assert!(parser.generated_parser_diagnostics.is_empty());
18127 }
18128
18129 #[test]
18130 fn generated_prediction_diagnostics_use_adaptive_context() {
18131 let atn = two_alt_decision_atn();
18132 let data = RecognizerData::new(
18133 "Mini.g4",
18134 Vocabulary::new(
18135 [None, Some("'x'"), Some("'y'")],
18136 [None, Some("X"), Some("Y")],
18137 [None::<&str>, None, None],
18138 ),
18139 )
18140 .with_rule_names(["s"]);
18141 let mut parser = BaseParser::new(
18142 CommonTokenStream::new(Source {
18143 tokens: vec![
18144 TestToken::new(1)
18145 .with_text("x")
18146 .with_position(1, 0)
18147 .with_span(0, 0),
18148 TestToken::new(2)
18149 .with_text("y")
18150 .with_position(1, 2)
18151 .with_span(1, 1),
18152 TestToken::eof("parser-test", 2, 1, 3),
18153 ],
18154 index: 0,
18155 }),
18156 data,
18157 );
18158 parser.set_report_diagnostic_errors(true);
18159
18160 parser.record_generated_prediction_diagnostic(
18161 &atn,
18162 1,
18163 &ParserAtnPrediction {
18164 alt: 1,
18165 requires_full_context: true,
18166 has_semantic_context: false,
18167 diagnostic: Some(ParserAtnPredictionDiagnostic {
18168 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
18169 start_index: 0,
18170 sll_stop_index: 1,
18171 ll_stop_index: 0,
18172 conflicting_alts: vec![1, 2],
18173 exact: false,
18174 }),
18175 },
18176 );
18177 parser.record_generated_prediction_diagnostic(
18182 &atn,
18183 1,
18184 &ParserAtnPrediction {
18185 alt: 1,
18186 requires_full_context: true,
18187 has_semantic_context: false,
18188 diagnostic: Some(ParserAtnPredictionDiagnostic {
18189 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
18190 start_index: 0,
18191 sll_stop_index: 1,
18192 ll_stop_index: 1,
18193 conflicting_alts: vec![1, 2],
18194 exact: false,
18195 }),
18196 },
18197 );
18198
18199 insta::assert_debug_snapshot!(
18202 "generated_prediction_diagnostics_use_adaptive_context",
18203 parser.generated_parser_diagnostics
18204 );
18205 }
18206
18207 #[test]
18208 fn generated_match_not_set_recovers_empty_complement_at_eof() {
18209 let atn = complement_set_atn();
18210 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18211 parser.rule_context_stack = vec![RuleContextFrame {
18212 rule_index: 0,
18213 invoking_state: 0,
18214 }];
18215
18216 let node = parser
18217 .match_not_token_set_recovering(
18218 atn.token_set(0).expect("excluded token set"),
18219 1,
18220 1,
18221 1,
18222 &atn,
18223 )
18224 .expect("empty complement should recover at EOF");
18225
18226 assert_eq!(node.children().len(), 1);
18227 assert!(!node.consumed_eof());
18230 assert_eq!(parser.la(1), TOKEN_EOF);
18231 assert_eq!(
18232 parser.generated_parser_diagnostics,
18233 [ParserDiagnostic {
18234 line: 1,
18235 column: 1,
18236 message: "missing {} at '<EOF>'".to_owned(),
18237 offending: parser.input.lt_id(1),
18238 }]
18239 );
18240 }
18241
18242 #[test]
18243 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
18244 let atn = wildcard_then_eof_atn();
18250 let data = RecognizerData::new(
18251 "Mini.g4",
18252 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18253 );
18254 let mut parser = BaseParser::new(
18255 CommonTokenStream::new(Source {
18256 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
18257 index: 0,
18258 }),
18259 data,
18260 );
18261 parser.rule_context_stack = vec![RuleContextFrame {
18262 rule_index: 0,
18263 invoking_state: 0,
18264 }];
18265
18266 let node = parser
18267 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
18268 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
18269
18270 assert_eq!(node.children().len(), 1);
18272 assert!(!node.consumed_eof());
18273 assert!(
18274 parser
18275 .node(node.children()[0])
18276 .text()
18277 .starts_with("<missing")
18278 );
18279 assert_eq!(parser.la(1), TOKEN_EOF);
18280 assert_eq!(
18281 parser.generated_parser_diagnostics,
18282 [ParserDiagnostic {
18283 line: 1,
18284 column: 1,
18285 message: "missing 'x' at '<EOF>'".to_owned(),
18286 offending: parser.input.lt_id(1),
18287 }]
18288 );
18289 }
18290
18291 #[test]
18292 fn generated_rule_recovery_consumes_to_parent_follow() {
18293 let atn = generated_match_recovery_atn();
18294 let data = RecognizerData::new(
18295 "Mini.g4",
18296 Vocabulary::new(
18297 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
18298 [None, Some("X"), Some("Y"), Some("Z")],
18299 [None::<&str>, None, None, None],
18300 ),
18301 );
18302 let mut parser = BaseParser::new(
18303 CommonTokenStream::new(Source {
18304 tokens: vec![
18305 TestToken::new(3).with_text("z"),
18306 TestToken::eof("parser-test", 1, 1, 1),
18307 ],
18308 index: 0,
18309 }),
18310 data,
18311 );
18312 let _parent = parser.enter_rule(0, 0);
18313 let marker = parser.push_invoking_state(1);
18314 let mut child = parser.enter_rule(4, 1);
18315 parser.discard_invoking_state(marker);
18316
18317 let offending = parser.input.lt_id(1);
18320 assert!(offending.is_some(), "the 'z' token should be buffered");
18321 parser.recover_generated_rule(
18322 &mut child,
18323 &atn,
18324 AntlrError::ParserError {
18325 line: 1,
18326 column: 0,
18327 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
18328 offending,
18329 },
18330 );
18331 let tree = parser.finish_rule(child, false);
18332
18333 assert_eq!(parser.la(1), TOKEN_EOF);
18334 assert_eq!(
18335 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
18336 "(a z)"
18337 );
18338 assert_eq!(parser.number_of_syntax_errors(), 1);
18339 assert_eq!(
18340 parser.generated_parser_diagnostics,
18341 [ParserDiagnostic {
18342 line: 1,
18343 column: 0,
18344 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
18345 offending,
18346 }]
18347 );
18348 parser.exit_rule();
18349 }
18350
18351 #[test]
18352 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
18353 let atn = nested_nullable_context_atn();
18354 let mut parser = mini_parser(vec![
18355 TestToken::new(1).with_text("x"),
18356 TestToken::eof("parser-test", 1, 1, 1),
18357 ]);
18358 parser.rule_context_stack = vec![
18359 RuleContextFrame {
18360 rule_index: 0,
18361 invoking_state: 0,
18362 },
18363 RuleContextFrame {
18364 rule_index: 1,
18365 invoking_state: 1,
18366 },
18367 RuleContextFrame {
18368 rule_index: 2,
18369 invoking_state: 2,
18370 },
18371 ];
18372 parser.set_state(20);
18373 let mut context = ParserRuleContext::new(2, 2);
18374
18375 parser.recover_generated_rule(
18376 &mut context,
18377 &atn,
18378 AntlrError::NoViableAlternative {
18379 input: "'x'".to_owned(),
18380 },
18381 );
18382 assert_eq!(parser.input.index(), 0);
18383
18384 parser.set_state(21);
18385 parser.recover_generated_rule(
18386 &mut context,
18387 &atn,
18388 AntlrError::NoViableAlternative {
18389 input: "'x'".to_owned(),
18390 },
18391 );
18392 assert_eq!(parser.input.index(), 0);
18393 assert_eq!(
18394 parser.generated_recovery_error_states,
18395 BTreeSet::from([20, 21])
18396 );
18397
18398 parser.set_state(20);
18399 parser.recover_generated_rule(
18400 &mut context,
18401 &atn,
18402 AntlrError::NoViableAlternative {
18403 input: "'x'".to_owned(),
18404 },
18405 );
18406
18407 assert_eq!(parser.input.index(), 1);
18408 assert_eq!(parser.la(1), TOKEN_EOF);
18409 assert!(context.has_matched_child());
18410 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
18411
18412 parser.match_eof().expect("EOF should match");
18413 assert_eq!(parser.generated_recovery_error_index, None);
18414 assert!(parser.generated_recovery_error_states.is_empty());
18415 }
18416
18417 #[test]
18418 fn greedy_ll1_alt_handles_nullable_loop_exit() {
18419 let mut body_symbols = TokenBitSet::default();
18420 body_symbols.insert(1);
18421 let entry = DecisionLookahead {
18422 transitions: vec![
18423 TransitionLookSet {
18424 symbols: body_symbols,
18425 nullable: false,
18426 },
18427 TransitionLookSet {
18428 symbols: TokenBitSet::default(),
18429 nullable: true,
18430 },
18431 ],
18432 };
18433
18434 assert_eq!(ll1_unique_alt(&entry, 2), None);
18435 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
18436 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
18437 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
18438 }
18439
18440 #[test]
18441 fn ordinary_repetition_builds_tree_in_input_order() {
18442 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18443 let mut parser = mini_parser(repeated_x_tokens(3));
18444 let tree = parser
18445 .parse_atn_rule(&atn, 0)
18446 .expect("ordinary repetition should parse");
18447
18448 let root = parser
18449 .node(tree)
18450 .as_rule()
18451 .expect("entry result should be a rule");
18452 let body_rules = root.child_rules(1).collect::<Vec<_>>();
18453 assert_eq!(root.text(), "xxx<EOF>");
18454 assert_eq!(body_rules.len(), 3);
18455 assert_eq!(
18456 body_rules
18457 .iter()
18458 .map(|rule| rule.start_id().expect("body start").index())
18459 .collect::<Vec<_>>(),
18460 [0, 1, 2]
18461 );
18462 assert_eq!(
18463 body_rules
18464 .iter()
18465 .map(|rule| rule.stop_id().expect("body stop").index())
18466 .collect::<Vec<_>>(),
18467 [0, 1, 2]
18468 );
18469 assert_eq!(parser.number_of_syntax_errors(), 0);
18470 }
18471 }
18472
18473 #[test]
18474 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
18475 const DEPTH: usize = 20_000;
18476
18477 std::thread::Builder::new()
18478 .name("deferred-rule-materialization".to_owned())
18479 .stack_size(256 * 1024)
18480 .spawn(|| {
18481 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
18482 let mut root = FastDeferredNodeId::EMPTY;
18483 for depth in 0..DEPTH {
18484 root = parser
18485 .recognition_arena
18486 .deferred_rule_node(FastDeferredRule {
18487 rule_index: u32::try_from(depth).expect("depth fits in u32"),
18488 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
18489 start_index: 0,
18490 stop_index: None,
18491 deferred_children: root,
18492 children: NodeSeqId::EMPTY,
18493 });
18494 }
18495
18496 let (mut children, alt_number) =
18497 parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
18498 assert_eq!(alt_number, 0);
18499 for expected_rule in (0..DEPTH).rev() {
18500 let mut nodes = parser.recognition_arena.iter(children);
18501 let node = nodes.next().expect("nested rule node");
18502 assert!(nodes.next().is_none(), "each rule has one child");
18503 let ArenaRecognizedNode::Rule {
18504 rule_index,
18505 children: nested,
18506 ..
18507 } = parser.recognition_arena.node(node)
18508 else {
18509 panic!("expected nested rule");
18510 };
18511 assert_eq!(rule_index as usize, expected_rule);
18512 children = nested;
18513 }
18514 assert!(children.is_empty());
18515 })
18516 .expect("small-stack thread should start")
18517 .join()
18518 .expect("deferred rules should materialize without recursion");
18519 }
18520
18521 #[test]
18522 fn deferred_alternatives_preserve_left_recursive_contexts() {
18523 let mut parser = mini_parser(vec![
18524 TestToken::new(1).with_text("1"),
18525 TestToken::new(2).with_text("+"),
18526 TestToken::new(1).with_text("2"),
18527 TestToken::eof("parser-test", 3, 1, 3),
18528 ]);
18529 let base = parser.arena_token_node(0, false);
18530 let operator = parser.arena_token_node(1, false);
18531 let right = parser.arena_token_node(2, false);
18532
18533 let base = parser.recognition_arena.prepend(NodeSeqId::EMPTY, base);
18534 let base = parser.recognition_arena.deferred_fragment(base);
18535 let operator = parser.recognition_arena.prepend(NodeSeqId::EMPTY, operator);
18536 let operator = parser.recognition_arena.deferred_fragment(operator);
18537 let right = parser.recognition_arena.prepend(NodeSeqId::EMPTY, right);
18538 let right = parser.recognition_arena.deferred_fragment(right);
18539 let base_alt = parser.recognition_arena.deferred_alternative(1);
18540 let boundary = parser.recognition_arena.deferred_left_recursive_boundary(0);
18541 let operator_alt = parser.recognition_arena.deferred_alternative(6);
18542
18543 let mut deferred = FastDeferredNodeId::EMPTY;
18544 for fragment in [base_alt, base, boundary, operator_alt, operator, right] {
18545 deferred = parser
18546 .recognition_arena
18547 .concat_deferred_nodes(deferred, fragment);
18548 }
18549 let (nodes, root_alt_number) =
18550 parser.materialize_fast_deferred_nodes(deferred, NodeSeqId::EMPTY);
18551 let nodes = parser
18552 .recognition_arena
18553 .fold_left_recursive_boundaries(nodes);
18554
18555 let mut root = ParserRuleContext::new(0, -1);
18556 root.set_context_alt_number(root_alt_number);
18557 let mut cursor = nodes;
18558 while let Some(link) = parser.recognition_arena.link(cursor) {
18559 let child = parser
18560 .arena_recognized_node_tree(link.head, false, true)
18561 .expect("materialized child should become a public tree");
18562 parser.tree.add_child(&mut root, child);
18563 cursor = link.tail;
18564 }
18565 let tree = parser.rule_node(root);
18566 let contexts = parser
18567 .node(tree)
18568 .descendants()
18569 .filter_map(Node::as_rule)
18570 .map(|rule| {
18571 (
18572 rule.rule_index(),
18573 rule.alt_number(),
18574 rule.context_alt_number(),
18575 rule.text(),
18576 )
18577 })
18578 .collect::<Vec<_>>();
18579
18580 insta::assert_debug_snapshot!(
18581 "deferred_alternatives_preserve_left_recursive_contexts",
18582 contexts
18583 );
18584 }
18585
18586 #[test]
18587 fn fast_recognizer_preserves_labeled_left_recursive_operator_context() {
18588 let atn = labeled_left_recursive_operator_atn();
18589 let mut parser = mini_parser(vec![
18590 TestToken::new(1).with_text("a"),
18591 TestToken::new(3).with_text("+"),
18592 TestToken::new(1).with_text("b"),
18593 TestToken::eof("parser-test", 3, 1, 3),
18594 ]);
18595
18596 let (tree, _) = parser
18597 .parse_atn_rule_with_runtime_options(
18598 &atn,
18599 0,
18600 ParserRuntimeOptions {
18601 track_context_alt_numbers: true,
18602 ..ParserRuntimeOptions::default()
18603 },
18604 )
18605 .expect("labeled left-recursive addition should parse");
18606 let contexts = parser
18607 .node(tree)
18608 .descendants()
18609 .filter_map(Node::as_rule)
18610 .map(|rule| {
18611 let operator = rule
18612 .children()
18613 .next()
18614 .and_then(Node::as_rule)
18615 .is_some_and(|child| child.rule_index() == rule.rule_index());
18616 (operator, rule.context_alt_number(), rule.text())
18617 })
18618 .collect::<Vec<_>>();
18619
18620 insta::assert_debug_snapshot!(
18621 "fast_recognizer_preserves_labeled_left_recursive_operator_context",
18622 contexts
18623 );
18624 assert!(!parser.recognition_arena.deferred_nodes.is_empty());
18625 assert_eq!(parser.number_of_syntax_errors(), 0);
18626 }
18627
18628 #[test]
18629 fn deeply_nested_rule_calls_grow_the_stack() {
18630 const DEPTH: usize = 4_096;
18631 const STACK_SIZE: usize = 256 * 1024;
18632 let atn = nested_rule_chain_atn(DEPTH);
18633 std::thread::Builder::new()
18634 .name("nested-adaptive-set-rules".to_owned())
18635 .stack_size(STACK_SIZE)
18636 .spawn(move || {
18637 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
18638 parser.set_build_parse_trees(false);
18639 parser.fast_first_set_prefilter = false;
18642 parser
18643 .parse_atn_rule(&atn, 0)
18644 .expect("nested rule chain should grow the native stack");
18645 assert_eq!(parser.input.index(), 1);
18646 })
18647 .expect("small-stack thread should start")
18648 .join()
18649 .expect("nested rule chain should not overflow its stack");
18650 }
18651
18652 #[test]
18653 fn deeply_nested_branching_rules_grow_the_stack() {
18654 const DEPTH: usize = 4_096;
18655 const STACK_SIZE: usize = 256 * 1024;
18656 let atn = nested_rule_graph_atn(DEPTH, true, false);
18657 std::thread::Builder::new()
18658 .name("nested-branching-rules".to_owned())
18659 .stack_size(STACK_SIZE)
18660 .spawn(move || {
18661 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
18662 parser.set_build_parse_trees(false);
18663 parser
18664 .parse_atn_rule(&atn, 0)
18665 .expect("branching rule chain should grow the native stack");
18666 assert_eq!(parser.input.index(), 1);
18667 })
18668 .expect("small-stack thread should start")
18669 .join()
18670 .expect("branching rule chain should not overflow its stack");
18671 }
18672
18673 #[test]
18674 fn deeply_nested_rule_follows_grow_the_stack() {
18675 const DEPTH: usize = 4_096;
18676 const STACK_SIZE: usize = 256 * 1024;
18677 let atn = nested_rule_graph_atn(DEPTH, false, true);
18678 std::thread::Builder::new()
18679 .name("nested-rule-follows".to_owned())
18680 .stack_size(STACK_SIZE)
18681 .spawn(move || {
18682 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
18683 parser.set_build_parse_trees(false);
18684 parser.fast_first_set_prefilter = false;
18685 parser
18686 .parse_atn_rule(&atn, 0)
18687 .expect("rule follow chain should grow the native stack");
18688 assert_eq!(parser.input.index(), DEPTH);
18689 })
18690 .expect("small-stack thread should start")
18691 .join()
18692 .expect("nested rule follow chain should not overflow its stack");
18693 }
18694
18695 #[test]
18696 fn deeply_nested_recovery_grows_the_stack() {
18697 const DEPTH: usize = 4_096;
18698 const STACK_SIZE: usize = 256 * 1024;
18699 let atn = nested_rule_chain_atn(DEPTH);
18700 std::thread::Builder::new()
18701 .name("nested-rule-recovery".to_owned())
18702 .stack_size(STACK_SIZE)
18703 .spawn(move || {
18704 let mut parser = mini_parser(vec![
18705 TestToken::new(2).with_text("z"),
18706 TestToken::new(1).with_text("x"),
18707 TestToken::eof("parser-test", 2, 1, 2),
18708 ]);
18709 parser.set_build_parse_trees(false);
18710 parser.fast_first_set_prefilter = false;
18711 parser
18712 .parse_atn_rule(&atn, 0)
18713 .expect("nested recovery should grow the native stack");
18714 assert_eq!(parser.input.index(), 2);
18715 assert_eq!(parser.number_of_syntax_errors(), 1);
18716 })
18717 .expect("small-stack thread should start")
18718 .join()
18719 .expect("nested rule recovery should not overflow its stack");
18720 }
18721
18722 #[test]
18723 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
18724 const REPETITIONS: usize = 64;
18725
18726 let atn = ambiguous_ordinary_star_loop_atn();
18727 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18728 let tree = parser
18729 .parse_atn_rule(&atn, 0)
18730 .expect("ambiguous ordinary repetition should parse");
18731
18732 let root = parser
18733 .node(tree)
18734 .as_rule()
18735 .expect("entry result should be a rule");
18736 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
18737 assert_eq!(parser.input.index(), REPETITIONS);
18738 assert!(
18739 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
18740 "equivalent segmentations should keep deferred storage linear"
18741 );
18742 assert_eq!(parser.number_of_syntax_errors(), 0);
18743 }
18744
18745 #[test]
18746 fn long_ordinary_repetition_does_not_consume_native_stack() {
18747 const REPETITIONS: usize = 20_000;
18748
18749 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18750 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18751 parser.set_build_parse_trees(false);
18752 parser
18753 .parse_atn_rule(&atn, 0)
18754 .expect("long ordinary repetition should parse");
18755
18756 assert_eq!(parser.input.index(), REPETITIONS);
18757 assert_eq!(parser.number_of_syntax_errors(), 0);
18758 }
18759 }
18760
18761 #[test]
18762 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
18763 const REPETITIONS: usize = 2_000;
18764 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
18765
18766 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18767 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18768 let tree = parser
18769 .parse_atn_rule(&atn, 0)
18770 .expect("long rule repetition should parse");
18771
18772 let root = parser
18773 .node(tree)
18774 .as_rule()
18775 .expect("entry result should be a rule");
18776 assert_eq!(root.text(), expected_text);
18777 assert_eq!(root.child_rules(1).count(), REPETITIONS);
18778 let first_body = root.child_rules(1).next().expect("first body rule");
18779 let last_body = root.child_rules(1).next_back().expect("last body rule");
18780 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
18781 assert_eq!(
18782 last_body.stop_id().expect("last body stop").index(),
18783 REPETITIONS - 1
18784 );
18785
18786 let stats = parser.recognition_arena_stats();
18787 assert_eq!(
18788 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18789 (REPETITIONS, REPETITIONS, 0)
18790 );
18791 assert_eq!(
18792 (stats.total_links, stats.live_links, stats.dead_links),
18793 (REPETITIONS, REPETITIONS, 0)
18794 );
18795 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
18796 assert_eq!(
18797 parser.recognition_arena.deferred_nodes.len(),
18798 REPETITIONS * 2 - 1
18799 );
18800 assert_eq!(parser.number_of_syntax_errors(), 0);
18801 }
18802 }
18803
18804 #[test]
18805 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
18806 let key = |state_number| FastRecognizeKey {
18807 state_number,
18808 stop_state: 10,
18809 index: state_number,
18810 rule_start_index: 0,
18811 decision_start_index: None,
18812 precedence: 0,
18813 recovery_symbols_id: 0,
18814 recovery_state: None,
18815 };
18816
18817 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18818 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
18819 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
18820 }
18821 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
18822 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
18823
18824 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18825 let repeated = key(1);
18826 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
18827 assert!(promote.clean_memo_enabled_for_key(&repeated));
18828 }
18829 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
18830
18831 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
18832 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
18833 }
18834 assert!(sparse.clean_memo_enabled_for_key(&repeated));
18835 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
18836 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
18837 assert!(sparse.clean_memo_enabled_for_key(&repeated));
18838 }
18839 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
18840 }
18841
18842 #[test]
18843 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
18844 assert_eq!(
18845 fast_recognize_memo_capacity(0),
18846 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
18847 );
18848 assert_eq!(
18849 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
18850 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
18851 );
18852 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
18853 assert_eq!(
18854 fast_recognize_memo_capacity(usize::MAX),
18855 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
18856 );
18857 }
18858
18859 #[test]
18860 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
18861 let mut scratch = FastRecognizeTopScratch::default();
18862 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
18863 let retained_capacity = scratch.memo.capacity();
18864 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
18865 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
18866
18867 let larger_capacity = retained_capacity + 1;
18868 scratch.prepare(larger_capacity);
18869 let grown_capacity = scratch.memo.capacity();
18870 assert!(grown_capacity >= larger_capacity);
18871 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
18872
18873 scratch.memo.insert(
18874 FastRecognizeKey {
18875 state_number: 0,
18876 stop_state: 0,
18877 index: 0,
18878 rule_start_index: 0,
18879 decision_start_index: None,
18880 precedence: 0,
18881 recovery_symbols_id: 0,
18882 recovery_state: None,
18883 },
18884 Rc::from([FastRecognizeOutcome {
18885 index: 0,
18886 consumed_eof: false,
18887 diagnostics: DiagnosticSeqId::EMPTY,
18888 deferred_nodes: FastDeferredNodeId::EMPTY,
18889 nodes: NodeSeqId::EMPTY,
18890 }]),
18891 );
18892 scratch.release_oversized_memo();
18893 assert!(scratch.memo.is_empty());
18894 assert_eq!(scratch.memo.capacity(), grown_capacity);
18895
18896 scratch
18897 .memo
18898 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
18899 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
18900
18901 scratch.release_oversized_memo();
18902 assert!(scratch.memo.is_empty());
18903 assert_eq!(scratch.memo.capacity(), 0);
18904 }
18905
18906 #[test]
18907 fn clean_empty_multi_alt_outcomes_are_memoized() {
18908 let mut atn = ParserAtnBuilder::new(2);
18909 assert_eq!(
18910 atn.add_state(AtnStateKind::RuleStart, Some(0))
18911 .expect("state")
18912 .index(),
18913 0
18914 );
18915 assert_eq!(
18916 atn.add_state(AtnStateKind::BlockStart, Some(0))
18917 .expect("state")
18918 .index(),
18919 1
18920 );
18921 assert_eq!(
18922 atn.add_state(AtnStateKind::RuleStop, Some(0))
18923 .expect("state")
18924 .index(),
18925 2
18926 );
18927 atn.set_rule_to_start_state(vec![0])
18928 .expect("rule start states");
18929 atn.set_rule_to_stop_state(vec![2])
18930 .expect("rule stop states");
18931 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
18932 .expect("transition");
18933 atn.add_transition(
18934 1,
18935 ParserTransitionSpec::Atom {
18936 target: 2,
18937 label: 1,
18938 },
18939 )
18940 .expect("transition");
18941 atn.add_transition(
18942 1,
18943 ParserTransitionSpec::Atom {
18944 target: 2,
18945 label: 2,
18946 },
18947 )
18948 .expect("transition");
18949 let atn = finish_atn(atn);
18950
18951 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
18952 parser.fast_recovery_enabled = false;
18953 let mut visiting = FxHashSet::default();
18954 let mut memo = FxHashMap::default();
18955 let mut expected = ExpectedTokens::default();
18956 let outcomes = parser.recognize_state_fast(
18957 &atn,
18958 FastRecognizeRequest {
18959 state_number: 1,
18960 stop_state: 2,
18961 index: 0,
18962 rule_start_index: 0,
18963 decision_start_index: None,
18964 precedence: 0,
18965 depth: 0,
18966 recovery_symbols: parser.empty_recovery_symbols(),
18967 recovery_state: None,
18968 },
18969 FastRecognizeScratch {
18970 predicate_context: None,
18971 visiting: &mut visiting,
18972 memo: &mut memo,
18973 expected: &mut expected,
18974 native_depth: 0,
18975 },
18976 );
18977
18978 assert!(outcomes.is_empty());
18979 assert_eq!(memo.len(), 1);
18980 assert!(memo.values().next().expect("memo entry").is_empty());
18981
18982 parser.clean_memo_mode = CleanMemoMode::Sparse;
18983 visiting.clear();
18984 memo.clear();
18985 expected = ExpectedTokens::default();
18986 let sparse_outcomes = parser.recognize_state_fast(
18987 &atn,
18988 FastRecognizeRequest {
18989 state_number: 1,
18990 stop_state: 2,
18991 index: 0,
18992 rule_start_index: 0,
18993 decision_start_index: None,
18994 precedence: 0,
18995 depth: 0,
18996 recovery_symbols: parser.empty_recovery_symbols(),
18997 recovery_state: None,
18998 },
18999 FastRecognizeScratch {
19000 predicate_context: None,
19001 visiting: &mut visiting,
19002 memo: &mut memo,
19003 expected: &mut expected,
19004 native_depth: 0,
19005 },
19006 );
19007
19008 assert!(sparse_outcomes.is_empty());
19009 assert!(memo.is_empty());
19010 }
19011
19012 #[test]
19013 fn wildcard_matches_non_eof_only() {
19014 let mut parser = mini_parser(vec![
19015 TestToken::new(1).with_text("x"),
19016 TestToken::eof("parser-test", 1, 1, 1),
19017 ]);
19018 let matched = parser.match_wildcard().expect("wildcard");
19019 assert_eq!(parser.node(matched).text(), "x");
19020 assert!(parser.match_wildcard().is_err());
19021 }
19022
19023 #[test]
19024 fn add_parse_child_records_match_even_without_tree_building() {
19025 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
19030 let token = TestToken::new(1).with_text("x");
19031
19032 parser.set_build_parse_trees(false);
19033 let mut ctx = ParserRuleContext::new(0, 0);
19034 assert!(!ctx.has_matched_child());
19035 let child = parser.terminal_tree(token.id);
19036 parser.add_parse_child(&mut ctx, child);
19037 assert_eq!(ctx.child_count(), 0);
19039 assert_eq!(parser.parse_tree_storage().node_count(), 0);
19040 assert!(ctx.has_matched_child());
19042
19043 parser.set_build_parse_trees(true);
19045 let mut ctx = ParserRuleContext::new(0, 0);
19046 let child = parser.terminal_tree(token.id);
19047 parser.add_parse_child(&mut ctx, child);
19048 assert_eq!(ctx.child_count(), 1);
19049 assert!(ctx.has_matched_child());
19050 }
19051
19052 #[test]
19053 fn disabled_tree_building_does_not_grow_flat_storage() {
19054 let mut parser = mini_parser(vec![
19055 TestToken::new(1).with_text("x"),
19056 TestToken::new(1).with_text("y"),
19057 TestToken::eof("parser-test", 2, 1, 2),
19058 ]);
19059 parser.set_build_parse_trees(false);
19060 let mut context = ParserRuleContext::new(0, -1);
19061
19062 for _ in 0..2 {
19063 let child = parser.match_token(1).expect("token should match");
19064 parser.add_parse_child(&mut context, child);
19065 }
19066 let current = parser.input.lt_id(1).expect("EOF token");
19067 let error = parser.error_tree(current);
19068 parser.add_parse_child(&mut context, error);
19069 let root = parser.rule_node(context);
19070
19071 assert_eq!(
19072 parser.parse_tree_storage().stats(),
19073 ParseTreeStats::default()
19074 );
19075 assert!(
19076 parser
19077 .parse_tree_storage()
19078 .node(parser.token_store(), root)
19079 .is_none(),
19080 "the no-tree sentinel must not resolve to stored data"
19081 );
19082 }
19083
19084 #[test]
19085 fn disabled_tree_building_skips_recognition_rule_node_storage() {
19086 let atn = ordinary_star_loop_atn();
19087 let mut parser = mini_parser(repeated_x_tokens(3));
19088 parser.set_build_parse_trees(false);
19089
19090 parser
19091 .parse_atn_rule(&atn, 0)
19092 .expect("ordinary repetition should parse without a tree");
19093
19094 assert_eq!(parser.input.index(), 3);
19095 assert!(parser.recognition_arena.nodes.is_empty());
19096 assert!(parser.recognition_arena.seq_links.is_empty());
19097 assert!(parser.recognition_arena.deferred_nodes.is_empty());
19098 assert!(parser.recognition_arena.deferred_rules.is_empty());
19099 assert!(!parser.fast_token_nodes_enabled);
19100 assert!(parser.fast_recognize_scratch.memo.is_empty());
19101 }
19102
19103 #[test]
19104 fn parser_interprets_simple_atn_rule() {
19105 let atn = token_then_eof_atn();
19106 let mut parser = mini_parser(vec![
19107 TestToken::new(1).with_text("x"),
19108 TestToken::eof("parser-test", 1, 1, 1),
19109 ]);
19110
19111 let tree = parser
19112 .parse_atn_rule(&atn, 0)
19113 .expect("artificial parser rule should parse");
19114 assert_eq!(parser.node(tree).text(), "x<EOF>");
19115 assert_eq!(parser.number_of_syntax_errors(), 0);
19116 assert_eq!(
19117 parser
19118 .node(tree)
19119 .first_rule_stop(0)
19120 .expect("rule should stop at EOF")
19121 .token_type(),
19122 TOKEN_EOF
19123 );
19124
19125 let mut parser = mini_parser(vec![
19126 TestToken::new(1).with_text("x"),
19127 TestToken::eof("parser-test", 1, 1, 1),
19128 ]);
19129 let (tree, actions) = parser
19130 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19131 .expect("runtime-option parser rule should parse");
19132 assert!(actions.is_empty());
19133 assert_eq!(
19134 parser
19135 .node(tree)
19136 .first_rule_stop(0)
19137 .expect("rule should stop at EOF")
19138 .token_type(),
19139 TOKEN_EOF
19140 );
19141 }
19142
19143 #[test]
19144 fn runtime_options_default_ignores_noop_action_transitions() {
19145 let atn = noop_action_then_token_then_eof_atn();
19146 let mut parser = mini_parser(vec![
19147 TestToken::new(1).with_text("x"),
19148 TestToken::eof("parser-test", 1, 1, 1),
19149 ]);
19150
19151 let (tree, actions) = parser
19152 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19153 .expect("no-op parser action should not force action replay");
19154
19155 assert_eq!(parser.node(tree).text(), "x<EOF>");
19156 assert!(
19157 actions.is_empty(),
19158 "action_index=None transitions are ANTLR metadata, not replay actions"
19159 );
19160 assert_eq!(parser.number_of_syntax_errors(), 0);
19161 }
19162
19163 #[test]
19164 fn parser_exposes_buffered_token_stream_after_parse() {
19165 let atn = token_then_eof_atn();
19166 let mut parser = mini_parser(vec![
19167 TestToken::new(1).with_text("x"),
19168 TestToken::eof("parser-test", 1, 1, 1),
19169 ]);
19170
19171 let tree = parser
19172 .parse_atn_rule(&atn, 0)
19173 .expect("artificial parser rule should parse");
19174 assert_eq!(parser.node(tree).text(), "x<EOF>");
19175
19176 let stream = parser.token_stream();
19177 let source_index_after_parse = stream.token_source().index;
19178 let buffered = stream.tokens().collect::<Vec<_>>();
19179 assert_eq!(buffered.len(), 2);
19180 assert_eq!(buffered[0].text(), Some("x"));
19181 assert_eq!(buffered[0].token_id().index(), 0);
19182 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
19183 assert_eq!(stream.token_source().index, source_index_after_parse);
19184 drop(buffered);
19185
19186 let stream = parser.into_token_stream();
19187 assert_eq!(stream.token_source().index, source_index_after_parse);
19188 assert_eq!(
19189 stream.tokens().next().expect("first token").text(),
19190 Some("x")
19191 );
19192 assert_eq!(
19193 stream.tokens().nth(1).expect("EOF token").token_type(),
19194 TOKEN_EOF
19195 );
19196 }
19197
19198 #[test]
19199 fn parsed_file_exposes_all_buffered_tokens() {
19200 let atn = token_then_eof_atn();
19201 let mut parser = mini_parser(vec![
19202 TestToken::new(99)
19203 .with_text(" comment")
19204 .with_channel(HIDDEN_CHANNEL),
19205 TestToken::new(1).with_text("x"),
19206 TestToken::eof("parser-test", 9, 1, 9),
19207 ]);
19208
19209 let tree = parser
19210 .parse_atn_rule(&atn, 0)
19211 .expect("artificial parser rule should parse");
19212 let parsed = parser.into_parsed_file(tree);
19213
19214 insta::assert_debug_snapshot!(
19217 "parsed_file_exposes_all_buffered_tokens",
19218 parsed
19219 .tokens()
19220 .iter()
19221 .map(|token| (token.token_type(), token.channel(), token.text()))
19222 .collect::<Vec<_>>()
19223 );
19224 assert_eq!(parsed.tokens().into_iter().count(), 3);
19225 }
19226
19227 #[test]
19228 fn parser_syntax_error_count_tracks_interpreted_recovery() {
19229 let atn = token_then_eof_atn();
19230 let mut parser = mini_parser(vec![
19231 TestToken::new(1).with_text("x"),
19232 TestToken::new(2).with_text("y"),
19233 TestToken::eof("parser-test", 2, 1, 2),
19234 ]);
19235
19236 let tree = parser
19237 .parse_atn_rule(&atn, 0)
19238 .expect("invalid token should recover into an error node");
19239
19240 assert_eq!(parser.number_of_syntax_errors(), 1);
19241 assert_eq!(
19242 parser
19243 .node(tree)
19244 .first_error_token()
19245 .expect("recovery should embed an error token")
19246 .text(),
19247 Some("y")
19248 );
19249 }
19250
19251 #[test]
19252 fn failed_interpreted_parse_notifies_error_listener() {
19253 let atn = token_then_eof_atn();
19254 let mut parser = mini_parser(vec![
19255 TestToken::new(2)
19256 .with_text("y")
19257 .with_span(0, 0)
19258 .with_byte_span(0, 1)
19259 .with_position(3, 5),
19260 TestToken::eof("parser-test", 1, 1, 1),
19261 ]);
19262 parser.remove_error_listeners();
19263 let diagnostics = Arc::new(Mutex::new(Vec::new()));
19264 parser.add_error_listener(RecordingErrorListener {
19265 diagnostics: Arc::clone(&diagnostics),
19266 });
19267
19268 let error = parser
19269 .parse_atn_rule(&atn, 0)
19270 .expect_err("start-rule mismatch should remain a parser error");
19271
19272 assert_eq!(parser.number_of_syntax_errors(), 1);
19273 assert!(matches!(&error, AntlrError::ParserError { .. }));
19274 insta::assert_debug_snapshot!(
19275 "failed_interpreted_parse_notifies_error_listener",
19276 *diagnostics.lock().expect("recorded diagnostics lock")
19277 );
19278 }
19279
19280 #[test]
19281 fn adaptive_direct_rule_uses_simulator_decision() {
19282 let atn = two_alt_decision_atn();
19283 let mut simulator = ParserAtnSimulator::new(&atn);
19284 let mut parser = mini_parser(vec![
19285 TestToken::new(2).with_text("y"),
19286 TestToken::eof("parser-test", 1, 1, 1),
19287 ]);
19288
19289 let tree = parser
19290 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
19291 .expect("direct adaptive rule should parse");
19292
19293 assert_eq!(parser.node(tree).text(), "y");
19294 assert_eq!(parser.input.index(), 1);
19295 }
19296
19297 #[test]
19298 fn adaptive_direct_rule_restores_input_on_fallback() {
19299 let atn = predicate_after_token_atn();
19300 let mut simulator = ParserAtnSimulator::new(&atn);
19301 let mut parser = mini_parser(vec![
19302 TestToken::new(1).with_text("x"),
19303 TestToken::new(2).with_text("y"),
19304 TestToken::eof("parser-test", 2, 1, 2),
19305 ]);
19306
19307 let tree = parser
19308 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
19309 .expect("fallback recognizer should parse");
19310
19311 assert_eq!(parser.node(tree).text(), "xy");
19312 assert_eq!(parser.input.index(), 2);
19313 let stats = parser.parse_tree_storage().stats();
19314 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
19315 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
19316 assert_eq!(stats.scratch_links, 0);
19317 }
19318
19319 #[test]
19320 fn unknown_predicate_policy_defaults_to_assume_true() {
19321 let atn = predicate_after_token_atn();
19322 let mut parser = mini_parser(vec![
19323 TestToken::new(1).with_text("x"),
19324 TestToken::new(2).with_text("y"),
19325 TestToken::eof("parser-test", 2, 1, 2),
19326 ]);
19327
19328 let (tree, _) = parser
19329 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19330 .expect("unknown predicate should pass under the default policy");
19331
19332 assert_eq!(parser.node(tree).text(), "xy");
19333 assert_eq!(parser.number_of_syntax_errors(), 0);
19334 }
19335
19336 #[test]
19337 fn private_context_alt_tracking_keeps_fast_predicate_recognition() {
19338 let atn = predicate_gated_same_lookahead_atn([0, 1]);
19339 let mut parser = mini_parser(vec![
19340 TestToken::new(1).with_text("x"),
19341 TestToken::eof("parser-test", 1, 1, 1),
19342 ]);
19343
19344 let (tree, _) = parser
19345 .parse_atn_rule_with_runtime_options(
19346 &atn,
19347 0,
19348 ParserRuntimeOptions {
19349 predicates: &[
19350 (0, 0, ParserPredicate::False),
19351 (0, 1, ParserPredicate::True),
19352 ],
19353 track_context_alt_numbers: true,
19354 ..ParserRuntimeOptions::default()
19355 },
19356 )
19357 .expect("the second predicate-gated alternative should match");
19358
19359 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19360 insta::assert_debug_snapshot!(
19361 "private_context_alt_tracking_keeps_fast_predicate_recognition",
19362 (root.alt_number(), root.context_alt_number(), root.text())
19363 );
19364 assert_eq!(parser.number_of_syntax_errors(), 0);
19365 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
19366 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
19367 }
19368
19369 #[test]
19370 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
19371 let atn = token_then_eof_atn();
19375 let mut parser = mini_parser(vec![
19376 TestToken::new(1).with_text("x"),
19377 TestToken::eof("parser-test", 1, 1, 1),
19378 ]);
19379
19380 parser.unknown_predicate_hits.push((7, 3));
19382
19383 parser
19385 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19386 .expect("child rule parses");
19387
19388 let error = parser
19390 .take_unknown_semantic_error()
19391 .expect("parent's recorded coordinate must survive the nested interpreted parse");
19392 let AntlrError::Unsupported(message) = error else {
19393 panic!("expected AntlrError::Unsupported, got {error:?}");
19394 };
19395 assert!(message.contains("pred_index=3"), "message: {message}");
19396 }
19397
19398 #[test]
19399 fn nested_committed_parse_preserves_prior_unhandled_action_hits() {
19400 let atn = token_then_eof_atn();
19401 let mut parser = mini_parser(vec![
19402 TestToken::new(1).with_text("x"),
19403 TestToken::eof("parser-test", 1, 1, 1),
19404 ]);
19405 parser.unhandled_action_hits.push((7, 42));
19406
19407 parser
19408 .parse_atn_rule_with_runtime_options(
19409 &atn,
19410 0,
19411 ParserRuntimeOptions {
19412 action_indices: &[(usize::MAX, 0)],
19413 ..ParserRuntimeOptions::default()
19414 },
19415 )
19416 .expect("a child with no action miss must not observe its parent's miss");
19417
19418 let error = parser
19419 .take_unknown_semantic_error()
19420 .expect("the parent's action miss must survive the nested committed parse");
19421 let AntlrError::Unsupported(message) = error else {
19422 panic!("expected AntlrError::Unsupported, got {error:?}");
19423 };
19424 assert!(
19425 message.contains("rule_index=7") && message.contains("state=42"),
19426 "message: {message}"
19427 );
19428 }
19429
19430 #[test]
19431 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
19432 let atn = predicate_after_token_atn();
19433 let mut parser = mini_parser(vec![
19434 TestToken::new(1).with_text("x"),
19435 TestToken::new(2).with_text("y"),
19436 TestToken::eof("parser-test", 2, 1, 2),
19437 ]);
19438
19439 let result = parser.parse_atn_rule_with_runtime_options(
19440 &atn,
19441 0,
19442 ParserRuntimeOptions {
19443 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
19444 ..ParserRuntimeOptions::default()
19445 },
19446 );
19447
19448 assert!(
19449 result.is_err(),
19450 "the only path is predicate-guarded, so assume-false must fail the parse"
19451 );
19452 }
19453
19454 #[test]
19455 fn predicate_failure_message_keeps_semantic_recovery_path() {
19456 let atn = predicate_after_token_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_with_runtime_options(
19465 &atn,
19466 0,
19467 ParserRuntimeOptions {
19468 predicates: &[(
19469 0,
19470 0,
19471 ParserPredicate::FalseWithMessage {
19472 message: "predicate rejected input",
19473 },
19474 )],
19475 ..ParserRuntimeOptions::default()
19476 },
19477 )
19478 .expect("failure-message predicates recover through the semantic interpreter");
19479
19480 assert_eq!(parser.node(tree).text(), "xy");
19481 assert_eq!(parser.number_of_syntax_errors(), 1);
19482 assert!(
19483 parser.fast_predicate_cache.is_empty(),
19484 "failure-message predicates need the semantic interpreter's recovery outcome"
19485 );
19486 }
19487
19488 #[test]
19489 fn unknown_predicate_policy_error_names_the_coordinate() {
19490 let atn = predicate_after_token_atn();
19491 let mut parser = mini_parser(vec![
19492 TestToken::new(1).with_text("x"),
19493 TestToken::new(2).with_text("y"),
19494 TestToken::eof("parser-test", 2, 1, 2),
19495 ]);
19496
19497 let error = parser
19498 .parse_atn_rule_with_runtime_options(
19499 &atn,
19500 0,
19501 ParserRuntimeOptions {
19502 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19503 ..ParserRuntimeOptions::default()
19504 },
19505 )
19506 .expect_err("evaluating an unknown predicate under Error policy must fail");
19507
19508 let AntlrError::Unsupported(message) = error else {
19509 panic!("expected AntlrError::Unsupported, got {error:?}");
19510 };
19511 assert!(
19512 message.contains("unsupported semantic predicate"),
19513 "message should name the failure class: {message}"
19514 );
19515 assert!(
19516 message.contains("pred_index=0"),
19517 "message should carry the coordinate: {message}"
19518 );
19519 }
19520
19521 #[test]
19522 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
19523 let atn = predicate_after_token_atn();
19529 let mut parser = mini_parser(vec![
19530 TestToken::new(1).with_text("x"),
19531 TestToken::new(2).with_text("y"),
19532 TestToken::eof("parser-test", 2, 1, 2),
19533 ]);
19534
19535 parser
19536 .parse_atn_rule_with_runtime_options(
19537 &atn,
19538 0,
19539 ParserRuntimeOptions {
19540 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19541 ..ParserRuntimeOptions::default()
19542 },
19543 )
19544 .expect_err("first parse fails loud under the Error policy");
19545
19546 parser.reset_unknown_semantic_hits();
19551 assert!(
19552 parser.take_unknown_semantic_error().is_none(),
19553 "reset must drop stale unknown-predicate coordinates before a reused parse"
19554 );
19555 }
19556
19557 #[derive(Debug, Default)]
19558 struct RecordingHooks {
19559 predicates: Vec<(usize, usize, usize, Option<String>)>,
19560 actions: Vec<(usize, String, Option<String>)>,
19561 action_trees: Vec<Option<String>>,
19562 }
19563
19564 impl SemanticHooks for RecordingHooks {
19565 fn sempred<S>(
19566 &mut self,
19567 ctx: &mut ParserSemCtx<'_, S>,
19568 rule_index: usize,
19569 pred_index: usize,
19570 ) -> Option<bool>
19571 where
19572 S: TokenSource,
19573 {
19574 self.predicates.push((
19575 ctx.input_index(),
19576 rule_index,
19577 pred_index,
19578 ctx.token_text(1)
19579 .and_then(|token| token.text().map(str::to_owned)),
19580 ));
19581 Some(true)
19582 }
19583
19584 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19585 where
19586 S: TokenSource,
19587 {
19588 self.actions.push((
19589 action.source_state(),
19590 ctx.action_text(),
19591 ctx.rule_name().map(str::to_owned),
19592 ));
19593 self.action_trees.push(ctx.tree().map(Node::text));
19594 true
19595 }
19596 }
19597
19598 #[derive(Debug, Default)]
19599 struct StatefulActionHooks {
19600 entered: bool,
19601 events: Vec<String>,
19602 }
19603
19604 impl SemanticHooks for StatefulActionHooks {
19605 fn sempred<S>(
19606 &mut self,
19607 _ctx: &mut ParserSemCtx<'_, S>,
19608 _rule_index: usize,
19609 _pred_index: usize,
19610 ) -> Option<bool>
19611 where
19612 S: TokenSource,
19613 {
19614 self.events.push(format!("predicate:{}", self.entered));
19615 Some(self.entered)
19616 }
19617
19618 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19619 where
19620 S: TokenSource,
19621 {
19622 self.events.push(format!(
19623 "action:{}",
19624 action
19625 .action_index()
19626 .map_or_else(|| "legacy".to_owned(), |index| index.to_string())
19627 ));
19628 self.entered = true;
19629 true
19630 }
19631 }
19632
19633 #[derive(Debug, Default)]
19634 struct InitOrderingHooks {
19635 initialized: bool,
19636 events: Vec<String>,
19637 }
19638
19639 impl SemanticHooks for InitOrderingHooks {
19640 fn sempred<S>(
19641 &mut self,
19642 _ctx: &mut ParserSemCtx<'_, S>,
19643 _rule_index: usize,
19644 _pred_index: usize,
19645 ) -> Option<bool>
19646 where
19647 S: TokenSource,
19648 {
19649 self.events.push(format!("predicate:{}", self.initialized));
19650 Some(self.initialized)
19651 }
19652
19653 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19654 where
19655 S: TokenSource,
19656 {
19657 if action.is_rule_init() {
19658 self.initialized = true;
19659 self.events.push("init".to_owned());
19660 } else {
19661 self.events.push(format!(
19662 "action:{}:initialized={}",
19663 action
19664 .action_index()
19665 .map_or_else(|| "legacy".to_owned(), |index| index.to_string()),
19666 self.initialized
19667 ));
19668 }
19669 true
19670 }
19671 }
19672
19673 #[derive(Debug, Default)]
19674 struct ActionContextHooks {
19675 actions: Vec<(usize, Option<i64>, Option<usize>)>,
19676 }
19677
19678 impl SemanticHooks for ActionContextHooks {
19679 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19680 where
19681 S: TokenSource,
19682 {
19683 self.actions.push((
19684 action.action_index().unwrap_or(usize::MAX),
19685 ctx.local_int_arg(),
19686 action.stop_index(),
19687 ));
19688 true
19689 }
19690 }
19691
19692 #[derive(Debug, Default)]
19693 struct DecliningActionHooks {
19694 actions: Vec<usize>,
19695 }
19696
19697 impl SemanticHooks for DecliningActionHooks {
19698 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19699 where
19700 S: TokenSource,
19701 {
19702 self.actions.push(action.source_state());
19703 false
19704 }
19705 }
19706
19707 #[derive(Debug, Default)]
19708 struct ForcedSecondAlternativeHooks {
19709 decisions: Vec<(usize, usize, usize)>,
19710 }
19711
19712 impl SemanticHooks for ForcedSecondAlternativeHooks {
19713 fn observes_parser_decisions(&self) -> bool {
19714 true
19715 }
19716
19717 fn parser_decision_override(
19718 &mut self,
19719 decision: usize,
19720 input_index: usize,
19721 alternative_count: usize,
19722 ) -> Option<usize> {
19723 self.decisions
19724 .push((decision, input_index, alternative_count));
19725 Some(2)
19726 }
19727 }
19728
19729 struct RecordingParseListener {
19730 events: Arc<Mutex<Vec<String>>>,
19731 }
19732
19733 impl ParseListener for RecordingParseListener {
19734 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
19735 self.events
19736 .lock()
19737 .expect("parse-listener event lock")
19738 .push(format!("enter:{}", event.rule_index));
19739 Ok(())
19740 }
19741
19742 fn exit_every_rule(&mut self, rule_index: usize) {
19743 self.events
19744 .lock()
19745 .expect("parse-listener event lock")
19746 .push(format!("exit:{rule_index}"));
19747 }
19748 }
19749
19750 #[derive(Debug, Default)]
19751 struct RejectingPredicateHooks {
19752 predicates: Vec<(usize, usize, usize, Option<String>)>,
19753 }
19754
19755 impl SemanticHooks for RejectingPredicateHooks {
19756 fn sempred<S>(
19757 &mut self,
19758 ctx: &mut ParserSemCtx<'_, S>,
19759 rule_index: usize,
19760 pred_index: usize,
19761 ) -> Option<bool>
19762 where
19763 S: TokenSource,
19764 {
19765 self.predicates.push((
19766 ctx.input_index(),
19767 rule_index,
19768 pred_index,
19769 ctx.token_text(1)
19770 .and_then(|token| token.text().map(str::to_owned)),
19771 ));
19772 Some(false)
19773 }
19774 }
19775
19776 #[test]
19777 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
19778 let atn = predicate_gated_same_lookahead_atn([0, 0]);
19779 let mut parser = mini_parser_with_hooks(
19780 vec![
19781 TestToken::new(1).with_text("x"),
19782 TestToken::eof("parser-test", 1, 1, 1),
19783 ],
19784 RecordingHooks::default(),
19785 );
19786
19787 let (tree, _) = parser
19788 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19789 .expect("both alternatives share one replay-safe predicate result");
19790
19791 assert_eq!(parser.node(tree).text(), "x<EOF>");
19792 assert_eq!(
19793 parser.semantic_hooks.predicates,
19794 vec![(0, 0, 0, Some("x".to_owned()))]
19795 );
19796 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
19797 }
19798
19799 #[test]
19800 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
19801 let atn = predicate_after_token_atn();
19802 let mut parser = mini_parser_with_hooks(
19803 vec![
19804 TestToken::new(1).with_text("x"),
19805 TestToken::new(2).with_text("y"),
19806 TestToken::eof("parser-test", 2, 1, 2),
19807 ],
19808 RecordingHooks::default(),
19809 );
19810
19811 let (tree, _) = parser
19812 .parse_atn_rule_with_runtime_options(
19813 &atn,
19814 0,
19815 ParserRuntimeOptions {
19816 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19817 ..ParserRuntimeOptions::default()
19818 },
19819 )
19820 .expect("hook supplies the missing predicate result");
19821
19822 assert_eq!(parser.node(tree).text(), "xy");
19823 assert_eq!(
19824 parser.semantic_hooks.predicates,
19825 vec![(1, 0, 0, Some("y".to_owned()))]
19826 );
19827 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
19828 }
19829
19830 #[test]
19831 fn runtime_options_default_preserves_semantic_hook_predicates() {
19832 let atn = predicate_after_token_atn();
19833 let mut parser = mini_parser_with_hooks(
19834 vec![
19835 TestToken::new(1).with_text("x"),
19836 TestToken::new(2).with_text("y"),
19837 TestToken::eof("parser-test", 2, 1, 2),
19838 ],
19839 RejectingPredicateHooks::default(),
19840 );
19841
19842 let result =
19843 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
19844
19845 assert!(
19846 result.is_err(),
19847 "default runtime options must not bypass semantic hooks for predicate ATNs"
19848 );
19849 assert_eq!(
19850 parser.semantic_hooks.predicates,
19851 vec![(1, 0, 0, Some("y".to_owned()))]
19852 );
19853 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
19854 }
19855
19856 #[test]
19857 fn committed_action_runs_before_later_predicate() {
19858 let atn = committed_action_then_predicate_atn();
19859 let mut parser = mini_parser_with_hooks(
19860 vec![
19861 TestToken::new(1).with_text("x"),
19862 TestToken::eof("parser-test", 1, 1, 1),
19863 ],
19864 StatefulActionHooks::default(),
19865 );
19866
19867 let (tree, deferred_actions) = parser
19868 .parse_atn_rule_with_runtime_options(
19869 &atn,
19870 0,
19871 ParserRuntimeOptions {
19872 action_indices: &[(0, 7)],
19873 ..ParserRuntimeOptions::default()
19874 },
19875 )
19876 .expect("the predicate should observe the preceding committed action");
19877
19878 assert_eq!(parser.node(tree).text(), "x<EOF>");
19879 assert!(deferred_actions.is_empty());
19880 assert_eq!(parser.semantic_hooks.events, ["action:7", "predicate:true"]);
19881 }
19882
19883 #[test]
19884 fn committed_action_hook_observes_parameterized_rule_argument() {
19885 let atn = parameterized_child_action_eof_atn();
19886 let rule_args = [ParserRuleArg {
19887 source_state: 0,
19888 rule_index: 1,
19889 value: 42,
19890 inherit_local: false,
19891 }];
19892 let mut parser = mini_parser_with_hooks(
19893 vec![TestToken::eof("parser-test", 0, 1, 0)],
19894 ActionContextHooks::default(),
19895 );
19896
19897 parser
19898 .parse_atn_rule_with_runtime_options(
19899 &atn,
19900 0,
19901 ParserRuntimeOptions {
19902 action_indices: &[(1, 20), (4, 10)],
19903 rule_args: &rule_args,
19904 ..ParserRuntimeOptions::default()
19905 },
19906 )
19907 .expect("the parameterized child should parse");
19908
19909 assert_eq!(
19910 parser.semantic_hooks.actions[0],
19911 (10, Some(42), None),
19912 "the child action should observe its invocation argument"
19913 );
19914 }
19915
19916 #[test]
19917 fn committed_parent_propagates_child_eof_consumption() {
19918 let atn = parameterized_child_action_eof_atn();
19919 let mut parser = mini_parser_with_hooks(
19920 vec![TestToken::eof("parser-test", 0, 1, 0)],
19921 ActionContextHooks::default(),
19922 );
19923
19924 let (tree, _) = parser
19925 .parse_atn_rule_with_runtime_options(
19926 &atn,
19927 0,
19928 ParserRuntimeOptions {
19929 action_indices: &[(1, 20), (4, 10)],
19930 ..ParserRuntimeOptions::default()
19931 },
19932 )
19933 .expect("the parent should retain its child's EOF boundary");
19934
19935 assert_eq!(
19936 parser.semantic_hooks.actions[1],
19937 (20, None, Some(0)),
19938 "the parent action should stop at EOF"
19939 );
19940 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19941 assert_eq!(root.stop().map(|token| token.token_type()), Some(TOKEN_EOF));
19942 let child = root
19943 .child_rules(1)
19944 .next()
19945 .expect("the parent should contain the child rule");
19946 assert_eq!(
19947 child.stop().map(|token| token.token_type()),
19948 Some(TOKEN_EOF)
19949 );
19950 }
19951
19952 #[test]
19953 fn committed_walker_does_not_run_action_in_losing_alternative() {
19954 let atn = losing_alternative_action_atn();
19955 let mut parser = mini_parser_with_hooks(
19956 vec![
19957 TestToken::new(2).with_text("y"),
19958 TestToken::eof("parser-test", 1, 1, 1),
19959 ],
19960 StatefulActionHooks::default(),
19961 );
19962
19963 let (tree, deferred_actions) = parser
19964 .parse_atn_rule_with_runtime_options(
19965 &atn,
19966 0,
19967 ParserRuntimeOptions {
19968 action_indices: &[(2, 0)],
19969 ..ParserRuntimeOptions::default()
19970 },
19971 )
19972 .expect("the token-led second alternative should be selected");
19973
19974 assert_eq!(parser.node(tree).text(), "y");
19975 assert!(deferred_actions.is_empty());
19976 assert!(parser.semantic_hooks.events.is_empty());
19977 }
19978
19979 #[test]
19980 fn committed_walker_honors_decision_overrides() {
19981 let atn = predicate_gated_same_lookahead_atn([0, 1]);
19982 let predicates = [(0, 0, ParserPredicate::True), (0, 1, ParserPredicate::True)];
19983 let mut parser = mini_parser_with_hooks(
19984 vec![
19985 TestToken::new(1).with_text("x"),
19986 TestToken::eof("parser-test", 1, 1, 1),
19987 ],
19988 ForcedSecondAlternativeHooks::default(),
19989 );
19990
19991 let (tree, deferred_actions) = parser
19992 .parse_atn_rule_with_runtime_options(
19993 &atn,
19994 0,
19995 ParserRuntimeOptions {
19996 action_indices: &[(usize::MAX, 0)],
19997 track_alt_numbers: true,
19998 predicates: &predicates,
19999 ..ParserRuntimeOptions::default()
20000 },
20001 )
20002 .expect("the forced second alternative should parse");
20003
20004 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20005 assert_eq!(root.alt_number(), 2);
20006 assert_eq!(root.text(), "x<EOF>");
20007 assert!(deferred_actions.is_empty());
20008 assert_eq!(parser.semantic_hooks.decisions, [(0, 0, 2)]);
20009 assert_eq!(parser.number_of_syntax_errors(), 0);
20010 }
20011
20012 #[test]
20013 fn committed_walker_sll_mode_does_not_report_full_context_diagnostics() {
20014 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20015 let predicates = [(0, 0, ParserPredicate::True), (0, 1, ParserPredicate::True)];
20016 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20017 let mut parser = mini_parser(vec![
20018 TestToken::new(1).with_text("x"),
20019 TestToken::eof("parser-test", 1, 1, 1),
20020 ]);
20021 parser.set_prediction_mode(PredictionMode::Sll);
20022 parser.set_report_diagnostic_errors(true);
20023 parser.remove_error_listeners();
20024 parser.add_error_listener(RecordingErrorListener {
20025 diagnostics: Arc::clone(&diagnostics),
20026 });
20027
20028 let (tree, deferred_actions) = parser
20029 .parse_atn_rule_with_runtime_options(
20030 &atn,
20031 0,
20032 ParserRuntimeOptions {
20033 action_indices: &[(usize::MAX, 0)],
20034 predicates: &predicates,
20035 ..ParserRuntimeOptions::default()
20036 },
20037 )
20038 .expect("SLL prediction should select the first viable alternative");
20039
20040 assert_eq!(parser.node(tree).text(), "x<EOF>");
20041 assert!(deferred_actions.is_empty());
20042 assert_eq!(parser.number_of_syntax_errors(), 0);
20043 assert!(
20044 diagnostics
20045 .lock()
20046 .expect("recorded diagnostics lock")
20047 .is_empty(),
20048 "SLL mode must not retry with full context or report LL diagnostics"
20049 );
20050 }
20051
20052 #[test]
20053 fn committed_walker_filters_diagnostics_after_semantic_selection() {
20054 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20055 let predicates = [
20056 (0, 0, ParserPredicate::False),
20057 (0, 1, ParserPredicate::True),
20058 ];
20059 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20060 let mut parser = mini_parser(vec![
20061 TestToken::new(1).with_text("x"),
20062 TestToken::eof("parser-test", 1, 1, 1),
20063 ]);
20064 parser.set_prediction_mode(PredictionMode::LlExactAmbigDetection);
20065 parser.set_report_diagnostic_errors(true);
20066 parser.remove_error_listeners();
20067 parser.add_error_listener(RecordingErrorListener {
20068 diagnostics: Arc::clone(&diagnostics),
20069 });
20070
20071 let (tree, _) = parser
20072 .parse_atn_rule_with_runtime_options(
20073 &atn,
20074 0,
20075 ParserRuntimeOptions {
20076 action_indices: &[(usize::MAX, 0)],
20077 track_alt_numbers: true,
20078 predicates: &predicates,
20079 ..ParserRuntimeOptions::default()
20080 },
20081 )
20082 .expect("the true predicate should make the second alternative unique");
20083
20084 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20085 assert_eq!(root.alt_number(), 2);
20086 assert!(
20087 diagnostics
20088 .lock()
20089 .expect("recorded diagnostics lock")
20090 .is_empty(),
20091 "predicate filtering made the decision unambiguous"
20092 );
20093 }
20094
20095 #[test]
20096 fn committed_walker_skips_diagnostic_only_predicates_when_reporting_is_disabled() {
20097 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20098 let mut parser = mini_parser_with_hooks(
20099 vec![
20100 TestToken::new(1).with_text("x"),
20101 TestToken::eof("parser-test", 1, 1, 1),
20102 ],
20103 RecordingHooks::default(),
20104 );
20105 parser.set_prediction_mode(PredictionMode::LlExactAmbigDetection);
20106
20107 let (tree, _) = parser
20108 .parse_atn_rule_with_runtime_options(
20109 &atn,
20110 0,
20111 ParserRuntimeOptions {
20112 action_indices: &[(usize::MAX, 0)],
20113 track_alt_numbers: true,
20114 ..ParserRuntimeOptions::default()
20115 },
20116 )
20117 .expect("the first predicate-bearing alternative should parse");
20118
20119 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20120 assert_eq!(root.alt_number(), 1);
20121 assert_eq!(
20122 parser.semantic_hooks.predicates,
20123 [
20124 (0, 0, 0, Some("x".to_owned())),
20125 (0, 0, 0, Some("x".to_owned())),
20126 ],
20127 "diagnostic-only alternatives must not invoke semantic hooks"
20128 );
20129 }
20130
20131 #[test]
20132 fn committed_walker_falls_back_only_to_simulator_viable_alternatives() {
20133 let atn = semantic_fallback_viability_atn();
20134 let predicates = [
20135 (0, 0, ParserPredicate::False),
20136 (0, 1, ParserPredicate::True),
20137 ];
20138 let mut parser = mini_parser(vec![
20139 TestToken::new(1).with_text("a"),
20140 TestToken::new(3).with_text("c"),
20141 TestToken::eof("parser-test", 2, 1, 2),
20142 ]);
20143
20144 let (tree, deferred_actions) = parser
20145 .parse_atn_rule_with_runtime_options(
20146 &atn,
20147 0,
20148 ParserRuntimeOptions {
20149 action_indices: &[(usize::MAX, 0)],
20150 track_alt_numbers: true,
20151 predicates: &predicates,
20152 ..ParserRuntimeOptions::default()
20153 },
20154 )
20155 .expect("the true A C alternative should survive semantic fallback");
20156
20157 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20158 assert_eq!(root.alt_number(), 3);
20159 assert_eq!(root.text(), "ac<EOF>");
20160 assert!(deferred_actions.is_empty());
20161 assert_eq!(parser.number_of_syntax_errors(), 0);
20162 }
20163
20164 #[test]
20165 fn committed_walker_evaluates_predicates_reached_through_rule_calls() {
20166 let atn = rule_call_predicate_decision_atn();
20167 let predicates = [(1, 0, ParserPredicate::False)];
20168 let mut parser = mini_parser(vec![
20169 TestToken::new(1).with_text("a"),
20170 TestToken::eof("parser-test", 1, 1, 1),
20171 ]);
20172
20173 let (tree, deferred_actions) = parser
20174 .parse_atn_rule_with_runtime_options(
20175 &atn,
20176 0,
20177 ParserRuntimeOptions {
20178 action_indices: &[(usize::MAX, 0)],
20179 track_alt_numbers: true,
20180 predicates: &predicates,
20181 ..ParserRuntimeOptions::default()
20182 },
20183 )
20184 .expect("the direct caller alternative should survive the false callee predicate");
20185
20186 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20187 assert_eq!(root.alt_number(), 2);
20188 assert_eq!(root.text(), "a<EOF>");
20189 assert_eq!(root.child_rules(1).count(), 0);
20190 assert!(deferred_actions.is_empty());
20191 assert_eq!(parser.number_of_syntax_errors(), 0);
20192 }
20193
20194 #[test]
20195 fn committed_walker_uses_callee_argument_for_prediction_predicates() {
20196 let atn = rule_call_predicate_decision_atn();
20197 let predicates = [(1, 0, ParserPredicate::LocalIntEquals { value: 1 })];
20198 let rule_args = [ParserRuleArg {
20199 source_state: 2,
20200 rule_index: 1,
20201 value: 2,
20202 inherit_local: false,
20203 }];
20204 let mut parser = mini_parser(vec![
20205 TestToken::new(1).with_text("a"),
20206 TestToken::eof("parser-test", 1, 1, 1),
20207 ]);
20208
20209 let (tree, _) = parser
20210 .parse_atn_rule_with_runtime_options(
20211 &atn,
20212 0,
20213 ParserRuntimeOptions {
20214 action_indices: &[(usize::MAX, 0)],
20215 track_alt_numbers: true,
20216 predicates: &predicates,
20217 rule_args: &rule_args,
20218 ..ParserRuntimeOptions::default()
20219 },
20220 )
20221 .expect("the direct alternative should survive the false callee predicate");
20222
20223 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20224 assert_eq!(root.alt_number(), 2);
20225 assert_eq!(root.child_rules(1).count(), 0);
20226 assert_eq!(parser.number_of_syntax_errors(), 0);
20227 }
20228
20229 #[test]
20230 fn committed_predicate_star_loop_uses_single_token_deletion() {
20231 let atn = predicate_gated_star_loop_atn();
20232 let predicates = [(0, 0, ParserPredicate::True)];
20233 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20234 let mut parser = mini_parser(vec![
20235 TestToken::new(2).with_text("x"),
20236 TestToken::new(1).with_text("a"),
20237 TestToken::eof("parser-test", 2, 1, 2),
20238 ]);
20239 parser.remove_error_listeners();
20240 parser.add_error_listener(RecordingErrorListener {
20241 diagnostics: Arc::clone(&diagnostics),
20242 });
20243
20244 let (tree, deferred_actions) = parser
20245 .parse_atn_rule_with_runtime_options(
20246 &atn,
20247 0,
20248 ParserRuntimeOptions {
20249 action_indices: &[(usize::MAX, 0)],
20250 predicates: &predicates,
20251 ..ParserRuntimeOptions::default()
20252 },
20253 )
20254 .expect("the loop decision should delete the extraneous token and continue");
20255
20256 assert_eq!(parser.node(tree).text(), "xa<EOF>");
20257 assert!(deferred_actions.is_empty());
20258 assert_eq!(parser.number_of_syntax_errors(), 1);
20259 insta::assert_debug_snapshot!(
20260 "committed_predicate_star_loop_uses_single_token_deletion",
20261 *diagnostics.lock().expect("recorded diagnostics lock")
20262 );
20263 }
20264
20265 #[test]
20266 fn committed_walker_applies_legacy_and_semir_actions_before_indexed_hooks() {
20267 let atn = committed_action_then_predicate_atn();
20268 let member_actions = [ParserMemberAction {
20269 source_state: 0,
20270 member: 0,
20271 delta: 2,
20272 }];
20273 let return_actions = [ParserReturnAction {
20274 source_state: 0,
20275 rule_index: 0,
20276 name: "legacy",
20277 value: 3,
20278 }];
20279 let predicates = [(
20280 0,
20281 0,
20282 ParserPredicate::MemberEquals {
20283 member: 0,
20284 value: 7,
20285 equals: true,
20286 },
20287 )];
20288 let mut ir = SemIr::new();
20289 let semantic_member = ParserMemberAction {
20290 source_state: 0,
20291 member: 0,
20292 delta: 5,
20293 }
20294 .lower_into_semir(&mut ir);
20295 let semantic_return = ParserReturnAction {
20296 source_state: 0,
20297 rule_index: 0,
20298 name: "semantic",
20299 value: 11,
20300 }
20301 .lower_into_semir(&mut ir);
20302 let semantics = ParserSemantics {
20303 ir,
20304 predicates: Vec::new(),
20305 actions: vec![semantic_member, semantic_return],
20306 };
20307 let mut parser = mini_parser_with_hooks(
20308 vec![
20309 TestToken::new(1).with_text("x"),
20310 TestToken::eof("parser-test", 1, 1, 1),
20311 ],
20312 StatefulActionHooks::default(),
20313 );
20314
20315 let (tree, deferred_actions) = parser
20316 .parse_atn_rule_with_runtime_options(
20317 &atn,
20318 0,
20319 ParserRuntimeOptions {
20320 action_indices: &[(0, 7)],
20321 predicates: &predicates,
20322 semantics: Some(&semantics),
20323 member_actions: &member_actions,
20324 return_actions: &return_actions,
20325 ..ParserRuntimeOptions::default()
20326 },
20327 )
20328 .expect("the predicate should observe both committed member actions");
20329
20330 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20331 assert_eq!(root.text(), "x<EOF>");
20332 assert_eq!(root.int_return("legacy"), Some(3));
20333 assert_eq!(root.int_return("semantic"), Some(11));
20334 assert_eq!(parser.int_member(0), Some(7));
20335 assert!(deferred_actions.is_empty());
20336 assert_eq!(parser.semantic_hooks.events, ["action:7"]);
20337 assert_eq!(parser.number_of_syntax_errors(), 0);
20338 }
20339
20340 #[test]
20341 fn committed_walker_runs_action_once_per_star_loop_iteration() {
20342 let atn = committed_action_star_loop_atn();
20343 let mut parser = mini_parser_with_hooks(
20344 vec![
20345 TestToken::new(1).with_text("a"),
20346 TestToken::new(1).with_text("b"),
20347 TestToken::eof("parser-test", 2, 1, 2),
20348 ],
20349 StatefulActionHooks::default(),
20350 );
20351
20352 let (tree, deferred_actions) = parser
20353 .parse_atn_rule_with_runtime_options(
20354 &atn,
20355 0,
20356 ParserRuntimeOptions {
20357 action_indices: &[(2, 3)],
20358 ..ParserRuntimeOptions::default()
20359 },
20360 )
20361 .expect("the committed star loop should parse");
20362
20363 assert_eq!(parser.node(tree).text(), "ab<EOF>");
20364 assert!(deferred_actions.is_empty());
20365 assert_eq!(parser.semantic_hooks.events, ["action:3", "action:3"]);
20366 }
20367
20368 #[test]
20369 fn committed_walker_has_no_total_step_cap() {
20370 const TOKEN_COUNT: usize = RECOGNITION_DEPTH_LIMIT + 1;
20371 let atn = committed_action_star_loop_atn();
20372 let mut parser = mini_parser(repeated_x_tokens(TOKEN_COUNT));
20373 parser.set_build_parse_trees(false);
20374
20375 parser
20376 .parse_atn_rule_with_runtime_options(
20377 &atn,
20378 0,
20379 ParserRuntimeOptions {
20380 action_indices: &[(usize::MAX, 0)],
20381 ..ParserRuntimeOptions::default()
20382 },
20383 )
20384 .expect("valid committed loops must not have a total-work cap");
20385
20386 assert_eq!(parser.input.index(), TOKEN_COUNT);
20387 assert_eq!(parser.number_of_syntax_errors(), 0);
20388 }
20389
20390 #[test]
20391 fn committed_walker_rejects_non_consuming_cycles() {
20392 let atn = committed_non_consuming_cycle_atn();
20393 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
20394 parser.set_bail_on_error(true);
20395
20396 let error = parser
20397 .parse_atn_rule_with_runtime_options(
20398 &atn,
20399 0,
20400 ParserRuntimeOptions {
20401 action_indices: &[(usize::MAX, 0)],
20402 ..ParserRuntimeOptions::default()
20403 },
20404 )
20405 .expect_err("a non-consuming cycle must not spin forever");
20406
20407 assert!(
20408 error.to_string().contains("non-consuming ATN cycle"),
20409 "unexpected error: {error}"
20410 );
20411 }
20412
20413 #[test]
20414 fn deeply_nested_committed_rule_calls_grow_the_stack() {
20415 const DEPTH: usize = 4_096;
20416 const STACK_SIZE: usize = 256 * 1024;
20417 let atn = nested_rule_chain_atn(DEPTH);
20418 std::thread::Builder::new()
20419 .name("nested-committed-rules".to_owned())
20420 .stack_size(STACK_SIZE)
20421 .spawn(move || {
20422 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
20423 parser.set_build_parse_trees(false);
20424 parser
20425 .parse_atn_rule_with_runtime_options(
20426 &atn,
20427 0,
20428 ParserRuntimeOptions {
20429 action_indices: &[(usize::MAX, 0)],
20430 ..ParserRuntimeOptions::default()
20431 },
20432 )
20433 .expect("nested committed rules should grow the native stack");
20434 assert_eq!(parser.input.index(), 1);
20435 })
20436 .expect("small-stack thread should start")
20437 .join()
20438 .expect("nested committed rules should not overflow their stack");
20439 }
20440
20441 #[test]
20442 fn committed_walker_runs_action_once_per_left_recursive_operator() {
20443 let atn = committed_action_left_recursive_atn();
20444 let mut parser = mini_parser_with_hooks(
20445 vec![
20446 TestToken::new(1).with_text("a"),
20447 TestToken::new(3).with_text("+"),
20448 TestToken::new(1).with_text("b"),
20449 TestToken::new(3).with_text("+"),
20450 TestToken::new(1).with_text("c"),
20451 TestToken::eof("parser-test", 5, 1, 5),
20452 ],
20453 StatefulActionHooks::default(),
20454 );
20455
20456 let (tree, deferred_actions) = parser
20457 .parse_atn_rule_with_runtime_options(
20458 &atn,
20459 0,
20460 ParserRuntimeOptions {
20461 action_indices: &[(6, 11)],
20462 ..ParserRuntimeOptions::default()
20463 },
20464 )
20465 .expect("the committed left-recursive rule should parse");
20466
20467 assert_eq!(parser.node(tree).text(), "a+b+c");
20468 assert!(deferred_actions.is_empty());
20469 assert_eq!(parser.semantic_hooks.events, ["action:11", "action:11"]);
20470 }
20471
20472 #[test]
20473 fn committed_left_recursive_depth_cap_keeps_listener_events_balanced() {
20474 let atn = committed_action_left_recursive_atn();
20475 let events = Arc::new(Mutex::new(Vec::new()));
20476 let mut parser = mini_parser(vec![
20477 TestToken::new(1).with_text("a"),
20478 TestToken::new(3).with_text("+"),
20479 TestToken::new(1).with_text("b"),
20480 TestToken::eof("parser-test", 3, 1, 3),
20481 ]);
20482 parser.set_max_rule_depth(Some(1));
20483 parser.add_parse_listener(RecordingParseListener {
20484 events: Arc::clone(&events),
20485 });
20486
20487 let error = parser
20488 .parse_atn_rule_with_runtime_options(
20489 &atn,
20490 0,
20491 ParserRuntimeOptions {
20492 action_indices: &[(6, 11)],
20493 ..ParserRuntimeOptions::default()
20494 },
20495 )
20496 .expect_err("the left-recursive expansion should exceed the depth cap");
20497
20498 insta::assert_debug_snapshot!(
20499 "committed_left_recursive_depth_cap_keeps_listener_events_balanced",
20500 (
20501 error.to_string(),
20502 events.lock().expect("parse-listener event lock").as_slice(),
20503 )
20504 );
20505 }
20506
20507 #[test]
20508 fn committed_walker_preserves_nested_rule_listener_events() {
20509 let atn = ordinary_star_loop_atn();
20510 let events = Arc::new(Mutex::new(Vec::new()));
20511 let mut parser = mini_parser(vec![
20512 TestToken::new(1).with_text("a"),
20513 TestToken::new(1).with_text("b"),
20514 TestToken::eof("parser-test", 2, 1, 2),
20515 ]);
20516 parser.add_parse_listener(RecordingParseListener {
20517 events: Arc::clone(&events),
20518 });
20519
20520 let (tree, _) = parser
20521 .parse_atn_rule_with_runtime_options(
20522 &atn,
20523 0,
20524 ParserRuntimeOptions {
20525 action_indices: &[(usize::MAX, 0)],
20526 ..ParserRuntimeOptions::default()
20527 },
20528 )
20529 .expect("the committed nested-rule path should parse");
20530
20531 assert_eq!(parser.node(tree).text(), "ab<EOF>");
20532 assert_eq!(
20533 *events.lock().expect("parse-listener event lock"),
20534 [
20535 "enter:0", "enter:1", "exit:1", "enter:1", "exit:1", "exit:0",
20536 ]
20537 );
20538 }
20539
20540 #[test]
20541 fn committed_walker_enforces_rule_depth_cap() {
20542 let atn = ordinary_star_loop_atn();
20543 let mut parser = mini_parser(vec![
20544 TestToken::new(1).with_text("a"),
20545 TestToken::eof("parser-test", 1, 1, 1),
20546 ]);
20547 parser.set_max_rule_depth(Some(1));
20548
20549 let error = parser
20550 .parse_atn_rule_with_runtime_options(
20551 &atn,
20552 0,
20553 ParserRuntimeOptions {
20554 action_indices: &[(usize::MAX, 0)],
20555 ..ParserRuntimeOptions::default()
20556 },
20557 )
20558 .expect_err("the nested rule should exceed the committed-path cap");
20559
20560 assert!(
20561 error
20562 .to_string()
20563 .contains("rule nesting depth limit of 1 exceeded"),
20564 "unexpected error: {error}"
20565 );
20566 }
20567
20568 #[test]
20569 fn committed_abort_precedes_and_clears_unhandled_action_error() {
20570 let atn = action_then_nested_rule_atn();
20571 let mut parser = mini_parser_with_hooks(
20572 vec![TestToken::eof("parser-test", 0, 1, 0)],
20573 DecliningActionHooks::default(),
20574 );
20575 parser.set_max_rule_depth(Some(1));
20576
20577 let error = parser
20578 .parse_atn_rule_with_runtime_options(
20579 &atn,
20580 0,
20581 ParserRuntimeOptions {
20582 action_indices: &[(0, 7)],
20583 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20584 ..ParserRuntimeOptions::default()
20585 },
20586 )
20587 .expect_err("the recovered child abort must outrank the earlier action miss");
20588
20589 assert_eq!(parser.semantic_hooks.actions, [0]);
20590 assert!(
20591 error
20592 .to_string()
20593 .contains("rule nesting depth limit of 1 exceeded"),
20594 "unexpected error: {error}"
20595 );
20596 assert!(
20597 parser.take_parse_abort().is_none(),
20598 "the returned abort must not remain sticky"
20599 );
20600 assert!(
20601 parser.take_unknown_semantic_error().is_none(),
20602 "the masked action miss must not poison parser reuse"
20603 );
20604 }
20605
20606 #[test]
20607 fn top_level_committed_semantic_error_does_not_poison_reuse() {
20608 let atn = committed_action_then_predicate_atn();
20609 let predicates = [(0, 0, ParserPredicate::True)];
20610 let mut parser = mini_parser_with_hooks(
20611 vec![
20612 TestToken::new(1).with_text("x"),
20613 TestToken::eof("parser-test", 1, 1, 1),
20614 ],
20615 DecliningActionHooks::default(),
20616 );
20617
20618 let error = parser
20619 .parse_atn_rule_with_runtime_options(
20620 &atn,
20621 0,
20622 ParserRuntimeOptions {
20623 action_indices: &[(0, 7)],
20624 predicates: &predicates,
20625 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20626 ..ParserRuntimeOptions::default()
20627 },
20628 )
20629 .expect_err("the declined committed action must fail loud");
20630 assert!(
20631 error.to_string().contains("unhandled semantic action"),
20632 "unexpected error: {error}"
20633 );
20634
20635 parser.input.seek(0);
20636 let (tree, _) = parser
20637 .parse_atn_rule_with_runtime_options(
20638 &atn,
20639 0,
20640 ParserRuntimeOptions {
20641 predicates: &predicates,
20642 ..ParserRuntimeOptions::default()
20643 },
20644 )
20645 .expect("a clean interpreted reuse must not observe the prior action miss");
20646
20647 assert_eq!(parser.node(tree).text(), "x<EOF>");
20648 assert!(
20649 parser.take_unknown_semantic_error().is_none(),
20650 "the returned top-level semantic error must drain its recorded hit"
20651 );
20652 }
20653
20654 #[test]
20655 fn committed_walker_runs_handled_rule_init_before_indexed_action() {
20656 let atn = committed_action_then_predicate_atn();
20657 let mut parser = mini_parser_with_hooks(
20658 vec![
20659 TestToken::new(1).with_text("x"),
20660 TestToken::eof("parser-test", 1, 1, 1),
20661 ],
20662 InitOrderingHooks::default(),
20663 );
20664
20665 let (_, deferred_actions) = parser
20666 .parse_atn_rule_with_runtime_options(
20667 &atn,
20668 0,
20669 ParserRuntimeOptions {
20670 init_action_rules: &[0],
20671 action_indices: &[(0, 7)],
20672 ..ParserRuntimeOptions::default()
20673 },
20674 )
20675 .expect("the named action should observe rule-init state");
20676
20677 assert!(deferred_actions.is_empty());
20678 assert_eq!(
20679 parser.semantic_hooks.events,
20680 ["init", "action:7:initialized=true", "predicate:true",]
20681 );
20682 }
20683
20684 #[test]
20685 fn committed_walker_defers_unhandled_rule_init_for_legacy_replay() {
20686 let atn = token_then_eof_atn();
20687 let mut parser = mini_parser(vec![
20688 TestToken::new(1).with_text("x"),
20689 TestToken::eof("parser-test", 1, 1, 1),
20690 ]);
20691
20692 let (_, deferred_actions) = parser
20693 .parse_atn_rule_with_runtime_options(
20694 &atn,
20695 0,
20696 ParserRuntimeOptions {
20697 init_action_rules: &[0],
20698 action_indices: &[(usize::MAX, 0)],
20699 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20700 ..ParserRuntimeOptions::default()
20701 },
20702 )
20703 .expect("a declined init should remain available for legacy replay");
20704
20705 assert_eq!(
20706 deferred_actions,
20707 [ParserAction::new_rule_init(0, 0, Some(0))]
20708 );
20709 }
20710
20711 #[test]
20712 fn committed_walker_dispatches_recovery_diagnostics() {
20713 let atn = noop_action_then_token_then_eof_atn();
20714 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20715 let mut parser = mini_parser_with_hooks(
20716 vec![
20717 TestToken::new(1).with_text("x"),
20718 TestToken::new(2).with_text("y"),
20719 TestToken::eof("parser-test", 2, 1, 2),
20720 ],
20721 StatefulActionHooks::default(),
20722 );
20723 parser.remove_error_listeners();
20724 parser.add_error_listener(RecordingErrorListener {
20725 diagnostics: Arc::clone(&diagnostics),
20726 });
20727
20728 let (tree, _) = parser
20729 .parse_atn_rule_with_runtime_options(
20730 &atn,
20731 0,
20732 ParserRuntimeOptions {
20733 action_indices: &[(0, 5)],
20734 ..ParserRuntimeOptions::default()
20735 },
20736 )
20737 .expect("the committed rule should recover");
20738
20739 assert_eq!(parser.node(tree).text(), "xy<EOF>");
20740 assert_eq!(parser.number_of_syntax_errors(), 1);
20741 insta::assert_debug_snapshot!(
20742 "committed_walker_dispatches_recovery_diagnostics",
20743 *diagnostics.lock().expect("recorded diagnostics lock")
20744 );
20745 }
20746
20747 #[test]
20748 fn committed_bail_error_notifies_error_listener() {
20749 let atn = noop_action_then_token_then_eof_atn();
20750 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20751 let mut parser = mini_parser(vec![
20752 TestToken::new(2)
20753 .with_text("y")
20754 .with_span(0, 0)
20755 .with_byte_span(0, 1)
20756 .with_position(3, 5),
20757 TestToken::eof("parser-test", 1, 1, 1),
20758 ]);
20759 parser.set_bail_on_error(true);
20760 parser.remove_error_listeners();
20761 parser.add_error_listener(RecordingErrorListener {
20762 diagnostics: Arc::clone(&diagnostics),
20763 });
20764
20765 let error = parser
20766 .parse_atn_rule_with_runtime_options(
20767 &atn,
20768 0,
20769 ParserRuntimeOptions {
20770 action_indices: &[(0, 5)],
20771 ..ParserRuntimeOptions::default()
20772 },
20773 )
20774 .expect_err("bail mode must return the committed token mismatch");
20775 let diagnostics = diagnostics
20776 .lock()
20777 .expect("recorded diagnostics lock")
20778 .clone();
20779
20780 insta::assert_debug_snapshot!(
20781 "committed_bail_error_notifies_error_listener",
20782 (error, diagnostics)
20783 );
20784 }
20785
20786 #[test]
20787 fn semantic_hook_handles_committed_parser_action() {
20788 let atn = token_then_eof_atn();
20789 let mut parser = mini_parser_with_hooks(
20790 vec![
20791 TestToken::new(1).with_text("x"),
20792 TestToken::eof("parser-test", 1, 1, 1),
20793 ],
20794 RecordingHooks::default(),
20795 );
20796 let (tree, _) = parser
20797 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
20798 .expect("rule parses before action hook is tested");
20799
20800 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20801 assert_eq!(
20802 parser.semantic_hooks.actions,
20803 vec![(42, "x".to_owned(), Some("s".to_owned()))]
20804 );
20805 assert_eq!(
20806 parser.semantic_hooks.action_trees,
20807 [Some("x<EOF>".to_owned())]
20808 );
20809 }
20810
20811 #[test]
20812 fn unhandled_committed_action_fails_loud_under_error_policy() {
20813 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
20817 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
20818 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
20819
20820 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20822
20823 let error = parser
20824 .take_unknown_semantic_error()
20825 .expect("an unhandled committed action under Error policy must fail loud");
20826 let AntlrError::Unsupported(message) = error else {
20827 panic!("expected AntlrError::Unsupported, got {error:?}");
20828 };
20829 assert!(
20830 message.contains("unhandled semantic action") && message.contains("state=42"),
20831 "message should name the dropped action coordinate: {message}"
20832 );
20833
20834 let mut lenient =
20836 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
20837 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
20838 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20839 assert!(lenient.take_unknown_semantic_error().is_none());
20840 }
20841
20842 #[test]
20843 fn translated_predicate_is_unaffected_by_error_policy() {
20844 let atn = predicate_after_token_atn();
20845 let mut parser = mini_parser(vec![
20846 TestToken::new(1).with_text("x"),
20847 TestToken::new(2).with_text("y"),
20848 TestToken::eof("parser-test", 2, 1, 2),
20849 ]);
20850
20851 let (tree, _) = parser
20852 .parse_atn_rule_with_runtime_options(
20853 &atn,
20854 0,
20855 ParserRuntimeOptions {
20856 predicates: &[(0, 0, ParserPredicate::True)],
20857 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20858 ..ParserRuntimeOptions::default()
20859 },
20860 )
20861 .expect("a predicate covered by the table is not an unknown coordinate");
20862
20863 assert_eq!(parser.node(tree).text(), "xy");
20864 }
20865
20866 #[test]
20871 fn parser_speculative_replay_threads_stack_member_state() {
20872 let mut ir = SemIr::new();
20873 let one = ir.expr(PExpr::Int(1));
20874 let push = ir.stmt(AStmt::PushMember(0, one));
20875 let pop = ir.stmt(AStmt::PopMember(0));
20876 let semantics = ParserSemantics {
20877 ir,
20878 predicates: Vec::new(),
20879 actions: vec![
20880 ParserSemanticAction {
20881 source_state: 1,
20882 rule_index: usize::MAX,
20883 stmt: push,
20884 speculative: true,
20885 },
20886 ParserSemanticAction {
20887 source_state: 2,
20888 rule_index: usize::MAX,
20889 stmt: pop,
20890 speculative: true,
20891 },
20892 ],
20893 };
20894
20895 let pushed = member_values_after_action(1, &[], Some(&semantics), &MemberEnv::new());
20897 assert_eq!(pushed.stack_top(0), Some(1));
20898 assert_eq!(pushed.stack_len(0), 1);
20899
20900 assert_eq!(MemberEnv::new().stack_len(0), 0);
20903
20904 let popped = member_values_after_action(2, &[], Some(&semantics), &pushed);
20907 assert_eq!(popped.stack_top(0), None);
20908 assert_eq!(popped, MemberEnv::new(), "emptied stack must canonicalize");
20909
20910 let underflowed = member_values_after_action(2, &[], Some(&semantics), &MemberEnv::new());
20912 assert_eq!(underflowed, MemberEnv::new());
20913 }
20914
20915 fn hook_predicate_semantics() -> ParserSemantics {
20920 let mut ir = SemIr::new();
20921 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
20922 ParserSemantics {
20923 ir,
20924 predicates: vec![ParserSemanticPredicate {
20925 rule_index: 0,
20926 pred_index: 0,
20927 expr,
20928 failure_message: None,
20929 }],
20930 actions: Vec::new(),
20931 }
20932 }
20933
20934 #[derive(Debug, Default)]
20935 struct DecliningHooks;
20936
20937 impl SemanticHooks for DecliningHooks {}
20938
20939 #[test]
20940 fn semir_hook_none_falls_through_to_assume_true() {
20941 let atn = predicate_after_token_atn();
20942 let semantics = hook_predicate_semantics();
20943 let mut parser = mini_parser_with_hooks(
20944 vec![
20945 TestToken::new(1).with_text("x"),
20946 TestToken::new(2).with_text("y"),
20947 TestToken::eof("parser-test", 2, 1, 2),
20948 ],
20949 DecliningHooks,
20950 );
20951
20952 let (tree, _) = parser
20953 .parse_atn_rule_with_runtime_options(
20954 &atn,
20955 0,
20956 ParserRuntimeOptions {
20957 semantics: Some(&semantics),
20958 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
20959 ..ParserRuntimeOptions::default()
20960 },
20961 )
20962 .expect("a declined SemIR hook must pass under assume-true");
20963
20964 assert_eq!(parser.node(tree).text(), "xy");
20965 }
20966
20967 #[test]
20968 fn semir_hook_none_falls_through_to_assume_false() {
20969 let atn = predicate_after_token_atn();
20970 let semantics = hook_predicate_semantics();
20971 let mut parser = mini_parser_with_hooks(
20972 vec![
20973 TestToken::new(1).with_text("x"),
20974 TestToken::new(2).with_text("y"),
20975 TestToken::eof("parser-test", 2, 1, 2),
20976 ],
20977 DecliningHooks,
20978 );
20979
20980 let result = parser.parse_atn_rule_with_runtime_options(
20981 &atn,
20982 0,
20983 ParserRuntimeOptions {
20984 semantics: Some(&semantics),
20985 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
20986 ..ParserRuntimeOptions::default()
20987 },
20988 );
20989
20990 assert!(
20991 result.is_err(),
20992 "a declined SemIR hook must fail the only guarded path under assume-false"
20993 );
20994 }
20995
20996 #[test]
20997 fn semir_hook_none_records_coordinate_under_error_policy() {
20998 let atn = predicate_after_token_atn();
20999 let semantics = hook_predicate_semantics();
21000 let mut parser = mini_parser_with_hooks(
21001 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 DecliningHooks,
21007 );
21008
21009 let error = parser
21010 .parse_atn_rule_with_runtime_options(
21011 &atn,
21012 0,
21013 ParserRuntimeOptions {
21014 semantics: Some(&semantics),
21015 unknown_predicate_policy: UnknownSemanticPolicy::Error,
21016 ..ParserRuntimeOptions::default()
21017 },
21018 )
21019 .expect_err("a declined SemIR hook under Error policy must fail the parse");
21020
21021 let AntlrError::Unsupported(message) = error else {
21022 panic!("expected AntlrError::Unsupported, got {error:?}");
21023 };
21024 assert!(
21025 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
21026 "message should name the unresolved coordinate: {message}"
21027 );
21028 }
21029
21030 #[test]
21031 fn generated_direct_predicate_honors_installed_policy() {
21032 let semantics = hook_predicate_semantics();
21038 let context = ParserRuleContext::new(0, -1);
21039
21040 let mut assume_true =
21041 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21042 assert!(
21043 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
21044 &semantics, 0, 0, &context, 0
21045 ),
21046 "default AssumeTrue accepts a declined hook"
21047 );
21048 assert!(assume_true.take_unknown_semantic_error().is_none());
21049
21050 let mut error_policy =
21051 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21052 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
21053 assert!(
21054 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
21055 &semantics, 0, 0, &context, 0
21056 ),
21057 "Error policy rejects a declined hook on the generated-direct path"
21058 );
21059 let error = error_policy
21060 .take_unknown_semantic_error()
21061 .expect("Error policy records the unresolved coordinate for the generated path");
21062 let AntlrError::Unsupported(message) = error else {
21063 panic!("expected AntlrError::Unsupported, got {error:?}");
21064 };
21065 assert!(message.contains("pred_index=0"), "message: {message}");
21066 }
21067
21068 #[test]
21069 fn parser_rule_start_skips_leading_hidden_tokens() {
21070 let atn = token_then_eof_atn();
21071 let mut parser = mini_parser(vec![
21072 TestToken::new(99)
21073 .with_text(" ")
21074 .with_channel(HIDDEN_CHANNEL),
21075 TestToken::new(1).with_text("x"),
21076 TestToken::eof("parser-test", 2, 1, 2),
21077 ]);
21078
21079 let tree = parser
21080 .parse_atn_rule(&atn, 0)
21081 .expect("artificial parser rule should parse");
21082 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
21083 panic!("rule node should be present");
21084 };
21085 assert_eq!(
21086 rule.start()
21087 .expect("rule should have a start token")
21088 .token_type(),
21089 1
21090 );
21091 }
21092
21093 #[test]
21094 fn parser_action_after_eof_stops_at_eof_token() {
21095 let atn = eof_then_action_atn();
21096 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
21097
21098 let (_, actions) = parser
21099 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
21100 .expect("EOF action rule should parse");
21101
21102 assert_eq!(actions.len(), 1);
21103 assert_eq!(actions[0].stop_index(), Some(0));
21104 assert_eq!(
21105 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
21106 ""
21107 );
21108 }
21109
21110 #[test]
21111 fn after_action_stop_uses_rule_context_stop_not_cursor() {
21112 let mut id = TestToken::new(1).with_text("x");
21117 id.set_token_index(0);
21118 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
21119 eof.set_token_index(1);
21120 let mut parser = mini_parser(vec![id.clone(), eof]);
21121 parser.consume();
21123 assert_eq!(parser.la(1), TOKEN_EOF);
21124
21125 let mut ctx = ParserRuleContext::new(0, 0);
21128 parser.set_context_stop(
21129 &mut ctx,
21130 parser.token_id_at(0).expect("ID token should be buffered"),
21131 );
21132 let tree = parser.rule_node(ctx);
21133
21134 let current_index = parser.input.index();
21135 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
21137 assert_eq!(
21139 parser.after_action_stop_index_for_tree(tree, current_index),
21140 Some(0)
21141 );
21142 }
21143
21144 #[test]
21145 fn after_action_start_uses_rule_context_start_not_cursor() {
21146 let mut parser = mini_parser(vec![
21151 TestToken::new(9)
21152 .with_text(" ")
21153 .with_channel(HIDDEN_CHANNEL),
21154 TestToken::new(9)
21155 .with_text(" ")
21156 .with_channel(HIDDEN_CHANNEL),
21157 TestToken::new(1).with_text("x"),
21158 TestToken::eof("parser-test", 3, 1, 3),
21159 ]);
21160
21161 let mut ctx = ParserRuleContext::new(0, 0);
21162 parser.set_context_start(
21163 &mut ctx,
21164 parser.token_id_at(2).expect("ID token should be buffered"),
21165 );
21166 let tree = parser.rule_node(ctx);
21167
21168 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
21171
21172 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
21174 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
21175 }
21176
21177 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
21178 FastRecognizeOutcome {
21179 index,
21180 consumed_eof,
21181 diagnostics: DiagnosticSeqId::EMPTY,
21182 deferred_nodes: FastDeferredNodeId::EMPTY,
21183 nodes: NodeSeqId(marker),
21184 }
21185 }
21186
21187 #[test]
21188 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
21189 let mut outcomes = vec![
21190 clean_fast_outcome(4, false, 0),
21191 clean_fast_outcome(2, false, 1),
21192 clean_fast_outcome(4, false, 2),
21193 clean_fast_outcome(4, true, 3),
21194 clean_fast_outcome(2, false, 4),
21195 ];
21196 let mut scratch = FastOutcomeDedupScratch::default();
21197
21198 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21199
21200 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
21201 assert_eq!(
21202 outcomes
21203 .iter()
21204 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
21205 .collect::<Vec<_>>(),
21206 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
21207 );
21208 assert!(scratch.dense_words.is_empty());
21209 assert!(scratch.sparse_keys.is_empty());
21210 }
21211
21212 #[test]
21213 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
21214 let mut scratch = FastOutcomeDedupScratch::default();
21215 let mut outcomes = (100..109)
21216 .flat_map(|index| {
21217 [
21218 clean_fast_outcome(
21219 index,
21220 false,
21221 u32::try_from(index).expect("test index fits in u32"),
21222 ),
21223 clean_fast_outcome(index, false, u32::MAX),
21224 ]
21225 })
21226 .collect();
21227
21228 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21229
21230 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
21231 assert_eq!(outcomes.len(), 9);
21232 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
21233 let dense_capacity = scratch.dense_words.capacity();
21234
21235 let mut reused = (1_000..1_009)
21236 .map(|index| {
21237 clean_fast_outcome(
21238 index,
21239 false,
21240 u32::try_from(index).expect("test index fits in u32"),
21241 )
21242 })
21243 .collect();
21244 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
21245
21246 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
21247 assert_eq!(reused.len(), 9);
21248 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
21249 }
21250
21251 #[test]
21252 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
21253 let mut scratch = FastOutcomeDedupScratch::default();
21254 let sparse_indexes = [
21255 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
21256 ];
21257 let mut outcomes = sparse_indexes
21258 .into_iter()
21259 .chain([400_000])
21260 .enumerate()
21261 .map(|(marker, index)| {
21262 clean_fast_outcome(
21263 index,
21264 false,
21265 u32::try_from(marker).expect("test marker fits in u32"),
21266 )
21267 })
21268 .collect();
21269
21270 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21271
21272 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21273 assert_eq!(outcomes.len(), sparse_indexes.len());
21274 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
21275 let sparse_capacity = scratch.sparse_keys.capacity();
21276
21277 let mut reused = sparse_indexes
21278 .into_iter()
21279 .map(|index| {
21280 clean_fast_outcome(
21281 index,
21282 false,
21283 u32::try_from(index).expect("test index fits in u32"),
21284 )
21285 })
21286 .collect();
21287 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
21288
21289 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21290 assert_eq!(reused.len(), sparse_indexes.len());
21291 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
21292 }
21293
21294 #[test]
21295 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
21296 let mut scratch = FastOutcomeDedupScratch::default();
21297 scratch
21298 .sparse_keys
21299 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
21300 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
21301 let mut outcomes = (0..9)
21302 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
21303 .collect();
21304
21305 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21306
21307 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21308 assert!(scratch.sparse_keys.is_empty());
21309 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
21310 }
21311
21312 #[test]
21313 fn fast_outcome_selection_respects_sll_tie_order() {
21314 let mut arena = RecognitionArena::default();
21315 let first = FastRecognizeOutcome {
21316 index: 1,
21317 consumed_eof: false,
21318 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21319 line: 1,
21320 column: 0,
21321 message: "mismatched input 'x'".to_owned(),
21322 offending: None,
21323 }]),
21324 deferred_nodes: FastDeferredNodeId::EMPTY,
21325 nodes: NodeSeqId::EMPTY,
21326 };
21327 let second = FastRecognizeOutcome {
21328 index: first.index,
21329 consumed_eof: first.consumed_eof,
21330 diagnostics: DiagnosticSeqId::EMPTY,
21331 deferred_nodes: FastDeferredNodeId::EMPTY,
21332 nodes: NodeSeqId::EMPTY,
21333 };
21334
21335 let selected = select_best_fast_outcome(
21336 [first, second].into_iter(),
21337 PredictionMode::Sll,
21338 None,
21339 |_| panic!("caller-follow token probe should not run"),
21340 &arena,
21341 )
21342 .expect("one outcome should be selected");
21343 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
21344 let eof_second = FastRecognizeOutcome {
21345 index: second.index,
21346 consumed_eof: true,
21347 diagnostics: DiagnosticSeqId::EMPTY,
21348 deferred_nodes: FastDeferredNodeId::EMPTY,
21349 nodes: NodeSeqId::EMPTY,
21350 };
21351 let selected = select_best_fast_outcome(
21352 [first, eof_second].into_iter(),
21353 PredictionMode::Sll,
21354 None,
21355 |_| panic!("caller-follow token probe should not run"),
21356 &arena,
21357 )
21358 .expect("one outcome should be selected");
21359 assert!(!selected.consumed_eof);
21360 let selected = select_best_fast_outcome(
21361 [first, second].into_iter(),
21362 PredictionMode::Ll,
21363 None,
21364 |_| panic!("caller-follow token probe should not run"),
21365 &arena,
21366 )
21367 .expect("one outcome should be selected");
21368 assert!(selected.diagnostics.is_empty());
21369 }
21370
21371 #[test]
21372 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
21373 let mut arena = RecognitionArena::default();
21374 let first = FastRecognizeOutcome {
21375 index: 3,
21376 consumed_eof: false,
21377 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21378 line: 1,
21379 column: 0,
21380 message: "mismatched input 'x' expecting 'a'".to_owned(),
21381 offending: None,
21382 }]),
21383 deferred_nodes: FastDeferredNodeId::EMPTY,
21384 nodes: NodeSeqId::EMPTY,
21385 };
21386 let same_rank = FastRecognizeOutcome {
21387 index: first.index,
21388 consumed_eof: first.consumed_eof,
21389 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21390 line: 1,
21391 column: 0,
21392 message: "mismatched input 'x' expecting 'b'".to_owned(),
21393 offending: None,
21394 }]),
21395 deferred_nodes: FastDeferredNodeId::EMPTY,
21396 nodes: NodeSeqId::EMPTY,
21397 };
21398 let better_rank = FastRecognizeOutcome {
21399 index: first.index,
21400 consumed_eof: first.consumed_eof,
21401 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21402 line: 1,
21403 column: 0,
21404 message: "missing 'a' at 'x'".to_owned(),
21405 offending: None,
21406 }]),
21407 deferred_nodes: FastDeferredNodeId::EMPTY,
21408 nodes: NodeSeqId::EMPTY,
21409 };
21410 let mut outcomes = vec![first, same_rank, better_rank];
21411
21412 dedupe_fast_outcomes(&mut outcomes, &arena);
21413
21414 assert_eq!(outcomes.len(), 2);
21415 assert_eq!(
21416 arena
21417 .diagnostics(outcomes[0].diagnostics)
21418 .next()
21419 .expect("first diagnostic")
21420 .message,
21421 "mismatched input 'x' expecting 'a'"
21422 );
21423 assert_eq!(
21424 arena
21425 .diagnostics(outcomes[1].diagnostics)
21426 .next()
21427 .expect("second diagnostic")
21428 .message,
21429 "missing 'a' at 'x'"
21430 );
21431 }
21432
21433 #[test]
21434 fn fast_outcome_selection_prefers_generated_caller_follow() {
21435 let arena = RecognitionArena::default();
21436 let earlier = FastRecognizeOutcome {
21437 index: 7,
21438 consumed_eof: false,
21439 diagnostics: DiagnosticSeqId::EMPTY,
21440 deferred_nodes: FastDeferredNodeId::EMPTY,
21441 nodes: NodeSeqId::EMPTY,
21442 };
21443 let later = FastRecognizeOutcome {
21444 index: 8,
21445 consumed_eof: false,
21446 diagnostics: DiagnosticSeqId::EMPTY,
21447 deferred_nodes: FastDeferredNodeId::EMPTY,
21448 nodes: NodeSeqId::EMPTY,
21449 };
21450 let mut follow = TokenBitSet::default();
21451 follow.insert(5);
21452
21453 let selected = select_best_fast_outcome(
21454 [later, earlier].into_iter(),
21455 PredictionMode::Ll,
21456 Some(&follow),
21457 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
21458 &arena,
21459 )
21460 .expect("one outcome should be selected");
21461 assert_eq!(selected.index, 7);
21462
21463 let selected = select_best_fast_outcome(
21464 [later, earlier].into_iter(),
21465 PredictionMode::Ll,
21466 Some(&follow),
21467 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
21468 &arena,
21469 )
21470 .expect("one outcome should be selected");
21471 assert_eq!(selected.index, 8);
21472
21473 let indented_next_statement = FastRecognizeOutcome {
21474 index: 9,
21475 consumed_eof: false,
21476 diagnostics: DiagnosticSeqId::EMPTY,
21477 deferred_nodes: FastDeferredNodeId::EMPTY,
21478 nodes: NodeSeqId::EMPTY,
21479 };
21480 let selected = select_best_fast_outcome(
21481 [indented_next_statement, earlier].into_iter(),
21482 PredictionMode::Ll,
21483 Some(&follow),
21484 |index| {
21485 let is_boundary = index == 7;
21486 let is_boundary_gap = matches!(index, 7 | 8);
21487 (
21488 if index == 7 { 5 } else { TOKEN_EOF },
21489 is_boundary,
21490 is_boundary_gap,
21491 )
21492 },
21493 &arena,
21494 )
21495 .expect("one outcome should be selected");
21496 assert_eq!(selected.index, 7);
21497
21498 let continuation = FastRecognizeOutcome {
21499 index: 10,
21500 consumed_eof: false,
21501 diagnostics: DiagnosticSeqId::EMPTY,
21502 deferred_nodes: FastDeferredNodeId::EMPTY,
21503 nodes: NodeSeqId::EMPTY,
21504 };
21505 let selected = select_best_fast_outcome(
21506 [continuation, earlier].into_iter(),
21507 PredictionMode::Ll,
21508 Some(&follow),
21509 |index| {
21510 let is_boundary = matches!(index, 7 | 9);
21511 (
21512 if index == 7 { 5 } else { TOKEN_EOF },
21513 is_boundary,
21514 is_boundary,
21515 )
21516 },
21517 &arena,
21518 )
21519 .expect("one outcome should be selected");
21520 assert_eq!(selected.index, 10);
21521
21522 let selected = select_best_fast_outcome(
21523 [earlier, later].into_iter(),
21524 PredictionMode::Sll,
21525 Some(&follow),
21526 |_| panic!("caller-follow token probe should not run in SLL mode"),
21527 &arena,
21528 )
21529 .expect("one outcome should be selected");
21530 assert_eq!(selected.index, 8);
21531 }
21532
21533 #[test]
21534 fn caller_follow_boundary_text_requires_separator_shape() {
21535 assert!(is_caller_follow_boundary_text(";"));
21536 assert!(is_caller_follow_boundary_text("\n"));
21537 assert!(is_caller_follow_boundary_text("\r\n "));
21538 assert!(is_caller_follow_boundary_text(";\n"));
21539 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
21540 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
21541 assert!(!is_caller_follow_boundary_text("identifier"));
21542 assert!(is_caller_follow_boundary_gap_text(" \t "));
21543 assert!(is_caller_follow_boundary_gap_text("\n "));
21544 assert!(is_caller_follow_boundary_gap_text(";\t"));
21545 assert!(!is_caller_follow_boundary_gap_text(
21546 "\"\"\"line1\nline2\"\"\""
21547 ));
21548 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
21549 }
21550
21551 #[test]
21552 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
21553 let mut parser = mini_parser(vec![
21554 TestToken::new(5).with_text("\n"),
21555 TestToken::new(6)
21556 .with_text("// comment\n")
21557 .with_channel(HIDDEN_CHANNEL),
21558 TestToken::new(1).with_text("x"),
21559 TestToken::eof("parser-test", 1, 2, 0),
21560 ]);
21561
21562 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
21563 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
21564 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
21565 }
21566
21567 #[test]
21568 fn caller_follow_token_info_uses_stream_visible_channel() {
21569 let source = Source {
21570 tokens: vec![
21571 TestToken::new(5).with_text("\n").with_channel(2),
21572 TestToken::new(1).with_text("x").with_channel(2),
21573 TestToken::new(6)
21574 .with_text("// comment\n")
21575 .with_channel(HIDDEN_CHANNEL),
21576 TestToken::eof("parser-test", 1, 2, 0),
21577 ],
21578 index: 0,
21579 };
21580 let data = RecognizerData::new(
21581 "Mini.g4",
21582 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21583 );
21584 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
21585
21586 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
21587 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
21588 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
21589 }
21590
21591 #[test]
21592 fn reset_per_parse_caches_clears_state_expected_token_cache() {
21593 let atn = token_then_eof_atn();
21594 let mut parser = mini_parser(Vec::new());
21595
21596 let _ = parser.cached_state_expected_token_set(&atn, 0);
21597 assert!(!parser.state_expected_token_cache.is_empty());
21598
21599 parser.reset_per_parse_caches();
21600 assert!(parser.state_expected_token_cache.is_empty());
21601 }
21602
21603 #[test]
21604 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
21605 let cyclic = epsilon_cycle_atn();
21606 let acyclic = token_then_eof_atn();
21607 let mut parser = mini_parser(Vec::new());
21608
21609 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
21610 assert_eq!(
21611 parser.empty_cycle_cache_atn,
21612 Some(SharedAtnCacheKey::for_atn(&cyclic))
21613 );
21614 assert_eq!(parser.empty_cycle_cache[1], Some(true));
21615
21616 parser.reset_per_parse_caches();
21617 assert_eq!(parser.empty_cycle_cache[1], Some(true));
21618 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
21619
21620 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
21621 assert_eq!(
21622 parser.empty_cycle_cache_atn,
21623 Some(SharedAtnCacheKey::for_atn(&acyclic))
21624 );
21625 assert_eq!(parser.empty_cycle_cache[1], Some(false));
21626 }
21627
21628 #[test]
21629 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
21630 let source = Source {
21631 tokens: vec![
21632 TestToken::new(1).with_text("x"),
21633 TestToken::eof("parser-test", 1, 1, 1),
21634 ],
21635 index: 0,
21636 };
21637 let data = RecognizerData::new(
21638 "Mini.g4",
21639 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21640 );
21641 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
21642 let expected = ExpectedTokens {
21643 index: Some(0),
21644 symbols: BTreeSet::new(),
21645 no_viable: None,
21646 };
21647
21648 let (_, message) = parser.expected_error_message(0, 0, &expected);
21649
21650 assert_eq!(message, "mismatched input 'x'");
21651 }
21652
21653 #[test]
21654 fn eof_rule_stop_index_points_at_eof_token() {
21655 let source = Source {
21656 tokens: vec![
21657 TestToken::new(1).with_text("x"),
21658 TestToken::eof("parser-test", 1, 1, 1),
21659 ],
21660 index: 0,
21661 };
21662 let data = RecognizerData::new(
21663 "Mini.g4",
21664 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21665 );
21666 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
21667
21668 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
21669 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
21670 }
21671
21672 #[test]
21673 fn generated_parser_action_uses_current_rule_stop_boundary() {
21674 let mut parser = mini_parser(vec![
21675 TestToken::new(1).with_text("x"),
21676 TestToken::eof("parser-test", 1, 1, 1),
21677 ]);
21678
21679 parser.match_token(1).expect("token should match");
21680 let action = parser.parser_action_at_current(7, 0, 0, false);
21681 assert_eq!(action.source_state(), 7);
21682 assert_eq!(action.rule_index(), 0);
21683 assert_eq!(action.start_index(), 0);
21684 assert_eq!(action.stop_index(), Some(0));
21685
21686 parser.match_eof().expect("EOF should match");
21687 let action = parser.parser_action_at_current(8, 0, 0, true);
21688 assert_eq!(action.stop_index(), Some(1));
21689 }
21690
21691 #[test]
21692 fn folds_left_recursive_boundary_into_rule_node() {
21693 let mut arena = RecognitionArena::default();
21694 let first = arena.push_node(ArenaRecognizedNode::Token {
21695 token: TokenId::try_from(0).expect("test token ID"),
21696 });
21697 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
21698 rule_index: 1,
21699 alt_number: 3,
21700 });
21701 let second = arena.push_node(ArenaRecognizedNode::Token {
21702 token: TokenId::try_from(1).expect("test token ID"),
21703 });
21704 let mut nodes = NodeSeqId::EMPTY;
21705 for node in [first, boundary, second].into_iter().rev() {
21706 nodes = arena.prepend(nodes, node);
21707 }
21708
21709 let folded = arena.fold_left_recursive_boundaries(nodes);
21710 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
21711
21712 assert_eq!(folded_nodes.len(), 2);
21713 let ArenaRecognizedNode::Rule {
21714 rule_index,
21715 invoking_state,
21716 alt_number,
21717 start_index,
21718 stop_index,
21719 children,
21720 ..
21721 } = arena.node(folded_nodes[0])
21722 else {
21723 panic!("first folded node should be a rule");
21724 };
21725 insta::assert_debug_snapshot!(
21729 "folds_left_recursive_boundary_into_rule_node",
21730 (
21731 rule_index,
21732 invoking_state,
21733 alt_number,
21734 start_index,
21735 stop_index
21736 )
21737 );
21738 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
21739 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
21740
21741 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
21742 assert_eq!(
21743 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
21744 (4, 3, 1)
21745 );
21746 assert_eq!(
21747 (stats.total_links, stats.live_links, stats.dead_links),
21748 (9, 3, 6)
21749 );
21750 }
21751
21752 #[test]
21753 fn recognition_arena_reports_live_dead_and_retained_capacity() {
21754 let mut arena = RecognitionArena::default();
21755 let token = arena.push_node(ArenaRecognizedNode::Token {
21756 token: TokenId::try_from(0).expect("test token ID"),
21757 });
21758 let extra = arena.push_extra(RecognitionExtra::MissingToken {
21759 token_type: 2,
21760 at_index: 1,
21761 text: "<missing X>".to_owned(),
21762 });
21763 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
21764 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
21765 token: TokenId::try_from(1).expect("test token ID"),
21766 });
21767 let mut live = NodeSeqId::EMPTY;
21768 live = arena.prepend(live, missing);
21769 live = arena.prepend(live, token);
21770 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
21771 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
21772 line: 1,
21773 column: 0,
21774 message: "missing X".to_owned(),
21775 offending: None,
21776 }]);
21777 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
21778 line: 1,
21779 column: 1,
21780 message: "discarded".to_owned(),
21781 offending: None,
21782 }]);
21783 let deferred_children = arena.deferred_fragment(live);
21784 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
21785 rule_index: 0,
21786 invoking_state: -1,
21787 start_index: 0,
21788 stop_index: Some(1),
21789 deferred_children,
21790 children: NodeSeqId::EMPTY,
21791 });
21792
21793 let stats = arena.stats(live, live_diagnostics);
21794
21795 assert_eq!(
21796 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
21797 (3, 2, 1)
21798 );
21799 assert_eq!(
21800 (stats.total_links, stats.live_links, stats.dead_links),
21801 (5, 3, 2)
21802 );
21803 assert_eq!(
21804 (stats.total_extras, stats.live_extras, stats.dead_extras),
21805 (3, 2, 1)
21806 );
21807 assert!(size_of::<SeqLink>() <= 8);
21808 assert!(size_of::<DiagnosticLink>() <= 8);
21809 assert!(size_of::<FastDeferredNode>() <= 12);
21810 assert!(size_of::<FastDeferredRule>() <= 28);
21811 assert!(size_of::<FastRecognizeOutcome>() <= 24);
21812 let capacities = (
21813 stats.node_capacity,
21814 stats.link_capacity,
21815 stats.extra_capacity,
21816 );
21817 let deferred_capacities = (
21818 arena.deferred_nodes.capacity(),
21819 arena.deferred_rules.capacity(),
21820 );
21821
21822 arena.reset();
21823 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
21824 assert_eq!(
21825 (reset.total_nodes, reset.total_links, reset.total_extras),
21826 (0, 0, 0)
21827 );
21828 assert_eq!(
21829 (
21830 reset.node_capacity,
21831 reset.link_capacity,
21832 reset.extra_capacity,
21833 ),
21834 capacities
21835 );
21836 assert!(arena.deferred_nodes.is_empty());
21837 assert!(arena.deferred_rules.is_empty());
21838 assert_eq!(
21839 (
21840 arena.deferred_nodes.capacity(),
21841 arena.deferred_rules.capacity(),
21842 ),
21843 deferred_capacities
21844 );
21845 }
21846
21847 #[test]
21848 fn parser_computes_recognition_arena_stats_on_demand() {
21849 let mut parser = mini_parser(Vec::new());
21850 let live = parser
21851 .recognition_arena
21852 .push_node(ArenaRecognizedNode::Token {
21853 token: TokenId::try_from(0).expect("test token ID"),
21854 });
21855 let discarded = parser
21856 .recognition_arena
21857 .push_node(ArenaRecognizedNode::ErrorToken {
21858 token: TokenId::try_from(1).expect("test token ID"),
21859 });
21860 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
21861 let _discarded_root = parser
21862 .recognition_arena
21863 .prepend(NodeSeqId::EMPTY, discarded);
21864 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
21865
21866 let stats = parser.recognition_arena_stats();
21867
21868 assert_eq!(
21869 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
21870 (2, 1, 1)
21871 );
21872 assert_eq!(
21873 (stats.total_links, stats.live_links, stats.dead_links),
21874 (2, 1, 1)
21875 );
21876 }
21877
21878 #[test]
21879 fn recognition_arena_drops_capacity_above_retention_limit() {
21880 let mut storage = Vec::<u8>::with_capacity(4);
21881 storage.extend([1, 2, 3]);
21882
21883 reset_arena_vec(&mut storage, 3);
21884
21885 assert!(storage.is_empty());
21886 assert_eq!(storage.capacity(), 0);
21887 }
21888
21889 #[test]
21890 fn recognition_arena_concatenates_diagnostics_in_source_order() {
21891 let mut arena = RecognitionArena::default();
21892 let prefix = arena.diagnostic_sequence([
21893 ParserDiagnostic {
21894 line: 1,
21895 column: 0,
21896 message: "first".to_owned(),
21897 offending: None,
21898 },
21899 ParserDiagnostic {
21900 line: 1,
21901 column: 1,
21902 message: "second".to_owned(),
21903 offending: None,
21904 },
21905 ]);
21906 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
21907 line: 1,
21908 column: 2,
21909 message: "third".to_owned(),
21910 offending: None,
21911 }]);
21912 let extras_before = arena.extras.len();
21913
21914 let combined = arena.concat_diagnostics(prefix, suffix);
21915 let messages = arena
21916 .diagnostics(combined)
21917 .map(|diagnostic| diagnostic.message.as_str())
21918 .collect::<Vec<_>>();
21919
21920 assert_eq!(messages, ["first", "second", "third"]);
21921 assert_eq!(arena.extras.len(), extras_before);
21922 }
21923
21924 #[test]
21925 fn outcome_ties_keep_later_non_recursive_alternative() {
21926 let arena = RecognitionArena::default();
21927 let first = RecognizeOutcome {
21928 index: 1,
21929 consumed_eof: false,
21930 alt_number: 0,
21931 member_values: MemberEnv::new(),
21932 return_values: BTreeMap::new(),
21933 diagnostics: DiagnosticSeqId::EMPTY,
21934 decisions: Vec::new(),
21935 actions: vec![ParserAction::new(1, 0, 0, None)],
21936 nodes: NodeSeqId::EMPTY,
21937 };
21938 let second = RecognizeOutcome {
21939 actions: vec![ParserAction::new(2, 0, 0, None)],
21940 ..first.clone()
21941 };
21942
21943 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
21944 .expect("one outcome should be selected");
21945 assert_eq!(selected.actions[0].source_state(), 2);
21946 }
21947
21948 #[test]
21949 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
21950 let arena = RecognitionArena::default();
21951 let first = RecognizeOutcome {
21952 index: 1,
21953 consumed_eof: false,
21954 alt_number: 0,
21955 member_values: MemberEnv::new(),
21956 return_values: BTreeMap::new(),
21957 diagnostics: DiagnosticSeqId::EMPTY,
21958 decisions: Vec::new(),
21959 actions: vec![ParserAction::new(1, 0, 0, None)],
21960 nodes: NodeSeqId::EMPTY,
21961 };
21962 let second = RecognizeOutcome {
21963 actions: vec![
21964 ParserAction::new(2, 0, 0, None),
21965 ParserAction::new(3, 0, 0, None),
21966 ],
21967 ..first.clone()
21968 };
21969
21970 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
21971 .expect("one outcome should be selected");
21972 assert_eq!(selected.actions.len(), 2);
21973 }
21974
21975 #[test]
21976 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
21977 let arena = RecognitionArena::default();
21978 let first = RecognizeOutcome {
21979 index: 7,
21980 consumed_eof: false,
21981 alt_number: 0,
21982 member_values: MemberEnv::new(),
21983 return_values: BTreeMap::new(),
21984 diagnostics: DiagnosticSeqId::EMPTY,
21985 decisions: vec![1, 0],
21986 actions: vec![
21987 ParserAction::new(23, 2, 2, Some(4)),
21988 ParserAction::new(23, 2, 0, Some(6)),
21989 ],
21990 nodes: NodeSeqId::EMPTY,
21991 };
21992 let second = RecognizeOutcome {
21993 decisions: vec![0, 1],
21994 actions: vec![
21995 ParserAction::new(23, 2, 2, Some(6)),
21996 ParserAction::new(23, 2, 0, Some(6)),
21997 ],
21998 ..first.clone()
21999 };
22000
22001 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22002 .expect("one outcome should be selected");
22003 assert_eq!(selected.actions[0].stop_index(), Some(6));
22004 }
22005
22006 #[test]
22007 fn outcome_ties_keep_first_recursive_tree_shape() {
22008 let mut arena = RecognitionArena::default();
22009 let token = arena.push_node(ArenaRecognizedNode::Token {
22010 token: TokenId::try_from(0).expect("test token ID"),
22011 });
22012 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
22013 let inner = arena.push_node(ArenaRecognizedNode::Rule {
22014 rule_index: 1,
22015 invoking_state: -1,
22016 alt_number: 0,
22017 start_index: 0,
22018 stop_index: Some(0),
22019 return_values: None,
22020 children: token_children,
22021 });
22022 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
22023 let outer = arena.push_node(ArenaRecognizedNode::Rule {
22024 rule_index: 1,
22025 invoking_state: -1,
22026 alt_number: 0,
22027 start_index: 0,
22028 stop_index: Some(0),
22029 return_values: None,
22030 children: inner_children,
22031 });
22032 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
22033 let first = RecognizeOutcome {
22034 index: 1,
22035 consumed_eof: false,
22036 alt_number: 0,
22037 member_values: MemberEnv::new(),
22038 return_values: BTreeMap::new(),
22039 diagnostics: DiagnosticSeqId::EMPTY,
22040 decisions: Vec::new(),
22041 actions: vec![ParserAction::new(1, 0, 0, None)],
22042 nodes: recursive_nodes,
22043 };
22044 let second = RecognizeOutcome {
22045 index: 1,
22046 consumed_eof: false,
22047 alt_number: 0,
22048 member_values: MemberEnv::new(),
22049 return_values: BTreeMap::new(),
22050 diagnostics: DiagnosticSeqId::EMPTY,
22051 decisions: Vec::new(),
22052 actions: vec![ParserAction::new(2, 0, 0, None)],
22053 nodes: recursive_nodes,
22054 };
22055
22056 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22057 .expect("one outcome should be selected");
22058 assert_eq!(selected.actions[0].source_state(), 1);
22059 }
22060
22061 #[test]
22062 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
22063 let mut arena = RecognitionArena::default();
22064 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
22065 line: 1,
22066 column: 3,
22067 message: "missing 'Y' at '<EOF>'".to_owned(),
22068 offending: None,
22069 }]);
22070 let first_alt = RecognizeOutcome {
22071 index: 2,
22072 consumed_eof: true,
22073 alt_number: 0,
22074 member_values: MemberEnv::new(),
22075 return_values: BTreeMap::new(),
22076 diagnostics: recovered_diagnostics,
22077 decisions: vec![0],
22078 actions: vec![ParserAction::new(1, 0, 0, None)],
22079 nodes: NodeSeqId::EMPTY,
22080 };
22081 let second_alt = RecognizeOutcome {
22082 diagnostics: DiagnosticSeqId::EMPTY,
22083 decisions: vec![1],
22084 actions: vec![ParserAction::new(2, 0, 0, None)],
22085 ..first_alt.clone()
22086 };
22087
22088 let selected = select_best_outcome(
22089 [second_alt, first_alt].into_iter(),
22090 PredictionMode::Sll,
22091 &arena,
22092 )
22093 .expect("one outcome should be selected");
22094 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
22095 assert_eq!(selected.decisions, [0]);
22096 }
22097}