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
302#[macro_export]
318#[doc(hidden)]
319macro_rules! __antlr4_rust_invoke_subrule {
320 ($parser:ident, $state:expr, $call:expr, $ctx:ident) => {{
321 let __invoking_marker = $parser.base.push_invoking_state($state);
322 let __child = $call;
323 $parser.base.discard_invoking_state(__invoking_marker);
324 let __child = __child?;
325 $parser.base.add_parse_child(&mut $ctx, __child);
326 }};
327}
328
329pub trait ParseListener: Send {
377 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError>;
382
383 fn exit_every_rule(&mut self, rule_index: usize) {
387 let _ = rule_index;
388 }
389}
390
391impl<T: ParseListener + ?Sized> ParseListener for Box<T> {
395 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
396 (**self).enter_every_rule(event)
397 }
398
399 fn exit_every_rule(&mut self, rule_index: usize) {
400 (**self).exit_every_rule(rule_index);
401 }
402}
403
404#[derive(Debug)]
409#[non_exhaustive]
410pub struct EnterRuleEvent<'a> {
411 pub rule_index: usize,
414 pub current: Option<TokenView<'a>>,
417}
418
419struct ParseListenerSlot(Box<dyn ParseListener>);
420
421impl std::fmt::Debug for ParseListenerSlot {
422 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
423 f.write_str("ParseListener")
424 }
425}
426const CLEAN_MEMO_PROBE_LIMIT: usize = 4096;
430const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
431const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
434const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
435const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
436const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
437const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
438
439#[derive(Clone, Copy, Debug, Eq, PartialEq)]
440enum CleanMemoMode {
441 Probe,
442 Promote,
443 Sparse,
444}
445
446fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
447 intervals
448 .iter()
449 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
450}
451
452fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
453 let mut symbols = BTreeSet::new();
454 for (start, stop) in intervals {
455 symbols.extend(*start..=*stop);
456 }
457 symbols
458}
459
460fn interval_complement_symbols(
461 intervals: &[(i32, i32)],
462 min_vocabulary: i32,
463 max_vocabulary: i32,
464) -> BTreeSet<i32> {
465 (min_vocabulary..=max_vocabulary)
466 .filter(|symbol| !interval_set_contains(intervals, *symbol))
467 .collect()
468}
469
470#[cfg(feature = "perf-counters")]
471mod perf_counters {
472 use std::cell::Cell;
473 thread_local! {
474 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
475 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
476 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
477 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
478 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
479 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
480 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
481 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
482 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
483 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
484 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
485 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
486 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
487 }
488 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
489 c.with(|v| v.set(v.get() + n));
490 }
491 thread_local! {
492 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
493 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
494 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
495 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
496 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
497 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
498 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
499 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
500 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
501 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
502 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
503 }
504 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
505 [
506 ("rfs_calls", RFS_CALLS.with(Cell::get)),
507 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
508 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
509 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
510 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
511 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
512 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
513 (
514 "outcome_dedupe_inputs",
515 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
516 ),
517 (
518 "outcome_dedupe_removed",
519 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
520 ),
521 (
522 "outcome_dedupe_inline",
523 OUTCOME_DEDUPE_INLINE.with(Cell::get),
524 ),
525 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
526 (
527 "outcome_dedupe_sparse",
528 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
529 ),
530 (
531 "outcome_dedupe_dense_words",
532 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
533 ),
534 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
535 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
536 (
537 "atom_range_transitions",
538 ATOM_RANGE_TRANSITIONS.with(Cell::get),
539 ),
540 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
541 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
542 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
543 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
544 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
545 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
546 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
547 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
548 ]
549 }
550 pub fn reset() {
551 RFS_CALLS.with(|c| c.set(0));
552 RFS_MEMO_HITS.with(|c| c.set(0));
553 RFS_MEMO_MISSES.with(|c| c.set(0));
554 RFS_VISITING_CYCLE.with(|c| c.set(0));
555 MEMO_INSERTED.with(|c| c.set(0));
556 OUTCOMES_PUSHED.with(|c| c.set(0));
557 OUTCOMES_CLONED.with(|c| c.set(0));
558 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
559 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
560 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
561 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
562 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
563 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
564 EPSILON_TRANSITIONS.with(|c| c.set(0));
565 RULE_TRANSITIONS.with(|c| c.set(0));
566 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
567 SINGLE_TRANS_BODY.with(|c| c.set(0));
568 MULTI_TRANS_BODY.with(|c| c.set(0));
569 SINGLE_TRANS_RULE.with(|c| c.set(0));
570 SINGLE_TRANS_ATOM.with(|c| c.set(0));
571 SINGLE_TRANS_OTHER.with(|c| c.set(0));
572 OUTCOMES_RETURN_0.with(|c| c.set(0));
573 OUTCOMES_RETURN_1.with(|c| c.set(0));
574 OUTCOMES_RETURN_N.with(|c| c.set(0));
575 }
576 pub fn dump() {
577 for (name, value) in snapshot() {
578 #[allow(clippy::print_stderr)]
579 {
580 eprintln!("perf {name}={value}");
581 }
582 }
583 }
584}
585
586#[cfg(feature = "perf-counters")]
587pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
588const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
593#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
602pub struct ParserAction {
603 source_state: usize,
604 rule_index: usize,
605 action_index: Option<usize>,
606 start_index: usize,
607 stop_index: Option<usize>,
608 rule_init: bool,
609 expected_state: Option<usize>,
610}
611
612impl ParserAction {
613 pub const fn new(
615 source_state: usize,
616 rule_index: usize,
617 start_index: usize,
618 stop_index: Option<usize>,
619 ) -> Self {
620 Self {
621 source_state,
622 rule_index,
623 action_index: None,
624 start_index,
625 stop_index,
626 rule_init: false,
627 expected_state: None,
628 }
629 }
630
631 pub const fn new_indexed(
633 source_state: usize,
634 rule_index: usize,
635 action_index: usize,
636 start_index: usize,
637 stop_index: Option<usize>,
638 ) -> Self {
639 Self {
640 source_state,
641 rule_index,
642 action_index: Some(action_index),
643 start_index,
644 stop_index,
645 rule_init: false,
646 expected_state: None,
647 }
648 }
649
650 pub const fn new_rule_init(
652 rule_index: usize,
653 start_index: usize,
654 expected_state: Option<usize>,
655 ) -> Self {
656 Self {
657 source_state: usize::MAX,
658 rule_index,
659 action_index: None,
660 start_index,
661 stop_index: None,
662 rule_init: true,
663 expected_state,
664 }
665 }
666
667 pub const fn source_state(&self) -> usize {
669 self.source_state
670 }
671
672 pub const fn rule_index(&self) -> usize {
674 self.rule_index
675 }
676
677 pub const fn action_index(&self) -> Option<usize> {
679 self.action_index
680 }
681
682 pub const fn start_index(&self) -> usize {
684 self.start_index
685 }
686
687 pub const fn stop_index(&self) -> Option<usize> {
689 self.stop_index
690 }
691
692 pub const fn is_rule_init(&self) -> bool {
694 self.rule_init
695 }
696
697 pub const fn expected_state(&self) -> Option<usize> {
699 self.expected_state
700 }
701}
702
703pub struct ParserSemCtx<'a, S>
711where
712 S: TokenSource,
713{
714 input: &'a mut CommonTokenStream<S>,
715 tree_storage: &'a ParseTreeStorage,
716 rule_index: usize,
717 coordinate_index: usize,
718 rule_name: Option<String>,
719 context: Option<&'a ParserRuleContext>,
720 tree: Option<ParseTree>,
721 local_int_arg: Option<(usize, i64)>,
722 member_values: &'a MemberEnv,
723 action: Option<ParserAction>,
724}
725
726impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
727where
728 S: TokenSource,
729{
730 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
731 f.debug_struct("ParserSemCtx")
732 .field("rule_index", &self.rule_index)
733 .field("coordinate_index", &self.coordinate_index)
734 .field("rule_name", &self.rule_name)
735 .field("context", &self.context)
736 .field("tree", &self.tree)
737 .field("local_int_arg", &self.local_int_arg)
738 .field("member_values", &self.member_values)
739 .field("action", &self.action)
740 .finish_non_exhaustive()
741 }
742}
743
744impl<'a, S> ParserSemCtx<'a, S>
745where
746 S: TokenSource,
747{
748 #[must_use]
750 pub const fn rule_index(&self) -> usize {
751 self.rule_index
752 }
753
754 #[must_use]
756 pub fn rule_name(&self) -> Option<&str> {
757 self.rule_name.as_deref()
758 }
759
760 #[must_use]
763 pub const fn coordinate_index(&self) -> usize {
764 self.coordinate_index
765 }
766
767 #[must_use]
769 pub fn input_index(&self) -> usize {
770 self.input.index()
771 }
772
773 pub fn la(&mut self, offset: isize) -> i32 {
775 self.input.la(offset)
776 }
777
778 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
780 self.input.lt(offset)
781 }
782
783 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
785 self.lt(offset)
786 }
787
788 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
795 self.input.get(index)
796 }
797
798 #[must_use]
801 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
802 self.context
803 }
804
805 #[must_use]
807 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
808 self.tree_storage
809 }
810
811 #[must_use]
813 pub const fn token_store(&self) -> &TokenStore {
814 self.input.token_store()
815 }
816
817 #[must_use]
819 pub const fn tree_id(&self) -> Option<NodeId> {
820 self.tree
821 }
822
823 #[must_use]
826 pub fn tree(&self) -> Option<Node<'_>> {
827 self.tree
828 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
829 }
830
831 #[must_use]
833 pub fn local_int_arg(&self) -> Option<i64> {
834 self.local_int_arg.map(|(_, value)| value)
835 }
836
837 #[must_use]
839 pub fn member_int(&self, member: usize) -> Option<i64> {
840 self.member_values.scalar(member)
841 }
842
843 #[must_use]
846 pub fn member_stack_top(&self, member: usize) -> Option<i64> {
847 self.member_values.stack_top(member)
848 }
849
850 #[must_use]
852 pub fn member_stack_len(&self, member: usize) -> usize {
853 self.member_values.stack_len(member)
854 }
855
856 #[must_use]
859 pub const fn action(&self) -> Option<ParserAction> {
860 self.action
861 }
862
863 pub fn action_text(&self) -> String {
871 let Some(action) = self.action else {
872 return String::new();
873 };
874 let Some(stop) = action.stop_index() else {
875 return String::new();
876 };
877 let stop = if self
878 .input
879 .get(stop)
880 .is_some_and(|token| token.token_type() == TOKEN_EOF)
881 {
882 let Some(previous) = self.input.previous_visible_token_index(stop) else {
883 return String::new();
884 };
885 previous
886 } else {
887 stop
888 };
889 self.input.text(action.start_index(), stop)
890 }
891}
892
893pub trait SemanticHooks {
900 const ENABLES_LEXER_LIFECYCLE: bool = true;
907
908 fn observes_parser_predicates(&self) -> bool {
913 true
914 }
915
916 fn observes_parser_decisions(&self) -> bool {
921 false
922 }
923
924 fn parser_decision_override(
930 &mut self,
931 decision: usize,
932 input_index: usize,
933 alternative_count: usize,
934 ) -> Option<usize> {
935 let _ = (decision, input_index, alternative_count);
936 None
937 }
938
939 fn sempred<S>(
940 &mut self,
941 ctx: &mut ParserSemCtx<'_, S>,
942 rule_index: usize,
943 pred_index: usize,
944 ) -> Option<bool>
945 where
946 S: TokenSource,
947 {
948 let _ = (ctx, rule_index, pred_index);
949 None
950 }
951
952 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
953 where
954 S: TokenSource,
955 {
956 let _ = (ctx, action);
957 false
958 }
959
960 fn lexer_sempred<I>(
961 &mut self,
962 ctx: &mut LexerSemCtx<'_, I>,
963 rule_index: usize,
964 pred_index: usize,
965 ) -> Option<bool>
966 where
967 I: CharStream,
968 {
969 let _ = (ctx, rule_index, pred_index);
970 None
971 }
972
973 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
983 where
984 I: CharStream,
985 {
986 let _ = (ctx, action);
987 false
988 }
989
990 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
994 where
995 I: CharStream,
996 {
997 let _ = ctx;
998 }
999
1000 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
1006 where
1007 I: CharStream,
1008 {
1009 let _ = ctx;
1010 }
1011
1012 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
1021 where
1022 I: CharStream,
1023 {
1024 let _ = ctx;
1025 }
1026
1027 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
1034 let _ = token;
1035 }
1036}
1037
1038#[derive(Clone, Copy, Debug, Default)]
1041pub struct NoSemanticHooks;
1042
1043impl SemanticHooks for NoSemanticHooks {
1044 const ENABLES_LEXER_LIFECYCLE: bool = false;
1045
1046 fn observes_parser_predicates(&self) -> bool {
1047 false
1048 }
1049}
1050
1051#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1058pub enum ParserPredicate {
1059 True,
1060 False,
1061 FalseWithMessage {
1063 message: &'static str,
1064 },
1065 Invoke {
1068 value: bool,
1069 },
1070 LookaheadTextEquals {
1071 offset: isize,
1072 text: &'static str,
1073 },
1074 LookaheadNotEquals {
1075 offset: isize,
1076 token_type: i32,
1077 },
1078 TokenPairAdjacent,
1081 ContextChildRuleTextNotEquals {
1086 rule_index: usize,
1087 text: &'static str,
1088 },
1089 LocalIntEquals {
1092 value: i64,
1093 },
1094 LocalIntLessOrEqual {
1097 value: i64,
1098 },
1099 MemberModuloEquals {
1101 member: usize,
1102 modulus: i64,
1103 value: i64,
1104 equals: bool,
1105 },
1106 MemberEquals {
1108 member: usize,
1109 value: i64,
1110 equals: bool,
1111 },
1112}
1113
1114impl ParserPredicate {
1115 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
1121 match self {
1122 Self::True => ir.expr(PExpr::Bool(true)),
1123 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
1124 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
1125 Self::LookaheadTextEquals { offset, text } => {
1126 let token = ir.expr(PExpr::TokenText(offset));
1127 let text = ir.intern(text);
1128 let text = ir.expr(PExpr::Str(text));
1129 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
1130 }
1131 Self::LookaheadNotEquals { offset, token_type } => {
1132 let actual = ir.expr(PExpr::La(offset));
1133 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
1134 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
1135 }
1136 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
1137 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
1138 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
1139 let expected = ir.intern(text);
1140 let expected = ir.expr(PExpr::Str(expected));
1141 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
1142 }
1143 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
1144 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
1145 Self::MemberModuloEquals {
1146 member,
1147 modulus,
1148 value,
1149 equals,
1150 } => {
1151 if modulus == 0 {
1152 return ir.expr(PExpr::Bool(false));
1153 }
1154 let member = ir.expr(PExpr::Member(member));
1155 let modulus = ir.expr(PExpr::Int(modulus));
1156 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
1157 let expected = ir.expr(PExpr::Int(value));
1158 ir.expr(PExpr::Cmp(
1159 if equals { CmpOp::Eq } else { CmpOp::Ne },
1160 actual,
1161 expected,
1162 ))
1163 }
1164 Self::MemberEquals {
1165 member,
1166 value,
1167 equals,
1168 } => {
1169 let actual = ir.expr(PExpr::Member(member));
1170 let expected = ir.expr(PExpr::Int(value));
1171 ir.expr(PExpr::Cmp(
1172 if equals { CmpOp::Eq } else { CmpOp::Ne },
1173 actual,
1174 expected,
1175 ))
1176 }
1177 }
1178 }
1179
1180 #[must_use]
1181 pub const fn failure_message(self) -> Option<&'static str> {
1182 match self {
1183 Self::FalseWithMessage { message } => Some(message),
1184 Self::True
1185 | Self::False
1186 | Self::Invoke { .. }
1187 | Self::LookaheadTextEquals { .. }
1188 | Self::LookaheadNotEquals { .. }
1189 | Self::TokenPairAdjacent
1190 | Self::ContextChildRuleTextNotEquals { .. }
1191 | Self::LocalIntEquals { .. }
1192 | Self::LocalIntLessOrEqual { .. }
1193 | Self::MemberModuloEquals { .. }
1194 | Self::MemberEquals { .. } => None,
1195 }
1196 }
1197}
1198
1199fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
1200 let local = ir.expr(PExpr::LocalArg);
1201 let absent = ir.expr(PExpr::IsNull(local));
1202 let expected = ir.expr(PExpr::Int(value));
1203 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
1204 ir.expr(PExpr::Or([absent, comparison].into()))
1205}
1206
1207#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1220pub enum UnknownSemanticPolicy {
1221 #[default]
1223 AssumeTrue,
1224 AssumeFalse,
1226 Error,
1229}
1230
1231fn apply_unknown_predicate_policy(
1240 policy: UnknownSemanticPolicy,
1241 rule_index: usize,
1242 pred_index: usize,
1243 hits: &mut Vec<(usize, usize)>,
1244) -> bool {
1245 match policy {
1246 UnknownSemanticPolicy::AssumeTrue => true,
1247 UnknownSemanticPolicy::AssumeFalse => false,
1248 UnknownSemanticPolicy::Error => {
1249 let coordinate = (rule_index, pred_index);
1250 if !hits.contains(&coordinate) {
1251 hits.push(coordinate);
1252 }
1253 false
1254 }
1255 }
1256}
1257
1258#[derive(Clone, Debug, Eq, PartialEq)]
1262pub struct ExpectedTokenSet {
1263 symbols: BTreeSet<i32>,
1264}
1265
1266impl ExpectedTokenSet {
1267 #[must_use]
1269 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
1270 expected_symbols_display(&self.symbols, vocabulary)
1271 }
1272}
1273
1274#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1279pub struct BailErrorStrategy;
1280
1281impl BailErrorStrategy {
1282 #[must_use]
1283 pub const fn new() -> Self {
1284 Self
1285 }
1286}
1287
1288#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1290pub enum PredictionMode {
1291 Ll,
1294 Sll,
1297 LlExactAmbigDetection,
1299}
1300
1301#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1307pub struct ParserRuleArg {
1308 pub source_state: usize,
1310 pub rule_index: usize,
1312 pub value: i64,
1314 pub inherit_local: bool,
1316}
1317
1318#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1320pub struct ParserMemberAction {
1321 pub source_state: usize,
1323 pub member: usize,
1325 pub delta: i64,
1327}
1328
1329#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1336pub struct ParserReturnAction {
1337 pub source_state: usize,
1339 pub rule_index: usize,
1341 pub name: &'static str,
1343 pub value: i64,
1345}
1346
1347impl ParserMemberAction {
1348 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1350 let delta = ir.expr(PExpr::Int(self.delta));
1351 ParserSemanticAction {
1352 source_state: self.source_state,
1353 rule_index: usize::MAX,
1354 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
1355 speculative: true,
1356 }
1357 }
1358}
1359
1360impl ParserReturnAction {
1361 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1363 let name = ir.intern(self.name);
1364 let value = ir.expr(PExpr::Int(self.value));
1365 ParserSemanticAction {
1366 source_state: self.source_state,
1367 rule_index: self.rule_index,
1368 stmt: ir.stmt(AStmt::SetReturn(name, value)),
1369 speculative: false,
1370 }
1371 }
1372}
1373
1374#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1376pub struct ParserSemanticPredicate {
1377 pub rule_index: usize,
1379 pub pred_index: usize,
1381 pub expr: ExprId,
1383 pub failure_message: Option<&'static str>,
1385}
1386
1387#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1389pub struct ParserSemanticAction {
1390 pub source_state: usize,
1392 pub rule_index: usize,
1394 pub stmt: StmtId,
1396 pub speculative: bool,
1398}
1399
1400#[derive(Clone, Debug, Default, Eq, PartialEq)]
1407pub struct ParserSemantics {
1408 pub ir: SemIr,
1409 pub predicates: Vec<ParserSemanticPredicate>,
1410 pub actions: Vec<ParserSemanticAction>,
1411}
1412
1413#[derive(Clone, Copy, Debug, Default)]
1415pub struct ParserRuntimeOptions<'a> {
1416 pub init_action_rules: &'a [usize],
1419 pub action_indices: &'a [(usize, usize)],
1425 pub track_alt_numbers: bool,
1427 #[doc(hidden)]
1432 pub track_context_alt_numbers: bool,
1433 pub predicates: &'a [(usize, usize, ParserPredicate)],
1435 pub semantics: Option<&'a ParserSemantics>,
1437 pub rule_args: &'a [ParserRuleArg],
1439 pub member_actions: &'a [ParserMemberAction],
1441 pub return_actions: &'a [ParserReturnAction],
1443 pub unknown_predicate_policy: UnknownSemanticPolicy,
1446}
1447
1448pub trait Parser: Recognizer {
1449 fn build_parse_trees(&self) -> bool;
1452
1453 fn set_build_parse_trees(&mut self, build: bool);
1455
1456 fn number_of_syntax_errors(&self) -> usize {
1459 0
1460 }
1461
1462 fn report_diagnostic_errors(&self) -> bool {
1465 false
1466 }
1467
1468 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1471
1472 fn prediction_mode(&self) -> PredictionMode {
1474 PredictionMode::Ll
1475 }
1476
1477 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1479
1480 fn max_rule_depth(&self) -> Option<usize> {
1483 None
1484 }
1485
1486 fn set_max_rule_depth(&mut self, _depth: Option<usize>) {}
1502
1503 fn add_parse_listener(&mut self, _listener: Box<dyn ParseListener>) {}
1508
1509 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
1512 Vec::new()
1513 }
1514}
1515
1516#[derive(Debug)]
1517struct LeftRecursiveCallerOverlap {
1518 atn_key: SharedAtnCacheKey,
1519 state_number: usize,
1520 symbol: i32,
1521 context_version: usize,
1522 overlaps: bool,
1523}
1524
1525const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1526
1527#[derive(Debug)]
1528pub struct BaseParser<S, H = NoSemanticHooks> {
1529 input: CommonTokenStream<S>,
1530 tree: ParseTreeStorage,
1531 data: RecognizerData,
1532 semantic_hooks: H,
1533 decision_override_generation: usize,
1534 build_parse_trees: bool,
1535 syntax_errors: usize,
1536 report_diagnostic_errors: bool,
1537 prediction_mode: PredictionMode,
1538 prediction_diagnostics: Vec<ParserDiagnostic>,
1539 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1540 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1541 generated_sync_expected: Option<TokenBitSet>,
1542 generated_recovery_error_index: Option<usize>,
1543 generated_recovery_error_states: BTreeSet<isize>,
1544 int_members: MemberEnv,
1545 rule_context_stack: Vec<RuleContextFrame>,
1546 rule_context_version: usize,
1547 left_recursive_caller_overlap_cache:
1548 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1549 pending_invoking_states: Vec<isize>,
1550 precedence_stack: Vec<i32>,
1551 invoked_predicates: Vec<(usize, usize)>,
1555 bail_on_error: bool,
1559 parse_listeners: Vec<ParseListenerSlot>,
1564 parse_listener_abort: Option<AntlrError>,
1569 max_rule_depth: Option<usize>,
1573 rule_depth_error: Option<AntlrError>,
1578 recursion_expansions: usize,
1584 recursion_expansion_marks: Vec<usize>,
1588 unknown_predicate_policy: UnknownSemanticPolicy,
1591 unknown_predicate_hits: Vec<(usize, usize)>,
1594 unhandled_action_hits: Vec<(usize, usize)>,
1599 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1604 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1610 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1615 rule_stop_reach_cache: Vec<Option<bool>>,
1620 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1625 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1631 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1637 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1641 empty_cycle_cache: Vec<Option<bool>>,
1647 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1648 clean_memo_mode: CleanMemoMode,
1651 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1652 clean_memo_probe_samples: usize,
1653 clean_memo_probe_repeats: usize,
1654 clean_memo_sparse_samples: usize,
1655 fast_recognize_scratch: FastRecognizeTopScratch,
1657 fast_outcome_dedup: FastOutcomeDedupScratch,
1659 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1662 fast_first_set_prefilter: bool,
1670 fast_recovery_enabled: bool,
1674 fast_token_nodes_enabled: bool,
1679 fast_track_alt_numbers: bool,
1682 recognition_arena: RecognitionArena,
1686 last_recognition_arena_root: NodeSeqId,
1687 last_recognition_arena_diagnostics: DiagnosticSeqId,
1688}
1689
1690#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1692pub struct GeneratedDiagnosticsCheckpoint {
1693 diagnostics_len: usize,
1694 syntax_errors: usize,
1695 tree: ParseTreeCheckpoint,
1696}
1697
1698#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1701pub struct RecognitionArenaStats {
1702 pub total_nodes: usize,
1703 pub live_nodes: usize,
1704 pub dead_nodes: usize,
1705 pub node_capacity: usize,
1706 pub total_links: usize,
1707 pub live_links: usize,
1708 pub dead_links: usize,
1709 pub link_capacity: usize,
1710 pub total_extras: usize,
1711 pub live_extras: usize,
1712 pub dead_extras: usize,
1713 pub extra_capacity: usize,
1714}
1715
1716#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1717struct RuleContextFrame {
1718 rule_index: usize,
1719 invoking_state: isize,
1720}
1721
1722#[derive(Clone, Debug, Eq, PartialEq)]
1723struct RecognizeOutcome {
1724 index: usize,
1725 consumed_eof: bool,
1726 alt_number: usize,
1727 member_values: MemberEnv,
1728 return_values: BTreeMap<String, i64>,
1729 diagnostics: DiagnosticSeqId,
1730 decisions: Vec<usize>,
1731 actions: Vec<ParserAction>,
1732 nodes: NodeSeqId,
1733}
1734
1735#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1736struct FastRecognizeOutcome {
1737 index: usize,
1738 consumed_eof: bool,
1739 diagnostics: DiagnosticSeqId,
1740 deferred_nodes: FastDeferredNodeId,
1741 nodes: NodeSeqId,
1745}
1746
1747#[derive(Debug, Default)]
1748struct FastRecognizeTopScratch {
1749 visiting: FxHashSet<FastRecognizeKey>,
1750 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1751}
1752
1753impl FastRecognizeTopScratch {
1754 fn prepare(&mut self, memo_capacity: usize) {
1755 self.visiting.clear();
1756 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1757 self.memo.clear();
1758 self.memo.reserve(memo_capacity);
1759 }
1760
1761 fn release_oversized_memo(&mut self) {
1762 self.memo.clear();
1763 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1764 self.memo = FxHashMap::default();
1765 }
1766 }
1767}
1768
1769fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1770 buffered_tokens.saturating_mul(8).clamp(
1771 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1772 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1773 )
1774}
1775
1776#[derive(Debug, Default)]
1777struct FastOutcomeDedupScratch {
1778 dense_words: Vec<u64>,
1779 touched_dense_words: Vec<u32>,
1780 sparse_keys: FxHashSet<(usize, bool)>,
1781}
1782
1783#[repr(transparent)]
1788#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1789struct FastDeferredNodeId(u32);
1790
1791impl FastDeferredNodeId {
1792 const EMPTY: Self = Self(u32::MAX);
1793
1794 const fn is_empty(self) -> bool {
1795 self.0 == Self::EMPTY.0
1796 }
1797}
1798
1799impl Default for FastDeferredNodeId {
1800 fn default() -> Self {
1801 Self::EMPTY
1802 }
1803}
1804
1805#[repr(transparent)]
1806#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1807struct FastDeferredRuleId(u32);
1808
1809#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1811enum FastDeferredNode {
1812 Fragment(NodeSeqId),
1813 Rule(FastDeferredRuleId),
1814 Alternative(u32),
1815 LeftRecursiveBoundary {
1816 rule_index: u32,
1817 },
1818 Concat {
1819 prefix: FastDeferredNodeId,
1820 suffix: FastDeferredNodeId,
1821 },
1822}
1823
1824#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1825struct FastDeferredRule {
1826 rule_index: u32,
1827 invoking_state: i32,
1828 start_index: u32,
1829 stop_index: Option<u32>,
1830 deferred_children: FastDeferredNodeId,
1831 children: NodeSeqId,
1832}
1833
1834#[repr(transparent)]
1835#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1836struct RecognizedNodeId(u32);
1837
1838#[repr(transparent)]
1839#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1840struct NodeSeqId(u32);
1841
1842impl NodeSeqId {
1843 const EMPTY: Self = Self(u32::MAX);
1844
1845 const fn is_empty(self) -> bool {
1846 self.0 == Self::EMPTY.0
1847 }
1848}
1849
1850impl Default for NodeSeqId {
1851 fn default() -> Self {
1852 Self::EMPTY
1853 }
1854}
1855
1856#[repr(transparent)]
1857#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1858struct DiagnosticSeqId(u32);
1859
1860impl DiagnosticSeqId {
1861 const EMPTY: Self = Self(u32::MAX);
1862
1863 const fn is_empty(self) -> bool {
1864 self.0 == Self::EMPTY.0
1865 }
1866}
1867
1868impl Default for DiagnosticSeqId {
1869 fn default() -> Self {
1870 Self::EMPTY
1871 }
1872}
1873
1874#[repr(transparent)]
1875#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1876struct RecognitionExtraId(u32);
1877
1878#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1879struct SeqLink {
1880 head: RecognizedNodeId,
1881 tail: NodeSeqId,
1882}
1883
1884#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1885struct DiagnosticLink {
1886 head: RecognitionExtraId,
1887 tail: DiagnosticSeqId,
1888}
1889
1890struct ArenaRuleSpec {
1891 rule_index: usize,
1892 invoking_state: isize,
1893 alt_number: usize,
1894 start_index: usize,
1895 stop_index: Option<usize>,
1896 return_values: BTreeMap<String, i64>,
1897 children: NodeSeqId,
1898}
1899
1900#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1903enum ArenaRecognizedNode {
1904 Token {
1905 token: TokenId,
1906 },
1907 ErrorToken {
1908 token: TokenId,
1909 },
1910 MissingToken {
1911 extra: RecognitionExtraId,
1912 },
1913 Rule {
1914 rule_index: u32,
1915 invoking_state: i32,
1916 alt_number: u32,
1917 start_index: u32,
1918 stop_index: Option<u32>,
1919 return_values: Option<RecognitionExtraId>,
1920 children: NodeSeqId,
1921 },
1922 LeftRecursiveBoundary {
1926 rule_index: u32,
1927 alt_number: u32,
1928 },
1929}
1930
1931#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1932enum RecognitionExtra {
1933 MissingToken {
1934 token_type: i32,
1935 at_index: u32,
1936 text: String,
1937 },
1938 ReturnValues(BTreeMap<String, i64>),
1939 Diagnostic(ParserDiagnostic),
1940}
1941
1942#[derive(Debug, Default)]
1943struct RecognitionArena {
1944 nodes: Vec<ArenaRecognizedNode>,
1945 seq_links: Vec<SeqLink>,
1946 diagnostic_links: Vec<DiagnosticLink>,
1947 extras: Vec<RecognitionExtra>,
1948 deferred_nodes: Vec<FastDeferredNode>,
1949 deferred_rules: Vec<FastDeferredRule>,
1950}
1951
1952const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1955const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1956const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1957const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1958const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1959const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1960
1961impl RecognitionArena {
1962 fn reset(&mut self) {
1963 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1964 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1965 reset_arena_vec(
1966 &mut self.diagnostic_links,
1967 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1968 );
1969 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1970 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1971 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1972 }
1973
1974 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1975 let id = RecognizedNodeId(
1976 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1977 );
1978 self.nodes.push(node);
1979 id
1980 }
1981
1982 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1983 let id = RecognitionExtraId(
1984 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1985 );
1986 self.extras.push(extra);
1987 id
1988 }
1989
1990 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1991 let id = NodeSeqId(
1992 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1993 );
1994 self.seq_links.push(SeqLink { head, tail });
1995 id
1996 }
1997
1998 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1999 let id = FastDeferredNodeId(
2000 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
2001 );
2002 self.deferred_nodes.push(node);
2003 id
2004 }
2005
2006 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
2007 let id = FastDeferredRuleId(
2008 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
2009 );
2010 self.deferred_rules.push(rule);
2011 id
2012 }
2013
2014 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
2015 if nodes.is_empty() {
2016 FastDeferredNodeId::EMPTY
2017 } else {
2018 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
2019 }
2020 }
2021
2022 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
2023 let rule = self.push_deferred_rule(rule);
2024 self.push_deferred_node(FastDeferredNode::Rule(rule))
2025 }
2026
2027 fn deferred_alternative(&mut self, alt_number: usize) -> FastDeferredNodeId {
2028 self.push_deferred_node(FastDeferredNode::Alternative(
2029 u32::try_from(alt_number).expect("alternative number fits in u32"),
2030 ))
2031 }
2032
2033 fn deferred_left_recursive_boundary(&mut self, rule_index: usize) -> FastDeferredNodeId {
2034 self.push_deferred_node(FastDeferredNode::LeftRecursiveBoundary {
2035 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
2036 })
2037 }
2038
2039 fn concat_deferred_nodes(
2040 &mut self,
2041 prefix: FastDeferredNodeId,
2042 suffix: FastDeferredNodeId,
2043 ) -> FastDeferredNodeId {
2044 if prefix.is_empty() {
2045 return suffix;
2046 }
2047 if suffix.is_empty() {
2048 return prefix;
2049 }
2050 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
2051 }
2052
2053 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
2054 self.deferred_nodes[id.0 as usize]
2055 }
2056
2057 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
2058 self.deferred_rules[id.0 as usize]
2059 }
2060
2061 fn prepend_diagnostic(
2062 &mut self,
2063 tail: DiagnosticSeqId,
2064 diagnostic: ParserDiagnostic,
2065 ) -> DiagnosticSeqId {
2066 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
2067 self.prepend_diagnostic_id(tail, head)
2068 }
2069
2070 fn prepend_diagnostic_id(
2071 &mut self,
2072 tail: DiagnosticSeqId,
2073 head: RecognitionExtraId,
2074 ) -> DiagnosticSeqId {
2075 let id = DiagnosticSeqId(
2076 u32::try_from(self.diagnostic_links.len())
2077 .expect("diagnostic sequence arena fits in u32"),
2078 );
2079 self.diagnostic_links.push(DiagnosticLink { head, tail });
2080 id
2081 }
2082
2083 fn concat_diagnostics(
2084 &mut self,
2085 prefix: DiagnosticSeqId,
2086 mut suffix: DiagnosticSeqId,
2087 ) -> DiagnosticSeqId {
2088 if prefix.is_empty() {
2089 return suffix;
2090 }
2091 if suffix.is_empty() {
2092 return prefix;
2093 }
2094 let mut reversed = DiagnosticSeqId::EMPTY;
2095 let mut cursor = prefix;
2096 while let Some(link) = self.diagnostic_link(cursor) {
2097 reversed = self.prepend_diagnostic_id(reversed, link.head);
2098 cursor = link.tail;
2099 }
2100 while let Some(link) = self.diagnostic_link(reversed) {
2101 suffix = self.prepend_diagnostic_id(suffix, link.head);
2102 reversed = link.tail;
2103 }
2104 suffix
2105 }
2106
2107 #[cfg(test)]
2108 fn diagnostic_sequence(
2109 &mut self,
2110 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
2111 ) -> DiagnosticSeqId {
2112 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
2113 let mut sequence = DiagnosticSeqId::EMPTY;
2114 for diagnostic in diagnostics.into_iter().rev() {
2115 sequence = self.prepend_diagnostic(sequence, diagnostic);
2116 }
2117 sequence
2118 }
2119
2120 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
2121 self.nodes[id.0 as usize]
2122 }
2123
2124 fn set_boundary_alt_number(&mut self, id: RecognizedNodeId, alt_number: u32) {
2125 let ArenaRecognizedNode::LeftRecursiveBoundary {
2126 alt_number: stored, ..
2127 } = &mut self.nodes[id.0 as usize]
2128 else {
2129 unreachable!("deferred boundary must materialize as a boundary node");
2130 };
2131 *stored = alt_number;
2132 }
2133
2134 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
2135 &self.extras[id.0 as usize]
2136 }
2137
2138 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
2139 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
2140 }
2141
2142 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
2143 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
2144 }
2145
2146 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
2147 NodeSeqIter {
2148 arena: self,
2149 cursor: sequence,
2150 }
2151 }
2152
2153 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
2154 DiagnosticSeqIter {
2155 arena: self,
2156 cursor: sequence,
2157 }
2158 }
2159
2160 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
2161 self.diagnostics(sequence).count()
2162 }
2163
2164 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
2165 self.diagnostics(sequence)
2166 .filter(|diagnostic| {
2167 diagnostic.message.starts_with("mismatched input ")
2168 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
2169 })
2170 .count()
2171 }
2172
2173 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
2174 self.diagnostics(left).cmp(self.diagnostics(right))
2175 }
2176
2177 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
2178 self.iter(sequence).count()
2179 }
2180
2181 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
2182 self.iter(sequence).any(|node| match self.node(node) {
2183 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
2184 ArenaRecognizedNode::Rule { children, .. } => {
2185 self.sequence_has_left_recursive_boundary(children)
2186 }
2187 ArenaRecognizedNode::Token { .. }
2188 | ArenaRecognizedNode::ErrorToken { .. }
2189 | ArenaRecognizedNode::MissingToken { .. } => false,
2190 })
2191 }
2192
2193 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
2194 self.iter(sequence).any(|node| {
2195 matches!(
2196 self.node(node),
2197 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
2198 )
2199 })
2200 }
2201
2202 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
2203 self.iter(sequence).any(|node| {
2204 matches!(
2205 self.node(node),
2206 ArenaRecognizedNode::Token { .. }
2207 | ArenaRecognizedNode::ErrorToken { .. }
2208 | ArenaRecognizedNode::MissingToken { .. }
2209 )
2210 })
2211 }
2212
2213 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
2214 match self.node(node) {
2215 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
2216 Some(token.index())
2217 }
2218 ArenaRecognizedNode::MissingToken { extra } => {
2219 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
2220 unreachable!("missing-token node must reference missing-token extra");
2221 };
2222 Some(*at_index as usize)
2223 }
2224 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
2225 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
2226 }
2227 }
2228
2229 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
2230 match self.node(node) {
2231 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
2232 Some(token.index())
2233 }
2234 ArenaRecognizedNode::MissingToken { extra } => {
2235 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
2236 unreachable!("missing-token node must reference missing-token extra");
2237 };
2238 (*at_index as usize).checked_sub(1)
2239 }
2240 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
2241 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
2242 }
2243 }
2244
2245 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
2246 let start = self.node_start_index(node)?;
2247 let stop = self.node_stop_index(node);
2248 Some((start, stop))
2249 }
2250
2251 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
2252 self.iter(sequence)
2253 .find_map(|node| self.node_start_index(node))
2254 }
2255
2256 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
2257 let mut stop = None;
2258 for node in self.iter(sequence) {
2259 if let Some(index) = self.node_stop_index(node) {
2260 stop = Some(index);
2261 }
2262 }
2263 stop
2264 }
2265
2266 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
2267 self.iter(sequence)
2268 .any(|node| self.node_needs_stable_tie(node))
2269 }
2270
2271 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
2272 match self.node(node) {
2273 ArenaRecognizedNode::Token { .. }
2274 | ArenaRecognizedNode::ErrorToken { .. }
2275 | ArenaRecognizedNode::MissingToken { .. } => false,
2276 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
2277 ArenaRecognizedNode::Rule {
2278 rule_index,
2279 children,
2280 ..
2281 } => self.iter(children).any(|child| {
2282 matches!(
2283 self.node(child),
2284 ArenaRecognizedNode::Rule {
2285 rule_index: child_rule,
2286 ..
2287 } if child_rule == rule_index
2288 ) || self.node_needs_stable_tie(child)
2289 }),
2290 }
2291 }
2292
2293 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
2294 loop {
2295 match (self.link(left), self.link(right)) {
2296 (Some(left_link), Some(right_link)) => {
2297 let order = self.compare_nodes(left_link.head, right_link.head);
2298 if order != Ordering::Equal {
2299 return order;
2300 }
2301 left = left_link.tail;
2302 right = right_link.tail;
2303 }
2304 (None, None) => return Ordering::Equal,
2305 (None, Some(_)) => return Ordering::Less,
2306 (Some(_), None) => return Ordering::Greater,
2307 }
2308 }
2309 }
2310
2311 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
2312 let left = self.node(left);
2313 let right = self.node(right);
2314 match (left, right) {
2315 (
2316 ArenaRecognizedNode::Token { token: left },
2317 ArenaRecognizedNode::Token { token: right },
2318 )
2319 | (
2320 ArenaRecognizedNode::ErrorToken { token: left },
2321 ArenaRecognizedNode::ErrorToken { token: right },
2322 ) => left.cmp(&right),
2323 (
2324 ArenaRecognizedNode::MissingToken { extra: left },
2325 ArenaRecognizedNode::MissingToken { extra: right },
2326 ) => self.extra(left).cmp(self.extra(right)),
2327 (
2328 ArenaRecognizedNode::Rule {
2329 rule_index: left_rule,
2330 invoking_state: left_invoking,
2331 alt_number: left_alt,
2332 start_index: left_start,
2333 stop_index: left_stop,
2334 return_values: left_returns,
2335 children: left_children,
2336 },
2337 ArenaRecognizedNode::Rule {
2338 rule_index: right_rule,
2339 invoking_state: right_invoking,
2340 alt_number: right_alt,
2341 start_index: right_start,
2342 stop_index: right_stop,
2343 return_values: right_returns,
2344 children: right_children,
2345 },
2346 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
2347 .cmp(&(
2348 right_rule,
2349 right_invoking,
2350 right_alt,
2351 right_start,
2352 right_stop,
2353 ))
2354 .then_with(|| {
2355 left_returns
2356 .map(|id| self.extra(id))
2357 .cmp(&right_returns.map(|id| self.extra(id)))
2358 })
2359 .then_with(|| self.compare_sequences(left_children, right_children)),
2360 (
2361 ArenaRecognizedNode::LeftRecursiveBoundary {
2362 rule_index: left_rule,
2363 alt_number: left_alt,
2364 },
2365 ArenaRecognizedNode::LeftRecursiveBoundary {
2366 rule_index: right_rule,
2367 alt_number: right_alt,
2368 },
2369 ) => (left_rule, left_alt).cmp(&(right_rule, right_alt)),
2370 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
2371 }
2372 }
2373
2374 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2375 let mut reversed = NodeSeqId::EMPTY;
2376 while let Some(link) = self.link(sequence) {
2377 reversed = self.prepend(reversed, link.head);
2378 sequence = link.tail;
2379 }
2380 reversed
2381 }
2382
2383 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2384 if !self.sequence_has_direct_boundary(sequence) {
2385 return sequence;
2386 }
2387 let mut reversed = NodeSeqId::EMPTY;
2388 while let Some(link) = self.link(sequence) {
2389 match self.node(link.head) {
2390 ArenaRecognizedNode::LeftRecursiveBoundary {
2391 rule_index,
2392 alt_number,
2393 } => {
2394 if !reversed.is_empty() {
2395 let children = self.reverse_sequence(reversed);
2396 let start_index = self.sequence_start_index(children).unwrap_or_default();
2397 let stop_index = self.sequence_stop_index(children);
2398 let rule = self.push_node(ArenaRecognizedNode::Rule {
2399 rule_index,
2400 invoking_state: -1,
2401 alt_number,
2402 start_index: u32::try_from(start_index)
2403 .expect("left-recursive start index fits in u32"),
2404 stop_index: stop_index.map(|index| {
2405 u32::try_from(index).expect("left-recursive stop index fits in u32")
2406 }),
2407 return_values: None,
2408 children,
2409 });
2410 reversed = self.prepend(NodeSeqId::EMPTY, rule);
2411 }
2412 }
2413 _ => {
2414 reversed = self.prepend(reversed, link.head);
2415 }
2416 }
2417 sequence = link.tail;
2418 }
2419 self.reverse_sequence(reversed)
2420 }
2421
2422 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
2423 let mut live_nodes = vec![false; self.nodes.len()];
2424 let mut live_links = vec![false; self.seq_links.len()];
2425 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
2426 let mut live_extras = vec![false; self.extras.len()];
2427 let mut pending = vec![root];
2428 while let Some(mut sequence) = pending.pop() {
2429 while let Some(link) = self.link(sequence) {
2430 let link_index = sequence.0 as usize;
2431 if live_links[link_index] {
2432 break;
2433 }
2434 live_links[link_index] = true;
2435 let node_index = link.head.0 as usize;
2436 if !live_nodes[node_index] {
2437 live_nodes[node_index] = true;
2438 match self.node(link.head) {
2439 ArenaRecognizedNode::MissingToken { extra } => {
2440 live_extras[extra.0 as usize] = true;
2441 }
2442 ArenaRecognizedNode::Rule {
2443 return_values,
2444 children,
2445 ..
2446 } => {
2447 if let Some(extra) = return_values {
2448 live_extras[extra.0 as usize] = true;
2449 }
2450 pending.push(children);
2451 }
2452 ArenaRecognizedNode::Token { .. }
2453 | ArenaRecognizedNode::ErrorToken { .. }
2454 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
2455 }
2456 }
2457 sequence = link.tail;
2458 }
2459 }
2460 let mut diagnostics = diagnostics;
2461 while let Some(link) = self.diagnostic_link(diagnostics) {
2462 let link_index = diagnostics.0 as usize;
2463 if live_diagnostic_links[link_index] {
2464 break;
2465 }
2466 live_diagnostic_links[link_index] = true;
2467 live_extras[link.head.0 as usize] = true;
2468 diagnostics = link.tail;
2469 }
2470 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
2471 let live_link_count = live_links.into_iter().filter(|live| *live).count()
2472 + live_diagnostic_links
2473 .into_iter()
2474 .filter(|live| *live)
2475 .count();
2476 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
2477 let total_links = self.seq_links.len() + self.diagnostic_links.len();
2478 RecognitionArenaStats {
2479 total_nodes: self.nodes.len(),
2480 live_nodes: live_node_count,
2481 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
2482 node_capacity: self.nodes.capacity(),
2483 total_links,
2484 live_links: live_link_count,
2485 dead_links: total_links.saturating_sub(live_link_count),
2486 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
2487 total_extras: self.extras.len(),
2488 live_extras: live_extra_count,
2489 dead_extras: self.extras.len().saturating_sub(live_extra_count),
2490 extra_capacity: self.extras.capacity(),
2491 }
2492 }
2493}
2494
2495fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
2496 if storage.capacity() > max_retained_capacity {
2497 *storage = Vec::new();
2498 } else {
2499 storage.clear();
2500 }
2501}
2502
2503const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2504 match node {
2505 ArenaRecognizedNode::Token { .. } => 0,
2506 ArenaRecognizedNode::ErrorToken { .. } => 1,
2507 ArenaRecognizedNode::MissingToken { .. } => 2,
2508 ArenaRecognizedNode::Rule { .. } => 3,
2509 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2510 }
2511}
2512
2513struct NodeSeqIter<'a> {
2514 arena: &'a RecognitionArena,
2515 cursor: NodeSeqId,
2516}
2517
2518impl Iterator for NodeSeqIter<'_> {
2519 type Item = RecognizedNodeId;
2520
2521 fn next(&mut self) -> Option<Self::Item> {
2522 let link = self.arena.link(self.cursor)?;
2523 self.cursor = link.tail;
2524 Some(link.head)
2525 }
2526}
2527
2528struct DiagnosticSeqIter<'a> {
2529 arena: &'a RecognitionArena,
2530 cursor: DiagnosticSeqId,
2531}
2532
2533impl<'a> Iterator for DiagnosticSeqIter<'a> {
2534 type Item = &'a ParserDiagnostic;
2535
2536 fn next(&mut self) -> Option<Self::Item> {
2537 let link = self.arena.diagnostic_link(self.cursor)?;
2538 self.cursor = link.tail;
2539 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2540 unreachable!("diagnostic link must reference diagnostic extra");
2541 };
2542 Some(diagnostic)
2543 }
2544}
2545
2546#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2547struct ParserDiagnostic {
2548 line: usize,
2549 column: usize,
2550 message: String,
2551 offending: Option<TokenId>,
2555}
2556
2557#[derive(Clone, Debug, Default, Eq, PartialEq)]
2558struct ExpectedTokens {
2559 index: Option<usize>,
2560 symbols: BTreeSet<i32>,
2561 no_viable: Option<NoViableAlternative>,
2562}
2563
2564#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2565struct NoViableAlternative {
2566 start_index: usize,
2567 error_index: usize,
2568}
2569
2570impl ExpectedTokens {
2571 fn record_transition(
2574 &mut self,
2575 index: usize,
2576 transition: ParserTransition<'_>,
2577 max_token_type: i32,
2578 ) {
2579 let symbols = transition_expected_symbols(transition, max_token_type);
2580 match self.index {
2581 Some(current) if index < current => {}
2582 Some(current) if index == current => self.symbols.extend(symbols),
2583 _ => {
2584 self.index = Some(index);
2585 self.symbols = symbols;
2586 }
2587 }
2588 }
2589
2590 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2593 match self.no_viable {
2594 Some(current) if error_index < current.error_index => {}
2595 _ => {
2596 self.no_viable = Some(NoViableAlternative {
2597 start_index,
2598 error_index,
2599 });
2600 }
2601 }
2602 }
2603}
2604
2605#[derive(Clone, Debug, Default, Eq, PartialEq)]
2612struct TokenBitSet {
2613 words: Vec<u64>,
2614}
2615
2616impl TokenBitSet {
2617 fn insert(&mut self, symbol: i32) {
2618 let Some(slot) = token_bit_slot(symbol) else {
2619 return;
2620 };
2621 let word = slot / u64::BITS as usize;
2622 if word >= self.words.len() {
2623 self.words.resize(word + 1, 0);
2624 }
2625 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2626 }
2627
2628 fn extend_range(&mut self, start: i32, stop: i32) {
2629 let (start, stop) = if start <= stop {
2630 (start, stop)
2631 } else {
2632 (stop, start)
2633 };
2634 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2635 self.insert(TOKEN_EOF);
2636 }
2637 let positive_start = start.max(1);
2638 if positive_start > stop {
2639 return;
2640 }
2641 let Some(start_slot) = token_bit_slot(positive_start) else {
2642 return;
2643 };
2644 let Some(stop_slot) = token_bit_slot(stop) else {
2645 return;
2646 };
2647 self.extend_slot_range(start_slot, stop_slot);
2648 }
2649
2650 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2651 if start_slot > stop_slot {
2652 return;
2653 }
2654 let start_word = start_slot / u64::BITS as usize;
2655 let stop_word = stop_slot / u64::BITS as usize;
2656 if stop_word >= self.words.len() {
2657 self.words.resize(stop_word + 1, 0);
2658 }
2659 let start_offset = start_slot % u64::BITS as usize;
2660 let stop_offset = stop_slot % u64::BITS as usize;
2661 if start_word == stop_word {
2662 self.words[start_word] |=
2663 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2664 return;
2665 }
2666 self.words[start_word] |= !0_u64 << start_offset;
2667 for word in &mut self.words[(start_word + 1)..stop_word] {
2668 *word = !0_u64;
2669 }
2670 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2671 }
2672
2673 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2674 for symbol in symbols {
2675 self.insert(symbol);
2676 }
2677 }
2678
2679 fn extend_from(&mut self, other: &Self) {
2680 if other.words.len() > self.words.len() {
2681 self.words.resize(other.words.len(), 0);
2682 }
2683 for (left, right) in self.words.iter_mut().zip(&other.words) {
2684 *left |= *right;
2685 }
2686 }
2687
2688 fn contains(&self, symbol: i32) -> bool {
2689 let Some(slot) = token_bit_slot(symbol) else {
2690 return false;
2691 };
2692 let word = slot / u64::BITS as usize;
2693 self.words
2694 .get(word)
2695 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2696 }
2697
2698 fn is_empty(&self) -> bool {
2699 self.words.iter().all(|word| *word == 0)
2700 }
2701
2702 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2703 self.words
2704 .iter()
2705 .copied()
2706 .enumerate()
2707 .flat_map(|(word_index, mut bits)| {
2708 std::iter::from_fn(move || {
2709 while bits != 0 {
2710 let bit = bits.trailing_zeros() as usize;
2711 bits &= bits - 1;
2712 if let Some(symbol) =
2713 token_bit_symbol(word_index * u64::BITS as usize + bit)
2714 {
2715 return Some(symbol);
2716 }
2717 }
2718 None
2719 })
2720 })
2721 }
2722
2723 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2724 target.extend(self.symbols());
2725 }
2726
2727 fn to_btree_set(&self) -> BTreeSet<i32> {
2728 let mut out = BTreeSet::new();
2729 self.extend_btree_set(&mut out);
2730 out
2731 }
2732}
2733
2734fn token_bit_slot(symbol: i32) -> Option<usize> {
2735 if symbol == TOKEN_EOF {
2736 Some(0)
2737 } else if symbol > 0 {
2738 usize::try_from(symbol).ok()
2739 } else {
2740 None
2741 }
2742}
2743
2744fn token_bit_symbol(slot: usize) -> Option<i32> {
2745 if slot == 0 {
2746 Some(TOKEN_EOF)
2747 } else {
2748 i32::try_from(slot).ok()
2749 }
2750}
2751
2752fn transition_expected_symbols(
2755 transition: ParserTransition<'_>,
2756 max_token_type: i32,
2757) -> BTreeSet<i32> {
2758 let mut symbols = BTreeSet::new();
2759 match &transition.data() {
2760 Transition::Atom { label, .. } => {
2761 symbols.insert(*label);
2762 }
2763 Transition::Range { start, stop, .. } => {
2764 symbols.extend(*start..=*stop);
2765 }
2766 Transition::Set { set, .. } => {
2767 for (start, stop) in set.ranges() {
2768 symbols.extend(start..=stop);
2769 }
2770 }
2771 Transition::NotSet { set, .. } => {
2772 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2773 }
2774 Transition::Wildcard { .. } => {
2775 symbols.extend(1..=max_token_type);
2776 }
2777 Transition::Epsilon { .. }
2778 | Transition::Rule { .. }
2779 | Transition::Predicate { .. }
2780 | Transition::Action { .. }
2781 | Transition::Precedence { .. } => {}
2782 }
2783 symbols
2784}
2785
2786fn transition_expected_token_set(
2787 transition: ParserTransition<'_>,
2788 max_token_type: i32,
2789) -> TokenBitSet {
2790 let mut symbols = TokenBitSet::default();
2791 match &transition.data() {
2792 Transition::Atom { label, .. } => {
2793 symbols.insert(*label);
2794 }
2795 Transition::Range { start, stop, .. } => {
2796 symbols.extend_range(*start, *stop);
2797 }
2798 Transition::Set { set, .. } => {
2799 for (start, stop) in set.ranges() {
2800 symbols.extend_range(start, stop);
2801 }
2802 }
2803 Transition::NotSet { set, .. } => {
2804 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2805 }
2806 Transition::Wildcard { .. } => {
2807 symbols.extend_range(1, max_token_type);
2808 }
2809 Transition::Epsilon { .. }
2810 | Transition::Rule { .. }
2811 | Transition::Predicate { .. }
2812 | Transition::Action { .. }
2813 | Transition::Precedence { .. } => {}
2814 }
2815 symbols
2816}
2817
2818fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2822 let mut symbols = BTreeSet::new();
2823 let mut stack = vec![state_number];
2824 let mut visited = BTreeSet::new();
2825 while let Some(current) = stack.pop() {
2826 if !visited.insert(current) {
2827 continue;
2828 }
2829 let Some(state) = atn.state(current) else {
2830 continue;
2831 };
2832 for transition in &state.transitions() {
2833 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2834 if transition_symbols.is_empty() {
2835 if transition.is_epsilon() {
2836 stack.push(transition.target());
2837 }
2838 } else {
2839 symbols.extend(transition_symbols);
2840 }
2841 }
2842 }
2843 symbols
2844}
2845
2846fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2847 let mut symbols = TokenBitSet::default();
2848 let mut stack = vec![state_number];
2849 let mut visited = BTreeSet::new();
2850 while let Some(current) = stack.pop() {
2851 if !visited.insert(current) {
2852 continue;
2853 }
2854 let Some(state) = atn.state(current) else {
2855 continue;
2856 };
2857 for transition in &state.transitions() {
2858 let transition_symbols =
2859 transition_expected_token_set(transition, atn.max_token_type());
2860 if transition_symbols.is_empty() {
2861 if transition.is_epsilon() {
2862 stack.push(transition.target());
2863 }
2864 } else {
2865 symbols.extend_from(&transition_symbols);
2866 }
2867 }
2868 }
2869 symbols
2870}
2871
2872fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2873 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2874 return false;
2875 };
2876 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2877 return false;
2878 };
2879 epsilon_reaches_state(atn, state_number, stop_state)
2880}
2881
2882fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2883 let mut stack = vec![start];
2884 let mut visited = BTreeSet::new();
2885 while let Some(current) = stack.pop() {
2886 if current == target {
2887 return true;
2888 }
2889 if !visited.insert(current) {
2890 continue;
2891 }
2892 let Some(state) = atn.state(current) else {
2893 continue;
2894 };
2895 stack.extend(
2896 state
2897 .transitions()
2898 .iter()
2899 .filter(|transition| transition.is_epsilon())
2900 .map(ParserTransition::target),
2901 );
2902 }
2903 false
2904}
2905
2906#[derive(Clone, Debug, Default, Eq, PartialEq)]
2913struct FirstSet {
2914 symbols: TokenBitSet,
2915 nullable: bool,
2916}
2917
2918type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2925
2926type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2933
2934#[derive(Debug, Default)]
2935struct LeftRecursiveOperatorLookahead {
2936 single_token: TokenBitSet,
2940 multi_token_prefix: TokenBitSet,
2945 predicate_dependent: TokenBitSet,
2946}
2947
2948#[derive(Default)]
2949struct SharedAtnCache {
2950 first_set: FirstSetCache,
2951 decision_lookahead: DecisionLookaheadCache,
2952 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2953 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2954 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2955 rule_stop_reach: FxHashMap<usize, bool>,
2956 observable_action_transitions: Option<bool>,
2957 predicate_transitions: Option<bool>,
2958}
2959
2960thread_local! {
2961 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2962 RefCell::new(FxHashMap::default());
2963}
2964
2965#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2976struct SharedAtnCacheKey {
2977 atn: usize,
2978 states: usize,
2979 state_count: usize,
2980 max_token_type: i32,
2981}
2982
2983impl SharedAtnCacheKey {
2984 fn for_atn(atn: &Atn) -> Self {
2985 let (states, state_count) = atn.storage_identity();
2986 Self {
2987 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2988 states,
2989 state_count,
2990 max_token_type: atn.max_token_type(),
2991 }
2992 }
2993}
2994
2995fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2996 SHARED_ATN_CACHES.with(|cell| {
2997 let key = SharedAtnCacheKey::for_atn(atn);
2998 let mut map = cell.borrow_mut();
2999 let cache = map.entry(key).or_default();
3000 f(&mut cache.first_set)
3001 })
3002}
3003
3004fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
3005 SHARED_ATN_CACHES.with(|cell| {
3006 let key = SharedAtnCacheKey::for_atn(atn);
3007 let mut map = cell.borrow_mut();
3008 let cache = map.entry(key).or_default();
3009 f(cache)
3010 })
3011}
3012
3013#[derive(Debug, Default)]
3022struct DecisionLookahead {
3023 transitions: Vec<TransitionLookSet>,
3024}
3025
3026#[derive(Clone, Debug, Default)]
3033struct TransitionLookSet {
3034 symbols: TokenBitSet,
3035 nullable: bool,
3036}
3037
3038struct FirstSetCtx<'a> {
3042 cache: &'a mut FirstSetCache,
3043 in_progress: BTreeSet<(usize, usize)>,
3044 hit_cycle: bool,
3045}
3046
3047fn rule_first_set(
3056 atn: &Atn,
3057 target: usize,
3058 rule_stop_state: usize,
3059 cache: &mut FirstSetCache,
3060) -> Rc<FirstSet> {
3061 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
3062 return Rc::clone(cached);
3063 }
3064 let mut ctx = FirstSetCtx {
3065 cache,
3066 in_progress: BTreeSet::new(),
3067 hit_cycle: false,
3068 };
3069 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
3070}
3071
3072fn rule_first_set_cached(
3073 atn: &Atn,
3074 target: usize,
3075 rule_stop_state: usize,
3076 ctx: &mut FirstSetCtx<'_>,
3077) -> Rc<FirstSet> {
3078 let key = (target, rule_stop_state);
3079 if let Some(cached) = ctx.cache.get(&key) {
3080 return Rc::clone(cached);
3081 }
3082 if !ctx.in_progress.insert(key) {
3083 return Rc::new(FirstSet::default());
3087 }
3088 let saved_hit_cycle = ctx.hit_cycle;
3089 ctx.hit_cycle = false;
3090 let mut first = FirstSet::default();
3091 let mut visited = BTreeSet::new();
3092 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
3093 ctx.in_progress.remove(&key);
3094 let entry = Rc::new(first);
3095 if !ctx.hit_cycle {
3096 ctx.cache.insert(key, Rc::clone(&entry));
3097 }
3098 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3099 entry
3100}
3101
3102fn transition_first_set(
3106 atn: &Atn,
3107 transition: ParserTransition<'_>,
3108 rule_stop_state: usize,
3109 cache: &mut FirstSetCache,
3110) -> TransitionLookSet {
3111 match &transition.data() {
3112 Transition::Atom { label, .. } => {
3113 let mut symbols = TokenBitSet::default();
3114 symbols.insert(*label);
3115 TransitionLookSet {
3116 symbols,
3117 nullable: false,
3118 }
3119 }
3120 Transition::Range { start, stop, .. } => {
3121 let mut symbols = TokenBitSet::default();
3122 symbols.extend_range(*start, *stop);
3123 TransitionLookSet {
3124 symbols,
3125 nullable: false,
3126 }
3127 }
3128 Transition::Set { set, .. } => {
3129 let mut symbols = TokenBitSet::default();
3130 for (start, stop) in set.ranges() {
3131 symbols.extend_range(start, stop);
3132 }
3133 TransitionLookSet {
3134 symbols,
3135 nullable: false,
3136 }
3137 }
3138 Transition::NotSet { set, .. } => {
3139 let max = atn.max_token_type();
3140 let mut symbols = TokenBitSet::default();
3141 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
3142 TransitionLookSet {
3143 symbols,
3144 nullable: false,
3145 }
3146 }
3147 Transition::Wildcard { .. } => {
3148 let mut symbols = TokenBitSet::default();
3149 symbols.extend_range(1, atn.max_token_type());
3150 TransitionLookSet {
3151 symbols,
3152 nullable: false,
3153 }
3154 }
3155 Transition::Epsilon { target }
3156 | Transition::Action { target, .. }
3157 | Transition::Predicate { target, .. }
3158 | Transition::Precedence { target, .. } => {
3159 let first = rule_first_set(atn, *target, rule_stop_state, cache);
3162 TransitionLookSet {
3163 symbols: first.symbols.clone(),
3164 nullable: first.nullable,
3165 }
3166 }
3167 Transition::Rule {
3168 target,
3169 rule_index,
3170 follow_state,
3171 ..
3172 } => {
3173 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3174 return TransitionLookSet::default();
3175 };
3176 let child = rule_first_set(atn, *target, child_stop, cache);
3177 let mut symbols = child.symbols.clone();
3178 let nullable = if child.nullable {
3179 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
3180 symbols.extend_from(&follow.symbols);
3181 follow.nullable
3182 } else {
3183 false
3184 };
3185 TransitionLookSet { symbols, nullable }
3186 }
3187 }
3188}
3189
3190fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
3211 let mut chosen: Option<usize> = None;
3212 for (index, transition) in entry.transitions.iter().enumerate() {
3213 if transition.nullable {
3214 return None;
3215 }
3216 if transition.symbols.contains(symbol) {
3217 if chosen.is_some() {
3218 return None;
3219 }
3220 chosen = Some(index);
3221 }
3222 }
3223 chosen
3224}
3225
3226fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
3235 let mut matching_non_nullable_alt = None;
3236 let mut nullable_alt = None;
3237 for (index, transition) in entry.transitions.iter().enumerate() {
3238 if transition.nullable {
3239 if nullable_alt.is_some() {
3240 return None;
3241 }
3242 nullable_alt = Some(index);
3243 }
3244 if transition.symbols.contains(symbol) {
3245 if transition.nullable {
3246 continue;
3247 }
3248 if matching_non_nullable_alt.is_some() {
3249 return None;
3250 }
3251 matching_non_nullable_alt = Some(index);
3252 }
3253 }
3254 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
3255 return None;
3256 }
3257 if non_greedy {
3258 nullable_alt.or(matching_non_nullable_alt)
3259 } else {
3260 matching_non_nullable_alt.or(nullable_alt)
3261 }
3262}
3263
3264fn should_skip_via_lookahead(
3265 transition_kind: ParserTransitionKind,
3266 transition_index: usize,
3267 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
3268 index: usize,
3269 record_expected: bool,
3270 expected: &mut ExpectedTokens,
3271) -> bool {
3272 let prune_non_consuming = matches!(
3273 transition_kind,
3274 ParserTransitionKind::Epsilon
3275 | ParserTransitionKind::Action
3276 | ParserTransitionKind::Predicate
3277 | ParserTransitionKind::Rule
3278 | ParserTransitionKind::Precedence
3279 );
3280 if !prune_non_consuming {
3281 return false;
3282 }
3283 let Some((symbol, entry)) = lookahead_filter else {
3284 return false;
3285 };
3286 let Some(set) = entry.transitions.get(transition_index) else {
3287 return false;
3288 };
3289 if set.symbols.contains(*symbol) || set.nullable {
3290 return false;
3291 }
3292 if record_expected && !set.symbols.is_empty() {
3293 record_pruned_transition_expected(set, index, expected);
3294 }
3295 true
3296}
3297
3298fn should_skip_rule_via_first_set(
3299 first: &FirstSet,
3300 symbol: i32,
3301 record_expected: bool,
3302 index: usize,
3303 expected: &mut ExpectedTokens,
3304) -> bool {
3305 if first.nullable || first.symbols.contains(symbol) {
3306 return false;
3307 }
3308 if record_expected && !first.symbols.is_empty() {
3309 record_token_bit_expected(&first.symbols, index, expected);
3310 }
3311 true
3312}
3313
3314fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
3315 match expected.index {
3316 Some(current) if index < current => {}
3317 Some(current) if index == current => {
3318 symbols.extend_btree_set(&mut expected.symbols);
3319 }
3320 _ => {
3321 expected.index = Some(index);
3322 expected.symbols = symbols.to_btree_set();
3323 }
3324 }
3325}
3326
3327fn record_pruned_transition_expected(
3329 set: &TransitionLookSet,
3330 index: usize,
3331 expected: &mut ExpectedTokens,
3332) {
3333 match expected.index {
3334 Some(current) if index < current => {}
3335 Some(current) if index == current => {
3336 set.symbols.extend_btree_set(&mut expected.symbols);
3337 }
3338 _ => {
3339 expected.index = Some(index);
3340 expected.symbols = set.symbols.to_btree_set();
3341 }
3342 }
3343}
3344
3345fn rule_first_set_inner(
3346 atn: &Atn,
3347 state_number: usize,
3348 rule_stop_state: usize,
3349 ctx: &mut FirstSetCtx<'_>,
3350 visited: &mut BTreeSet<usize>,
3351 first: &mut FirstSet,
3352) {
3353 if !visited.insert(state_number) {
3354 return;
3355 }
3356 if state_number == rule_stop_state {
3357 first.nullable = true;
3358 return;
3359 }
3360 let Some(state) = atn.state(state_number) else {
3361 return;
3362 };
3363 for transition in &state.transitions() {
3364 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3365 if !transition_symbols.is_empty() {
3366 first.symbols.extend_iter(transition_symbols);
3367 continue;
3368 }
3369 match &transition.data() {
3370 Transition::Epsilon { target }
3371 | Transition::Action { target, .. }
3372 | Transition::Predicate { target, .. }
3373 | Transition::Precedence { target, .. } => {
3374 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
3375 }
3376 Transition::Rule {
3377 target,
3378 rule_index,
3379 follow_state,
3380 ..
3381 } => {
3382 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3383 continue;
3384 };
3385 let child_key = (*target, child_stop);
3386 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
3387 ctx.hit_cycle = true;
3388 }
3389 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
3390 first.symbols.extend_from(&child.symbols);
3391 if child.nullable {
3392 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
3393 }
3394 }
3395 Transition::Atom { .. }
3396 | Transition::Range { .. }
3397 | Transition::Set { .. }
3398 | Transition::NotSet { .. }
3399 | Transition::Wildcard { .. } => {}
3400 }
3401 }
3402}
3403
3404fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
3407 let mut symbols = BTreeSet::new();
3408 state_sync_symbols_inner(
3409 atn,
3410 state_number,
3411 stop_state,
3412 &mut BTreeSet::new(),
3413 &mut symbols,
3414 );
3415 symbols
3416}
3417
3418fn state_sync_symbols_inner(
3421 atn: &Atn,
3422 state_number: usize,
3423 stop_state: usize,
3424 visited: &mut BTreeSet<usize>,
3425 symbols: &mut BTreeSet<i32>,
3426) {
3427 if !visited.insert(state_number) {
3428 return;
3429 }
3430 if state_number == stop_state {
3431 symbols.insert(TOKEN_EOF);
3432 return;
3433 }
3434 let Some(state) = atn.state(state_number) else {
3435 return;
3436 };
3437 for transition in &state.transitions() {
3438 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3439 if transition_symbols.is_empty() {
3440 match &transition.data() {
3441 Transition::Rule { target, .. }
3442 | Transition::Epsilon { target }
3443 | Transition::Action { target, .. }
3444 | Transition::Predicate { target, .. }
3445 | Transition::Precedence { target, .. } => {
3446 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
3447 }
3448 Transition::Atom { .. }
3449 | Transition::Range { .. }
3450 | Transition::Set { .. }
3451 | Transition::NotSet { .. }
3452 | Transition::Wildcard { .. } => {}
3453 }
3454 } else {
3455 symbols.extend(transition_symbols);
3456 }
3457 }
3458}
3459
3460#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
3461struct OperatorSymbolReachability {
3462 single_token: bool,
3464 multi_token: bool,
3466 predicate_dependent: bool,
3468}
3469
3470impl OperatorSymbolReachability {
3471 const ADAPTIVE_FALLBACK: Self = Self {
3472 single_token: false,
3473 multi_token: false,
3474 predicate_dependent: true,
3475 };
3476
3477 const fn single_token(predicate_dependent: bool) -> Self {
3478 if predicate_dependent {
3479 Self {
3480 single_token: false,
3481 multi_token: false,
3482 predicate_dependent: true,
3483 }
3484 } else {
3485 Self {
3486 single_token: true,
3487 multi_token: false,
3488 predicate_dependent: false,
3489 }
3490 }
3491 }
3492
3493 const fn multi_token(predicate_dependent: bool) -> Self {
3494 if predicate_dependent {
3495 Self {
3496 single_token: false,
3497 multi_token: false,
3498 predicate_dependent: true,
3499 }
3500 } else {
3501 Self {
3502 single_token: false,
3503 multi_token: true,
3504 predicate_dependent: false,
3505 }
3506 }
3507 }
3508
3509 const fn union(self, other: Self) -> Self {
3510 Self {
3511 single_token: self.single_token || other.single_token,
3512 multi_token: self.multi_token || other.multi_token,
3513 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3514 }
3515 }
3516}
3517
3518#[derive(Clone, Copy)]
3519struct OperatorReachabilityRequest {
3520 symbol: i32,
3521 precedence: i32,
3522 predicate_dependent: bool,
3523 operator_rule_index: usize,
3524}
3525
3526#[derive(Clone, Copy, Debug)]
3527struct OperatorRuleContinuation {
3528 stop_state: usize,
3529 follow_state: usize,
3530 return_precedence: i32,
3531}
3532
3533struct NullablePrecedenceCtx {
3534 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3535 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3536 hit_cycle: bool,
3537}
3538
3539fn state_is_nullable_with_precedence(
3540 atn: &Atn,
3541 state_number: usize,
3542 stop_state_number: usize,
3543 precedence: i32,
3544 allow_predicates: bool,
3545 ctx: &mut NullablePrecedenceCtx,
3546) -> bool {
3547 let saved_hit_cycle = ctx.hit_cycle;
3548 ctx.hit_cycle = false;
3549 let nullable = state_is_nullable_with_precedence_cached(
3550 atn,
3551 state_number,
3552 stop_state_number,
3553 precedence,
3554 allow_predicates,
3555 ctx,
3556 );
3557 ctx.hit_cycle = saved_hit_cycle;
3558 nullable
3559}
3560
3561fn state_is_nullable_with_precedence_cached(
3562 atn: &Atn,
3563 state_number: usize,
3564 stop_state_number: usize,
3565 precedence: i32,
3566 allow_predicates: bool,
3567 ctx: &mut NullablePrecedenceCtx,
3568) -> bool {
3569 if state_number == stop_state_number {
3570 return true;
3571 }
3572 let key = (
3573 state_number,
3574 stop_state_number,
3575 precedence,
3576 allow_predicates,
3577 );
3578 if let Some(cached) = ctx.cache.get(&key) {
3579 return *cached;
3580 }
3581 if !ctx.in_progress.insert(key) {
3582 ctx.hit_cycle = true;
3583 return false;
3584 }
3585 let saved_hit_cycle = ctx.hit_cycle;
3586 ctx.hit_cycle = false;
3587 let nullable = atn.state(state_number).is_some_and(|state| {
3588 state
3589 .transitions()
3590 .iter()
3591 .any(|transition| match &transition.data() {
3592 Transition::Rule {
3593 target,
3594 rule_index,
3595 follow_state,
3596 precedence: rule_precedence,
3597 } => {
3598 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3599 return false;
3600 };
3601 state_is_nullable_with_precedence_cached(
3602 atn,
3603 *target,
3604 child_stop,
3605 *rule_precedence,
3606 allow_predicates,
3607 ctx,
3608 ) && state_is_nullable_with_precedence_cached(
3609 atn,
3610 *follow_state,
3611 stop_state_number,
3612 precedence,
3613 allow_predicates,
3614 ctx,
3615 )
3616 }
3617 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3618 state_is_nullable_with_precedence_cached(
3619 atn,
3620 *target,
3621 stop_state_number,
3622 precedence,
3623 allow_predicates,
3624 ctx,
3625 )
3626 }
3627 Transition::Predicate { target, .. } if allow_predicates => {
3628 state_is_nullable_with_precedence_cached(
3629 atn,
3630 *target,
3631 stop_state_number,
3632 precedence,
3633 allow_predicates,
3634 ctx,
3635 )
3636 }
3637 Transition::Precedence {
3638 target,
3639 precedence: transition_precedence,
3640 } if *transition_precedence >= precedence => {
3641 state_is_nullable_with_precedence_cached(
3642 atn,
3643 *target,
3644 stop_state_number,
3645 precedence,
3646 allow_predicates,
3647 ctx,
3648 )
3649 }
3650 Transition::Atom { .. }
3651 | Transition::Range { .. }
3652 | Transition::Set { .. }
3653 | Transition::NotSet { .. }
3654 | Transition::Wildcard { .. }
3655 | Transition::Predicate { .. }
3656 | Transition::Precedence { .. } => false,
3657 })
3658 });
3659 ctx.in_progress.remove(&key);
3660 if !ctx.hit_cycle {
3661 ctx.cache.insert(key, nullable);
3662 }
3663 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3664 nullable
3665}
3666
3667fn state_operator_token_prefix_reachability(
3669 atn: &Atn,
3670 state_number: usize,
3671 request: OperatorReachabilityRequest,
3672 continuations: &[OperatorRuleContinuation],
3673 visited: &mut BTreeSet<(usize, i32, bool)>,
3674) -> OperatorSymbolReachability {
3675 let key = (
3676 state_number,
3677 request.precedence,
3678 request.predicate_dependent,
3679 );
3680 if !visited.insert(key) {
3681 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3685 }
3686 if let Some((continuation, remaining)) = continuations.split_last()
3687 && state_number == continuation.stop_state
3688 {
3689 let result = state_operator_token_prefix_reachability(
3690 atn,
3691 continuation.follow_state,
3692 OperatorReachabilityRequest {
3693 precedence: continuation.return_precedence,
3694 ..request
3695 },
3696 remaining,
3697 visited,
3698 );
3699 visited.remove(&key);
3700 return result;
3701 }
3702 let Some(state) = atn.state(state_number) else {
3703 visited.remove(&key);
3704 return OperatorSymbolReachability::default();
3705 };
3706 let completes_operator = match state.kind() {
3707 AtnStateKind::RuleStop => continuations.is_empty(),
3708 AtnStateKind::StarLoopBack
3709 | AtnStateKind::StarLoopEntry
3710 | AtnStateKind::PlusLoopBack
3711 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3712 _ => false,
3713 };
3714 if completes_operator {
3715 visited.remove(&key);
3716 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3717 }
3718 let mut reachability = OperatorSymbolReachability::default();
3719 for transition in &state.transitions() {
3720 let transition_reachability = match &transition.data() {
3721 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3722 OperatorSymbolReachability::single_token(request.predicate_dependent)
3723 }
3724 Transition::Rule {
3725 target,
3726 rule_index,
3727 follow_state,
3728 precedence: rule_precedence,
3729 } => {
3730 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3731 continue;
3732 };
3733 let mut nested = continuations.to_vec();
3734 nested.push(OperatorRuleContinuation {
3735 stop_state: child_stop,
3736 follow_state: *follow_state,
3737 return_precedence: request.precedence,
3738 });
3739 state_operator_token_prefix_reachability(
3740 atn,
3741 *target,
3742 OperatorReachabilityRequest {
3743 precedence: *rule_precedence,
3744 ..request
3745 },
3746 &nested,
3747 visited,
3748 )
3749 }
3750 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3751 state_operator_token_prefix_reachability(
3752 atn,
3753 *target,
3754 request,
3755 continuations,
3756 visited,
3757 )
3758 }
3759 Transition::Precedence {
3760 target,
3761 precedence: transition_precedence,
3762 } => {
3763 if *transition_precedence < request.precedence {
3764 OperatorSymbolReachability::default()
3765 } else {
3766 state_operator_token_prefix_reachability(
3767 atn,
3768 *target,
3769 request,
3770 continuations,
3771 visited,
3772 )
3773 }
3774 }
3775 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3776 atn,
3777 *target,
3778 OperatorReachabilityRequest {
3779 predicate_dependent: true,
3780 ..request
3781 },
3782 continuations,
3783 visited,
3784 ),
3785 Transition::Atom { .. }
3786 | Transition::Range { .. }
3787 | Transition::Set { .. }
3788 | Transition::NotSet { .. }
3789 | Transition::Wildcard { .. } => {
3790 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3791 }
3792 };
3793 reachability = reachability.union(transition_reachability);
3794 }
3795 visited.remove(&key);
3796 reachability
3797}
3798
3799fn state_can_reach_symbol_with_precedence(
3800 atn: &Atn,
3801 state_number: usize,
3802 request: OperatorReachabilityRequest,
3803 nullable_ctx: &mut NullablePrecedenceCtx,
3804 continuations: &mut Vec<OperatorRuleContinuation>,
3805 visited: &mut BTreeSet<(usize, i32, bool)>,
3806) -> OperatorSymbolReachability {
3807 let key = (
3808 state_number,
3809 request.precedence,
3810 request.predicate_dependent,
3811 );
3812 if !visited.insert(key) {
3813 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3814 }
3815 let Some(state) = atn.state(state_number) else {
3816 visited.remove(&key);
3817 return OperatorSymbolReachability::default();
3818 };
3819 let mut reachability = OperatorSymbolReachability::default();
3820 for transition in &state.transitions() {
3821 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3822 reachability = reachability.union(state_operator_token_prefix_reachability(
3823 atn,
3824 transition.target(),
3825 request,
3826 continuations,
3827 &mut BTreeSet::new(),
3828 ));
3829 continue;
3830 }
3831 let transition_reachability = match &transition.data() {
3832 Transition::Rule {
3833 target,
3834 rule_index,
3835 follow_state,
3836 precedence: rule_precedence,
3837 } => {
3838 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3839 continue;
3840 };
3841 continuations.push(OperatorRuleContinuation {
3842 stop_state: child_stop,
3843 follow_state: *follow_state,
3844 return_precedence: request.precedence,
3845 });
3846 let mut result = state_can_reach_symbol_with_precedence(
3847 atn,
3848 *target,
3849 OperatorReachabilityRequest {
3850 precedence: *rule_precedence,
3851 ..request
3852 },
3853 nullable_ctx,
3854 continuations,
3855 visited,
3856 );
3857 continuations.pop();
3858 if state_is_nullable_with_precedence(
3859 atn,
3860 *target,
3861 child_stop,
3862 *rule_precedence,
3863 true,
3864 nullable_ctx,
3865 ) {
3866 let child_predicate_dependent = request.predicate_dependent
3867 || !state_is_nullable_with_precedence(
3868 atn,
3869 *target,
3870 child_stop,
3871 *rule_precedence,
3872 false,
3873 nullable_ctx,
3874 );
3875 result = result.union(state_can_reach_symbol_with_precedence(
3876 atn,
3877 *follow_state,
3878 OperatorReachabilityRequest {
3879 predicate_dependent: child_predicate_dependent,
3880 ..request
3881 },
3882 nullable_ctx,
3883 continuations,
3884 visited,
3885 ));
3886 }
3887 result
3888 }
3889 Transition::Epsilon { target }
3890 | Transition::Action { target, .. }
3891 | Transition::Precedence { target, .. } => {
3892 if matches!(
3893 &transition.data(),
3894 Transition::Precedence {
3895 precedence: transition_precedence,
3896 ..
3897 } if *transition_precedence < request.precedence
3898 ) {
3899 continue;
3900 }
3901 state_can_reach_symbol_with_precedence(
3902 atn,
3903 *target,
3904 request,
3905 nullable_ctx,
3906 continuations,
3907 visited,
3908 )
3909 }
3910 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3911 atn,
3912 *target,
3913 OperatorReachabilityRequest {
3914 predicate_dependent: true,
3915 ..request
3916 },
3917 nullable_ctx,
3918 continuations,
3919 visited,
3920 ),
3921 Transition::Atom { .. }
3922 | Transition::Range { .. }
3923 | Transition::Set { .. }
3924 | Transition::NotSet { .. }
3925 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3926 };
3927 reachability = reachability.union(transition_reachability);
3928 }
3929 visited.remove(&key);
3930 reachability
3931}
3932
3933fn left_recursive_operator_lookahead(
3934 atn: &Atn,
3935 state_number: usize,
3936 precedence: i32,
3937) -> LeftRecursiveOperatorLookahead {
3938 let Some(state) = atn.state(state_number) else {
3939 return LeftRecursiveOperatorLookahead::default();
3940 };
3941 let Some(operator_rule_index) = state.rule_index() else {
3942 return LeftRecursiveOperatorLookahead::default();
3943 };
3944 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3945 let mut nullable_ctx = NullablePrecedenceCtx {
3946 cache: FxHashMap::default(),
3947 in_progress: BTreeSet::new(),
3948 hit_cycle: false,
3949 };
3950 for transition in &state.transitions() {
3951 let target = transition.target();
3952 if atn
3953 .state(target)
3954 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3955 {
3956 continue;
3957 }
3958 for symbol in 1..=atn.max_token_type() {
3959 let reachability = state_can_reach_symbol_with_precedence(
3960 atn,
3961 target,
3962 OperatorReachabilityRequest {
3963 symbol,
3964 precedence,
3965 predicate_dependent: false,
3966 operator_rule_index,
3967 },
3968 &mut nullable_ctx,
3969 &mut Vec::new(),
3970 &mut BTreeSet::new(),
3971 );
3972 if reachability.single_token {
3973 lookahead.single_token.insert(symbol);
3974 }
3975 if reachability.multi_token {
3976 lookahead.multi_token_prefix.insert(symbol);
3977 }
3978 if reachability.predicate_dependent {
3979 lookahead.predicate_dependent.insert(symbol);
3980 }
3981 }
3982 }
3983 lookahead
3984}
3985
3986#[derive(Debug, Default)]
3987struct StateBeforeStopLookahead {
3988 symbols: TokenBitSet,
3989 reaches_context_boundary: bool,
3990}
3991
3992fn state_before_stop_lookahead(
3993 atn: &Atn,
3994 state_number: usize,
3995 stop_state_number: usize,
3996) -> Rc<StateBeforeStopLookahead> {
3997 with_shared_atn_caches(atn, |cache| {
3998 let key = (state_number, stop_state_number);
3999 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
4000 return Rc::clone(cached);
4001 }
4002 let mut lookahead = StateBeforeStopLookahead::default();
4003 state_before_stop_lookahead_inner(
4004 atn,
4005 state_number,
4006 stop_state_number,
4007 &mut BTreeSet::new(),
4008 &mut cache.first_set,
4009 &mut lookahead,
4010 );
4011 let lookahead = Rc::new(lookahead);
4012 cache
4013 .state_before_stop_lookahead
4014 .insert(key, Rc::clone(&lookahead));
4015 lookahead
4016 })
4017}
4018
4019fn state_before_stop_lookahead_inner(
4020 atn: &Atn,
4021 state_number: usize,
4022 stop_state_number: usize,
4023 visited: &mut BTreeSet<usize>,
4024 first_set_cache: &mut FirstSetCache,
4025 lookahead: &mut StateBeforeStopLookahead,
4026) {
4027 if state_number == stop_state_number {
4028 lookahead.reaches_context_boundary = true;
4029 return;
4030 }
4031 if !visited.insert(state_number) {
4032 return;
4033 }
4034 let Some(state) = atn.state(state_number) else {
4035 return;
4036 };
4037 if state.kind() == AtnStateKind::RuleStop {
4038 lookahead.reaches_context_boundary = true;
4039 return;
4040 }
4041 for transition in &state.transitions() {
4042 match &transition.data() {
4043 Transition::Epsilon { target }
4044 | Transition::Action { target, .. }
4045 | Transition::Predicate { target, .. }
4046 | Transition::Precedence { target, .. } => {
4047 state_before_stop_lookahead_inner(
4048 atn,
4049 *target,
4050 stop_state_number,
4051 visited,
4052 first_set_cache,
4053 lookahead,
4054 );
4055 }
4056 Transition::Rule {
4057 target,
4058 rule_index,
4059 follow_state,
4060 ..
4061 } => {
4062 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
4063 continue;
4064 };
4065 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
4066 lookahead.symbols.extend_from(&child.symbols);
4067 if child.nullable {
4068 state_before_stop_lookahead_inner(
4069 atn,
4070 *follow_state,
4071 stop_state_number,
4072 visited,
4073 first_set_cache,
4074 lookahead,
4075 );
4076 }
4077 }
4078 Transition::Atom { .. }
4079 | Transition::Range { .. }
4080 | Transition::Set { .. }
4081 | Transition::NotSet { .. }
4082 | Transition::Wildcard { .. } => {
4083 lookahead.symbols.extend_iter(transition_expected_symbols(
4084 transition,
4085 atn.max_token_type(),
4086 ));
4087 }
4088 }
4089 }
4090}
4091
4092fn caller_context_can_match_symbol_before_state(
4093 atn: &Atn,
4094 return_states: impl DoubleEndedIterator<Item = usize>,
4095 stop_state_number: usize,
4096 symbol: i32,
4097) -> bool {
4098 for return_state in return_states.rev() {
4099 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
4100 if lookahead.symbols.contains(symbol) {
4101 return true;
4102 }
4103 if !lookahead.reaches_context_boundary {
4104 return false;
4105 }
4106 }
4107 false
4108}
4109
4110fn next_recovery_context(
4114 atn: &Atn,
4115 state: AtnState<'_>,
4116 inherited: &BTreeSet<i32>,
4117 inherited_state: Option<usize>,
4118) -> (BTreeSet<i32>, Option<usize>) {
4119 let state_symbols = state_expected_symbols(atn, state.state_number());
4120 if state.transitions().len() > 1 && !state_symbols.is_empty() {
4121 let mut symbols = state_symbols;
4122 symbols.extend(inherited.iter().copied());
4123 return (symbols, Some(state.state_number()));
4124 }
4125 (inherited.clone(), inherited_state)
4126}
4127
4128fn recovery_expected_symbols(
4129 atn: &Atn,
4130 state_number: usize,
4131 inherited: &BTreeSet<i32>,
4132) -> BTreeSet<i32> {
4133 let mut symbols = state_expected_symbols(atn, state_number);
4134 symbols.extend(inherited.iter().copied());
4135 symbols
4136}
4137
4138fn fast_next_recovery_context<S, H>(
4142 parser: &mut BaseParser<S, H>,
4143 atn: &Atn,
4144 state: AtnState<'_>,
4145 inherited: &Rc<BTreeSet<i32>>,
4146 inherited_state: Option<usize>,
4147) -> (Rc<BTreeSet<i32>>, Option<usize>)
4148where
4149 S: TokenSource,
4150 H: SemanticHooks,
4151{
4152 if state.transitions().len() <= 1 {
4153 return (Rc::clone(inherited), inherited_state);
4154 }
4155 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
4156 if state_symbols.is_empty() {
4157 return (Rc::clone(inherited), inherited_state);
4158 }
4159 if inherited.is_empty() {
4160 return (state_symbols, Some(state.state_number()));
4161 }
4162 if Rc::ptr_eq(&state_symbols, inherited) {
4163 return (state_symbols, Some(state.state_number()));
4164 }
4165 let mut combined = (*state_symbols).clone();
4166 combined.extend(inherited.iter().copied());
4167 (
4168 parser.intern_recovery_symbols(combined),
4169 Some(state.state_number()),
4170 )
4171}
4172
4173fn fast_recovery_expected_symbols<S, H>(
4177 parser: &mut BaseParser<S, H>,
4178 atn: &Atn,
4179 state_number: usize,
4180 inherited: &Rc<BTreeSet<i32>>,
4181) -> Rc<BTreeSet<i32>>
4182where
4183 S: TokenSource,
4184 H: SemanticHooks,
4185{
4186 let cached = parser.cached_state_expected_symbols(atn, state_number);
4187 if inherited.is_empty() {
4188 return cached;
4189 }
4190 if cached.is_empty() {
4191 return Rc::clone(inherited);
4192 }
4193 if Rc::ptr_eq(&cached, inherited) {
4194 return cached;
4195 }
4196 let mut combined = (*cached).clone();
4197 combined.extend(inherited.iter().copied());
4198 parser.intern_recovery_symbols(combined)
4199}
4200
4201struct ParserTableSemCtx<'a> {
4202 member_values: &'a mut MemberEnv,
4203 return_values: &'a mut BTreeMap<String, i64>,
4204}
4205
4206impl semir::PredContext for ParserTableSemCtx<'_> {
4207 type TokenText<'a>
4208 = &'a str
4209 where
4210 Self: 'a;
4211
4212 fn la(&mut self, _offset: isize) -> i64 {
4213 i64::from(TOKEN_EOF)
4214 }
4215
4216 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
4217 None
4218 }
4219
4220 fn token_index_adjacent(&mut self) -> bool {
4221 false
4222 }
4223
4224 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
4225 None
4226 }
4227
4228 fn member(&self, member: usize) -> Option<i64> {
4229 Some(self.member_values.scalar(member).unwrap_or_default())
4230 }
4231
4232 fn member_top(&self, member: usize) -> Option<i64> {
4233 self.member_values.stack_top(member)
4234 }
4235
4236 fn member_len(&self, member: usize) -> usize {
4237 self.member_values.stack_len(member)
4238 }
4239
4240 fn local_arg(&self) -> Option<i64> {
4241 None
4242 }
4243
4244 fn column(&self) -> Option<i64> {
4245 None
4246 }
4247
4248 fn token_start_column(&self) -> Option<i64> {
4249 None
4250 }
4251
4252 fn token_text_so_far(&self) -> Option<String> {
4253 None
4254 }
4255
4256 fn hook(&mut self, _hook: HookId) -> bool {
4257 false
4258 }
4259}
4260
4261impl semir::ActContext for ParserTableSemCtx<'_> {
4262 fn set_member(&mut self, member: usize, value: i64) {
4263 self.member_values.set_scalar(member, value);
4264 }
4265
4266 fn push_member(&mut self, member: usize, value: i64) {
4267 self.member_values.push_stack(member, value);
4268 }
4269
4270 fn pop_member(&mut self, member: usize) -> Option<i64> {
4271 self.member_values.pop_stack(member)
4272 }
4273
4274 fn set_return(&mut self, name: &str, value: i64) {
4275 self.return_values.insert(name.to_owned(), value);
4276 }
4277
4278 fn action_hook(&mut self, _hook: HookId) {}
4279}
4280
4281fn apply_member_actions(
4283 source_state: usize,
4284 actions: &[ParserMemberAction],
4285 semantics: Option<&ParserSemantics>,
4286 values: &mut MemberEnv,
4287) {
4288 for action in actions
4289 .iter()
4290 .filter(|action| action.source_state == source_state)
4291 {
4292 values.add_scalar(action.member, action.delta);
4293 }
4294 let Some(semantics) = semantics else {
4295 return;
4296 };
4297 let mut return_values = BTreeMap::new();
4298 let mut ctx = ParserTableSemCtx {
4299 member_values: values,
4300 return_values: &mut return_values,
4301 };
4302 for action in semantics
4303 .actions
4304 .iter()
4305 .filter(|action| action.source_state == source_state && action.speculative)
4306 {
4307 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4308 }
4309}
4310
4311fn member_values_after_action(
4313 source_state: usize,
4314 actions: &[ParserMemberAction],
4315 semantics: Option<&ParserSemantics>,
4316 values: &MemberEnv,
4317) -> MemberEnv {
4318 let mut values = values.clone();
4319 apply_member_actions(source_state, actions, semantics, &mut values);
4320 values
4321}
4322
4323fn return_values_after_action(
4325 source_state: usize,
4326 rule_index: usize,
4327 actions: &[ParserReturnAction],
4328 semantics: Option<&ParserSemantics>,
4329 values: &BTreeMap<String, i64>,
4330) -> BTreeMap<String, i64> {
4331 let mut values = values.clone();
4332 for action in actions
4333 .iter()
4334 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
4335 {
4336 values.insert(action.name.to_owned(), action.value);
4337 }
4338 if let Some(semantics) = semantics {
4339 let mut member_values = MemberEnv::new();
4340 let mut ctx = ParserTableSemCtx {
4341 member_values: &mut member_values,
4342 return_values: &mut values,
4343 };
4344 for action in semantics.actions.iter().filter(|action| {
4345 action.source_state == source_state
4346 && action.rule_index == rule_index
4347 && !action.speculative
4348 }) {
4349 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4350 }
4351 }
4352 values
4353}
4354
4355fn rule_local_int_arg(
4357 rule_args: &[ParserRuleArg],
4358 source_state: usize,
4359 rule_index: usize,
4360 local_int_arg: Option<(usize, i64)>,
4361) -> Option<(usize, i64)> {
4362 rule_args
4363 .iter()
4364 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
4365 .map(|arg| {
4366 let value = if arg.inherit_local {
4367 local_int_arg.map_or(arg.value, |(_, value)| value)
4368 } else {
4369 arg.value
4370 };
4371 (rule_index, value)
4372 })
4373}
4374
4375fn stop_outcome(
4378 index: usize,
4379 consumed_eof: bool,
4380 rule_alt_number: usize,
4381 member_values: MemberEnv,
4382 return_values: BTreeMap<String, i64>,
4383) -> Vec<RecognizeOutcome> {
4384 vec![RecognizeOutcome {
4385 index,
4386 consumed_eof,
4387 alt_number: rule_alt_number,
4388 member_values,
4389 return_values,
4390 diagnostics: DiagnosticSeqId::EMPTY,
4391 decisions: Vec::new(),
4392 actions: Vec::new(),
4393 nodes: NodeSeqId::EMPTY,
4394 }]
4395}
4396
4397fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
4398 with_shared_atn_caches(atn, |cache| {
4399 *cache.observable_action_transitions.get_or_insert_with(|| {
4400 atn.states().any(|state| {
4401 state.transitions().iter().any(|transition| {
4402 matches!(
4403 &transition.data(),
4404 Transition::Action {
4405 action_index: Some(_),
4406 ..
4407 }
4408 )
4409 })
4410 })
4411 })
4412 })
4413}
4414
4415fn atn_has_predicate_transitions(atn: &Atn) -> bool {
4416 with_shared_atn_caches(atn, |cache| {
4417 *cache.predicate_transitions.get_or_insert_with(|| {
4418 atn.states().any(|state| {
4419 state
4420 .transitions()
4421 .iter()
4422 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
4423 })
4424 })
4425 })
4426}
4427
4428fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
4433 options.init_action_rules.is_empty()
4434 && options.action_indices.is_empty()
4435 && !options.track_alt_numbers
4436 && options
4437 .predicates
4438 .iter()
4439 .all(|(_, _, predicate)| predicate.failure_message().is_none())
4440 && options.semantics.is_none_or(|semantics| {
4441 semantics.actions.is_empty()
4442 && semantics
4443 .predicates
4444 .iter()
4445 .all(|predicate| predicate.failure_message.is_none())
4446 })
4447 && options.rule_args.is_empty()
4448 && options.member_actions.is_empty()
4449 && options.return_actions.is_empty()
4450 && !atn_has_observable_action_transitions(atn)
4451}
4452
4453#[derive(Clone, Debug, Eq, PartialEq)]
4454struct RecognizeRequest<'a> {
4455 state_number: usize,
4456 stop_state: usize,
4457 index: usize,
4458 rule_start_index: usize,
4459 decision_start_index: Option<usize>,
4460 init_action_rules: &'a BTreeSet<usize>,
4461 predicates: &'a [(usize, usize, ParserPredicate)],
4462 semantics: Option<&'a ParserSemantics>,
4463 rule_args: &'a [ParserRuleArg],
4464 member_actions: &'a [ParserMemberAction],
4465 return_actions: &'a [ParserReturnAction],
4466 local_int_arg: Option<(usize, i64)>,
4467 member_values: MemberEnv,
4468 return_values: BTreeMap<String, i64>,
4469 rule_alt_number: usize,
4470 track_alt_numbers: bool,
4471 consumed_eof: bool,
4472 committed_decision: bool,
4473 precedence: i32,
4476 depth: usize,
4477 recovery_symbols: BTreeSet<i32>,
4478 recovery_state: Option<usize>,
4479}
4480
4481#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4482struct RecognizeKey {
4483 state_number: usize,
4484 stop_state: usize,
4485 index: usize,
4486 rule_start_index: usize,
4487 decision_start_index: Option<usize>,
4488 local_int_arg: Option<(usize, i64)>,
4489 member_values: MemberEnv,
4490 return_values: BTreeMap<String, i64>,
4491 rule_alt_number: usize,
4492 track_alt_numbers: bool,
4493 consumed_eof: bool,
4494 committed_decision: bool,
4495 precedence: i32,
4496 recovery_symbols: BTreeSet<i32>,
4497 recovery_state: Option<usize>,
4498}
4499
4500#[derive(Clone, Debug, Eq, PartialEq)]
4501struct EpsilonActionStep {
4502 source_state: usize,
4503 target: usize,
4504 action_rule_index: Option<usize>,
4505 action_index: Option<usize>,
4506 left_recursive_boundary: Option<usize>,
4507 decision: Option<usize>,
4508 decision_start_index: Option<usize>,
4509 alt_number: usize,
4510 recovery_symbols: BTreeSet<i32>,
4511 recovery_state: Option<usize>,
4512}
4513
4514struct RecognizeScratch<'a> {
4515 visiting: &'a mut BTreeSet<RecognizeKey>,
4516 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4517 expected: &'a mut ExpectedTokens,
4518}
4519
4520#[derive(Clone, Debug, Eq, PartialEq)]
4521struct FastRecognizeRequest {
4522 state_number: usize,
4523 stop_state: usize,
4524 index: usize,
4525 rule_start_index: usize,
4526 decision_start_index: Option<usize>,
4527 precedence: i32,
4528 depth: usize,
4529 recovery_symbols: Rc<BTreeSet<i32>>,
4530 recovery_state: Option<usize>,
4531}
4532
4533#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4534struct FastRecognizeTopRequest {
4535 start_state: usize,
4536 stop_state: usize,
4537 start_index: usize,
4538 precedence: i32,
4539 caller_follow_state: Option<usize>,
4540}
4541
4542#[derive(Clone, Copy, Debug)]
4543struct FastPredicateContext<'a> {
4544 predicates: &'a [(usize, usize, ParserPredicate)],
4545 semantics: Option<&'a ParserSemantics>,
4546 member_values: &'a MemberEnv,
4547}
4548
4549#[derive(Clone, Copy, Debug, Default)]
4550struct AltNumberTracking {
4551 public: bool,
4552 context: bool,
4553}
4554
4555impl AltNumberTracking {
4556 const fn any(self) -> bool {
4557 self.public || self.context
4558 }
4559}
4560
4561struct FastRecognizeScratch<'a, 'b> {
4562 predicate_context: Option<FastPredicateContext<'a>>,
4563 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4564 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4565 expected: &'b mut ExpectedTokens,
4566 native_depth: usize,
4567}
4568
4569#[derive(Clone, Copy, Debug)]
4570struct FastRepetitionShape {
4571 enter_target: usize,
4572 exit_target: usize,
4573 body_stop_state: usize,
4574 enter_transition_index: usize,
4575 exit_transition_index: usize,
4576}
4577
4578#[derive(Clone, Copy, Debug)]
4579struct FastRepetitionPath {
4580 index: usize,
4581 deferred_nodes: FastDeferredNodeId,
4582 diagnostics: DiagnosticSeqId,
4583 consumed_eof: bool,
4584}
4585
4586enum FastRepetitionWork {
4587 Enter(FastRepetitionPath),
4588 Exit(FastRepetitionPath),
4589}
4590
4591struct FastRepetitionCoordinates {
4596 base_index: usize,
4597 base_state: u8,
4598 later_states: Vec<u8>,
4599}
4600
4601impl FastRepetitionCoordinates {
4602 const ENTERED: u8 = 0;
4603 const EXITED: u8 = 2;
4604
4605 const fn new(base_index: usize) -> Self {
4606 Self {
4607 base_index,
4608 base_state: 0,
4609 later_states: Vec::new(),
4610 }
4611 }
4612
4613 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4614 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4615 }
4616
4617 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4618 self.insert(path.index, path.consumed_eof, Self::EXITED)
4619 }
4620
4621 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4622 let Some(offset) = index.checked_sub(self.base_index) else {
4623 return false;
4624 };
4625 let state = if offset == 0 {
4626 &mut self.base_state
4627 } else {
4628 if self.later_states.len() < offset {
4629 self.later_states.resize(offset, 0);
4630 }
4631 &mut self.later_states[offset - 1]
4632 };
4633 let bit = 1 << (base_bit + u8::from(consumed_eof));
4634 let is_new = *state & bit == 0;
4635 *state |= bit;
4636 is_new
4637 }
4638}
4639
4640fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4641 if state.precedence_rule_decision()
4642 || !matches!(
4643 state.kind(),
4644 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4645 )
4646 || state.transitions().len() != 2
4647 {
4648 return None;
4649 }
4650 let mut enter = None;
4651 let mut exit = None;
4652 for (index, transition) in state.transitions().iter().enumerate() {
4653 if transition.kind() != ParserTransitionKind::Epsilon {
4654 return None;
4655 }
4656 let target = transition.target();
4657 if atn
4658 .state(target)
4659 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4660 {
4661 if exit.replace((index, target)).is_some() {
4662 return None;
4663 }
4664 } else if enter.replace((index, target)).is_some() {
4665 return None;
4666 }
4667 }
4668 let (enter_transition_index, enter_target) = enter?;
4669 let (exit_transition_index, exit_target) = exit?;
4670 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4671 atn.state(exit_target)?.loop_back_state()?
4672 } else {
4673 state.state_number()
4674 };
4675 Some(FastRepetitionShape {
4676 enter_target,
4677 exit_target,
4678 body_stop_state,
4679 enter_transition_index,
4680 exit_transition_index,
4681 })
4682}
4683
4684fn push_fast_repetition_work(
4685 work: &mut Vec<FastRepetitionWork>,
4686 shape: FastRepetitionShape,
4687 path: FastRepetitionPath,
4688 lookahead: Option<&DecisionLookahead>,
4689 symbol: i32,
4690) {
4691 let transition_is_viable = |transition_index: usize| {
4694 let Some(entry) = lookahead else {
4695 return true;
4696 };
4697 let Some(transition) = entry.transitions.get(transition_index) else {
4698 return true;
4699 };
4700 transition.nullable || transition.symbols.contains(symbol)
4701 };
4702 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4703 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4704 if shape.enter_transition_index < shape.exit_transition_index {
4705 if exit_is_viable {
4706 work.push(FastRepetitionWork::Exit(path));
4707 }
4708 if enter_is_viable {
4709 work.push(FastRepetitionWork::Enter(path));
4710 }
4711 } else {
4712 if enter_is_viable {
4713 work.push(FastRepetitionWork::Enter(path));
4714 }
4715 if exit_is_viable {
4716 work.push(FastRepetitionWork::Exit(path));
4717 }
4718 }
4719}
4720
4721#[derive(Clone, Debug)]
4728struct FastRecognizeKey {
4729 state_number: usize,
4730 stop_state: usize,
4731 index: usize,
4732 rule_start_index: usize,
4733 decision_start_index: Option<usize>,
4734 precedence: i32,
4735 recovery_symbols_id: usize,
4736 recovery_state: Option<usize>,
4737}
4738
4739impl PartialEq for FastRecognizeKey {
4740 fn eq(&self, other: &Self) -> bool {
4741 if self.state_number != other.state_number
4742 || self.stop_state != other.stop_state
4743 || self.index != other.index
4744 || self.rule_start_index != other.rule_start_index
4745 || self.decision_start_index != other.decision_start_index
4746 || self.precedence != other.precedence
4747 || self.recovery_state != other.recovery_state
4748 || self.recovery_symbols_id != other.recovery_symbols_id
4749 {
4750 return false;
4751 }
4752 true
4753 }
4754}
4755
4756impl Eq for FastRecognizeKey {}
4757
4758impl Hash for FastRecognizeKey {
4759 fn hash<H: Hasher>(&self, hasher: &mut H) {
4760 self.state_number.hash(hasher);
4761 self.stop_state.hash(hasher);
4762 self.index.hash(hasher);
4763 self.rule_start_index.hash(hasher);
4764 self.decision_start_index.hash(hasher);
4765 self.precedence.hash(hasher);
4766 self.recovery_state.hash(hasher);
4767 self.recovery_symbols_id.hash(hasher);
4768 }
4769}
4770
4771struct FastRecoveryRequest<'a, 'b> {
4772 atn: &'a Atn,
4773 transition: ParserTransition<'a>,
4774 expected_symbols: Rc<BTreeSet<i32>>,
4775 target: usize,
4776 request: FastRecognizeRequest,
4777 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4778 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4779 expected: &'b mut ExpectedTokens,
4780}
4781
4782struct FastCurrentTokenDeletionRequest<'a, 'b> {
4783 atn: &'a Atn,
4784 expected_symbols: Rc<BTreeSet<i32>>,
4785 request: FastRecognizeRequest,
4786 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4787 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4788 expected: &'b mut ExpectedTokens,
4789}
4790
4791#[derive(Clone, Copy)]
4792struct FastChildRuleFailureRecoveryRequest<'a> {
4793 atn: &'a Atn,
4794 rule_index: usize,
4795 start_index: usize,
4796 follow_state: usize,
4797 stop_state: usize,
4798 expected: &'a ExpectedTokens,
4799}
4800
4801struct RecoveryRequest<'a, 'b> {
4802 atn: &'a Atn,
4803 transition: ParserTransition<'a>,
4804 expected_symbols: BTreeSet<i32>,
4805 target: usize,
4806 request: RecognizeRequest<'a>,
4807 visiting: &'b mut BTreeSet<RecognizeKey>,
4808 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4809 expected: &'b mut ExpectedTokens,
4810}
4811
4812struct CurrentTokenDeletionRequest<'a, 'b> {
4813 atn: &'a Atn,
4814 expected_symbols: BTreeSet<i32>,
4815 request: RecognizeRequest<'a>,
4816 visiting: &'b mut BTreeSet<RecognizeKey>,
4817 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4818 expected: &'b mut ExpectedTokens,
4819}
4820
4821struct ConsumingFailureFallback<'a> {
4824 atn: &'a Atn,
4825 target: usize,
4826 request: RecognizeRequest<'a>,
4827 symbol: i32,
4828 expected_symbols: BTreeSet<i32>,
4829 decision_start_index: Option<usize>,
4830 decision: Option<usize>,
4831}
4832
4833struct ChildRuleFailureRecovery<'a> {
4836 atn: &'a Atn,
4837 rule_index: usize,
4838 start_index: usize,
4839 follow_state: usize,
4840 stop_state: usize,
4841 member_values: MemberEnv,
4842 expected: &'a ExpectedTokens,
4843}
4844
4845#[derive(Clone, Copy, Debug)]
4847struct PredicateEval<'a> {
4848 index: usize,
4849 rule_index: usize,
4850 pred_index: usize,
4851 predicates: &'a [(usize, usize, ParserPredicate)],
4852 semantics: Option<&'a ParserSemantics>,
4853 context: Option<&'a ParserRuleContext>,
4854 local_int_arg: Option<(usize, i64)>,
4855 member_values: &'a MemberEnv,
4856}
4857
4858#[derive(Clone, Copy, Debug)]
4859struct ParserSemanticHookRequest<'a> {
4860 index: usize,
4861 rule_index: usize,
4862 pred_index: usize,
4863 context: Option<&'a ParserRuleContext>,
4864 local_int_arg: Option<(usize, i64)>,
4865 member_values: &'a MemberEnv,
4866}
4867
4868struct ParserSemIrCtx<'a, S, H>
4877where
4878 S: TokenSource,
4879 H: SemanticHooks,
4880{
4881 input: &'a mut CommonTokenStream<S>,
4882 tree_storage: &'a ParseTreeStorage,
4883 semantic_hooks: &'a mut H,
4884 rule_index: usize,
4885 coordinate_index: usize,
4886 rule_name: Option<&'a str>,
4887 context: Option<&'a ParserRuleContext>,
4888 local_int_arg: Option<(usize, i64)>,
4889 member_values: &'a MemberEnv,
4890 invoked_predicates: &'a mut Vec<(usize, usize)>,
4891 unknown_predicate_policy: UnknownSemanticPolicy,
4895 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4896}
4897
4898impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4899where
4900 S: TokenSource,
4901 H: SemanticHooks,
4902{
4903 type TokenText<'a>
4904 = TokenView<'a>
4905 where
4906 Self: 'a;
4907
4908 fn la(&mut self, offset: isize) -> i64 {
4909 i64::from(self.input.la(offset))
4910 }
4911
4912 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4913 self.input.lt(offset)
4914 }
4915
4916 fn token_index_adjacent(&mut self) -> bool {
4917 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4918 return false;
4919 };
4920 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4921 return false;
4922 };
4923 first + 1 == second
4924 }
4925
4926 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4927 self.context.and_then(|context| {
4928 context
4929 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4930 .next()
4931 .map(crate::tree::RuleNodeView::text)
4932 })
4933 }
4934
4935 fn member(&self, member: usize) -> Option<i64> {
4936 Some(self.member_values.scalar(member).unwrap_or_default())
4937 }
4938
4939 fn member_top(&self, member: usize) -> Option<i64> {
4940 self.member_values.stack_top(member)
4941 }
4942
4943 fn member_len(&self, member: usize) -> usize {
4944 self.member_values.stack_len(member)
4945 }
4946
4947 fn local_arg(&self) -> Option<i64> {
4948 self.local_int_arg.map(|(_, value)| value)
4949 }
4950
4951 fn column(&self) -> Option<i64> {
4952 None
4953 }
4954
4955 fn token_start_column(&self) -> Option<i64> {
4956 None
4957 }
4958
4959 fn token_text_so_far(&self) -> Option<String> {
4960 None
4961 }
4962
4963 fn hook(&mut self, _hook: HookId) -> bool {
4964 let mut ctx = ParserSemCtx {
4965 input: &mut *self.input,
4966 tree_storage: self.tree_storage,
4967 rule_index: self.rule_index,
4968 coordinate_index: self.coordinate_index,
4969 rule_name: self.rule_name.map(str::to_owned),
4970 context: self.context,
4971 tree: None,
4972 local_int_arg: self.local_int_arg,
4973 member_values: self.member_values,
4974 action: None,
4975 };
4976 match self
4977 .semantic_hooks
4978 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4979 {
4980 Some(result) => result,
4981 None => apply_unknown_predicate_policy(
4985 self.unknown_predicate_policy,
4986 self.rule_index,
4987 self.coordinate_index,
4988 self.unknown_predicate_hits,
4989 ),
4990 }
4991 }
4992
4993 fn trace_bool(&mut self, value: bool) -> bool {
4994 let key = (self.rule_index, self.coordinate_index);
4995 if !self.invoked_predicates.contains(&key) {
4996 self.invoked_predicates.push(key);
4997 use std::io::Write as _;
4998 let mut stdout = std::io::stdout().lock();
4999 let _ = writeln!(stdout, "eval={value}");
5000 }
5001 value
5002 }
5003}
5004
5005struct PredicateFailureRecovery<'a> {
5007 rule_index: usize,
5008 index: usize,
5009 message: &'a str,
5010 member_values: MemberEnv,
5011 return_values: BTreeMap<String, i64>,
5012 rule_alt_number: usize,
5013}
5014
5015#[derive(Debug)]
5016enum DirectAdaptiveParseControl {
5017 Fallback(DirectAdaptiveFallback),
5018}
5019
5020#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5021enum DirectAdaptiveFallback {
5022 Action,
5023 InvalidAlt,
5024 LeftRecursiveBoundary,
5025 MissingAtn,
5026 NoTransition,
5027 Predicate,
5028 Prediction,
5029 Precedence,
5030 RuleStop,
5031 SemanticContext,
5032 StepLimit,
5033 TokenMismatch,
5034 UnknownDecision,
5035}
5036
5037type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
5038
5039struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
5040where
5041 S: TokenSource,
5042 H: SemanticHooks,
5043{
5044 parser: &'sim mut BaseParser<S, H>,
5045 atn: &'atn Atn,
5046 simulator: &'sim mut ParserAtnSimulator<'atn>,
5047 decision_by_state: Vec<Option<usize>>,
5048 steps: usize,
5049}
5050
5051struct CommittedAtnParser<'atn, 'sim, 'options, S, H = NoSemanticHooks>
5052where
5053 S: TokenSource,
5054 H: SemanticHooks,
5055{
5056 parser: &'sim mut BaseParser<S, H>,
5057 atn: &'atn Atn,
5058 simulator: ParserAtnSimulator<'atn>,
5059 options: ParserRuntimeOptions<'options>,
5060 decision_by_state: Vec<Option<usize>>,
5061 action_index_by_state: FxHashMap<usize, usize>,
5062 deferred_actions: Vec<ParserAction>,
5063}
5064
5065struct CommittedRuleOutcome {
5066 tree: ParseTree,
5067 consumed_eof: bool,
5068}
5069
5070struct CommittedDecisionContext<'a> {
5071 precedence: i32,
5072 local_int_arg: Option<(usize, i64)>,
5073 context: &'a mut ParserRuleContext,
5074 entered_loops: &'a mut BTreeSet<usize>,
5075}
5076
5077#[derive(Clone, Debug, Eq, PartialEq)]
5087pub struct GeneratedMatch {
5088 children: GeneratedMatchChildren,
5089 consumed_eof: bool,
5090}
5091
5092#[derive(Clone, Copy)]
5093enum GeneratedExpectedSymbols<'a> {
5094 Tree(&'a BTreeSet<i32>),
5095 TokenSet(ParserIntervalSet<'a>),
5096 TokenSetComplement {
5097 set: ParserIntervalSet<'a>,
5098 min_vocabulary: i32,
5099 max_vocabulary: i32,
5100 },
5101}
5102
5103impl GeneratedExpectedSymbols<'_> {
5104 fn is_empty(self) -> bool {
5105 match self {
5106 Self::Tree(symbols) => symbols.is_empty(),
5107 Self::TokenSet(set) => set.is_empty(),
5108 Self::TokenSetComplement {
5109 set,
5110 min_vocabulary,
5111 max_vocabulary,
5112 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
5113 }
5114 }
5115
5116 fn first(self) -> Option<i32> {
5117 match self {
5118 Self::Tree(symbols) => symbols.iter().next().copied(),
5119 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
5120 Self::TokenSetComplement {
5121 set,
5122 min_vocabulary,
5123 max_vocabulary,
5124 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
5125 }
5126 }
5127
5128 fn display(self, vocabulary: &Vocabulary) -> String {
5129 match self {
5130 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
5131 Self::TokenSet(set) => expected_symbols_display_iter(
5132 set.ranges().flat_map(|(start, stop)| start..=stop),
5133 vocabulary,
5134 ),
5135 Self::TokenSetComplement {
5136 set,
5137 min_vocabulary,
5138 max_vocabulary,
5139 } => expected_symbols_display_iter(
5140 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
5141 vocabulary,
5142 ),
5143 }
5144 }
5145}
5146
5147#[derive(Clone, Debug, Eq, PartialEq)]
5148enum GeneratedMatchChildren {
5149 One(ParseTree),
5150 Many(Vec<ParseTree>),
5151}
5152
5153struct GeneratedMatchChildrenIntoIter {
5154 one: Option<ParseTree>,
5155 many: Option<std::vec::IntoIter<ParseTree>>,
5156}
5157
5158impl Iterator for GeneratedMatchChildrenIntoIter {
5159 type Item = ParseTree;
5160
5161 fn next(&mut self) -> Option<Self::Item> {
5162 self.one
5163 .take()
5164 .or_else(|| self.many.as_mut().and_then(Iterator::next))
5165 }
5166}
5167
5168impl GeneratedMatch {
5169 #[must_use]
5173 pub fn children(&self) -> &[ParseTree] {
5174 match &self.children {
5175 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
5176 GeneratedMatchChildren::Many(children) => children,
5177 }
5178 }
5179
5180 #[must_use]
5183 pub fn into_children(self) -> Vec<ParseTree> {
5184 match self.children {
5185 GeneratedMatchChildren::One(child) => vec![child],
5186 GeneratedMatchChildren::Many(children) => children,
5187 }
5188 }
5189
5190 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
5192 match self.children {
5193 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
5194 one: Some(child),
5195 many: None,
5196 },
5197 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
5198 one: None,
5199 many: Some(children.into_iter()),
5200 },
5201 }
5202 }
5203
5204 #[must_use]
5206 pub const fn consumed_eof(&self) -> bool {
5207 self.consumed_eof
5208 }
5209}
5210
5211impl<S> BaseParser<S, NoSemanticHooks>
5212where
5213 S: TokenSource,
5214{
5215 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
5218 Self::with_semantic_hooks(input, data, NoSemanticHooks)
5219 }
5220}
5221
5222impl<S, H> BaseParser<S, H>
5223where
5224 S: TokenSource,
5225 H: SemanticHooks,
5226{
5227 pub fn with_semantic_hooks(
5229 input: CommonTokenStream<S>,
5230 data: RecognizerData,
5231 semantic_hooks: H,
5232 ) -> Self {
5233 Self {
5234 input,
5235 tree: ParseTreeStorage::new(),
5236 data,
5237 semantic_hooks,
5238 decision_override_generation: 0,
5239 build_parse_trees: true,
5240 syntax_errors: 0,
5241 report_diagnostic_errors: false,
5242 prediction_mode: PredictionMode::Ll,
5243 prediction_diagnostics: Vec::new(),
5244 reported_prediction_diagnostics: BTreeSet::new(),
5245 generated_parser_diagnostics: Vec::new(),
5246 generated_sync_expected: None,
5247 generated_recovery_error_index: None,
5248 generated_recovery_error_states: BTreeSet::new(),
5249 int_members: MemberEnv::new(),
5250 rule_context_stack: Vec::new(),
5251 rule_context_version: 0,
5252 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
5253 pending_invoking_states: Vec::new(),
5254 precedence_stack: vec![0],
5255 invoked_predicates: Vec::new(),
5256 bail_on_error: false,
5257 parse_listeners: Vec::new(),
5258 parse_listener_abort: None,
5259 max_rule_depth: None,
5260 rule_depth_error: None,
5261 recursion_expansions: 0,
5262 recursion_expansion_marks: Vec::new(),
5263 unknown_predicate_policy: UnknownSemanticPolicy::default(),
5264 unknown_predicate_hits: Vec::new(),
5265 unhandled_action_hits: Vec::new(),
5266 rule_first_set_cache: Vec::new(),
5267 state_expected_cache: FxHashMap::default(),
5268 state_expected_token_cache: FxHashMap::default(),
5269 rule_stop_reach_cache: Vec::new(),
5270 recovery_symbols_intern: FxHashMap::default(),
5271 decision_lookahead_cache: FxHashMap::default(),
5272 ll1_decision_cache: FxHashMap::default(),
5273 fast_predicate_cache: FxHashMap::default(),
5274 empty_cycle_cache: Vec::new(),
5275 empty_cycle_cache_atn: None,
5276 clean_memo_mode: CleanMemoMode::Probe,
5277 clean_memo_probe_seen: FxHashSet::default(),
5278 clean_memo_probe_samples: 0,
5279 clean_memo_probe_repeats: 0,
5280 clean_memo_sparse_samples: 0,
5281 fast_recognize_scratch: FastRecognizeTopScratch::default(),
5282 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
5283 empty_recovery_symbols: Rc::new(BTreeSet::new()),
5284 fast_first_set_prefilter: true,
5285 fast_recovery_enabled: true,
5286 fast_token_nodes_enabled: true,
5287 fast_track_alt_numbers: false,
5288 recognition_arena: RecognitionArena::default(),
5289 last_recognition_arena_root: NodeSeqId::EMPTY,
5290 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
5291 }
5292 }
5293
5294 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
5295 &mut self.input
5296 }
5297
5298 pub fn reset(&mut self) {
5303 self.input.seek(0);
5304 self.tree.reset();
5305 self.data.set_state(-1);
5306 self.syntax_errors = 0;
5307 self.prediction_diagnostics.clear();
5308 self.reported_prediction_diagnostics.clear();
5309 self.generated_parser_diagnostics.clear();
5310 self.generated_sync_expected = None;
5311 self.reset_generated_recovery_state();
5312 self.rule_context_stack.clear();
5313 self.advance_rule_context_version();
5314 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
5315 self.pending_invoking_states.clear();
5316 self.precedence_stack.clear();
5317 self.precedence_stack.push(0);
5318 self.invoked_predicates.clear();
5319 self.decision_override_generation = 0;
5320 self.unknown_predicate_hits.clear();
5321 self.unhandled_action_hits.clear();
5322 self.parse_listener_abort = None;
5323 self.rule_depth_error = None;
5324 self.recursion_expansions = 0;
5325 self.recursion_expansion_marks.clear();
5326 self.reset_per_parse_caches();
5327 self.fast_first_set_prefilter = true;
5328 self.fast_recovery_enabled = true;
5329 self.fast_token_nodes_enabled = self.build_parse_trees;
5330 self.fast_track_alt_numbers = false;
5331 self.reset_recognition_arena();
5332 }
5333
5334 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
5336 self.input = input;
5337 self.reset();
5338 }
5339
5340 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
5351 self.unknown_predicate_policy = policy;
5352 }
5353
5354 #[must_use]
5360 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
5361 let error = self.unknown_semantic_error();
5362 self.unknown_predicate_hits.clear();
5363 self.unhandled_action_hits.clear();
5364 error
5365 }
5366
5367 pub fn reset_unknown_semantic_hits(&mut self) {
5374 self.unknown_predicate_hits.clear();
5375 self.unhandled_action_hits.clear();
5376 }
5377
5378 #[must_use]
5380 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
5381 &self.input
5382 }
5383
5384 #[must_use]
5386 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
5387 &mut self.input
5388 }
5389
5390 #[must_use]
5392 pub const fn token_store(&self) -> &TokenStore {
5393 self.input.token_store()
5394 }
5395
5396 #[must_use]
5398 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
5399 &self.tree
5400 }
5401
5402 #[must_use]
5404 pub fn node(&self, id: NodeId) -> Node<'_> {
5405 self.tree
5406 .node(self.input.token_store(), id)
5407 .expect("parser-produced node ID should remain valid")
5408 }
5409
5410 #[must_use]
5412 pub fn into_token_stream(self) -> CommonTokenStream<S> {
5413 self.input
5414 }
5415
5416 #[must_use]
5418 pub fn into_token_store(self) -> TokenStore {
5419 self.input.into_token_store()
5420 }
5421
5422 #[must_use]
5424 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
5425 ParsedFile::new(self.input.into_token_store(), self.tree, root)
5426 }
5427
5428 pub const fn number_of_syntax_errors(&self) -> usize {
5431 self.syntax_errors
5432 }
5433
5434 #[must_use]
5440 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
5441 self.recognition_arena.stats(
5442 self.last_recognition_arena_root,
5443 self.last_recognition_arena_diagnostics,
5444 )
5445 }
5446
5447 pub const fn record_generated_syntax_error(&mut self) {
5450 self.record_syntax_errors(1);
5451 }
5452
5453 const fn record_syntax_errors(&mut self, count: usize) {
5454 self.syntax_errors = self.syntax_errors.saturating_add(count);
5455 }
5456
5457 const fn is_top_level_entry(&self) -> bool {
5459 self.rule_context_stack.is_empty() && self.pending_invoking_states.is_empty()
5460 }
5461
5462 pub fn report_token_source_errors(&mut self) {
5465 let errors = self.input.drain_source_errors();
5466 self.dispatch_token_source_errors(&errors);
5467 }
5468
5469 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
5472 GeneratedDiagnosticsCheckpoint {
5473 diagnostics_len: self.generated_parser_diagnostics.len(),
5474 syntax_errors: self.syntax_errors,
5475 tree: self.tree.checkpoint(),
5476 }
5477 }
5478
5479 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5481 self.generated_parser_diagnostics
5482 .truncate(marker.diagnostics_len);
5483 self.syntax_errors = marker.syntax_errors;
5484 self.rollback_generated_tree(marker);
5485 }
5486
5487 pub fn rollback_generated_tree(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5493 self.generated_sync_expected = None;
5494 self.tree.rollback(marker.tree);
5495 }
5496
5497 pub fn report_generated_parser_diagnostics(&mut self) {
5499 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
5500 let token_errors = self.input.drain_source_errors();
5501 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
5502 }
5503
5504 fn syntax_error_event<'a>(
5505 &'a self,
5506 offending: Option<TokenId>,
5507 line: usize,
5508 column: usize,
5509 message: &'a str,
5510 error: Option<&'a AntlrError>,
5511 ) -> SyntaxErrorEvent<'a> {
5512 let offending = offending.and_then(|token| self.token_store().view(token));
5513 SyntaxErrorEvent {
5514 offending,
5515 line,
5516 column,
5517 span: offending.and_then(|token| token.byte_span()),
5518 message,
5519 error,
5520 }
5521 }
5522
5523 pub fn report_unrecovered_parser_error(&self, error: &AntlrError) {
5528 let AntlrError::ParserError {
5529 line,
5530 column,
5531 message,
5532 offending,
5533 } = error
5534 else {
5535 return;
5536 };
5537 self.notify_error_listeners(self.syntax_error_event(
5538 *offending,
5539 *line,
5540 *column,
5541 message,
5542 Some(error),
5543 ));
5544 }
5545
5546 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
5547 self.notify_error_listeners(self.syntax_error_event(
5548 diagnostic.offending,
5549 diagnostic.line,
5550 diagnostic.column,
5551 &diagnostic.message,
5552 None,
5553 ));
5554 }
5555
5556 fn dispatch_parser_diagnostics<'a>(
5557 &self,
5558 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
5559 ) {
5560 for diagnostic in diagnostics {
5561 self.dispatch_parser_diagnostic(diagnostic);
5562 }
5563 }
5564
5565 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
5566 if self.input.token_source().report_error(source_error) {
5567 return;
5568 }
5569 self.notify_error_listeners(source_error.into());
5572 }
5573
5574 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
5575 for error in errors {
5576 self.dispatch_token_source_error(error);
5577 }
5578 }
5579
5580 fn dispatch_generated_diagnostics(
5583 &self,
5584 parser_diagnostics: &[ParserDiagnostic],
5585 token_errors: &[TokenSourceError],
5586 ) {
5587 let mut token_iter = token_errors.iter().peekable();
5593 for diagnostic in parser_diagnostics {
5594 while let Some(error) = token_iter.peek() {
5595 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
5596 self.dispatch_token_source_error(error);
5597 token_iter.next();
5598 } else {
5599 break;
5600 }
5601 }
5602 self.dispatch_parser_diagnostic(diagnostic);
5603 }
5604 for error in token_iter {
5605 self.dispatch_token_source_error(error);
5606 }
5607 }
5608
5609 pub fn record_generated_ambiguity_diagnostic(
5612 &mut self,
5613 atn: &Atn,
5614 state_number: usize,
5615 start_index: usize,
5616 stop_index: usize,
5617 alts: &[usize],
5618 ) {
5619 if !self.report_diagnostic_errors || alts.len() < 2 {
5620 return;
5621 }
5622 let Some(decision) = atn
5623 .decision_to_state()
5624 .iter()
5625 .position(|candidate| candidate == state_number)
5626 else {
5627 return;
5628 };
5629 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5630 return;
5631 };
5632 let rule_name = self
5633 .rule_names()
5634 .get(rule_index)
5635 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5636 let input = display_input_text(&self.input.text(start_index, stop_index));
5637 let alts = alts
5638 .iter()
5639 .map(usize::to_string)
5640 .collect::<Vec<_>>()
5641 .join(", ");
5642 let key = (decision, start_index, format!("{alts}:{input}"));
5643 if !self.reported_prediction_diagnostics.insert(key) {
5644 return;
5645 }
5646 let start_diagnostic = diagnostic_for_token(
5647 self.token_at(start_index),
5648 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5649 );
5650 let stop_diagnostic = diagnostic_for_token(
5651 self.token_at(stop_index),
5652 format!(
5653 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5654 ),
5655 );
5656 self.generated_parser_diagnostics.push(start_diagnostic);
5657 self.generated_parser_diagnostics.push(stop_diagnostic);
5658 }
5659
5660 pub fn record_generated_prediction_diagnostic(
5663 &mut self,
5664 atn: &Atn,
5665 state_number: usize,
5666 prediction: &ParserAtnPrediction,
5667 ) {
5668 let Some(diagnostic) = &prediction.diagnostic else {
5669 return;
5670 };
5671 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5672 return;
5673 }
5674 let Some(decision) = atn
5675 .decision_to_state()
5676 .iter()
5677 .position(|candidate| candidate == state_number)
5678 else {
5679 return;
5680 };
5681 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5682 return;
5683 };
5684 let rule_name = self
5685 .rule_names()
5686 .get(rule_index)
5687 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5688 let attempt_input = display_input_text(
5689 &self
5690 .input
5691 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5692 );
5693 let result_input = display_input_text(
5694 &self
5695 .input
5696 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5697 );
5698 let alts = diagnostic
5699 .conflicting_alts
5700 .iter()
5701 .map(usize::to_string)
5702 .collect::<Vec<_>>()
5703 .join(", ");
5704 let key = (
5705 decision,
5706 diagnostic.start_index,
5707 format!(
5708 "{:?}:{alts}:{attempt_input}:{result_input}",
5709 diagnostic.kind
5710 ),
5711 );
5712 if !self.reported_prediction_diagnostics.insert(key) {
5713 return;
5714 }
5715 let attempt_diagnostic = diagnostic_for_token(
5716 self.token_at(diagnostic.sll_stop_index),
5717 format!(
5718 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5719 ),
5720 );
5721 self.generated_parser_diagnostics.push(attempt_diagnostic);
5722 let message = match diagnostic.kind {
5723 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5724 if !diagnostic.exact {
5729 return;
5730 }
5731 format!(
5732 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5733 )
5734 }
5735 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5736 format!(
5737 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5738 )
5739 }
5740 };
5741 let result_diagnostic =
5742 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5743 self.generated_parser_diagnostics.push(result_diagnostic);
5744 }
5745
5746 pub fn la(&self, offset: isize) -> i32 {
5747 self.input.la_token(offset)
5748 }
5749
5750 pub fn consume(&mut self) {
5751 IntStream::consume(&mut self.input);
5752 }
5753
5754 pub fn set_int_member(&mut self, member: usize, value: i64) {
5756 self.int_members.set_scalar(member, value);
5757 }
5758
5759 pub fn int_member(&self, member: usize) -> Option<i64> {
5761 self.int_members.scalar(member)
5762 }
5763
5764 pub fn push_stack_member(&mut self, member: usize, value: i64) {
5766 self.int_members.push_stack(member, value);
5767 }
5768
5769 pub fn pop_stack_member(&mut self, member: usize) -> Option<i64> {
5772 self.int_members.pop_stack(member)
5773 }
5774
5775 #[must_use]
5778 pub fn stack_member_top(&self, member: usize) -> Option<i64> {
5779 self.int_members.stack_top(member)
5780 }
5781
5782 #[must_use]
5784 pub fn stack_member_len(&self, member: usize) -> usize {
5785 self.int_members.stack_len(member)
5786 }
5787
5788 pub fn set_initial_members(&mut self, initial: impl IntoIterator<Item = (usize, i64)>) {
5795 self.int_members = MemberEnv::with_initial_scalars(initial);
5796 }
5797
5798 #[must_use]
5804 pub fn int_members_checkpoint(&self) -> MemberEnv {
5805 self.int_members.clone()
5806 }
5807
5808 pub fn restore_int_members(&mut self, members: MemberEnv) {
5810 self.int_members = members;
5811 }
5812
5813 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5815 self.int_members.add_scalar(member, delta)
5816 }
5817
5818 fn token_type_for_id(&self, id: TokenId) -> i32 {
5819 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5820 }
5821
5822 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5823 if self.build_parse_trees {
5824 self.tree.terminal(id)
5825 } else {
5826 NodeId::placeholder()
5827 }
5828 }
5829
5830 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5831 if self.build_parse_trees {
5832 self.tree.error(id)
5833 } else {
5834 NodeId::placeholder()
5835 }
5836 }
5837
5838 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5839 context.set_start_id(id);
5840 }
5841
5842 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5843 context.set_stop_id(id);
5844 }
5845
5846 fn insert_synthetic_token(
5847 &mut self,
5848 token_type: i32,
5849 text: String,
5850 line: usize,
5851 column: usize,
5852 ) -> Result<TokenId, AntlrError> {
5853 self.input
5854 .insert(
5855 TokenSpec::explicit(token_type, text)
5856 .with_span(usize::MAX, usize::MAX)
5857 .with_position(line, column),
5858 )
5859 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5860 }
5861
5862 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5869 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5870 line: 0,
5871 column: 0,
5872 message: "missing current token".to_owned(),
5873 offending: None,
5874 })?;
5875 let current_type = self.token_type_for_id(current);
5876 if current_type == token_type {
5877 self.reset_generated_recovery_state();
5878 self.consume();
5879 Ok(self.terminal_tree(current))
5880 } else {
5881 Err(AntlrError::MismatchedInput {
5882 expected: self.vocabulary().display_name(token_type),
5883 found: self.vocabulary().display_name(current_type),
5884 })
5885 }
5886 }
5887
5888 pub fn match_token_recovering(
5892 &mut self,
5893 token_type: i32,
5894 follow_state: usize,
5895 atn: &Atn,
5896 ) -> Result<GeneratedMatch, AntlrError> {
5897 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5898 line: 0,
5899 column: 0,
5900 message: "missing current token".to_owned(),
5901 offending: None,
5902 })?;
5903 let current_type = self.token_type_for_id(current);
5904 if current_type == token_type {
5905 self.generated_sync_expected = None;
5906 self.reset_generated_recovery_state();
5907 let consumed_eof = current_type == TOKEN_EOF;
5908 self.consume();
5909 return Ok(GeneratedMatch {
5910 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5911 consumed_eof,
5912 });
5913 }
5914 let mut expected_symbols = BTreeSet::new();
5915 expected_symbols.insert(token_type);
5916 self.recover_generated_match(
5917 current,
5918 GeneratedExpectedSymbols::Tree(&expected_symbols),
5919 follow_state,
5920 atn,
5921 |symbol| symbol == token_type,
5922 )
5923 }
5924
5925 pub fn match_set_recovering(
5926 &mut self,
5927 intervals: &[(i32, i32)],
5928 follow_state: usize,
5929 atn: &Atn,
5930 ) -> Result<GeneratedMatch, AntlrError> {
5931 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5932 line: 0,
5933 column: 0,
5934 message: "missing current token".to_owned(),
5935 offending: None,
5936 })?;
5937 let current_type = self.token_type_for_id(current);
5938 if interval_set_contains(intervals, current_type) {
5939 self.generated_sync_expected = None;
5940 self.reset_generated_recovery_state();
5941 let consumed_eof = current_type == TOKEN_EOF;
5942 self.consume();
5943 return Ok(GeneratedMatch {
5944 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5945 consumed_eof,
5946 });
5947 }
5948 let expected_symbols = interval_symbols(intervals);
5949 self.recover_generated_match(
5950 current,
5951 GeneratedExpectedSymbols::Tree(&expected_symbols),
5952 follow_state,
5953 atn,
5954 |symbol| interval_set_contains(intervals, symbol),
5955 )
5956 }
5957
5958 pub fn match_token_set_recovering(
5959 &mut self,
5960 set: ParserIntervalSet<'_>,
5961 follow_state: usize,
5962 atn: &Atn,
5963 ) -> Result<GeneratedMatch, AntlrError> {
5964 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5965 line: 0,
5966 column: 0,
5967 message: "missing current token".to_owned(),
5968 offending: None,
5969 })?;
5970 let current_type = self.token_type_for_id(current);
5971 if set.contains(current_type) {
5972 self.generated_sync_expected = None;
5973 self.reset_generated_recovery_state();
5974 let consumed_eof = current_type == TOKEN_EOF;
5975 self.consume();
5976 return Ok(GeneratedMatch {
5977 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5978 consumed_eof,
5979 });
5980 }
5981 self.recover_generated_match(
5982 current,
5983 GeneratedExpectedSymbols::TokenSet(set),
5984 follow_state,
5985 atn,
5986 |symbol| set.contains(symbol),
5987 )
5988 }
5989
5990 pub fn match_not_set_recovering(
5991 &mut self,
5992 intervals: &[(i32, i32)],
5993 min_vocabulary: i32,
5994 max_vocabulary: i32,
5995 follow_state: usize,
5996 atn: &Atn,
5997 ) -> Result<GeneratedMatch, AntlrError> {
5998 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5999 line: 0,
6000 column: 0,
6001 message: "missing current token".to_owned(),
6002 offending: None,
6003 })?;
6004 let current_type = self.token_type_for_id(current);
6005 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
6006 && !interval_set_contains(intervals, current_type)
6007 {
6008 self.generated_sync_expected = None;
6009 self.reset_generated_recovery_state();
6010 let consumed_eof = current_type == TOKEN_EOF;
6011 self.consume();
6012 return Ok(GeneratedMatch {
6013 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
6014 consumed_eof,
6015 });
6016 }
6017 let expected_symbols =
6018 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
6019 self.recover_generated_match(
6020 current,
6021 GeneratedExpectedSymbols::Tree(&expected_symbols),
6022 follow_state,
6023 atn,
6024 |symbol| {
6025 (min_vocabulary..=max_vocabulary).contains(&symbol)
6026 && !interval_set_contains(intervals, symbol)
6027 },
6028 )
6029 }
6030
6031 pub fn match_not_token_set_recovering(
6032 &mut self,
6033 set: ParserIntervalSet<'_>,
6034 min_vocabulary: i32,
6035 max_vocabulary: i32,
6036 follow_state: usize,
6037 atn: &Atn,
6038 ) -> Result<GeneratedMatch, AntlrError> {
6039 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6040 line: 0,
6041 column: 0,
6042 message: "missing current token".to_owned(),
6043 offending: None,
6044 })?;
6045 let current_type = self.token_type_for_id(current);
6046 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
6047 {
6048 self.generated_sync_expected = None;
6049 self.reset_generated_recovery_state();
6050 let consumed_eof = current_type == TOKEN_EOF;
6051 self.consume();
6052 return Ok(GeneratedMatch {
6053 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
6054 consumed_eof,
6055 });
6056 }
6057 self.recover_generated_match(
6058 current,
6059 GeneratedExpectedSymbols::TokenSetComplement {
6060 set,
6061 min_vocabulary,
6062 max_vocabulary,
6063 },
6064 follow_state,
6065 atn,
6066 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
6067 )
6068 }
6069
6070 fn recover_generated_match(
6071 &mut self,
6072 current: TokenId,
6073 expected_symbols: GeneratedExpectedSymbols<'_>,
6074 follow_state: usize,
6075 atn: &Atn,
6076 matches: impl Fn(i32) -> bool,
6077 ) -> Result<GeneratedMatch, AntlrError> {
6078 let expected_display = expected_symbols.display(self.vocabulary());
6079 let (current_type, current_line, current_column, current_display) = {
6080 let token = self
6081 .input
6082 .token_view(current)
6083 .expect("current token ID should be valid");
6084 (
6085 token.token_type(),
6086 token.line(),
6087 token.column(),
6088 token_input_display(&token),
6089 )
6090 };
6091 if self.bail_on_error {
6092 return Err(AntlrError::ParserError {
6093 line: current_line,
6094 column: current_column,
6095 message: format!("mismatched input {current_display} expecting {expected_display}"),
6096 offending: Some(current),
6097 });
6098 }
6099 if current_type != TOKEN_EOF
6100 && let Some(next) = self.input.lt_id(2)
6101 && matches(self.token_type_for_id(next))
6102 {
6103 let message =
6104 format!("extraneous input {current_display} expecting {expected_display}");
6105 self.push_generated_parser_diagnostic(ParserDiagnostic {
6106 line: current_line,
6107 column: current_column,
6108 message,
6109 offending: Some(current),
6110 });
6111 self.record_syntax_errors(1);
6112 self.generated_sync_expected = None;
6113 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
6116 self.consume();
6117 self.consume();
6118 self.reset_generated_recovery_state();
6119 return Ok(GeneratedMatch {
6120 children: GeneratedMatchChildren::Many(vec![
6121 self.error_tree(current),
6122 self.terminal_tree(next),
6123 ]),
6124 consumed_eof,
6125 });
6126 }
6127 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
6128 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
6137 && self
6138 .cached_state_expected_symbols(atn, follow_state)
6139 .contains(&TOKEN_EOF);
6140 if follow_symbols.contains(¤t_type)
6141 && (current_type != TOKEN_EOF
6142 || self.rule_context_stack.len() > 1
6143 || expected_symbols.is_empty()
6144 || follow_explicitly_expects_eof)
6145 {
6146 let message = format!("missing {expected_display} at {current_display}");
6147 self.push_generated_parser_diagnostic(ParserDiagnostic {
6148 line: current_line,
6149 column: current_column,
6150 message,
6151 offending: Some(current),
6152 });
6153 self.record_syntax_errors(1);
6154 self.generated_sync_expected = None;
6155 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
6156 let missing_display = expected_symbol_display(token_type, self.vocabulary());
6157 let token = self.insert_synthetic_token(
6158 token_type,
6159 format!("<missing {missing_display}>"),
6160 current_line,
6161 current_column,
6162 )?;
6163 return Ok(GeneratedMatch {
6168 children: GeneratedMatchChildren::One(self.error_tree(token)),
6169 consumed_eof: false,
6170 });
6171 }
6172 let mismatch_expected_display = self
6173 .generated_sync_expected
6174 .take()
6175 .map_or(expected_display, |symbols| {
6176 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
6177 });
6178 Err(AntlrError::ParserError {
6179 line: current_line,
6180 column: current_column,
6181 message: format!(
6182 "mismatched input {current_display} expecting {mismatch_expected_display}"
6183 ),
6184 offending: Some(current),
6185 })
6186 }
6187
6188 fn generated_recovery_follow_symbols(
6189 &mut self,
6190 atn: &Atn,
6191 follow_state: usize,
6192 ) -> BTreeSet<i32> {
6193 let mut follow = self
6194 .cached_state_expected_symbols(atn, follow_state)
6195 .as_ref()
6196 .clone();
6197 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
6198 follow.extend(self.context_expected_symbols(atn));
6199 }
6200 follow
6201 }
6202
6203 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
6204 self.match_token(TOKEN_EOF)
6205 }
6206
6207 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
6208 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
6209 }
6210
6211 pub fn match_not_set(
6212 &mut self,
6213 intervals: &[(i32, i32)],
6214 min_vocabulary: i32,
6215 max_vocabulary: i32,
6216 ) -> Result<ParseTree, AntlrError> {
6217 self.match_interval_condition(intervals, |symbol| {
6218 (min_vocabulary..=max_vocabulary).contains(&symbol)
6219 && !interval_set_contains(intervals, symbol)
6220 })
6221 }
6222
6223 fn match_interval_condition(
6224 &mut self,
6225 intervals: &[(i32, i32)],
6226 matches: impl FnOnce(i32) -> bool,
6227 ) -> Result<ParseTree, AntlrError> {
6228 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6229 line: 0,
6230 column: 0,
6231 message: "missing current token".to_owned(),
6232 offending: None,
6233 })?;
6234 let current_type = self.token_type_for_id(current);
6235 if matches(current_type) {
6236 self.reset_generated_recovery_state();
6237 self.consume();
6238 Ok(self.terminal_tree(current))
6239 } else {
6240 Err(AntlrError::MismatchedInput {
6241 expected: self.interval_display(intervals),
6242 found: self.vocabulary().display_name(current_type),
6243 })
6244 }
6245 }
6246
6247 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
6248 let values = intervals
6249 .iter()
6250 .map(|(start, stop)| {
6251 if start == stop {
6252 self.vocabulary().display_name(*start)
6253 } else {
6254 format!(
6255 "{}..{}",
6256 self.vocabulary().display_name(*start),
6257 self.vocabulary().display_name(*stop)
6258 )
6259 }
6260 })
6261 .collect::<Vec<_>>()
6262 .join(", ");
6263 format!("{{{values}}}")
6264 }
6265
6266 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
6267 if self.build_parse_trees {
6268 self.tree.finish_rule(context)
6269 } else {
6270 NodeId::placeholder()
6271 }
6272 }
6273
6274 #[must_use]
6283 pub const fn generated_rule_stack_check_due(&self) -> bool {
6284 self.rule_context_stack
6285 .len()
6286 .is_multiple_of(GENERATED_RULE_STACK_CHECK_INTERVAL)
6287 }
6288
6289 #[inline]
6307 pub fn rule_depth_cap_violation(&mut self) -> Option<AntlrError> {
6308 let max = self.max_rule_depth?;
6309 if self.rule_depth_error.is_none()
6312 && self.rule_context_stack.len() + self.recursion_expansions < max
6313 {
6314 return None;
6315 }
6316 Some(self.rule_depth_cap_violation_cold(max))
6317 }
6318
6319 #[cold]
6320 fn rule_depth_cap_violation_cold(&mut self, max: usize) -> AntlrError {
6321 if let Some(error) = &self.rule_depth_error {
6322 return error.clone();
6323 }
6324 let current = self.input.lt(1);
6325 let (line, column) = current
6326 .as_ref()
6327 .map_or((0, 0), |token| (token.line(), token.column()));
6328 let error = AntlrError::ParserError {
6329 line,
6330 column,
6331 message: format!("rule nesting depth limit of {max} exceeded"),
6332 offending: current.as_ref().map(Token::token_id),
6333 };
6334 self.rule_depth_error = Some(error.clone());
6335 error
6336 }
6337
6338 pub const fn take_rule_depth_error(&mut self) -> Option<AntlrError> {
6345 self.rule_depth_error.take()
6346 }
6347
6348 #[must_use]
6355 pub const fn has_rule_depth_cap(&self) -> bool {
6356 self.max_rule_depth.is_some()
6357 }
6358
6359 pub fn add_parse_listener<L>(&mut self, listener: L)
6363 where
6364 L: ParseListener + 'static,
6365 {
6366 self.parse_listeners
6367 .push(ParseListenerSlot(Box::new(listener)));
6368 }
6369
6370 pub fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
6377 self.parse_listener_abort = None;
6378 self.parse_listeners.drain(..).map(|slot| slot.0).collect()
6379 }
6380
6381 #[must_use]
6387 pub const fn has_parse_listeners(&self) -> bool {
6388 !self.parse_listeners.is_empty()
6389 }
6390
6391 #[doc(hidden)]
6396 #[must_use]
6397 pub fn observes_parser_decisions(&self) -> bool {
6398 self.semantic_hooks.observes_parser_decisions()
6399 }
6400
6401 pub fn parse_listener_enter_rule(&mut self, rule_index: usize) -> Option<AntlrError> {
6412 if self.parse_listeners.is_empty() {
6413 return None;
6414 }
6415 self.parse_listener_enter_rule_dispatch(rule_index)
6416 }
6417
6418 fn parse_listener_enter_rule_dispatch(&mut self, rule_index: usize) -> Option<AntlrError> {
6419 if let Some(error) = &self.parse_listener_abort {
6420 return Some(error.clone());
6421 }
6422 let event = EnterRuleEvent {
6423 rule_index,
6424 current: self.input.lt(1),
6425 };
6426 let mut listeners = std::mem::take(&mut self.parse_listeners);
6430 let mut abort = None;
6431 for slot in &mut listeners {
6432 if let Err(error) = slot.0.enter_every_rule(&event) {
6433 abort = Some(error);
6434 break;
6435 }
6436 }
6437 self.parse_listeners = listeners;
6438 if let Some(error) = abort {
6439 self.parse_listener_abort = Some(error.clone());
6440 return Some(error);
6441 }
6442 None
6443 }
6444
6445 pub fn parse_listener_exit_rule(&mut self, rule_index: usize) {
6452 if self.parse_listeners.is_empty() {
6453 return;
6454 }
6455 for slot in self.parse_listeners.iter_mut().rev() {
6458 slot.0.exit_every_rule(rule_index);
6459 }
6460 }
6461
6462 pub const fn take_parse_listener_abort(&mut self) -> Option<AntlrError> {
6469 self.parse_listener_abort.take()
6470 }
6471
6472 pub fn take_parse_abort(&mut self) -> Option<AntlrError> {
6481 if let Some(error) = self.rule_depth_error.take() {
6482 self.parse_listener_abort = None;
6483 return Some(error);
6484 }
6485 self.parse_listener_abort.take()
6486 }
6487
6488 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
6491 self.set_state(state);
6492 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
6493 self.rule_context_stack.push(RuleContextFrame {
6494 rule_index,
6495 invoking_state,
6496 });
6497 self.advance_rule_context_version();
6498 let start_index = self.current_visible_index();
6499 let mut context = ParserRuleContext::new(rule_index, invoking_state);
6500 if let Some(token) = self.token_id_at(start_index) {
6501 self.set_context_start(&mut context, token);
6502 }
6503 context
6504 }
6505
6506 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
6513 let marker = self.pending_invoking_states.len();
6514 self.pending_invoking_states.push(invoking_state);
6515 marker
6516 }
6517
6518 pub fn discard_invoking_state(&mut self, marker: usize) {
6520 self.pending_invoking_states.truncate(marker);
6521 }
6522
6523 pub fn exit_rule(&mut self) {
6525 self.rule_context_stack.pop();
6526 self.advance_rule_context_version();
6527 }
6528
6529 pub fn prediction_context_return_states<'a>(
6532 &'a self,
6533 atn: &'a Atn,
6534 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
6535 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
6536 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
6537 return None;
6538 };
6539 let Some(Transition::Rule { follow_state, .. }) = atn
6540 .state(state_number)
6541 .and_then(|state| state.transitions().first())
6542 .map(ParserTransition::data)
6543 else {
6544 return None;
6545 };
6546 Some(follow_state)
6547 })
6548 }
6549
6550 pub const fn rule_context_version(&self) -> usize {
6555 self.rule_context_version
6556 }
6557
6558 const fn advance_rule_context_version(&mut self) {
6559 self.rule_context_version = self.rule_context_version.wrapping_add(1);
6560 }
6561
6562 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
6567 if self.build_parse_trees {
6568 self.tree.add_child(context, child);
6569 } else {
6570 context.note_matched_child();
6571 }
6572 }
6573
6574 #[inline]
6580 pub fn sync_into(
6581 &mut self,
6582 atn: &Atn,
6583 state_number: usize,
6584 context: &mut ParserRuleContext,
6585 loop_back: bool,
6586 sync_error: &mut Option<AntlrError>,
6587 ) -> Result<(), AntlrError> {
6588 let current_context_empty = !context.has_matched_child();
6589 match self.sync_decision(atn, state_number, current_context_empty, loop_back) {
6590 Ok(children) => {
6591 for child in children {
6592 self.add_parse_child(context, child);
6593 }
6594 Ok(())
6595 }
6596 Err(error) => {
6597 *sync_error = Some(error.clone());
6598 Err(error)
6599 }
6600 }
6601 }
6602
6603 #[inline]
6607 pub fn match_token_into(
6608 &mut self,
6609 token_type: i32,
6610 follow_state: usize,
6611 atn: &Atn,
6612 context: &mut ParserRuleContext,
6613 consumed_eof: &mut bool,
6614 ) -> Result<(), AntlrError> {
6615 let m = self.match_token_recovering(token_type, follow_state, atn)?;
6616 *consumed_eof |= m.consumed_eof();
6617 for child in m.into_child_iter() {
6618 self.add_parse_child(context, child);
6619 }
6620 Ok(())
6621 }
6622
6623 #[inline]
6626 pub fn match_token_set_into(
6627 &mut self,
6628 token_set: ParserIntervalSet<'_>,
6629 follow_state: usize,
6630 atn: &Atn,
6631 context: &mut ParserRuleContext,
6632 consumed_eof: &mut bool,
6633 ) -> Result<(), AntlrError> {
6634 let m = self.match_token_set_recovering(token_set, follow_state, atn)?;
6635 *consumed_eof |= m.consumed_eof();
6636 for child in m.into_child_iter() {
6637 self.add_parse_child(context, child);
6638 }
6639 Ok(())
6640 }
6641
6642 #[inline]
6645 pub fn match_set_into(
6646 &mut self,
6647 intervals: &[(i32, i32)],
6648 follow_state: usize,
6649 atn: &Atn,
6650 context: &mut ParserRuleContext,
6651 consumed_eof: &mut bool,
6652 ) -> Result<(), AntlrError> {
6653 let m = self.match_set_recovering(intervals, follow_state, atn)?;
6654 *consumed_eof |= m.consumed_eof();
6655 for child in m.into_child_iter() {
6656 self.add_parse_child(context, child);
6657 }
6658 Ok(())
6659 }
6660
6661 #[allow(clippy::too_many_arguments)]
6664 #[inline]
6665 pub fn match_not_token_set_into(
6666 &mut self,
6667 token_set: ParserIntervalSet<'_>,
6668 min_vocabulary: i32,
6669 max_vocabulary: i32,
6670 follow_state: usize,
6671 atn: &Atn,
6672 context: &mut ParserRuleContext,
6673 consumed_eof: &mut bool,
6674 ) -> Result<(), AntlrError> {
6675 let m = self.match_not_token_set_recovering(
6676 token_set,
6677 min_vocabulary,
6678 max_vocabulary,
6679 follow_state,
6680 atn,
6681 )?;
6682 *consumed_eof |= m.consumed_eof();
6683 for child in m.into_child_iter() {
6684 self.add_parse_child(context, child);
6685 }
6686 Ok(())
6687 }
6688
6689 #[allow(clippy::too_many_arguments)]
6692 #[inline]
6693 pub fn match_not_set_into(
6694 &mut self,
6695 intervals: &[(i32, i32)],
6696 min_vocabulary: i32,
6697 max_vocabulary: i32,
6698 follow_state: usize,
6699 atn: &Atn,
6700 context: &mut ParserRuleContext,
6701 consumed_eof: &mut bool,
6702 ) -> Result<(), AntlrError> {
6703 let m = self.match_not_set_recovering(
6704 intervals,
6705 min_vocabulary,
6706 max_vocabulary,
6707 follow_state,
6708 atn,
6709 )?;
6710 *consumed_eof |= m.consumed_eof();
6711 for child in m.into_child_iter() {
6712 self.add_parse_child(context, child);
6713 }
6714 Ok(())
6715 }
6716
6717 fn release_tree_scratch_if_idle(&mut self) {
6718 if self.rule_context_stack.is_empty() {
6719 self.tree.release_scratch();
6720 }
6721 }
6722
6723 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
6725 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6726 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6727 self.set_context_stop(&mut context, token);
6728 }
6729 let node = self.rule_node(context);
6730 self.exit_rule();
6731 self.release_tree_scratch_if_idle();
6732 node
6733 }
6734
6735 pub fn recover_generated_rule(
6742 &mut self,
6743 context: &mut ParserRuleContext,
6744 atn: &Atn,
6745 error: AntlrError,
6746 ) {
6747 let diagnostic = self.generated_rule_error_diagnostic(error);
6748 self.push_generated_parser_diagnostic(diagnostic);
6749 self.generated_sync_expected = None;
6750 let error_index = self.input.index();
6751 let error_state = self.data.state();
6752 if self.generated_recovery_error_index == Some(error_index)
6757 && self.generated_recovery_error_states.contains(&error_state)
6758 && self.la(1) != TOKEN_EOF
6759 && let Some(token) = self.input.lt_id(1)
6760 {
6761 self.consume();
6762 let child = self.error_tree(token);
6763 self.add_parse_child(context, child);
6764 }
6765 let recovery_index = self.input.index();
6766 if self.generated_recovery_error_index != Some(recovery_index) {
6767 self.generated_recovery_error_index = Some(recovery_index);
6768 self.generated_recovery_error_states.clear();
6769 }
6770 self.generated_recovery_error_states.insert(error_state);
6771 let recovery_symbols = self.context_expected_symbols(atn);
6772 loop {
6773 let symbol = self.la(1);
6774 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
6775 break;
6776 }
6777 let Some(token) = self.input.lt_id(1) else {
6778 break;
6779 };
6780 self.consume();
6781 let child = self.error_tree(token);
6782 self.add_parse_child(context, child);
6783 }
6784 self.record_syntax_errors(1);
6785 }
6786
6787 fn reset_generated_recovery_state(&mut self) {
6788 if self.generated_recovery_error_index.is_some() {
6789 self.generated_recovery_error_index = None;
6790 self.generated_recovery_error_states.clear();
6791 }
6792 }
6793
6794 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
6795 if self
6796 .generated_parser_diagnostics
6797 .iter()
6798 .any(|existing| existing == &diagnostic)
6799 {
6800 return;
6801 }
6802 self.generated_parser_diagnostics.push(diagnostic);
6803 }
6804
6805 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
6806 match error {
6807 AntlrError::ParserError {
6811 line,
6812 column,
6813 message,
6814 offending,
6815 } => ParserDiagnostic {
6816 line,
6817 column,
6818 message,
6819 offending,
6820 },
6821 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
6822 self.input.lt(1),
6823 format!("mismatched input {found} expecting {expected}"),
6824 ),
6825 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
6826 self.input.lt(1),
6827 format!("no viable alternative at input {input}"),
6828 ),
6829 AntlrError::LexerError {
6830 line,
6831 column,
6832 message,
6833 } => ParserDiagnostic {
6834 line,
6835 column,
6836 message,
6837 offending: None,
6838 },
6839 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
6840 }
6841 }
6842
6843 pub fn finish_recursion_rule(
6845 &mut self,
6846 mut context: ParserRuleContext,
6847 consumed_eof: bool,
6848 ) -> ParseTree {
6849 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6850 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6851 self.set_context_stop(&mut context, token);
6852 }
6853 let node = self.rule_node(context);
6854 self.unroll_recursion_context();
6855 self.release_tree_scratch_if_idle();
6856 node
6857 }
6858
6859 pub fn enter_recursion_rule(
6861 &mut self,
6862 state: isize,
6863 rule_index: usize,
6864 precedence: i32,
6865 ) -> ParserRuleContext {
6866 self.precedence_stack.push(precedence);
6867 self.recursion_expansion_marks
6868 .push(self.recursion_expansions);
6869 self.enter_rule(state, rule_index)
6870 }
6871
6872 pub fn push_new_recursion_context(
6874 &mut self,
6875 state: isize,
6876 rule_index: usize,
6877 ) -> ParserRuleContext {
6878 self.set_state(state);
6879 self.recursion_expansions += 1;
6882 ParserRuleContext::new(rule_index, state)
6883 }
6884
6885 pub fn push_new_recursion_context_with_previous(
6888 &mut self,
6889 state: isize,
6890 rule_index: usize,
6891 current: &mut ParserRuleContext,
6892 ) {
6893 self.set_state(state);
6894 self.recursion_expansions += 1;
6900 if let Some(stop) = self
6901 .rule_stop_token_index(self.input.index(), false)
6902 .and_then(|index| self.token_id_at(index))
6903 {
6904 self.set_context_stop(current, stop);
6905 }
6906 let invoking_state = current.invoking_state();
6907 let start = current.start_id();
6908 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
6909 if start.is_some() {
6910 replacement.set_start_from_context(current);
6911 }
6912 let previous = std::mem::replace(current, replacement);
6913 if self.build_parse_trees {
6914 let previous = self.rule_node(previous);
6915 self.tree.add_child(current, previous);
6916 }
6917 }
6918
6919 pub fn unroll_recursion_context(&mut self) {
6921 if self.precedence_stack.len() > 1 {
6922 self.precedence_stack.pop();
6923 }
6924 if let Some(mark) = self.recursion_expansion_marks.pop() {
6930 self.recursion_expansions = mark;
6931 }
6932 self.exit_rule();
6933 }
6934
6935 pub fn left_recursive_loop_enter_prediction(
6949 &mut self,
6950 atn: &Atn,
6951 state_number: usize,
6952 precedence: i32,
6953 ) -> Option<bool> {
6954 let symbol = self.la(1);
6955 if symbol == TOKEN_EOF {
6956 return Some(false);
6957 }
6958 let operator_lookahead =
6959 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
6960 let can_single = operator_lookahead.single_token.contains(symbol);
6961 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
6962 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
6963 if !can_single && !can_multi && !can_predicate {
6964 return Some(false);
6965 }
6966 if can_predicate && !can_single {
6967 return None;
6968 }
6969 if !can_single && can_multi && precedence > 0 {
6973 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
6974 if baseline.single_token.contains(symbol) {
6975 return None;
6976 }
6977 }
6978 let atn_key = SharedAtnCacheKey::for_atn(atn);
6979 let cached_overlap = self
6980 .left_recursive_caller_overlap_cache
6981 .iter()
6982 .flatten()
6983 .find(|entry| {
6984 entry.atn_key == atn_key
6985 && entry.state_number == state_number
6986 && entry.symbol == symbol
6987 && entry.context_version == self.rule_context_version
6988 })
6989 .map(|entry| entry.overlaps);
6990 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
6991 let overlaps = caller_context_can_match_symbol_before_state(
6992 atn,
6993 self.prediction_context_return_states(atn),
6994 state_number,
6995 symbol,
6996 );
6997 if let Some(slot) = self
6998 .left_recursive_caller_overlap_cache
6999 .iter_mut()
7000 .find(|slot| slot.is_none())
7001 {
7002 *slot = Some(LeftRecursiveCallerOverlap {
7003 atn_key,
7004 state_number,
7005 symbol,
7006 context_version: self.rule_context_version,
7007 overlaps,
7008 });
7009 }
7010 overlaps
7011 });
7012 if caller_overlaps {
7013 return None;
7014 }
7015 Some(true)
7016 }
7017
7018 fn cached_left_recursive_operator_lookahead(
7019 atn: &Atn,
7020 state_number: usize,
7021 precedence: i32,
7022 ) -> Rc<LeftRecursiveOperatorLookahead> {
7023 with_shared_atn_caches(atn, |cache| {
7024 let key = (state_number, precedence);
7025 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
7026 return Rc::clone(cached);
7027 }
7028 let lookahead = Rc::new(left_recursive_operator_lookahead(
7029 atn,
7030 state_number,
7031 precedence,
7032 ));
7033 cache
7034 .left_recursive_operator_lookahead
7035 .insert(key, Rc::clone(&lookahead));
7036 lookahead
7037 })
7038 }
7039
7040 pub fn left_recursive_loop_enter_matches(
7043 &mut self,
7044 atn: &Atn,
7045 state_number: usize,
7046 precedence: i32,
7047 ) -> bool {
7048 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
7049 }
7050
7051 pub fn precpred(&self, precedence: i32) -> bool {
7053 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
7054 }
7055
7056 pub fn parser_semantic_predicate_matches(
7059 &mut self,
7060 predicates: &[(usize, usize, ParserPredicate)],
7061 rule_index: usize,
7062 pred_index: usize,
7063 ) -> bool {
7064 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
7065 }
7066
7067 pub fn parser_semantic_predicate_matches_with_local(
7070 &mut self,
7071 predicates: &[(usize, usize, ParserPredicate)],
7072 rule_index: usize,
7073 pred_index: usize,
7074 local_int_arg: i32,
7075 ) -> bool {
7076 self.parser_semantic_predicate_matches_inner(
7077 predicates,
7078 rule_index,
7079 pred_index,
7080 Some((rule_index, i64::from(local_int_arg))),
7081 )
7082 }
7083
7084 fn parser_semantic_predicate_matches_inner(
7085 &mut self,
7086 predicates: &[(usize, usize, ParserPredicate)],
7087 rule_index: usize,
7088 pred_index: usize,
7089 local_int_arg: Option<(usize, i64)>,
7090 ) -> bool {
7091 let index = self.input.index();
7092 let member_values = self.int_members.clone();
7093 self.parser_predicate_matches(PredicateEval {
7094 index,
7095 rule_index,
7096 pred_index,
7097 predicates,
7098 semantics: None,
7099 context: None,
7100 local_int_arg,
7101 member_values: &member_values,
7102 })
7103 }
7104
7105 pub fn parser_semantic_predicate_matches_with_context_and_local(
7108 &mut self,
7109 predicates: &[(usize, usize, ParserPredicate)],
7110 rule_index: usize,
7111 pred_index: usize,
7112 context: &ParserRuleContext,
7113 local_int_arg: i32,
7114 ) -> bool {
7115 let index = self.input.index();
7116 let member_values = self.int_members.clone();
7117 self.parser_predicate_matches(PredicateEval {
7118 index,
7119 rule_index,
7120 pred_index,
7121 predicates,
7122 semantics: None,
7123 context: Some(context),
7124 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
7125 member_values: &member_values,
7126 })
7127 }
7128
7129 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
7132 &mut self,
7133 semantics: &ParserSemantics,
7134 rule_index: usize,
7135 pred_index: usize,
7136 context: &ParserRuleContext,
7137 local_int_arg: i32,
7138 ) -> bool {
7139 let index = self.input.index();
7140 let member_values = self.int_members.clone();
7141 self.parser_predicate_matches(PredicateEval {
7142 index,
7143 rule_index,
7144 pred_index,
7145 predicates: &[],
7146 semantics: Some(semantics),
7147 context: Some(context),
7148 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
7149 member_values: &member_values,
7150 })
7151 }
7152
7153 pub fn parser_semantic_predicate_failure_message(
7156 &self,
7157 rule_index: usize,
7158 pred_index: usize,
7159 predicates: &[(usize, usize, ParserPredicate)],
7160 ) -> Option<&'static str> {
7161 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
7162 }
7163
7164 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
7166 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
7167 line: 0,
7168 column: 0,
7169 message: "missing current token".to_owned(),
7170 offending: None,
7171 })?;
7172 if self.token_type_for_id(current) == TOKEN_EOF {
7173 return Err(AntlrError::MismatchedInput {
7174 expected: "wildcard".to_owned(),
7175 found: self.vocabulary().display_name(TOKEN_EOF),
7176 });
7177 }
7178 self.reset_generated_recovery_state();
7179 self.consume();
7180 Ok(self.terminal_tree(current))
7181 }
7182
7183 #[allow(clippy::unnecessary_wraps)]
7187 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
7188 self.set_state(state);
7189 Ok(())
7190 }
7191
7192 pub fn sync_decision(
7200 &mut self,
7201 atn: &Atn,
7202 state_number: usize,
7203 _current_context_empty: bool,
7204 loop_back: bool,
7205 ) -> Result<Vec<ParseTree>, AntlrError> {
7206 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
7207 self.generated_sync_expected = None;
7208 let Some(state) = atn.state(state_number) else {
7209 return Ok(Vec::new());
7210 };
7211 let Some(rule_index) = state.rule_index() else {
7212 return Ok(Vec::new());
7213 };
7214 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
7215 return Ok(Vec::new());
7216 };
7217 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
7218 let symbol = self.la(1);
7219 let mut has_expected_symbols = false;
7220 let mut nullable = false;
7221 let mut explicit_eof_expected = false;
7229 for transition in &entry.transitions {
7230 if transition.symbols.contains(symbol) {
7231 return Ok(Vec::new());
7232 }
7233 has_expected_symbols |= !transition.symbols.is_empty();
7234 nullable |= transition.nullable;
7235 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
7236 }
7237 if nullable {
7244 if self.context_expected_contains(atn, symbol) {
7248 return Ok(Vec::new());
7249 }
7250 let mut expected = self.context_expected_token_set(atn);
7251 for transition in &entry.transitions {
7252 expected.extend_from(&transition.symbols);
7253 }
7254 self.generated_sync_expected = Some(expected);
7255 return Ok(Vec::new());
7256 }
7257 if !has_expected_symbols {
7258 return Ok(Vec::new());
7259 }
7260 let mut expected = TokenBitSet::default();
7261 for transition in &entry.transitions {
7262 expected.extend_from(&transition.symbols);
7263 }
7264 let loop_sync = loop_back;
7281 if symbol != TOKEN_EOF {
7282 let mut cursor = self.input.index();
7283 let mut skipped = Vec::new();
7284 loop {
7285 let current = self.token_type_at(cursor);
7286 if current == TOKEN_EOF {
7287 break;
7288 }
7289 skipped.push(cursor);
7290 let next = self.consume_index(cursor, current);
7291 if next == cursor {
7292 break;
7293 }
7294 let next_symbol = self.token_type_at(next);
7295 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
7303 explicit_eof_expected
7304 } else {
7305 expected.contains(next_symbol)
7306 };
7307 if next_is_expected_stop {
7308 let current_token = self.input.lt(1);
7309 let expected_symbols = expected.to_btree_set();
7310 let message = format!(
7311 "extraneous input {} expecting {}",
7312 current_token
7313 .as_ref()
7314 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7315 self.expected_symbols_display(&expected_symbols)
7316 );
7317 self.push_generated_parser_diagnostic(diagnostic_for_token(
7318 current_token,
7319 message,
7320 ));
7321 self.record_syntax_errors(1);
7322 let mut children = Vec::with_capacity(skipped.len());
7323 for index in skipped {
7324 if let Some(token) = self.token_id_at(index) {
7325 self.consume();
7326 children.push(self.error_tree(token));
7327 }
7328 }
7329 if !loop_sync {
7330 self.reset_generated_recovery_state();
7331 }
7332 return Ok(children);
7333 }
7334 if !loop_sync {
7338 break;
7339 }
7340 cursor = next;
7341 }
7342 }
7343 let current = self.input.lt(1);
7344 let expected_symbols = expected.to_btree_set();
7345 Err(AntlrError::ParserError {
7346 line: current.as_ref().map(Token::line).unwrap_or_default(),
7347 column: current.as_ref().map(Token::column).unwrap_or_default(),
7348 message: format!(
7349 "mismatched input {} expecting {}",
7350 current
7351 .as_ref()
7352 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7353 self.expected_symbols_display(&expected_symbols)
7354 ),
7355 offending: current.as_ref().map(Token::token_id),
7356 })
7357 }
7358
7359 pub fn ll1_decision_prediction(
7366 &mut self,
7367 atn: &Atn,
7368 state_number: usize,
7369 ) -> Option<ParserAtnPrediction> {
7370 let state = atn.state(state_number)?;
7371 if state.precedence_rule_decision() {
7372 return None;
7373 }
7374 let rule_stop = state
7375 .rule_index()
7376 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
7377 let symbol = self.la(1);
7378 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
7379 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
7380 alt: alt + 1,
7381 requires_full_context: false,
7382 has_semantic_context: false,
7383 diagnostic: None,
7384 })
7385 }
7386
7387 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
7388 let mut expected = BTreeSet::new();
7389 for index in (1..self.rule_context_stack.len()).rev() {
7390 let invoking_state = self.rule_context_stack[index].invoking_state;
7391 let Ok(state_number) = usize::try_from(invoking_state) else {
7392 continue;
7393 };
7394 let Some(Transition::Rule { follow_state, .. }) = atn
7395 .state(state_number)
7396 .and_then(|state| state.transitions().first())
7397 .map(ParserTransition::data)
7398 else {
7399 continue;
7400 };
7401 let return_state = follow_state;
7402 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
7403 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
7404 return expected;
7405 }
7406 }
7407 expected.insert(TOKEN_EOF);
7408 expected
7409 }
7410
7411 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
7412 let mut expected = TokenBitSet::default();
7413 for index in (1..self.rule_context_stack.len()).rev() {
7414 let invoking_state = self.rule_context_stack[index].invoking_state;
7415 let Ok(state_number) = usize::try_from(invoking_state) else {
7416 continue;
7417 };
7418 let Some(Transition::Rule { follow_state, .. }) = atn
7419 .state(state_number)
7420 .and_then(|state| state.transitions().first())
7421 .map(ParserTransition::data)
7422 else {
7423 continue;
7424 };
7425 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
7426 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7427 return expected;
7428 }
7429 }
7430 expected.insert(TOKEN_EOF);
7431 expected
7432 }
7433
7434 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
7441 for index in (1..self.rule_context_stack.len()).rev() {
7442 let invoking_state = self.rule_context_stack[index].invoking_state;
7443 let Ok(state_number) = usize::try_from(invoking_state) else {
7444 continue;
7445 };
7446 let Some(Transition::Rule { follow_state, .. }) = atn
7447 .state(state_number)
7448 .and_then(|state| state.transitions().first())
7449 .map(ParserTransition::data)
7450 else {
7451 continue;
7452 };
7453 if self
7454 .cached_state_expected_token_set(atn, follow_state)
7455 .contains(symbol)
7456 {
7457 return true;
7458 }
7459 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7460 return false;
7461 }
7462 }
7463 symbol == TOKEN_EOF
7464 }
7465
7466 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
7468 let error_index = self.input.index();
7469 self.no_viable_alternative_error_at(start_index, error_index)
7470 }
7471
7472 pub fn no_viable_alternative_error_at(
7477 &self,
7478 start_index: usize,
7479 error_index: usize,
7480 ) -> AntlrError {
7481 let diagnostic = self.no_viable_alternative(start_index, error_index);
7482 AntlrError::ParserError {
7483 line: diagnostic.line,
7484 column: diagnostic.column,
7485 message: diagnostic.message,
7486 offending: diagnostic.offending,
7487 }
7488 }
7489
7490 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
7492 let current = self.input.lt(1);
7493 AntlrError::ParserError {
7494 line: current.as_ref().map(Token::line).unwrap_or_default(),
7495 column: current.as_ref().map(Token::column).unwrap_or_default(),
7496 message: format!("rule failed predicate: {}", message.into()),
7497 offending: current.as_ref().map(Token::token_id),
7498 }
7499 }
7500
7501 pub fn failed_predicate_option_error(
7504 &self,
7505 rule_index: usize,
7506 message: impl Into<String>,
7507 ) -> AntlrError {
7508 let current = self.input.lt(1);
7509 let rule_name = self
7510 .rule_names()
7511 .get(rule_index)
7512 .map_or_else(|| rule_index.to_string(), Clone::clone);
7513 AntlrError::ParserError {
7514 line: current.as_ref().map(Token::line).unwrap_or_default(),
7515 column: current.as_ref().map(Token::column).unwrap_or_default(),
7516 message: format!("rule {rule_name} {}", message.into()),
7517 offending: current.as_ref().map(Token::token_id),
7518 }
7519 }
7520
7521 pub fn parser_action_at_current(
7523 &mut self,
7524 source_state: usize,
7525 rule_index: usize,
7526 start_index: usize,
7527 consumed_eof: bool,
7528 ) -> ParserAction {
7529 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7530 ParserAction::new(source_state, rule_index, start_index, stop_index)
7531 }
7532
7533 pub fn parser_action_at_current_indexed(
7535 &mut self,
7536 source_state: usize,
7537 rule_index: usize,
7538 action_index: usize,
7539 start_index: usize,
7540 consumed_eof: bool,
7541 ) -> ParserAction {
7542 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7543 ParserAction::new_indexed(
7544 source_state,
7545 rule_index,
7546 action_index,
7547 start_index,
7548 stop_index,
7549 )
7550 }
7551
7552 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
7557 self.parser_action_hook_inner(action, None, Some(tree), None, true)
7558 }
7559
7560 pub fn parser_action_hook_with_context(
7565 &mut self,
7566 action: ParserAction,
7567 context: &ParserRuleContext,
7568 ) -> bool {
7569 self.parser_action_hook_inner(action, Some(context), None, None, true)
7570 }
7571
7572 pub fn parser_action_hook_with_context_and_local(
7578 &mut self,
7579 action: ParserAction,
7580 context: &ParserRuleContext,
7581 local_int_arg: i32,
7582 ) -> bool {
7583 self.parser_action_hook_inner(
7584 action,
7585 Some(context),
7586 None,
7587 Some((action.rule_index(), i64::from(local_int_arg))),
7588 true,
7589 )
7590 }
7591
7592 fn parser_rule_init_hook_with_context(
7597 &mut self,
7598 action: ParserAction,
7599 context: &ParserRuleContext,
7600 local_int_arg: Option<(usize, i64)>,
7601 ) -> bool {
7602 debug_assert!(action.is_rule_init());
7603 self.parser_action_hook_inner(action, Some(context), None, local_int_arg, false)
7604 }
7605
7606 fn parser_action_hook_inner(
7607 &mut self,
7608 action: ParserAction,
7609 context: Option<&ParserRuleContext>,
7610 tree: Option<ParseTree>,
7611 local_int_arg: Option<(usize, i64)>,
7612 record_unhandled: bool,
7613 ) -> bool {
7614 let rule_index = action.rule_index();
7615 let rule_name = self.rule_names().get(rule_index).cloned();
7616 let input = &mut self.input;
7617 let semantic_hooks = &mut self.semantic_hooks;
7618 let member_values = &self.int_members;
7619 let mut ctx = ParserSemCtx {
7620 input,
7621 tree_storage: &self.tree,
7622 rule_index,
7623 coordinate_index: action.action_index().unwrap_or(usize::MAX),
7624 rule_name,
7625 context,
7626 tree,
7627 local_int_arg,
7628 member_values,
7629 action: Some(action),
7630 };
7631 let handled = semantic_hooks.action(&mut ctx, action);
7632 if record_unhandled
7638 && !handled
7639 && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error)
7640 {
7641 let coordinate = (rule_index, action.source_state());
7642 if !self.unhandled_action_hits.contains(&coordinate) {
7643 self.unhandled_action_hits.push(coordinate);
7644 }
7645 }
7646 handled
7647 }
7648
7649 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
7654 &mut self,
7655 atn: &'atn Atn,
7656 simulator: &mut ParserAtnSimulator<'atn>,
7657 rule_index: usize,
7658 ) -> Result<ParseTree, AntlrError> {
7659 let start_index = self.current_visible_index();
7660 self.clear_prediction_diagnostics();
7661 self.reset_per_parse_caches();
7662 self.reset_recognition_arena();
7663 let tree_checkpoint = self.tree.checkpoint();
7664 let mut decision_by_state = vec![None; atn.states().len()];
7665 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
7666 if let Some(slot) = decision_by_state.get_mut(state_number) {
7667 *slot = Some(decision);
7668 }
7669 }
7670
7671 let result = DirectAdaptiveParser {
7672 parser: self,
7673 atn,
7674 simulator,
7675 decision_by_state,
7676 steps: 0,
7677 }
7678 .parse_rule(rule_index, -1, 0);
7679
7680 match result {
7681 Ok(tree) => {
7682 self.report_token_source_errors();
7683 self.release_tree_scratch_if_idle();
7684 Ok(tree)
7685 }
7686 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
7687 let _ = reason;
7688 self.tree.rollback(tree_checkpoint);
7689 self.input.seek(start_index);
7690 self.parse_atn_rule(atn, rule_index)
7691 }
7692 }
7693 }
7694
7695 pub fn parse_atn_rule(
7705 &mut self,
7706 atn: &Atn,
7707 rule_index: usize,
7708 ) -> Result<ParseTree, AntlrError> {
7709 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
7710 }
7711
7712 pub fn parse_atn_rule_with_precedence(
7715 &mut self,
7716 atn: &Atn,
7717 rule_index: usize,
7718 precedence: i32,
7719 ) -> Result<ParseTree, AntlrError> {
7720 self.parse_atn_rule_with_precedence_inner(
7721 atn,
7722 rule_index,
7723 precedence,
7724 None,
7725 AltNumberTracking::default(),
7726 )
7727 }
7728
7729 fn parse_atn_rule_with_precedence_inner(
7730 &mut self,
7731 atn: &Atn,
7732 rule_index: usize,
7733 precedence: i32,
7734 predicate_context: Option<FastPredicateContext<'_>>,
7735 alt_tracking: AltNumberTracking,
7736 ) -> Result<ParseTree, AntlrError> {
7737 let report_unrecovered_error = self.is_top_level_entry();
7738 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7739 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7740 })?;
7741 let stop_state = atn
7742 .rule_to_stop_state()
7743 .get(rule_index)
7744 .filter(|state| *state != usize::MAX)
7745 .ok_or_else(|| {
7746 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7747 })?;
7748
7749 let start_index = self.current_visible_index();
7750 self.clear_prediction_diagnostics();
7751 self.reset_per_parse_caches();
7752 self.reset_recognition_arena();
7753 let caller_follow_state = self.pending_invoking_follow_state(atn);
7754 self.fast_recovery_enabled = false;
7755 self.fast_token_nodes_enabled = false;
7756 self.fast_track_alt_numbers = alt_tracking.any();
7757 let top_request = FastRecognizeTopRequest {
7758 start_state,
7759 stop_state,
7760 start_index,
7761 precedence,
7762 caller_follow_state,
7763 };
7764 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
7765 self.fast_token_nodes_enabled = self.build_parse_trees;
7766 let needs_tree_retry = matches!(
7767 &first_pass,
7768 Ok((outcome, _, _))
7769 if self.build_parse_trees
7770 && self
7771 .recognition_arena
7772 .sequence_has_left_recursive_boundary(outcome.nodes)
7773 );
7774 let needs_retry = match &first_pass {
7775 Err(_) => true,
7788 Ok((outcome, _, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
7789 };
7790 let (outcome, _expected, alt_number) = if needs_retry {
7791 self.fast_first_set_prefilter = false;
7792 self.fast_recovery_enabled = false;
7793 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7794 let clean_selected = if needs_tree_retry {
7795 match clean_retry {
7796 ok @ Ok(_) => ok,
7797 Err(_) => first_pass,
7798 }
7799 } else {
7800 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
7801 };
7802 let selected = if clean_selected.is_err()
7803 || matches!(&clean_selected, Ok((outcome, _, _)) if !outcome.diagnostics.is_empty())
7804 {
7805 self.fast_recovery_enabled = true;
7806 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7807 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
7808 } else {
7809 clean_selected
7810 };
7811 self.fast_first_set_prefilter = true;
7812 self.fast_recovery_enabled = true;
7813 selected.map_err(|expected| {
7814 if predicate_context.is_some()
7815 && let Some(error) = self.unknown_semantic_error()
7816 {
7817 self.report_token_source_errors();
7818 return error;
7819 }
7820 let error = self.recognition_error(rule_index, start_index, &expected);
7821 self.record_syntax_errors(1);
7822 self.report_token_source_errors();
7823 if report_unrecovered_error {
7824 self.report_unrecovered_parser_error(&error);
7825 }
7826 error
7827 })?
7828 } else {
7829 first_pass.expect("first_pass is Ok in the no-retry branch")
7830 };
7831 if predicate_context.is_some()
7832 && let Some(error) = self.unknown_semantic_error()
7833 {
7834 self.report_token_source_errors();
7835 return Err(error);
7836 }
7837 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7838 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7839 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7840 self.report_token_source_errors();
7841 let mut context = ParserRuleContext::with_child_capacity(
7842 rule_index,
7843 self.state(),
7844 if self.build_parse_trees {
7845 self.recognition_arena.sequence_len(outcome.nodes)
7846 } else {
7847 0
7848 },
7849 );
7850 if alt_tracking.public {
7851 context.set_alt_number(alt_number.max(1));
7852 }
7853 if alt_tracking.context {
7854 context.set_context_alt_number(alt_number);
7855 }
7856 if let Some(token) = self.token_id_at(start_index) {
7857 self.set_context_start(&mut context, token);
7858 }
7859 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
7860 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
7861 self.set_context_stop(&mut context, token);
7862 }
7863 let live_root = if self.build_parse_trees {
7864 self.recognition_arena
7865 .fold_left_recursive_boundaries(outcome.nodes)
7866 } else {
7867 outcome.nodes
7868 };
7869 if self.build_parse_trees {
7870 if self
7871 .recognition_arena
7872 .sequence_has_explicit_token(live_root)
7873 {
7874 let mut cursor = live_root;
7875 while let Some(link) = self.recognition_arena.link(cursor) {
7876 let child = self.arena_recognized_node_tree(
7877 link.head,
7878 alt_tracking.public,
7879 alt_tracking.context,
7880 )?;
7881 self.tree.add_child(&mut context, child);
7882 cursor = link.tail;
7883 }
7884 } else {
7885 self.add_arena_implicit_token_children(
7886 &mut context,
7887 start_index,
7888 stop_index,
7889 live_root,
7890 alt_tracking,
7891 )?;
7892 }
7893 }
7894 self.finish_recognition_arena(live_root, outcome.diagnostics);
7895 self.input.seek(outcome.index);
7896
7897 let tree = self.rule_node(context);
7898 self.release_tree_scratch_if_idle();
7899 Ok(tree)
7900 }
7901
7902 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
7903 let invoking_state = self.pending_invoking_states.last().copied()?;
7904 let state_number = usize::try_from(invoking_state).ok()?;
7905 match atn.state(state_number)?.transitions().first()?.data() {
7906 Transition::Rule { follow_state, .. } => Some(follow_state),
7907 _ => None,
7908 }
7909 }
7910
7911 #[cfg(test)]
7912 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
7913 caller_follow_token_info_for_stream(&mut self.input, index)
7914 }
7915
7916 fn fast_recognize_top(
7921 &mut self,
7922 atn: &Atn,
7923 request: FastRecognizeTopRequest,
7924 predicate_context: Option<FastPredicateContext<'_>>,
7925 ) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
7926 let FastRecognizeTopRequest {
7927 start_state,
7928 stop_state,
7929 start_index,
7930 precedence,
7931 caller_follow_state,
7932 } = request;
7933 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
7942 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
7943 recognize_scratch.prepare(memo_capacity);
7944 let mut expected = ExpectedTokens::default();
7945 let empty_recovery = self.empty_recovery_symbols();
7946 let outcomes = self.recognize_state_fast(
7947 atn,
7948 FastRecognizeRequest {
7949 state_number: start_state,
7950 stop_state,
7951 index: start_index,
7952 rule_start_index: start_index,
7953 decision_start_index: None,
7954 precedence,
7955 depth: 0,
7956 recovery_symbols: empty_recovery,
7957 recovery_state: None,
7958 },
7959 FastRecognizeScratch {
7960 predicate_context,
7961 visiting: &mut recognize_scratch.visiting,
7962 memo: &mut recognize_scratch.memo,
7963 expected: &mut expected,
7964 native_depth: 0,
7965 },
7966 );
7967 recognize_scratch.release_oversized_memo();
7968 self.fast_recognize_scratch = recognize_scratch;
7969 #[cfg(feature = "perf-counters")]
7970 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
7971 perf_counters::dump();
7972 perf_counters::reset();
7973 }
7974 let caller_follow =
7975 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
7976 let selected = {
7977 let arena = &self.recognition_arena;
7978 let input = &mut self.input;
7979 select_best_fast_outcome(
7980 outcomes.into_iter(),
7981 self.prediction_mode,
7982 caller_follow.as_deref(),
7983 |index| caller_follow_token_info_for_stream(input, index),
7984 arena,
7985 )
7986 };
7987 match selected {
7988 Some(mut outcome) => {
7989 let alt_number = if self.build_parse_trees || self.fast_track_alt_numbers {
7990 self.materialize_fast_outcome_nodes(&mut outcome)
7991 } else {
7992 0
7993 };
7994 Ok((outcome, expected, alt_number))
7995 }
7996 None => Err(expected),
7997 }
7998 }
7999
8000 fn arena_recognized_node_tree(
8002 &mut self,
8003 node_id: RecognizedNodeId,
8004 track_alt_numbers: bool,
8005 track_context_alt_numbers: bool,
8006 ) -> Result<ParseTree, AntlrError> {
8007 let node = self.recognition_arena.node(node_id);
8008 match node {
8009 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
8010 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
8011 ArenaRecognizedNode::MissingToken { extra } => {
8012 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
8013 RecognitionExtra::MissingToken {
8014 token_type,
8015 at_index,
8016 text,
8017 } => (*token_type, *at_index as usize, text.clone()),
8018 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
8019 unreachable!("missing-token node must reference missing-token extra")
8020 }
8021 };
8022 let (line, column) = self
8023 .token_at(at_index)
8024 .map_or((0, 0), |token| (token.line(), token.column()));
8025 let token = self.insert_synthetic_token(token_type, text, line, column)?;
8026 Ok(self.error_tree(token))
8027 }
8028 ArenaRecognizedNode::Rule {
8029 rule_index,
8030 invoking_state,
8031 alt_number,
8032 start_index,
8033 stop_index,
8034 return_values,
8035 children,
8036 } => {
8037 let mut context = ParserRuleContext::with_child_capacity(
8038 rule_index as usize,
8039 invoking_state as isize,
8040 self.recognition_arena.sequence_len(children),
8041 );
8042 if track_alt_numbers {
8043 context.set_alt_number((alt_number as usize).max(1));
8044 }
8045 if track_context_alt_numbers {
8046 context.set_context_alt_number(alt_number as usize);
8047 }
8048 if let Some(extra) = return_values {
8049 let RecognitionExtra::ReturnValues(values) =
8050 self.recognition_arena.extra(extra)
8051 else {
8052 unreachable!("rule node must reference return-values extra");
8053 };
8054 for (name, value) in values {
8055 context.set_int_return(name.clone(), *value);
8056 }
8057 }
8058 if let Some(token) = self.token_id_at(start_index as usize) {
8059 self.set_context_start(&mut context, token);
8060 }
8061 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
8062 self.set_context_stop(&mut context, token);
8063 }
8064 let mut cursor = self
8065 .recognition_arena
8066 .fold_left_recursive_boundaries(children);
8067 while let Some(link) = self.recognition_arena.link(cursor) {
8068 let child = self.arena_recognized_node_tree(
8069 link.head,
8070 track_alt_numbers,
8071 track_context_alt_numbers,
8072 )?;
8073 self.tree.add_child(&mut context, child);
8074 cursor = link.tail;
8075 }
8076 Ok(self.rule_node(context))
8077 }
8078 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
8079 Err(AntlrError::Unsupported(format!(
8080 "unfolded left-recursive boundary for rule {rule_index}"
8081 )))
8082 }
8083 }
8084 }
8085
8086 fn arena_recognized_node_tree_with_implicit_tokens(
8087 &mut self,
8088 node_id: RecognizedNodeId,
8089 alt_tracking: AltNumberTracking,
8090 ) -> Result<ParseTree, AntlrError> {
8091 let node = self.recognition_arena.node(node_id);
8092 match node {
8093 ArenaRecognizedNode::Rule {
8094 rule_index,
8095 invoking_state,
8096 alt_number,
8097 start_index,
8098 stop_index,
8099 children,
8100 ..
8101 } => {
8102 let mut context = ParserRuleContext::with_child_capacity(
8103 rule_index as usize,
8104 invoking_state as isize,
8105 self.recognition_arena.sequence_len(children),
8106 );
8107 if alt_tracking.public {
8108 context.set_alt_number((alt_number as usize).max(1));
8109 }
8110 if alt_tracking.context {
8111 context.set_context_alt_number(alt_number as usize);
8112 }
8113 if let Some(token) = self.token_id_at(start_index as usize) {
8114 self.set_context_start(&mut context, token);
8115 }
8116 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
8117 self.set_context_stop(&mut context, token);
8118 }
8119 let children = self
8120 .recognition_arena
8121 .fold_left_recursive_boundaries(children);
8122 self.add_arena_implicit_token_children(
8123 &mut context,
8124 start_index as usize,
8125 stop_index.map(|index| index as usize),
8126 children,
8127 alt_tracking,
8128 )?;
8129 Ok(self.rule_node(context))
8130 }
8131 _ => {
8132 self.arena_recognized_node_tree(node_id, alt_tracking.public, alt_tracking.context)
8133 }
8134 }
8135 }
8136
8137 fn add_arena_implicit_token_children(
8138 &mut self,
8139 context: &mut ParserRuleContext,
8140 start_index: usize,
8141 stop_index: Option<usize>,
8142 mut children: NodeSeqId,
8143 alt_tracking: AltNumberTracking,
8144 ) -> Result<(), AntlrError> {
8145 let mut cursor = Some(start_index);
8146 while let Some(link) = self.recognition_arena.link(children) {
8147 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
8148 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
8149 let child =
8150 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
8151 self.tree.add_child(context, child);
8152 if let Some(child_stop) = child_stop {
8153 let next = self.next_visible_after_token(child_stop);
8154 cursor = match (cursor, next) {
8155 (None, _) | (_, None) => None,
8156 (Some(current), Some(next)) => Some(current.max(next)),
8157 };
8158 }
8159 } else {
8160 let child =
8161 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
8162 self.tree.add_child(context, child);
8163 }
8164 children = link.tail;
8165 }
8166 if let Some(stop) = stop_index {
8167 self.add_visible_terminals_through(context, cursor, stop)?;
8168 }
8169 Ok(())
8170 }
8171
8172 fn add_visible_terminals_before(
8173 &mut self,
8174 context: &mut ParserRuleContext,
8175 cursor: &mut Option<usize>,
8176 before: usize,
8177 ) -> Result<(), AntlrError> {
8178 let Some(stop) = before.checked_sub(1) else {
8179 return Ok(());
8180 };
8181 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
8182 *cursor = next;
8183 Ok(())
8184 }
8185
8186 fn add_visible_terminals_through(
8187 &mut self,
8188 context: &mut ParserRuleContext,
8189 mut cursor: Option<usize>,
8190 stop: usize,
8191 ) -> Result<Option<usize>, AntlrError> {
8192 while let Some(index) = cursor {
8193 if index > stop {
8194 return Ok(Some(index));
8195 }
8196 let token = self
8197 .input
8198 .get_id(index)
8199 .ok_or_else(|| AntlrError::ParserError {
8200 line: 0,
8201 column: 0,
8202 message: format!("missing token at index {index}"),
8203 offending: None,
8204 })?;
8205 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
8206 let child = self.terminal_tree(token);
8207 self.tree.add_child(context, child);
8208 if is_eof {
8209 return Ok(None);
8210 }
8211 cursor = self.next_visible_after_token(index);
8212 }
8213 Ok(None)
8214 }
8215
8216 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
8217 let next = self.input.next_visible_after(index);
8218 (next != index).then_some(next)
8219 }
8220
8221 pub fn parse_atn_rule_with_actions(
8228 &mut self,
8229 atn: &Atn,
8230 rule_index: usize,
8231 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8232 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
8233 }
8234
8235 pub fn parse_atn_rule_with_action_inits(
8243 &mut self,
8244 atn: &Atn,
8245 rule_index: usize,
8246 init_action_rules: &[usize],
8247 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8248 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
8249 }
8250
8251 pub fn parse_atn_rule_with_action_options(
8257 &mut self,
8258 atn: &Atn,
8259 rule_index: usize,
8260 init_action_rules: &[usize],
8261 track_alt_numbers: bool,
8262 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8263 self.parse_atn_rule_with_runtime_options(
8264 atn,
8265 rule_index,
8266 ParserRuntimeOptions {
8267 init_action_rules,
8268 track_alt_numbers,
8269 ..ParserRuntimeOptions::default()
8270 },
8271 )
8272 }
8273
8274 pub fn parse_atn_rule_with_runtime_options(
8281 &mut self,
8282 atn: &Atn,
8283 rule_index: usize,
8284 options: ParserRuntimeOptions<'_>,
8285 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8286 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
8287 }
8288
8289 fn parse_atn_rule_committed_with_runtime_options(
8290 &mut self,
8291 atn: &Atn,
8292 rule_index: usize,
8293 precedence: i32,
8294 options: ParserRuntimeOptions<'_>,
8295 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8296 let top_level_entry = self.is_top_level_entry();
8297 self.unknown_predicate_policy = options.unknown_predicate_policy;
8298 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8299 let prior_unhandled_action_hits = std::mem::take(&mut self.unhandled_action_hits);
8300 self.clear_prediction_diagnostics();
8301 self.reset_per_parse_caches();
8302 self.reset_recognition_arena();
8303
8304 let mut decision_by_state = vec![None; atn.states().len()];
8305 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
8306 if let Some(slot) = decision_by_state.get_mut(state_number) {
8307 *slot = Some(decision);
8308 }
8309 }
8310 let mut action_index_by_state = FxHashMap::default();
8311 for &(state, index) in options.action_indices {
8312 action_index_by_state.entry(state).or_insert(index);
8313 }
8314 let mut simulator = ParserAtnSimulator::new(atn);
8315 simulator.set_track_prediction_rule_calls(!options.rule_args.is_empty());
8316 let (result, deferred_actions) = {
8317 let mut committed = CommittedAtnParser {
8318 parser: self,
8319 atn,
8320 simulator,
8321 options,
8322 decision_by_state,
8323 action_index_by_state,
8324 deferred_actions: Vec::new(),
8325 };
8326 let result = committed.parse_rule(rule_index, precedence, None, None);
8327 (result, committed.deferred_actions)
8328 };
8329
8330 if top_level_entry {
8331 self.report_generated_parser_diagnostics();
8332 }
8333 let semantic_error = self.unknown_semantic_error();
8334 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8335 self.restore_prior_unhandled_action_hits(prior_unhandled_action_hits);
8336 if top_level_entry && let Some(error) = self.take_parse_abort() {
8337 self.reset_unknown_semantic_hits();
8338 return Err(error);
8339 }
8340 if let Some(error) = semantic_error {
8341 if top_level_entry {
8342 self.reset_unknown_semantic_hits();
8343 }
8344 return Err(error);
8345 }
8346 let result = result.map(|outcome| (outcome.tree, deferred_actions));
8347 if top_level_entry && let Err(error) = &result {
8348 self.report_unrecovered_parser_error(error);
8349 }
8350 result
8351 }
8352
8353 pub fn parse_atn_rule_with_runtime_options_and_precedence(
8356 &mut self,
8357 atn: &Atn,
8358 rule_index: usize,
8359 precedence: i32,
8360 options: ParserRuntimeOptions<'_>,
8361 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8362 if !options.action_indices.is_empty() {
8363 return self.parse_atn_rule_committed_with_runtime_options(
8364 atn, rule_index, precedence, options,
8365 );
8366 }
8367 let report_unrecovered_error = self.is_top_level_entry();
8368 let ParserRuntimeOptions {
8369 init_action_rules,
8370 track_alt_numbers,
8371 track_context_alt_numbers,
8372 predicates,
8373 semantics,
8374 rule_args,
8375 member_actions,
8376 return_actions,
8377 unknown_predicate_policy,
8378 ..
8379 } = options;
8380 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
8381 if init_action_rules.is_empty()
8382 && !capture_alt_numbers
8383 && predicates.is_empty()
8384 && semantics.is_none()
8385 && rule_args.is_empty()
8386 && member_actions.is_empty()
8387 && return_actions.is_empty()
8388 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
8389 && !atn_has_observable_action_transitions(atn)
8390 && !self.semantic_hooks.observes_parser_decisions()
8391 && (!self.semantic_hooks.observes_parser_predicates()
8392 || !atn_has_predicate_transitions(atn))
8393 {
8394 return self
8395 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
8396 .map(|tree| (tree, Vec::new()));
8397 }
8398 if !self.semantic_hooks.observes_parser_decisions()
8399 && can_use_fast_predicate_recognizer(atn, &options)
8400 {
8401 self.unknown_predicate_policy = unknown_predicate_policy;
8402 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8403 let member_values = self.int_members.clone();
8404 let result = self
8405 .parse_atn_rule_with_precedence_inner(
8406 atn,
8407 rule_index,
8408 precedence,
8409 Some(FastPredicateContext {
8410 predicates,
8411 semantics,
8412 member_values: &member_values,
8413 }),
8414 AltNumberTracking {
8415 public: track_alt_numbers,
8416 context: track_context_alt_numbers,
8417 },
8418 )
8419 .map(|tree| (tree, Vec::new()));
8420 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
8421 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8422 }
8423 return result;
8424 }
8425 self.unknown_predicate_policy = unknown_predicate_policy;
8426 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8433 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
8434 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
8435 })?;
8436 let stop_state = atn
8437 .rule_to_stop_state()
8438 .get(rule_index)
8439 .filter(|state| *state != usize::MAX)
8440 .ok_or_else(|| {
8441 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
8442 })?;
8443
8444 let start_index = self.current_visible_index();
8445 self.clear_prediction_diagnostics();
8446 self.reset_per_parse_caches();
8447 self.reset_recognition_arena();
8448 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
8449 let invoking_state = self.pending_invoking_states.pop();
8450 let local_int_arg = invoking_state
8451 .and_then(|state| usize::try_from(state).ok())
8452 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
8453 let mut visiting = BTreeSet::new();
8454 let mut memo = BTreeMap::new();
8455 let mut expected = ExpectedTokens::default();
8456 let member_values = self.int_members.clone();
8457 let return_values = BTreeMap::new();
8458 let outcomes = self.recognize_state(
8459 atn,
8460 RecognizeRequest {
8461 state_number: start_state,
8462 stop_state,
8463 index: start_index,
8464 rule_start_index: start_index,
8465 decision_start_index: None,
8466 init_action_rules: &init_action_rules,
8467 predicates,
8468 semantics,
8469 rule_args,
8470 member_actions,
8471 return_actions,
8472 local_int_arg,
8473 member_values,
8474 return_values,
8475 rule_alt_number: 0,
8476 track_alt_numbers: capture_alt_numbers,
8477 consumed_eof: false,
8478 committed_decision: false,
8479 precedence,
8480 depth: 0,
8481 recovery_symbols: BTreeSet::new(),
8482 recovery_state: None,
8483 },
8484 &mut visiting,
8485 &mut memo,
8486 &mut expected,
8487 );
8488 if let Some(error) = self.unknown_semantic_error() {
8489 self.report_token_source_errors();
8490 return Err(error);
8497 }
8498 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8501 let Some(outcome) = select_best_outcome(
8502 outcomes.into_iter(),
8503 self.prediction_mode,
8504 &self.recognition_arena,
8505 ) else {
8506 let error = self.recognition_error(rule_index, start_index, &expected);
8507 self.record_syntax_errors(1);
8508 self.report_token_source_errors();
8509 if report_unrecovered_error {
8510 self.report_unrecovered_parser_error(&error);
8511 }
8512 return Err(error);
8513 };
8514
8515 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
8516 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
8517 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
8518 self.report_token_source_errors();
8519 let mut actions = outcome.actions;
8520 if init_action_rules.contains(&rule_index) {
8521 actions.insert(
8522 0,
8523 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
8524 );
8525 }
8526 let mut context =
8527 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
8528 if track_alt_numbers {
8529 context.set_alt_number(outcome.alt_number.max(1));
8530 }
8531 if track_context_alt_numbers {
8532 context.set_context_alt_number(outcome.alt_number);
8533 }
8534 for (name, value) in outcome.return_values {
8535 context.set_int_return(name, value);
8536 }
8537 if let Some(token) = self.token_id_at(start_index) {
8538 self.set_context_start(&mut context, token);
8539 }
8540 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
8541 self.set_context_stop(&mut context, token);
8542 }
8543 let live_root = if self.build_parse_trees {
8544 self.recognition_arena
8545 .fold_left_recursive_boundaries(outcome.nodes)
8546 } else {
8547 outcome.nodes
8548 };
8549 if self.build_parse_trees {
8550 let mut nodes = live_root;
8551 while let Some(link) = self.recognition_arena.link(nodes) {
8552 let child = self.arena_recognized_node_tree(
8553 link.head,
8554 track_alt_numbers,
8555 track_context_alt_numbers,
8556 )?;
8557 self.tree.add_child(&mut context, child);
8558 nodes = link.tail;
8559 }
8560 }
8561 self.finish_recognition_arena(live_root, outcome.diagnostics);
8562 self.input.seek(outcome.index);
8563
8564 let tree = self.rule_node(context);
8565 self.release_tree_scratch_if_idle();
8566 Ok((tree, actions))
8567 }
8568
8569 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
8576 let mut context = ParserRuleContext::new(rule_index, self.state());
8577 while self.la(1) != TOKEN_EOF {
8578 let token_type = self.la(1);
8579 let child = self.match_token(token_type)?;
8580 if self.build_parse_trees {
8581 self.tree.add_child(&mut context, child);
8582 }
8583 }
8584 if self.build_parse_trees {
8585 let child = self.match_eof()?;
8586 self.tree.add_child(&mut context, child);
8587 }
8588 let tree = self.rule_node(context);
8589 self.release_tree_scratch_if_idle();
8590 Ok(tree)
8591 }
8592
8593 fn recognition_error(
8596 &mut self,
8597 rule_index: usize,
8598 start_index: usize,
8599 expected: &ExpectedTokens,
8600 ) -> AntlrError {
8601 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
8602 self.input.seek(index);
8603 let current = self.input.lt(1);
8604 let line = current.as_ref().map(Token::line).unwrap_or_default();
8605 let column = current.as_ref().map(Token::column).unwrap_or_default();
8606 AntlrError::ParserError {
8607 line,
8608 column,
8609 message,
8610 offending: current.as_ref().map(Token::token_id),
8611 }
8612 }
8613
8614 fn expected_error_message(
8616 &mut self,
8617 rule_index: usize,
8618 start_index: usize,
8619 expected: &ExpectedTokens,
8620 ) -> (usize, String) {
8621 let index = expected
8622 .index
8623 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
8624 .unwrap_or_else(|| self.input.index());
8625 self.input.seek(index);
8626 let current = self.input.lt(1);
8627 let message = if expected
8628 .no_viable
8629 .as_ref()
8630 .is_some_and(|no_viable| no_viable.error_index == index)
8631 {
8632 let start = expected
8633 .no_viable
8634 .as_ref()
8635 .map_or(start_index, |no_viable| no_viable.start_index);
8636 let text = display_input_text(&self.input.text(start, index));
8637 format!("no viable alternative at input '{text}'")
8638 } else if expected.symbols.is_empty() {
8639 if expected.index.is_some() {
8640 let found = current
8641 .as_ref()
8642 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
8643 if current
8644 .as_ref()
8645 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8646 {
8647 format!(
8648 "missing {} at {found}",
8649 self.expected_symbols_display(&expected.symbols)
8650 )
8651 } else {
8652 format!("mismatched input {found}")
8653 }
8654 } else {
8655 format!("no viable alternative while parsing rule {rule_index}")
8656 }
8657 } else {
8658 format!(
8659 "mismatched input {} expecting {}",
8660 current
8661 .as_ref()
8662 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8663 self.expected_symbols_display(&expected.symbols)
8664 )
8665 };
8666 (index, message)
8667 }
8668
8669 fn child_rule_failure_recovery(
8672 &mut self,
8673 rule_index: usize,
8674 start_index: usize,
8675 sync_symbols: &BTreeSet<i32>,
8676 member_values: MemberEnv,
8677 expected: &ExpectedTokens,
8678 ) -> Option<RecognizeOutcome> {
8679 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8680 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8681 let mut next_index = error_index;
8682 loop {
8683 let symbol = self.token_type_at(next_index);
8684 if sync_symbols.contains(&symbol) {
8685 if next_index == error_index {
8686 return None;
8687 }
8688 break;
8689 }
8690 if symbol == TOKEN_EOF {
8691 break;
8692 }
8693 let after = self.consume_index(next_index, symbol);
8694 if after == next_index {
8695 break;
8696 }
8697 next_index = after;
8698 }
8699 let mut nodes = NodeSeqId::EMPTY;
8700 let error = self.arena_token_node(error_index, true);
8701 self.arena_prepend(&mut nodes, error);
8702 let diagnostics = self
8703 .recognition_arena
8704 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8705 Some(RecognizeOutcome {
8706 index: next_index,
8707 consumed_eof: false,
8708 alt_number: 0,
8709 member_values,
8710 return_values: BTreeMap::new(),
8711 diagnostics,
8712 decisions: Vec::new(),
8713 actions: Vec::new(),
8714 nodes,
8715 })
8716 }
8717
8718 fn child_rule_failure_recovery_outcomes(
8721 &mut self,
8722 request: ChildRuleFailureRecovery<'_>,
8723 ) -> Vec<RecognizeOutcome> {
8724 let sync_symbols =
8725 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
8726 self.child_rule_failure_recovery(
8727 request.rule_index,
8728 request.start_index,
8729 &sync_symbols,
8730 request.member_values,
8731 request.expected,
8732 )
8733 .into_iter()
8734 .collect()
8735 }
8736
8737 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
8739 expected_symbols_display(symbols, self.vocabulary())
8740 }
8741
8742 fn single_token_deletion(
8745 &mut self,
8746 transition: ParserTransition<'_>,
8747 index: usize,
8748 max_token_type: i32,
8749 expected_symbols: &BTreeSet<i32>,
8750 ) -> Option<(ParserDiagnostic, usize, i32)> {
8751 let current_symbol = self.token_type_at(index);
8752 if current_symbol == TOKEN_EOF {
8753 return None;
8754 }
8755 let next_index = self.consume_index(index, current_symbol);
8756 if next_index == index {
8757 return None;
8758 }
8759 let next_symbol = self.token_type_at(next_index);
8760 if !transition.matches(next_symbol, 1, max_token_type) {
8761 return None;
8762 }
8763 let transition_expected = transition_expected_symbols(transition, max_token_type);
8764 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8765 &transition_expected
8766 } else {
8767 expected_symbols
8768 });
8769 let current = self.token_at(index);
8770 let message = format!(
8771 "extraneous input {} expecting {expected_display}",
8772 current
8773 .as_ref()
8774 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8775 );
8776 Some((
8777 diagnostic_for_token(current, message),
8778 next_index,
8779 next_symbol,
8780 ))
8781 }
8782
8783 fn current_token_deletion(
8786 &mut self,
8787 index: usize,
8788 expected_symbols: &BTreeSet<i32>,
8789 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
8790 if expected_symbols.is_empty() {
8791 return None;
8792 }
8793 let current_symbol = self.token_type_at(index);
8794 if current_symbol == TOKEN_EOF {
8795 return None;
8796 }
8797 let current = self.token_at(index);
8798 let message = format!(
8799 "extraneous input {} expecting {}",
8800 current
8801 .as_ref()
8802 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8803 self.expected_symbols_display(expected_symbols)
8804 );
8805 let diagnostic = diagnostic_for_token(current, message);
8806 let mut skipped = Vec::new();
8807 let mut cursor = index;
8808 loop {
8809 let symbol = self.token_type_at(cursor);
8810 if symbol == TOKEN_EOF {
8811 return None;
8812 }
8813 skipped.push(cursor);
8814 let next_index = self.consume_index(cursor, symbol);
8815 if next_index == cursor {
8816 return None;
8817 }
8818 let next_symbol = self.token_type_at(next_index);
8819 if expected_symbols.contains(&next_symbol) {
8820 return Some((diagnostic, next_index, skipped));
8821 }
8822 cursor = next_index;
8823 }
8824 }
8825
8826 fn single_token_insertion(
8830 &mut self,
8831 transition: ParserTransition<'_>,
8832 index: usize,
8833 max_token_type: i32,
8834 expected_symbols: &BTreeSet<i32>,
8835 follow_symbols: &BTreeSet<i32>,
8836 ) -> Option<(ParserDiagnostic, i32, String)> {
8837 let current_symbol = self.token_type_at(index);
8838 if !follow_symbols.contains(¤t_symbol) {
8839 return None;
8840 }
8841 let transition_expected = transition_expected_symbols(transition, max_token_type);
8842 let token_type = transition_expected.iter().next().copied()?;
8843 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8844 &transition_expected
8845 } else {
8846 expected_symbols
8847 });
8848 let mut token_symbols = BTreeSet::new();
8849 token_symbols.insert(token_type);
8850 let missing_token_display = self.expected_symbols_display(&token_symbols);
8851 let current = self.token_at(index);
8852 let message = format!(
8853 "missing {expected_display} at {}",
8854 current
8855 .as_ref()
8856 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8857 );
8858 let text = format!("<missing {missing_token_display}>");
8859 Some((
8860 diagnostic_for_token(current.as_ref(), message),
8861 token_type,
8862 text,
8863 ))
8864 }
8865
8866 fn fast_single_token_deletion_recovery(
8870 &mut self,
8871 recovery: FastRecoveryRequest<'_, '_>,
8872 predicate_context: Option<FastPredicateContext<'_>>,
8873 ) -> Vec<FastRecognizeOutcome> {
8874 let FastRecoveryRequest {
8875 atn,
8876 transition,
8877 expected_symbols,
8878 target,
8879 request,
8880 visiting,
8881 memo,
8882 expected,
8883 } = recovery;
8884 let FastRecognizeRequest {
8885 stop_state,
8886 index,
8887 rule_start_index,
8888 decision_start_index,
8889 precedence,
8890 depth,
8891 ..
8892 } = request;
8893 let Some((diagnostic, next_index, next_symbol)) =
8894 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8895 else {
8896 return Vec::new();
8897 };
8898 let after_next = self.consume_index(next_index, next_symbol);
8899 let empty_recovery = self.empty_recovery_symbols();
8900 self.recognize_state_fast(
8901 atn,
8902 FastRecognizeRequest {
8903 state_number: target,
8904 stop_state,
8905 index: after_next,
8906 rule_start_index,
8907 decision_start_index,
8908 precedence,
8909 depth: depth + 1,
8910 recovery_symbols: empty_recovery,
8911 recovery_state: None,
8912 },
8913 FastRecognizeScratch {
8914 predicate_context,
8915 visiting,
8916 memo,
8917 expected,
8918 native_depth: 0,
8919 },
8920 )
8921 .into_iter()
8922 .map(|mut outcome| {
8923 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
8924 outcome.diagnostics = self
8925 .recognition_arena
8926 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8927 if self.fast_token_nodes_enabled {
8928 let token = self.arena_token_node(next_index, false);
8929 self.defer_fast_outcome_node(&mut outcome, token);
8930 let error = self.arena_token_node(index, true);
8931 self.defer_fast_outcome_node(&mut outcome, error);
8932 }
8933 outcome
8934 })
8935 .collect()
8936 }
8937
8938 fn fast_single_token_insertion_recovery(
8942 &mut self,
8943 recovery: FastRecoveryRequest<'_, '_>,
8944 predicate_context: Option<FastPredicateContext<'_>>,
8945 ) -> Vec<FastRecognizeOutcome> {
8946 let FastRecoveryRequest {
8947 atn,
8948 transition,
8949 expected_symbols,
8950 target,
8951 request,
8952 visiting,
8953 memo,
8954 expected,
8955 } = recovery;
8956 let FastRecognizeRequest {
8957 stop_state,
8958 index,
8959 rule_start_index,
8960 decision_start_index,
8961 precedence,
8962 depth,
8963 ..
8964 } = request;
8965 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
8966 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
8967 transition,
8968 index,
8969 atn.max_token_type(),
8970 &expected_symbols,
8971 &follow_symbols,
8972 ) else {
8973 return Vec::new();
8974 };
8975 let empty_recovery = self.empty_recovery_symbols();
8976 self.recognize_state_fast(
8977 atn,
8978 FastRecognizeRequest {
8979 state_number: target,
8980 stop_state,
8981 index,
8982 rule_start_index,
8983 decision_start_index,
8984 precedence,
8985 depth: depth + 1,
8986 recovery_symbols: empty_recovery,
8987 recovery_state: None,
8988 },
8989 FastRecognizeScratch {
8990 predicate_context,
8991 visiting,
8992 memo,
8993 expected,
8994 native_depth: 0,
8995 },
8996 )
8997 .into_iter()
8998 .map(|mut outcome| {
8999 outcome.diagnostics = self
9000 .recognition_arena
9001 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9002 let missing = self.arena_missing_token_node(token_type, index, text.clone());
9003 self.defer_fast_outcome_node(&mut outcome, missing);
9004 outcome
9005 })
9006 .collect()
9007 }
9008
9009 fn fast_current_token_deletion_recovery(
9012 &mut self,
9013 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
9014 predicate_context: Option<FastPredicateContext<'_>>,
9015 ) -> Vec<FastRecognizeOutcome> {
9016 let FastCurrentTokenDeletionRequest {
9017 atn,
9018 expected_symbols,
9019 mut request,
9020 visiting,
9021 memo,
9022 expected,
9023 } = recovery;
9024 if request.index == request.rule_start_index {
9025 return Vec::new();
9026 }
9027 let Some((diagnostic, next_index, skipped)) =
9028 self.current_token_deletion(request.index, &expected_symbols)
9029 else {
9030 return Vec::new();
9031 };
9032 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9033 request.index = next_index;
9034 request.depth += 1;
9035 request.recovery_state = None;
9036 self.recognize_state_fast(
9037 atn,
9038 request,
9039 FastRecognizeScratch {
9040 predicate_context,
9041 visiting,
9042 memo,
9043 expected,
9044 native_depth: 0,
9045 },
9046 )
9047 .into_iter()
9048 .map(|mut outcome| {
9049 outcome.diagnostics = self
9050 .recognition_arena
9051 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9052 for index in skipped.iter().rev() {
9053 let error = self.arena_token_node(*index, true);
9054 self.defer_fast_outcome_node(&mut outcome, error);
9055 }
9056 outcome
9057 })
9058 .collect()
9059 }
9060
9061 fn fast_child_rule_failure_recovery(
9064 &mut self,
9065 rule_index: usize,
9066 start_index: usize,
9067 sync_symbols: &BTreeSet<i32>,
9068 expected: &ExpectedTokens,
9069 ) -> Option<FastRecognizeOutcome> {
9070 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
9071 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
9072 let mut next_index = error_index;
9073 loop {
9074 let symbol = self.token_type_at(next_index);
9075 if sync_symbols.contains(&symbol) {
9076 if next_index == error_index {
9077 return None;
9078 }
9079 break;
9080 }
9081 if symbol == TOKEN_EOF {
9082 break;
9083 }
9084 let after = self.consume_index(next_index, symbol);
9085 if after == next_index {
9086 break;
9087 }
9088 next_index = after;
9089 }
9090 let diagnostics = self
9091 .recognition_arena
9092 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
9093 let mut nodes = NodeSeqId::EMPTY;
9094 if self.fast_token_nodes_enabled {
9095 let error = self.arena_token_node(error_index, true);
9096 self.arena_prepend(&mut nodes, error);
9097 }
9098 Some(FastRecognizeOutcome {
9099 index: next_index,
9100 consumed_eof: false,
9101 diagnostics,
9102 deferred_nodes: FastDeferredNodeId::EMPTY,
9103 nodes,
9104 })
9105 }
9106
9107 fn fast_child_rule_failure_recovery_outcomes(
9110 &mut self,
9111 request: FastChildRuleFailureRecoveryRequest<'_>,
9112 ) -> Vec<FastRecognizeOutcome> {
9113 let FastChildRuleFailureRecoveryRequest {
9114 atn,
9115 rule_index,
9116 start_index,
9117 follow_state,
9118 stop_state,
9119 expected,
9120 } = request;
9121 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
9122 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
9123 .into_iter()
9124 .collect()
9125 }
9126
9127 fn defer_fast_outcome_node(
9128 &mut self,
9129 outcome: &mut FastRecognizeOutcome,
9130 node: RecognizedNodeId,
9131 ) {
9132 if outcome.deferred_nodes.is_empty() {
9133 self.arena_prepend(&mut outcome.nodes, node);
9134 return;
9135 }
9136 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
9137 let fragment = self.recognition_arena.deferred_fragment(fragment);
9138 outcome.deferred_nodes = self
9139 .recognition_arena
9140 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
9141 }
9142
9143 fn defer_fast_outcome_alternative(
9144 &mut self,
9145 outcome: &mut FastRecognizeOutcome,
9146 alt_number: usize,
9147 ) {
9148 let alternative = self.recognition_arena.deferred_alternative(alt_number);
9149 outcome.deferred_nodes = self
9150 .recognition_arena
9151 .concat_deferred_nodes(alternative, outcome.deferred_nodes);
9152 }
9153
9154 fn defer_fast_outcome_boundary(
9155 &mut self,
9156 outcome: &mut FastRecognizeOutcome,
9157 rule_index: usize,
9158 ) {
9159 let boundary = self
9160 .recognition_arena
9161 .deferred_left_recursive_boundary(rule_index);
9162 outcome.deferred_nodes = self
9163 .recognition_arena
9164 .concat_deferred_nodes(boundary, outcome.deferred_nodes);
9165 }
9166
9167 fn materialize_fast_deferred_nodes(
9168 &mut self,
9169 root: FastDeferredNodeId,
9170 initial_suffix: NodeSeqId,
9171 ) -> (NodeSeqId, usize) {
9172 if root.is_empty() {
9173 return (initial_suffix, 0);
9174 }
9175
9176 enum Frame {
9177 Visit(FastDeferredNodeId),
9178 ContinuePrefix(FastDeferredNodeId),
9179 FinishRule {
9180 rule: FastDeferredRule,
9181 parent_suffix: NodeSeqId,
9182 parent_alt_number: u32,
9183 parent_pending_boundary: Option<RecognizedNodeId>,
9184 },
9185 }
9186
9187 let mut result = initial_suffix;
9188 let mut alt_number = 0;
9192 let mut pending_boundary = None;
9193 let mut pending = Vec::with_capacity(16);
9194 pending.push(Frame::Visit(root));
9195 let mut fragment_nodes = Vec::new();
9196 while let Some(frame) = pending.pop() {
9197 match frame {
9198 Frame::Visit(deferred) => {
9199 if deferred.is_empty() {
9200 continue;
9201 }
9202
9203 match self.recognition_arena.deferred_node(deferred) {
9204 FastDeferredNode::Fragment(sequence) => {
9205 fragment_nodes.clear();
9206 fragment_nodes.extend(self.recognition_arena.iter(sequence));
9207 while let Some(node) = fragment_nodes.pop() {
9208 self.arena_prepend(&mut result, node);
9209 }
9210 }
9211 FastDeferredNode::Rule(rule) => {
9212 let rule = self.recognition_arena.deferred_rule(rule);
9213 let parent_suffix = result;
9214 let parent_alt_number = alt_number;
9215 let parent_pending_boundary = pending_boundary;
9216 result = rule.children;
9217 alt_number = 0;
9218 pending_boundary = None;
9219 pending.push(Frame::FinishRule {
9220 rule,
9221 parent_suffix,
9222 parent_alt_number,
9223 parent_pending_boundary,
9224 });
9225 pending.push(Frame::Visit(rule.deferred_children));
9226 }
9227 FastDeferredNode::Alternative(selected) => {
9228 if let Some(boundary) = pending_boundary {
9229 self.recognition_arena
9230 .set_boundary_alt_number(boundary, selected);
9231 } else {
9232 alt_number = selected;
9233 }
9234 }
9235 FastDeferredNode::LeftRecursiveBoundary { rule_index } => {
9236 let boundary = self.arena_boundary_node(rule_index as usize, 0);
9237 self.arena_prepend(&mut result, boundary);
9238 pending_boundary = Some(boundary);
9239 }
9240 FastDeferredNode::Concat {
9241 prefix,
9242 suffix: deferred_suffix,
9243 } => {
9244 pending.push(Frame::ContinuePrefix(prefix));
9245 pending.push(Frame::Visit(deferred_suffix));
9246 }
9247 }
9248 }
9249 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
9250 Frame::FinishRule {
9251 rule,
9252 parent_suffix,
9253 parent_alt_number,
9254 parent_pending_boundary,
9255 } => {
9256 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
9257 rule_index: rule.rule_index,
9258 invoking_state: rule.invoking_state,
9259 alt_number,
9260 start_index: rule.start_index,
9261 stop_index: rule.stop_index,
9262 return_values: None,
9263 children: result,
9264 });
9265 result = parent_suffix;
9266 self.arena_prepend(&mut result, node);
9267 alt_number = parent_alt_number;
9268 pending_boundary = parent_pending_boundary;
9269 }
9270 }
9271 }
9272 (result, alt_number as usize)
9273 }
9274
9275 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) -> usize {
9276 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
9277 let (nodes, alt_number) =
9278 self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
9279 outcome.nodes = nodes;
9280 alt_number
9281 }
9282
9283 fn recognize_repetition_fast(
9286 &mut self,
9287 atn: &Atn,
9288 request: &FastRecognizeRequest,
9289 shape: FastRepetitionShape,
9290 scratch: FastRecognizeScratch<'_, '_>,
9291 ) -> Vec<FastRecognizeOutcome> {
9292 let FastRecognizeScratch {
9293 predicate_context,
9294 visiting,
9295 memo,
9296 expected,
9297 native_depth,
9298 } = scratch;
9299 let lookahead = if self.fast_first_set_prefilter {
9300 atn.state(request.state_number).and_then(|state| {
9301 state
9302 .rule_index()
9303 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9304 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
9305 })
9306 } else {
9307 None
9308 };
9309 let (enter_alt_number, exit_alt_number) = if self.fast_track_alt_numbers {
9310 let state = atn
9311 .state(request.state_number)
9312 .expect("repetition request state must exist");
9313 (
9314 next_alt_number(state, 2, shape.enter_transition_index, 0, true),
9315 next_alt_number(state, 2, shape.exit_transition_index, 0, true),
9316 )
9317 } else {
9318 (0, 0)
9319 };
9320 let mut work = Vec::with_capacity(2);
9321 push_fast_repetition_work(
9322 &mut work,
9323 shape,
9324 FastRepetitionPath {
9325 index: request.index,
9326 deferred_nodes: FastDeferredNodeId::EMPTY,
9327 diagnostics: DiagnosticSeqId::EMPTY,
9328 consumed_eof: false,
9329 },
9330 lookahead.as_deref(),
9331 self.token_type_at(request.index),
9332 );
9333 let mut coordinates = FastRepetitionCoordinates::new(request.index);
9334 let mut outcomes = Vec::new();
9335 while let Some(item) = work.pop() {
9336 match item {
9337 FastRepetitionWork::Enter(path) => {
9338 if !coordinates.insert_entered(path) {
9339 continue;
9340 }
9341 let path_nodes = if enter_alt_number == 0 {
9342 path.deferred_nodes
9343 } else {
9344 let alternative = self
9345 .recognition_arena
9346 .deferred_alternative(enter_alt_number);
9347 self.recognition_arena
9348 .concat_deferred_nodes(path.deferred_nodes, alternative)
9349 };
9350 let body_outcomes = self.recognize_state_fast(
9351 atn,
9352 FastRecognizeRequest {
9353 state_number: shape.enter_target,
9354 stop_state: shape.body_stop_state,
9355 index: path.index,
9356 rule_start_index: request.rule_start_index,
9357 decision_start_index: request.decision_start_index,
9358 precedence: request.precedence,
9359 depth: request.depth.saturating_add(1),
9360 recovery_symbols: Rc::clone(&request.recovery_symbols),
9361 recovery_state: request.recovery_state,
9362 },
9363 FastRecognizeScratch {
9364 predicate_context,
9365 visiting: &mut *visiting,
9366 memo: &mut *memo,
9367 expected: &mut *expected,
9368 native_depth: native_depth + 1,
9369 },
9370 );
9371 for body in body_outcomes.into_iter().rev() {
9372 if body.index <= path.index {
9376 continue;
9377 }
9378 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
9379 let body_nodes = self
9380 .recognition_arena
9381 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
9382 let deferred_nodes = self
9383 .recognition_arena
9384 .concat_deferred_nodes(path_nodes, body_nodes);
9385 let next_path = FastRepetitionPath {
9386 index: body.index,
9387 deferred_nodes,
9388 diagnostics: self
9389 .recognition_arena
9390 .concat_diagnostics(path.diagnostics, body.diagnostics),
9391 consumed_eof: path.consumed_eof || body.consumed_eof,
9392 };
9393 let symbol = self.token_type_at(next_path.index);
9394 push_fast_repetition_work(
9395 &mut work,
9396 shape,
9397 next_path,
9398 lookahead.as_deref(),
9399 symbol,
9400 );
9401 }
9402 }
9403 FastRepetitionWork::Exit(path) => {
9404 if !coordinates.insert_exited(path) {
9405 continue;
9406 }
9407 let path_nodes = if exit_alt_number == 0 {
9408 path.deferred_nodes
9409 } else {
9410 let alternative =
9411 self.recognition_arena.deferred_alternative(exit_alt_number);
9412 self.recognition_arena
9413 .concat_deferred_nodes(path.deferred_nodes, alternative)
9414 };
9415 let suffixes = self.recognize_state_fast(
9416 atn,
9417 FastRecognizeRequest {
9418 state_number: shape.exit_target,
9419 stop_state: request.stop_state,
9420 index: path.index,
9421 rule_start_index: request.rule_start_index,
9422 decision_start_index: request.decision_start_index,
9423 precedence: request.precedence,
9424 depth: request.depth.saturating_add(1),
9425 recovery_symbols: Rc::clone(&request.recovery_symbols),
9426 recovery_state: request.recovery_state,
9427 },
9428 FastRecognizeScratch {
9429 predicate_context,
9430 visiting: &mut *visiting,
9431 memo: &mut *memo,
9432 expected: &mut *expected,
9433 native_depth: native_depth + 1,
9434 },
9435 );
9436 for mut outcome in suffixes {
9437 outcome.deferred_nodes = self
9438 .recognition_arena
9439 .concat_deferred_nodes(path_nodes, outcome.deferred_nodes);
9440 outcome.diagnostics = self
9441 .recognition_arena
9442 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
9443 outcome.consumed_eof |= path.consumed_eof;
9444 outcomes.push(outcome);
9445 }
9446 }
9447 }
9448 }
9449 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9450 outcomes
9451 }
9452
9453 fn recognize_state_fast(
9456 &mut self,
9457 atn: &Atn,
9458 request: FastRecognizeRequest,
9459 scratch: FastRecognizeScratch<'_, '_>,
9460 ) -> Vec<FastRecognizeOutcome> {
9461 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
9462 return self.recognize_state_fast_inner(atn, request, scratch);
9463 }
9464 self.recognize_state_fast_checked(atn, request, scratch)
9465 }
9466
9467 #[inline(never)]
9468 fn recognize_state_fast_checked(
9469 &mut self,
9470 atn: &Atn,
9471 request: FastRecognizeRequest,
9472 mut scratch: FastRecognizeScratch<'_, '_>,
9473 ) -> Vec<FastRecognizeOutcome> {
9474 scratch.native_depth = 1;
9475 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
9476 self.recognize_state_fast_inner(atn, request, scratch)
9477 })
9478 }
9479
9480 #[allow(clippy::too_many_lines)]
9481 fn recognize_state_fast_inner(
9482 &mut self,
9483 atn: &Atn,
9484 request: FastRecognizeRequest,
9485 scratch: FastRecognizeScratch<'_, '_>,
9486 ) -> Vec<FastRecognizeOutcome> {
9487 #[cfg(feature = "perf-counters")]
9488 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
9489 let FastRecognizeScratch {
9490 predicate_context,
9491 visiting,
9492 memo,
9493 expected,
9494 native_depth,
9495 } = scratch;
9496 let FastRecognizeRequest {
9497 mut state_number,
9498 stop_state,
9499 mut index,
9500 rule_start_index,
9501 decision_start_index,
9502 precedence,
9503 mut depth,
9504 recovery_symbols,
9505 recovery_state,
9506 } = request;
9507 let max_token_type = atn.max_token_type();
9508 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
9527 let mut inline_consumed_eof = false;
9528 loop {
9529 if depth > RECOGNITION_DEPTH_LIMIT {
9530 return Vec::new();
9531 }
9532 if state_number == stop_state {
9533 let mut nodes = NodeSeqId::EMPTY;
9534 if self.fast_token_nodes_enabled {
9535 for token_index in inline_consumed_tokens.iter().rev() {
9536 let token = self.arena_token_node(*token_index, false);
9537 self.arena_prepend(&mut nodes, token);
9538 }
9539 }
9540 return vec![FastRecognizeOutcome {
9541 index,
9542 consumed_eof: inline_consumed_eof,
9543 diagnostics: DiagnosticSeqId::EMPTY,
9544 deferred_nodes: FastDeferredNodeId::EMPTY,
9545 nodes,
9546 }];
9547 }
9548 let Some(state) = atn.state(state_number) else {
9549 return Vec::new();
9550 };
9551 let transitions = state.transitions();
9552 if transitions.len() == 1 && !state.precedence_rule_decision() {
9553 let transition = transitions
9554 .first()
9555 .expect("single transition checked above");
9556 let transition_kind = transition.kind();
9557 let target = transition.target();
9558 match transition_kind {
9559 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
9560 if left_recursive_boundary(atn, state, target).is_none() =>
9561 {
9562 #[cfg(feature = "perf-counters")]
9563 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9564 state_number = target;
9565 depth += 1;
9566 continue;
9567 }
9568 ParserTransitionKind::Predicate
9569 if left_recursive_boundary(atn, state, target).is_none() =>
9570 {
9571 #[cfg(feature = "perf-counters")]
9572 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9573 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
9574 {
9575 record_predicate_no_viable(expected, decision_start_index, index);
9576 return Vec::new();
9577 }
9578 state_number = target;
9579 depth += 1;
9580 continue;
9581 }
9582 ParserTransitionKind::Precedence
9583 if packed_i32(transition.arg0()) >= precedence
9584 && left_recursive_boundary(atn, state, target).is_none() =>
9585 {
9586 #[cfg(feature = "perf-counters")]
9587 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9588 state_number = target;
9589 depth += 1;
9590 continue;
9591 }
9592 ParserTransitionKind::Atom
9602 | ParserTransitionKind::Range
9603 | ParserTransitionKind::Set
9604 | ParserTransitionKind::NotSet
9605 | ParserTransitionKind::Wildcard
9606 if !self.fast_recovery_enabled =>
9607 {
9608 let symbol = self.token_type_at(index);
9609 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9610 #[cfg(feature = "perf-counters")]
9611 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9612 if self.fast_token_nodes_enabled {
9613 inline_consumed_tokens.push(index);
9614 }
9615 inline_consumed_eof |= symbol == TOKEN_EOF;
9616 index = self.consume_index(index, symbol);
9617 state_number = target;
9618 depth += 1;
9619 continue;
9620 }
9621 }
9624 _ => {}
9625 }
9626 }
9627 break;
9628 }
9629 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
9633 let Some(state) = atn.state(state_number) else {
9634 return Vec::new();
9635 };
9636 let transitions = state.transitions();
9637 let transition_count = transitions.len();
9638 if !self.fast_recovery_enabled
9639 && let Some(shape) = fast_repetition_shape(atn, state)
9640 {
9641 let mut outcomes = self.recognize_repetition_fast(
9642 atn,
9643 &FastRecognizeRequest {
9644 state_number,
9645 stop_state,
9646 index,
9647 rule_start_index,
9648 decision_start_index,
9649 precedence,
9650 depth,
9651 recovery_symbols: Rc::clone(&recovery_symbols),
9652 recovery_state,
9653 },
9654 shape,
9655 FastRecognizeScratch {
9656 predicate_context,
9657 visiting: &mut *visiting,
9658 memo: &mut *memo,
9659 expected: &mut *expected,
9660 native_depth: native_depth + 1,
9661 },
9662 );
9663 if inline_pending {
9664 for outcome in &mut outcomes {
9665 outcome.consumed_eof |= inline_consumed_eof;
9666 if self.fast_token_nodes_enabled {
9667 for token_index in inline_consumed_tokens.iter().rev() {
9668 let token = self.arena_token_node(*token_index, false);
9669 self.defer_fast_outcome_node(outcome, token);
9670 }
9671 }
9672 }
9673 }
9674 return outcomes;
9675 }
9676 let key = if self.fast_recovery_enabled {
9686 FastRecognizeKey {
9687 state_number,
9688 stop_state,
9689 index,
9690 rule_start_index,
9691 decision_start_index,
9692 precedence,
9693 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
9694 recovery_state,
9695 }
9696 } else {
9697 FastRecognizeKey {
9698 state_number,
9699 stop_state,
9700 index,
9701 rule_start_index: 0,
9702 decision_start_index: None,
9703 precedence,
9704 recovery_symbols_id: 0,
9705 recovery_state: None,
9706 }
9707 };
9708 let memo_lookup_enabled = self.fast_recovery_enabled
9713 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
9714 if memo_lookup_enabled {
9715 if let Some(outcomes) = memo.get(&key) {
9716 #[cfg(feature = "perf-counters")]
9717 {
9718 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
9719 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
9720 }
9721 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
9725 let inline_eof = inline_consumed_eof;
9726 let inline_tokens = &inline_consumed_tokens;
9727 return outcomes
9728 .iter()
9729 .copied()
9730 .map(|mut outcome| {
9731 if inline_eof {
9732 outcome.consumed_eof = true;
9733 }
9734 if self.fast_token_nodes_enabled {
9735 for token_index in inline_tokens.iter().rev() {
9736 let token = self.arena_token_node(*token_index, false);
9737 self.defer_fast_outcome_node(&mut outcome, token);
9738 }
9739 }
9740 outcome
9741 })
9742 .collect();
9743 }
9744 return outcomes.to_vec();
9745 }
9746 #[cfg(feature = "perf-counters")]
9747 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
9748 }
9749
9750 let needs_cycle_guard = if self.fast_recovery_enabled {
9755 transitions.iter().any(ParserTransition::is_epsilon)
9756 } else {
9757 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
9758 };
9759 #[cfg(feature = "perf-counters")]
9760 if needs_cycle_guard {
9761 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
9762 } else {
9763 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
9764 match state
9765 .transitions()
9766 .first()
9767 .expect("single-transition path requires one transition")
9768 .data()
9769 {
9770 Transition::Rule { .. } => {
9771 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
9772 }
9773 Transition::Atom { .. }
9774 | Transition::Range { .. }
9775 | Transition::Set { .. }
9776 | Transition::NotSet { .. }
9777 | Transition::Wildcard { .. } => {
9778 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
9779 }
9780 _ => {
9781 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
9782 }
9783 }
9784 }
9785 let has_inserted_cycle_guard = if needs_cycle_guard {
9786 if !visiting.insert(key.clone()) {
9787 #[cfg(feature = "perf-counters")]
9788 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
9789 return Vec::new();
9790 }
9791 true
9792 } else {
9793 false
9794 };
9795 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9796 Some(index)
9797 } else {
9798 decision_start_index
9799 };
9800 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
9801 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
9802 } else {
9803 (Rc::clone(&recovery_symbols), recovery_state)
9804 };
9805
9806 let lookahead_filter = if transition_count > 1
9825 && self.fast_first_set_prefilter
9826 && !state.precedence_rule_decision()
9827 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
9828 {
9829 state
9830 .rule_index()
9831 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9832 .map(|rule_stop| {
9833 let symbol = self.token_type_at(index);
9834 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
9835 (symbol, entry)
9836 })
9837 } else {
9838 None
9839 };
9840 let ll1_only_alt: Option<usize> = if transition_count > 1
9849 && let Some((symbol, entry)) = lookahead_filter.as_ref()
9850 {
9851 let key = (state.state_number(), *symbol);
9852 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
9853 cached
9854 } else {
9855 let result = ll1_unique_alt(entry, *symbol);
9856 self.ll1_decision_cache.insert(key, result);
9857 result
9858 }
9859 } else {
9860 None
9861 };
9862 let lookahead_filter = lookahead_filter.as_ref();
9863 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
9869 for (transition_index, transition) in transitions.iter().enumerate() {
9870 if let Some(alt) = ll1_only_alt {
9871 if alt != transition_index {
9873 continue;
9874 }
9875 }
9876 let transition_kind = transition.kind();
9877 if ll1_only_alt.is_none()
9878 && should_skip_via_lookahead(
9879 transition_kind,
9880 transition_index,
9881 lookahead_filter,
9882 index,
9883 self.fast_recovery_enabled,
9884 expected,
9885 )
9886 {
9887 continue;
9888 }
9889 let target = transition.target();
9890 let outcomes_before_transition = outcomes.len();
9891 let left_recursive_boundary = match transition_kind {
9892 ParserTransitionKind::Epsilon
9893 | ParserTransitionKind::Action
9894 | ParserTransitionKind::Predicate
9895 | ParserTransitionKind::Precedence => left_recursive_boundary(atn, state, target),
9896 ParserTransitionKind::Atom
9897 | ParserTransitionKind::Range
9898 | ParserTransitionKind::Set
9899 | ParserTransitionKind::NotSet
9900 | ParserTransitionKind::Wildcard
9901 | ParserTransitionKind::Rule => None,
9902 };
9903 match transition_kind {
9904 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
9905 #[cfg(feature = "perf-counters")]
9906 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9907 outcomes.extend(self.recognize_state_fast(
9908 atn,
9909 FastRecognizeRequest {
9910 state_number: target,
9911 stop_state,
9912 index,
9913 rule_start_index,
9914 decision_start_index: next_decision_start_index,
9915 precedence,
9916 depth: depth + 1,
9917 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9918 recovery_state: epsilon_recovery_state,
9919 },
9920 FastRecognizeScratch {
9921 predicate_context,
9922 visiting,
9923 memo,
9924 expected,
9925 native_depth: native_depth + 1,
9926 },
9927 ));
9928 }
9929 ParserTransitionKind::Predicate => {
9930 #[cfg(feature = "perf-counters")]
9931 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9932 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
9933 outcomes.extend(self.recognize_state_fast(
9934 atn,
9935 FastRecognizeRequest {
9936 state_number: target,
9937 stop_state,
9938 index,
9939 rule_start_index,
9940 decision_start_index: next_decision_start_index,
9941 precedence,
9942 depth: depth + 1,
9943 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9944 recovery_state: epsilon_recovery_state,
9945 },
9946 FastRecognizeScratch {
9947 predicate_context,
9948 visiting,
9949 memo,
9950 expected,
9951 native_depth: native_depth + 1,
9952 },
9953 ));
9954 } else {
9955 record_predicate_no_viable(expected, next_decision_start_index, index);
9956 }
9957 }
9958 ParserTransitionKind::Precedence => {
9959 let transition_precedence = packed_i32(transition.arg0());
9960 if transition_precedence >= precedence {
9961 outcomes.extend(self.recognize_state_fast(
9962 atn,
9963 FastRecognizeRequest {
9964 state_number: target,
9965 stop_state,
9966 index,
9967 rule_start_index,
9968 decision_start_index: next_decision_start_index,
9969 precedence,
9970 depth: depth + 1,
9971 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9972 recovery_state: epsilon_recovery_state,
9973 },
9974 FastRecognizeScratch {
9975 predicate_context,
9976 visiting,
9977 memo,
9978 expected,
9979 native_depth: native_depth + 1,
9980 },
9981 ));
9982 }
9983 }
9984 ParserTransitionKind::Rule => {
9985 let rule_index = transition.arg0() as usize;
9986 let follow_state = transition.arg1() as usize;
9987 let rule_precedence = packed_i32(transition.arg2());
9988 #[cfg(feature = "perf-counters")]
9989 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
9990 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
9991 continue;
9992 };
9993 let symbol = self.token_type_at(index);
10005 if self.fast_first_set_prefilter {
10006 let first = self.cached_rule_first_set(atn, target, child_stop);
10019 if should_skip_rule_via_first_set(
10020 &first,
10021 symbol,
10022 self.fast_recovery_enabled,
10023 index,
10024 expected,
10025 ) {
10026 continue;
10027 }
10028 }
10029 let expected_before_child =
10030 self.fast_recovery_enabled.then(|| expected.clone());
10031 let mut children = self.recognize_state_fast(
10032 atn,
10033 FastRecognizeRequest {
10034 state_number: target,
10035 stop_state: child_stop,
10036 index,
10037 rule_start_index: index,
10038 decision_start_index: None,
10039 precedence: rule_precedence,
10040 depth: depth + 1,
10041 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
10042 recovery_state: epsilon_recovery_state,
10043 },
10044 FastRecognizeScratch {
10045 predicate_context,
10046 visiting,
10047 memo,
10048 expected,
10049 native_depth: native_depth + 1,
10050 },
10051 );
10052 if children.is_empty() && self.fast_recovery_enabled {
10053 children = self.fast_child_rule_failure_recovery_outcomes(
10054 FastChildRuleFailureRecoveryRequest {
10055 atn,
10056 rule_index,
10057 start_index: index,
10058 follow_state,
10059 stop_state,
10060 expected,
10061 },
10062 );
10063 }
10064 if let Some(expected_before_child) = expected_before_child {
10065 if children
10066 .iter()
10067 .any(|child| child.diagnostics.is_empty() && child.index > index)
10068 {
10069 *expected = expected_before_child;
10070 }
10071 }
10072 for child in children {
10073 let child_index = child.index;
10074 let child_consumed_eof = child.consumed_eof;
10075 let child_diagnostics = child.diagnostics;
10076 let empty_recovery = self.empty_recovery_symbols();
10077 let follow_outcomes = self.recognize_state_fast(
10078 atn,
10079 FastRecognizeRequest {
10080 state_number: follow_state,
10081 stop_state,
10082 index: child_index,
10083 rule_start_index,
10084 decision_start_index: next_decision_start_index,
10085 precedence,
10086 depth: depth + 1,
10087 recovery_symbols: empty_recovery,
10088 recovery_state: None,
10089 },
10090 FastRecognizeScratch {
10091 predicate_context,
10092 visiting,
10093 memo,
10094 expected,
10095 native_depth: native_depth + 1,
10096 },
10097 );
10098 if follow_outcomes.is_empty() {
10099 continue;
10100 }
10101 let child_stop_index =
10102 self.rule_stop_token_index(child_index, child_consumed_eof);
10103 let child_node = self.build_parse_trees.then(|| {
10104 self.recognition_arena.deferred_rule_node(FastDeferredRule {
10105 rule_index: u32::try_from(rule_index)
10106 .expect("rule index fits in u32"),
10107 invoking_state: i32::try_from(invoking_state_number(state_number))
10108 .expect("invoking state fits in i32"),
10109 start_index: u32::try_from(index)
10110 .expect("rule start index fits in u32"),
10111 stop_index: child_stop_index.map(|stop_index| {
10112 u32::try_from(stop_index).expect("rule stop index fits in u32")
10113 }),
10114 deferred_children: child.deferred_nodes,
10115 children: child.nodes,
10116 })
10117 });
10118 let child_diags_empty = child_diagnostics.is_empty();
10119 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
10120 outcome.consumed_eof |= child_consumed_eof;
10121 if !child_diags_empty {
10124 outcome.diagnostics = self
10125 .recognition_arena
10126 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
10127 }
10128 if let Some(child_node) = child_node {
10129 outcome.deferred_nodes = self
10130 .recognition_arena
10131 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
10132 }
10133 outcome
10134 }));
10135 }
10136 }
10137 ParserTransitionKind::Atom
10138 | ParserTransitionKind::Range
10139 | ParserTransitionKind::Set
10140 | ParserTransitionKind::NotSet
10141 | ParserTransitionKind::Wildcard => {
10142 #[cfg(feature = "perf-counters")]
10143 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
10144 let symbol = self.token_type_at(index);
10145 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
10146 let next_index = self.consume_index(index, symbol);
10147 let empty_recovery = self.empty_recovery_symbols();
10148 outcomes.extend(
10149 self.recognize_state_fast(
10150 atn,
10151 FastRecognizeRequest {
10152 state_number: target,
10153 stop_state,
10154 index: next_index,
10155 rule_start_index,
10156 decision_start_index: next_decision_start_index,
10157 precedence,
10158 depth: depth + 1,
10159 recovery_symbols: empty_recovery,
10160 recovery_state: None,
10161 },
10162 FastRecognizeScratch {
10163 predicate_context,
10164 visiting,
10165 memo,
10166 expected,
10167 native_depth: native_depth + 1,
10168 },
10169 )
10170 .into_iter()
10171 .map(|mut outcome| {
10172 outcome.consumed_eof |= symbol == TOKEN_EOF;
10173 if self.fast_token_nodes_enabled {
10174 let token = self.arena_token_node(index, false);
10175 self.defer_fast_outcome_node(&mut outcome, token);
10176 }
10177 outcome
10178 }),
10179 );
10180 } else {
10181 if !self.fast_recovery_enabled {
10182 continue;
10190 }
10191 let expected_symbols = fast_recovery_expected_symbols(
10192 self,
10193 atn,
10194 state.state_number(),
10195 &recovery_symbols,
10196 );
10197 if expected_symbols.contains(&symbol) {
10198 continue;
10199 }
10200 {
10201 expected.record_transition(index, transition, max_token_type);
10202 record_no_viable_if_ambiguous(
10203 expected,
10204 next_decision_start_index,
10205 index,
10206 );
10207 outcomes.extend(self.fast_single_token_deletion_recovery(
10208 FastRecoveryRequest {
10209 atn,
10210 transition,
10211 expected_symbols: Rc::clone(&expected_symbols),
10212 target,
10213 request: FastRecognizeRequest {
10214 state_number,
10215 stop_state,
10216 index,
10217 rule_start_index,
10218 decision_start_index,
10219 precedence,
10220 depth,
10221 recovery_symbols: Rc::clone(&recovery_symbols),
10222 recovery_state,
10223 },
10224 visiting,
10225 memo,
10226 expected,
10227 },
10228 predicate_context,
10229 ));
10230 if !state_is_left_recursive_rule(atn, state) {
10231 outcomes.extend(self.fast_single_token_insertion_recovery(
10232 FastRecoveryRequest {
10233 atn,
10234 transition,
10235 expected_symbols: Rc::clone(&expected_symbols),
10236 target,
10237 request: FastRecognizeRequest {
10238 state_number,
10239 stop_state,
10240 index,
10241 rule_start_index,
10242 decision_start_index,
10243 precedence,
10244 depth,
10245 recovery_symbols: Rc::clone(&recovery_symbols),
10246 recovery_state,
10247 },
10248 visiting,
10249 memo,
10250 expected,
10251 },
10252 predicate_context,
10253 ));
10254 }
10255 outcomes.extend(self.fast_current_token_deletion_recovery(
10256 FastCurrentTokenDeletionRequest {
10257 atn,
10258 expected_symbols,
10259 request: FastRecognizeRequest {
10260 state_number,
10261 stop_state,
10262 index,
10263 rule_start_index,
10264 decision_start_index,
10265 precedence,
10266 depth,
10267 recovery_symbols: Rc::clone(&recovery_symbols),
10268 recovery_state,
10269 },
10270 visiting,
10271 memo,
10272 expected,
10273 },
10274 predicate_context,
10275 ));
10276 }
10277 }
10278 }
10279 }
10280 let alt_number = next_alt_number(
10281 state,
10282 transition_count,
10283 transition_index,
10284 0,
10285 self.fast_track_alt_numbers,
10286 );
10287 if alt_number != 0 || left_recursive_boundary.is_some() {
10288 for outcome in &mut outcomes[outcomes_before_transition..] {
10289 if alt_number != 0 {
10290 self.defer_fast_outcome_alternative(outcome, alt_number);
10291 }
10292 if let Some(rule_index) = left_recursive_boundary {
10293 self.defer_fast_outcome_boundary(outcome, rule_index);
10294 }
10295 }
10296 }
10297 }
10298
10299 if has_inserted_cycle_guard {
10300 visiting.remove(&key);
10301 }
10302 if matches!(
10303 self.prediction_mode,
10304 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
10305 ) && self.fast_recovery_enabled
10306 {
10307 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
10311 }
10312 if self.fast_recovery_enabled {
10313 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
10314 } else {
10315 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
10316 }
10317 let should_memoize = self.fast_recovery_enabled
10327 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
10328 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
10332 if inline_consumed_eof {
10333 outcome.consumed_eof = true;
10334 }
10335 if !inline_consumed_tokens.is_empty() {
10336 for token_index in inline_consumed_tokens.iter().rev() {
10337 let token = self.arena_token_node(*token_index, false);
10338 self.defer_fast_outcome_node(&mut outcome, token);
10339 }
10340 }
10341 outcome
10342 };
10343 if should_memoize {
10344 #[cfg(feature = "perf-counters")]
10345 {
10346 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
10347 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
10348 match outcomes.len() {
10349 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
10350 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
10351 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
10352 }
10353 }
10354 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
10359 memo.insert(key, Rc::clone(&stored));
10360 if inline_pending {
10361 return stored
10362 .iter()
10363 .copied()
10364 .map(&mut apply_inline_pending)
10365 .collect();
10366 }
10367 return stored.to_vec();
10368 }
10369 #[cfg(feature = "perf-counters")]
10370 match outcomes.len() {
10371 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
10372 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
10373 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
10374 }
10375 if inline_pending {
10376 return outcomes.into_iter().map(apply_inline_pending).collect();
10377 }
10378 outcomes
10379 }
10380
10381 fn single_token_deletion_recovery(
10384 &mut self,
10385 recovery: RecoveryRequest<'_, '_>,
10386 ) -> Vec<RecognizeOutcome> {
10387 let RecoveryRequest {
10388 atn,
10389 transition,
10390 expected_symbols,
10391 target,
10392 request,
10393 visiting,
10394 memo,
10395 expected,
10396 } = recovery;
10397 let RecognizeRequest {
10398 stop_state,
10399 index,
10400 rule_start_index,
10401 decision_start_index,
10402 init_action_rules,
10403 predicates,
10404 semantics,
10405 rule_args,
10406 member_actions,
10407 return_actions,
10408 local_int_arg,
10409 member_values,
10410 return_values,
10411 rule_alt_number,
10412 track_alt_numbers,
10413 consumed_eof,
10414 precedence,
10415 depth,
10416 ..
10417 } = request;
10418 let Some((diagnostic, next_index, next_symbol)) =
10419 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
10420 else {
10421 return Vec::new();
10422 };
10423 let after_next = self.consume_index(next_index, next_symbol);
10424 self.recognize_state(
10425 atn,
10426 RecognizeRequest {
10427 state_number: target,
10428 stop_state,
10429 index: after_next,
10430 rule_start_index,
10431 decision_start_index,
10432 init_action_rules,
10433 predicates,
10434 semantics,
10435 rule_args,
10436 member_actions,
10437 return_actions,
10438 local_int_arg,
10439 member_values,
10440 return_values,
10441 rule_alt_number,
10442 track_alt_numbers,
10443 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
10444 committed_decision: false,
10445 precedence,
10446 depth: depth + 1,
10447 recovery_symbols: BTreeSet::new(),
10448 recovery_state: None,
10449 },
10450 visiting,
10451 memo,
10452 expected,
10453 )
10454 .into_iter()
10455 .map(|mut outcome| {
10456 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
10457 outcome.diagnostics = self
10458 .recognition_arena
10459 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10460 let token = self.arena_token_node(next_index, false);
10461 self.arena_prepend(&mut outcome.nodes, token);
10462 let error = self.arena_token_node(index, true);
10463 self.arena_prepend(&mut outcome.nodes, error);
10464 outcome
10465 })
10466 .collect()
10467 }
10468
10469 fn current_token_deletion_recovery(
10472 &mut self,
10473 recovery: CurrentTokenDeletionRequest<'_, '_>,
10474 ) -> Vec<RecognizeOutcome> {
10475 let CurrentTokenDeletionRequest {
10476 atn,
10477 expected_symbols,
10478 mut request,
10479 visiting,
10480 memo,
10481 expected,
10482 } = recovery;
10483 let error_index = request.index;
10484 if error_index == request.rule_start_index {
10485 return Vec::new();
10486 }
10487 let Some((diagnostic, next_index, skipped)) =
10488 self.current_token_deletion(error_index, &expected_symbols)
10489 else {
10490 return Vec::new();
10491 };
10492 request.state_number = request.recovery_state.unwrap_or(request.state_number);
10493 request.index = next_index;
10494 request.committed_decision = false;
10495 request.depth += 1;
10496 request.recovery_state = None;
10497 self.recognize_state(atn, request, visiting, memo, expected)
10498 .into_iter()
10499 .map(|mut outcome| {
10500 outcome.diagnostics = self
10501 .recognition_arena
10502 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10503 for index in skipped.iter().rev() {
10504 let error = self.arena_token_node(*index, true);
10505 self.arena_prepend(&mut outcome.nodes, error);
10506 }
10507 outcome
10508 })
10509 .collect()
10510 }
10511
10512 fn consuming_failure_fallback(
10515 &mut self,
10516 fallback: ConsumingFailureFallback<'_>,
10517 visiting: &mut BTreeSet<RecognizeKey>,
10518 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10519 expected: &mut ExpectedTokens,
10520 ) -> Vec<RecognizeOutcome> {
10521 if fallback.expected_symbols.is_empty() {
10522 return Vec::new();
10523 }
10524 if fallback.symbol == TOKEN_EOF {
10525 return self.eof_consuming_failure_fallback(fallback, expected);
10526 }
10527 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
10528 }
10529
10530 fn non_eof_consuming_failure_fallback(
10533 &mut self,
10534 fallback: ConsumingFailureFallback<'_>,
10535 visiting: &mut BTreeSet<RecognizeKey>,
10536 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10537 expected: &mut ExpectedTokens,
10538 ) -> Vec<RecognizeOutcome> {
10539 let ConsumingFailureFallback {
10540 atn,
10541 target,
10542 request,
10543 symbol,
10544 expected_symbols,
10545 decision_start_index,
10546 decision,
10547 } = fallback;
10548 let error_index = request.index;
10549 let diagnostic =
10550 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
10551 let next_index = self.consume_index(error_index, symbol);
10552 self.recognize_state(
10553 atn,
10554 RecognizeRequest {
10555 state_number: target,
10556 stop_state: request.stop_state,
10557 index: next_index,
10558 rule_start_index: request.rule_start_index,
10559 decision_start_index,
10560 init_action_rules: request.init_action_rules,
10561 predicates: request.predicates,
10562 semantics: request.semantics,
10563 rule_args: request.rule_args,
10564 member_actions: request.member_actions,
10565 return_actions: request.return_actions,
10566 local_int_arg: request.local_int_arg,
10567 member_values: request.member_values,
10568 return_values: request.return_values,
10569 rule_alt_number: request.rule_alt_number,
10570 track_alt_numbers: request.track_alt_numbers,
10571 consumed_eof: request.consumed_eof,
10572 committed_decision: false,
10573 precedence: request.precedence,
10574 depth: request.depth + 1,
10575 recovery_symbols: BTreeSet::new(),
10576 recovery_state: None,
10577 },
10578 visiting,
10579 memo,
10580 expected,
10581 )
10582 .into_iter()
10583 .map(|mut outcome| {
10584 prepend_decision(&mut outcome, decision);
10585 outcome.diagnostics = self
10586 .recognition_arena
10587 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10588 let error = self.arena_token_node(error_index, true);
10589 self.arena_prepend(&mut outcome.nodes, error);
10590 outcome
10591 })
10592 .collect()
10593 }
10594
10595 fn eof_consuming_failure_fallback(
10598 &mut self,
10599 fallback: ConsumingFailureFallback<'_>,
10600 expected: &ExpectedTokens,
10601 ) -> Vec<RecognizeOutcome> {
10602 let request = fallback.request;
10603 if request.index == request.rule_start_index {
10604 return Vec::new();
10605 }
10606 let diagnostic =
10607 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
10608 let diagnostics = self
10609 .recognition_arena
10610 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10611 vec![RecognizeOutcome {
10612 index: request.index,
10613 consumed_eof: request.consumed_eof,
10614 alt_number: request.rule_alt_number,
10615 member_values: request.member_values,
10616 return_values: request.return_values,
10617 diagnostics,
10618 decisions: Vec::new(),
10619 actions: Vec::new(),
10620 nodes: NodeSeqId::EMPTY,
10621 }]
10622 }
10623
10624 fn single_token_insertion_recovery(
10627 &mut self,
10628 recovery: RecoveryRequest<'_, '_>,
10629 ) -> Vec<RecognizeOutcome> {
10630 let RecoveryRequest {
10631 atn,
10632 transition,
10633 expected_symbols,
10634 target,
10635 request,
10636 visiting,
10637 memo,
10638 expected,
10639 } = recovery;
10640 let RecognizeRequest {
10641 stop_state,
10642 index,
10643 rule_start_index,
10644 decision_start_index,
10645 init_action_rules,
10646 predicates,
10647 semantics,
10648 rule_args,
10649 member_actions,
10650 return_actions,
10651 local_int_arg,
10652 member_values,
10653 return_values,
10654 rule_alt_number,
10655 track_alt_numbers,
10656 consumed_eof,
10657 precedence,
10658 depth,
10659 ..
10660 } = request;
10661 let follow_symbols = state_expected_symbols(atn, transition.target());
10662 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
10663 transition,
10664 index,
10665 atn.max_token_type(),
10666 &expected_symbols,
10667 &follow_symbols,
10668 ) else {
10669 return Vec::new();
10670 };
10671 self.recognize_state(
10672 atn,
10673 RecognizeRequest {
10674 state_number: target,
10675 stop_state,
10676 index,
10677 rule_start_index,
10678 decision_start_index,
10679 init_action_rules,
10680 predicates,
10681 semantics,
10682 rule_args,
10683 member_actions,
10684 return_actions,
10685 local_int_arg,
10686 member_values,
10687 return_values,
10688 rule_alt_number,
10689 track_alt_numbers,
10690 consumed_eof,
10691 committed_decision: false,
10692 precedence,
10693 depth: depth + 1,
10694 recovery_symbols: BTreeSet::new(),
10695 recovery_state: None,
10696 },
10697 visiting,
10698 memo,
10699 expected,
10700 )
10701 .into_iter()
10702 .map(|mut outcome| {
10703 outcome.diagnostics = self
10704 .recognition_arena
10705 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10706 let missing = self.arena_missing_token_node(token_type, index, text.clone());
10707 self.arena_prepend(&mut outcome.nodes, missing);
10708 outcome
10709 })
10710 .collect()
10711 }
10712
10713 #[allow(clippy::too_many_lines)]
10716 fn recognize_state(
10717 &mut self,
10718 atn: &Atn,
10719 request: RecognizeRequest<'_>,
10720 visiting: &mut BTreeSet<RecognizeKey>,
10721 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10722 expected: &mut ExpectedTokens,
10723 ) -> Vec<RecognizeOutcome> {
10724 let request_template = request.clone();
10725 let RecognizeRequest {
10726 state_number,
10727 stop_state,
10728 index,
10729 rule_start_index,
10730 decision_start_index,
10731 init_action_rules,
10732 predicates,
10733 semantics,
10734 rule_args,
10735 member_actions,
10736 return_actions,
10737 local_int_arg,
10738 member_values,
10739 return_values,
10740 rule_alt_number,
10741 track_alt_numbers,
10742 consumed_eof,
10743 committed_decision,
10744 precedence,
10745 depth,
10746 recovery_symbols,
10747 recovery_state,
10748 } = request;
10749 if depth > RECOGNITION_DEPTH_LIMIT {
10750 return Vec::new();
10751 }
10752 if state_number == stop_state {
10753 return stop_outcome(
10754 index,
10755 consumed_eof,
10756 rule_alt_number,
10757 member_values,
10758 return_values,
10759 );
10760 }
10761 let key = RecognizeKey {
10762 state_number,
10763 stop_state,
10764 index,
10765 rule_start_index,
10766 decision_start_index,
10767 local_int_arg,
10768 member_values: member_values.clone(),
10769 return_values: return_values.clone(),
10770 rule_alt_number,
10771 track_alt_numbers,
10772 consumed_eof,
10773 committed_decision,
10774 precedence,
10775 recovery_symbols: recovery_symbols.clone(),
10776 recovery_state,
10777 };
10778 if let Some(outcomes) = memo.get(&key) {
10779 return outcomes.clone();
10780 }
10781
10782 let visit_key = key.clone();
10783 if !visiting.insert(visit_key.clone()) {
10784 return Vec::new();
10785 }
10786
10787 let Some(state) = atn.state(state_number) else {
10788 visiting.remove(&visit_key);
10789 return Vec::new();
10790 };
10791 let decision_override_generation = self.decision_override_generation;
10792 let transitions = state.transitions();
10793 let transition_count = transitions.len();
10794 let overridden_transition = if transition_count > 1
10795 && self.semantic_hooks.observes_parser_decisions()
10796 {
10797 atn.decision_to_state()
10798 .iter()
10799 .position(|candidate| candidate == state_number)
10800 .and_then(|decision| {
10801 self.semantic_hooks
10802 .parser_decision_override(decision, index, transition_count)
10803 })
10804 .and_then(|alternative| alternative.checked_sub(1))
10805 .filter(|alternative| *alternative < transition_count)
10806 } else {
10807 None
10808 };
10809 if overridden_transition.is_some() {
10810 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
10811 }
10812 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
10813 Some(index)
10814 } else {
10815 decision_start_index
10816 };
10817 let (epsilon_recovery_symbols, epsilon_recovery_state) =
10818 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
10819 let mut outcomes = Vec::new();
10820 for (transition_index, transition) in transitions.iter().enumerate() {
10821 if overridden_transition.is_some_and(|forced| forced != transition_index) {
10822 continue;
10823 }
10824 let transition_committed =
10825 committed_decision || overridden_transition == Some(transition_index);
10826 let mut transition_request = request_template.clone();
10827 transition_request.committed_decision = transition_committed;
10828 let decision =
10829 transition_decision(atn, state, transition_count, transition_index, predicates);
10830 let next_alt_number = next_alt_number(
10831 state,
10832 transition_count,
10833 transition_index,
10834 rule_alt_number,
10835 track_alt_numbers,
10836 );
10837 let transition_data = transition.data();
10838 match &transition_data {
10839 Transition::Epsilon { target } | Transition::Action { target, .. } => {
10840 let (action_rule_index, action_index) = match &transition_data {
10841 Transition::Action {
10842 rule_index,
10843 action_index,
10844 ..
10845 } => (Some(*rule_index), *action_index),
10846 _ => (None, None),
10847 };
10848 outcomes.extend(self.recognize_epsilon_or_action_step(
10849 atn,
10850 &transition_request,
10851 EpsilonActionStep {
10852 source_state: state_number,
10853 target: *target,
10854 action_rule_index,
10855 action_index,
10856 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
10857 decision,
10858 decision_start_index: next_decision_start_index,
10859 alt_number: next_alt_number,
10860 recovery_symbols: epsilon_recovery_symbols.clone(),
10861 recovery_state: epsilon_recovery_state,
10862 },
10863 RecognizeScratch {
10864 visiting,
10865 memo,
10866 expected,
10867 },
10868 ));
10869 }
10870 Transition::Predicate {
10871 target,
10872 rule_index,
10873 pred_index,
10874 ..
10875 } => {
10876 let predicate = PredicateEval {
10877 index,
10878 rule_index: *rule_index,
10879 pred_index: *pred_index,
10880 predicates,
10881 semantics,
10882 context: None,
10883 local_int_arg,
10884 member_values: &member_values,
10885 };
10886 if self.parser_predicate_matches(predicate) {
10887 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
10888 outcomes.extend(
10889 self.recognize_state(
10890 atn,
10891 RecognizeRequest {
10892 state_number: *target,
10893 stop_state,
10894 index,
10895 rule_start_index,
10896 decision_start_index: next_decision_start_index,
10897 init_action_rules,
10898 predicates,
10899 semantics,
10900 rule_args,
10901 member_actions,
10902 return_actions,
10903 local_int_arg,
10904 member_values: member_values.clone(),
10905 return_values: return_values.clone(),
10906 rule_alt_number: next_alt_number,
10907 track_alt_numbers,
10908 consumed_eof,
10909 committed_decision: transition_committed,
10910 precedence,
10911 depth: depth + 1,
10912 recovery_symbols: epsilon_recovery_symbols.clone(),
10913 recovery_state: epsilon_recovery_state,
10914 },
10915 visiting,
10916 memo,
10917 expected,
10918 )
10919 .into_iter()
10920 .map(|mut outcome| {
10921 prepend_decision(&mut outcome, decision);
10922 if let Some(rule_index) = left_recursive_boundary {
10923 let boundary =
10924 self.arena_boundary_node(rule_index, next_alt_number);
10925 self.arena_prepend(&mut outcome.nodes, boundary);
10926 }
10927 outcome
10928 }),
10929 );
10930 } else if let Some(message) = semantics
10931 .and_then(|semantics| {
10932 self.parser_semantic_ir_predicate_failure_message(
10933 *rule_index,
10934 *pred_index,
10935 semantics,
10936 )
10937 })
10938 .or_else(|| {
10939 self.parser_predicate_failure_message(
10940 *rule_index,
10941 *pred_index,
10942 predicates,
10943 )
10944 })
10945 {
10946 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
10947 rule_index: *rule_index,
10948 index,
10949 message,
10950 member_values: member_values.clone(),
10951 return_values: return_values.clone(),
10952 rule_alt_number,
10953 }));
10954 } else {
10955 record_predicate_no_viable(expected, next_decision_start_index, index);
10956 }
10957 }
10958 Transition::Precedence {
10959 target,
10960 precedence: transition_precedence,
10961 } => {
10962 if *transition_precedence >= precedence {
10963 outcomes.extend(
10964 self.recognize_state(
10965 atn,
10966 RecognizeRequest {
10967 state_number: *target,
10968 stop_state,
10969 index,
10970 rule_start_index,
10971 decision_start_index: next_decision_start_index,
10972 init_action_rules,
10973 predicates,
10974 semantics,
10975 rule_args,
10976 member_actions,
10977 return_actions,
10978 local_int_arg,
10979 member_values: member_values.clone(),
10980 return_values: return_values.clone(),
10981 rule_alt_number: next_alt_number,
10982 track_alt_numbers,
10983 consumed_eof,
10984 committed_decision: transition_committed,
10985 precedence,
10986 depth: depth + 1,
10987 recovery_symbols: epsilon_recovery_symbols.clone(),
10988 recovery_state: epsilon_recovery_state,
10989 },
10990 visiting,
10991 memo,
10992 expected,
10993 )
10994 .into_iter()
10995 .map(|mut outcome| {
10996 prepend_decision(&mut outcome, decision);
10997 outcome
10998 }),
10999 );
11000 }
11001 }
11002 Transition::Rule {
11003 target,
11004 rule_index,
11005 follow_state,
11006 precedence: rule_precedence,
11007 ..
11008 } => {
11009 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
11010 continue;
11011 };
11012 let child_local_int_arg =
11013 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
11014 let expected_before_child = expected.clone();
11015 let children = self.recognize_state(
11016 atn,
11017 RecognizeRequest {
11018 state_number: *target,
11019 stop_state: child_stop,
11020 index,
11021 rule_start_index: index,
11022 decision_start_index: None,
11023 init_action_rules,
11024 predicates,
11025 semantics,
11026 rule_args,
11027 member_actions,
11028 return_actions,
11029 local_int_arg: child_local_int_arg,
11030 member_values: member_values.clone(),
11031 return_values: BTreeMap::new(),
11032 rule_alt_number: 0,
11033 track_alt_numbers,
11034 consumed_eof: false,
11035 committed_decision: transition_committed,
11036 precedence: *rule_precedence,
11037 depth: depth + 1,
11038 recovery_symbols: epsilon_recovery_symbols.clone(),
11039 recovery_state: epsilon_recovery_state,
11040 },
11041 visiting,
11042 memo,
11043 expected,
11044 );
11045 let children = if children.is_empty() {
11046 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
11047 atn,
11048 rule_index: *rule_index,
11049 start_index: index,
11050 follow_state: *follow_state,
11051 stop_state,
11052 member_values: member_values.clone(),
11053 expected,
11054 })
11055 } else {
11056 children
11057 };
11058 let preserve_child_expected =
11059 self.child_expected_reaches_clean_eof(&children, expected);
11060 restore_expected(
11061 &children,
11062 index,
11063 expected,
11064 expected_before_child,
11065 preserve_child_expected,
11066 );
11067 for child in children {
11068 let child_stop_index =
11069 self.rule_stop_token_index(child.index, child.consumed_eof);
11070 let child_nodes = self
11071 .recognition_arena
11072 .fold_left_recursive_boundaries(child.nodes);
11073 let child_node = self.arena_rule_node(ArenaRuleSpec {
11074 rule_index: *rule_index,
11075 invoking_state: invoking_state_number(state_number),
11076 alt_number: child.alt_number,
11077 start_index: index,
11078 stop_index: child_stop_index,
11079 return_values: child.return_values.clone(),
11080 children: child_nodes,
11081 });
11082 outcomes.extend(
11083 self.recognize_state(
11084 atn,
11085 RecognizeRequest {
11086 state_number: *follow_state,
11087 stop_state,
11088 index: child.index,
11089 rule_start_index,
11090 decision_start_index: next_decision_start_index,
11091 init_action_rules,
11092 predicates,
11093 semantics,
11094 rule_args,
11095 member_actions,
11096 return_actions,
11097 local_int_arg,
11098 member_values: child.member_values.clone(),
11099 return_values: return_values.clone(),
11100 rule_alt_number,
11101 track_alt_numbers,
11102 consumed_eof: consumed_eof || child.consumed_eof,
11103 committed_decision: transition_committed
11104 && child.index == index,
11105 precedence,
11106 depth: depth + 1,
11107 recovery_symbols: BTreeSet::new(),
11108 recovery_state: None,
11109 },
11110 visiting,
11111 memo,
11112 expected,
11113 )
11114 .into_iter()
11115 .map(|mut outcome| {
11116 outcome.consumed_eof |= child.consumed_eof;
11117 outcome.diagnostics = self
11118 .recognition_arena
11119 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
11120 let mut decisions = child.decisions.clone();
11121 decisions.append(&mut outcome.decisions);
11122 outcome.decisions = decisions;
11123 prepend_decision(&mut outcome, decision);
11124 let mut actions = child.actions.clone();
11125 if init_action_rules.contains(rule_index) {
11126 actions.insert(
11127 0,
11128 ParserAction::new_rule_init(
11129 *rule_index,
11130 index,
11131 Some(*follow_state),
11132 ),
11133 );
11134 }
11135 actions.append(&mut outcome.actions);
11136 outcome.actions = actions;
11137 self.arena_prepend(&mut outcome.nodes, child_node);
11138 outcome
11139 }),
11140 );
11141 }
11142 }
11143 Transition::Atom { target, .. }
11144 | Transition::Range { target, .. }
11145 | Transition::Set { target, .. }
11146 | Transition::NotSet { target, .. }
11147 | Transition::Wildcard { target, .. } => {
11148 let symbol = self.token_type_at(index);
11149 if transition_data.matches(symbol, 1, atn.max_token_type()) {
11150 let next_index = self.consume_index(index, symbol);
11151 outcomes.extend(
11152 self.recognize_state(
11153 atn,
11154 RecognizeRequest {
11155 state_number: *target,
11156 stop_state,
11157 index: next_index,
11158 rule_start_index,
11159 decision_start_index: next_decision_start_index,
11160 init_action_rules,
11161 predicates,
11162 semantics,
11163 rule_args,
11164 member_actions,
11165 return_actions,
11166 local_int_arg,
11167 member_values: member_values.clone(),
11168 return_values: return_values.clone(),
11169 rule_alt_number: next_alt_number,
11170 track_alt_numbers,
11171 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
11172 committed_decision: false,
11173 precedence,
11174 depth: depth + 1,
11175 recovery_symbols: BTreeSet::new(),
11176 recovery_state: None,
11177 },
11178 visiting,
11179 memo,
11180 expected,
11181 )
11182 .into_iter()
11183 .map(|mut outcome| {
11184 prepend_decision(&mut outcome, decision);
11185 outcome.consumed_eof |= symbol == TOKEN_EOF;
11186 let token = self.arena_token_node(index, false);
11187 self.arena_prepend(&mut outcome.nodes, token);
11188 outcome
11189 }),
11190 );
11191 } else {
11192 let expected_symbols =
11193 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
11194 if expected_symbols.contains(&symbol) && !transition_committed {
11195 continue;
11196 }
11197 expected.record_transition(index, transition, atn.max_token_type());
11198 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
11199 let before_recovery = outcomes.len();
11200 let recovery_request = transition_request.clone();
11201 if transition_committed {
11202 outcomes.extend(self.consuming_failure_fallback(
11203 ConsumingFailureFallback {
11204 atn,
11205 target: *target,
11206 request: recovery_request,
11207 symbol,
11208 expected_symbols,
11209 decision_start_index: next_decision_start_index,
11210 decision,
11211 },
11212 visiting,
11213 memo,
11214 expected,
11215 ));
11216 break;
11217 }
11218 outcomes.extend(
11219 self.single_token_deletion_recovery(RecoveryRequest {
11220 atn,
11221 transition,
11222 expected_symbols: expected_symbols.clone(),
11223 target: *target,
11224 request: recovery_request.clone(),
11225 visiting,
11226 memo,
11227 expected,
11228 })
11229 .into_iter()
11230 .map(|mut outcome| {
11231 prepend_decision(&mut outcome, decision);
11232 outcome
11233 }),
11234 );
11235 if !state_is_left_recursive_rule(atn, state) {
11236 outcomes.extend(
11237 self.single_token_insertion_recovery(RecoveryRequest {
11238 atn,
11239 transition,
11240 expected_symbols: expected_symbols.clone(),
11241 target: *target,
11242 request: recovery_request.clone(),
11243 visiting,
11244 memo,
11245 expected,
11246 })
11247 .into_iter()
11248 .map(|mut outcome| {
11249 prepend_decision(&mut outcome, decision);
11250 outcome
11251 }),
11252 );
11253 }
11254 outcomes.extend(self.current_token_deletion_recovery(
11255 CurrentTokenDeletionRequest {
11256 atn,
11257 expected_symbols: expected_symbols.clone(),
11258 request: recovery_request.clone(),
11259 visiting,
11260 memo,
11261 expected,
11262 },
11263 ));
11264 if outcomes.len() == before_recovery {
11265 outcomes.extend(self.consuming_failure_fallback(
11266 ConsumingFailureFallback {
11267 atn,
11268 target: *target,
11269 request: recovery_request,
11270 symbol,
11271 expected_symbols,
11272 decision_start_index: next_decision_start_index,
11273 decision,
11274 },
11275 visiting,
11276 memo,
11277 expected,
11278 ));
11279 }
11280 }
11281 }
11282 }
11283 if self.decision_override_generation != decision_override_generation {
11284 break;
11285 }
11286 }
11287
11288 visiting.remove(&visit_key);
11289 self.record_prediction_diagnostics(atn, state, index, &outcomes);
11290 if matches!(
11291 self.prediction_mode,
11292 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11293 ) {
11294 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
11295 }
11296 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
11297 memo.insert(key, outcomes.clone());
11298 outcomes
11299 }
11300
11301 fn recognize_epsilon_or_action_step(
11304 &mut self,
11305 atn: &Atn,
11306 request: &RecognizeRequest<'_>,
11307 step: EpsilonActionStep,
11308 scratch: RecognizeScratch<'_>,
11309 ) -> Vec<RecognizeOutcome> {
11310 let RecognizeScratch {
11311 visiting,
11312 memo,
11313 expected,
11314 } = scratch;
11315 let action = step.action_rule_index.map(|rule_index| {
11316 let stop_index = self.rule_stop_token_index(request.index, request.consumed_eof);
11317 step.action_index.map_or_else(
11318 || {
11319 ParserAction::new(
11320 step.source_state,
11321 rule_index,
11322 request.rule_start_index,
11323 stop_index,
11324 )
11325 },
11326 |action_index| {
11327 ParserAction::new_indexed(
11328 step.source_state,
11329 rule_index,
11330 action_index,
11331 request.rule_start_index,
11332 stop_index,
11333 )
11334 },
11335 )
11336 });
11337 let next_member_values = if action.is_some() {
11338 member_values_after_action(
11339 step.source_state,
11340 request.member_actions,
11341 request.semantics,
11342 &request.member_values,
11343 )
11344 } else {
11345 request.member_values.clone()
11346 };
11347 let next_return_values = action.map_or_else(
11348 || request.return_values.clone(),
11349 |action| {
11350 return_values_after_action(
11351 step.source_state,
11352 action.rule_index(),
11353 request.return_actions,
11354 request.semantics,
11355 &request.return_values,
11356 )
11357 },
11358 );
11359
11360 self.recognize_state(
11361 atn,
11362 RecognizeRequest {
11363 state_number: step.target,
11364 stop_state: request.stop_state,
11365 index: request.index,
11366 rule_start_index: request.rule_start_index,
11367 decision_start_index: step.decision_start_index,
11368 init_action_rules: request.init_action_rules,
11369 predicates: request.predicates,
11370 semantics: request.semantics,
11371 rule_args: request.rule_args,
11372 member_actions: request.member_actions,
11373 return_actions: request.return_actions,
11374 local_int_arg: request.local_int_arg,
11375 member_values: next_member_values,
11376 return_values: next_return_values,
11377 rule_alt_number: if step.left_recursive_boundary.is_some() {
11378 0
11379 } else {
11380 step.alt_number
11381 },
11382 track_alt_numbers: request.track_alt_numbers,
11383 consumed_eof: request.consumed_eof,
11384 committed_decision: request.committed_decision,
11385 precedence: request.precedence,
11386 depth: request.depth + 1,
11387 recovery_symbols: step.recovery_symbols,
11388 recovery_state: step.recovery_state,
11389 },
11390 visiting,
11391 memo,
11392 expected,
11393 )
11394 .into_iter()
11395 .map(|mut outcome| {
11396 prepend_decision(&mut outcome, step.decision);
11397 if let Some(rule_index) = step.left_recursive_boundary {
11398 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
11399 self.arena_prepend(&mut outcome.nodes, boundary);
11400 }
11401 if let Some(action) = action {
11402 outcome.actions.insert(0, action);
11403 }
11404 outcome
11405 })
11406 .collect()
11407 }
11408
11409 fn token_type_at(&mut self, index: usize) -> i32 {
11414 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
11415 self.input.fill();
11416 }
11417 self.input.token_type_at_index(index)
11418 }
11419
11420 fn cached_state_expected_symbols(
11432 &mut self,
11433 atn: &Atn,
11434 state_number: usize,
11435 ) -> Rc<BTreeSet<i32>> {
11436 if let Some(cached) = self.state_expected_cache.get(&state_number) {
11437 return Rc::clone(cached);
11438 }
11439 let symbols = state_expected_symbols(atn, state_number);
11440 let entry = self.intern_recovery_symbols(symbols);
11441 self.state_expected_cache
11442 .insert(state_number, Rc::clone(&entry));
11443 entry
11444 }
11445
11446 fn cached_state_expected_token_set(
11447 &mut self,
11448 atn: &Atn,
11449 state_number: usize,
11450 ) -> Rc<TokenBitSet> {
11451 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
11452 return Rc::clone(cached);
11453 }
11454 let symbols = with_shared_atn_caches(atn, |cache| {
11458 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
11459 return Rc::clone(cached);
11460 }
11461 let symbols = Rc::new(state_expected_token_set(atn, state_number));
11462 cache
11463 .state_expected_tokens
11464 .insert(state_number, Rc::clone(&symbols));
11465 symbols
11466 });
11467 self.state_expected_token_cache
11468 .insert(state_number, Rc::clone(&symbols));
11469 symbols
11470 }
11471
11472 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
11473 if self.rule_stop_reach_cache.len() <= state_number {
11474 self.rule_stop_reach_cache
11475 .resize_with(atn.states().len().max(state_number + 1), || None);
11476 }
11477 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
11478 return reaches;
11479 }
11480 let reaches = with_shared_atn_caches(atn, |cache| {
11481 *cache
11482 .rule_stop_reach
11483 .entry(state_number)
11484 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
11485 });
11486 self.rule_stop_reach_cache[state_number] = Some(reaches);
11487 reaches
11488 }
11489
11490 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
11493 Rc::clone(&self.empty_recovery_symbols)
11494 }
11495
11496 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
11505 if set.is_empty() {
11506 return Rc::clone(&self.empty_recovery_symbols);
11507 }
11508 let candidate = Rc::new(set);
11509 match self.recovery_symbols_intern.get(&candidate) {
11510 Some(existing) => Rc::clone(existing),
11511 None => {
11512 self.recovery_symbols_intern
11513 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
11514 candidate
11515 }
11516 }
11517 }
11518
11519 fn cached_decision_lookahead(
11524 &mut self,
11525 atn: &Atn,
11526 state: AtnState<'_>,
11527 rule_stop_state: usize,
11528 ) -> Rc<DecisionLookahead> {
11529 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
11536 return Rc::clone(cached);
11537 }
11538 let entry = with_shared_atn_caches(atn, |cache| {
11539 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
11540 return Rc::clone(cached);
11541 }
11542 let mut entry = DecisionLookahead {
11543 transitions: Vec::with_capacity(state.transitions().len()),
11544 };
11545 for transition in &state.transitions() {
11546 entry.transitions.push(transition_first_set(
11547 atn,
11548 transition,
11549 rule_stop_state,
11550 &mut cache.first_set,
11551 ));
11552 }
11553 let entry = Rc::new(entry);
11554 cache
11555 .decision_lookahead
11556 .insert(state.state_number(), Rc::clone(&entry));
11557 entry
11558 });
11559 self.decision_lookahead_cache
11560 .insert(state.state_number(), Rc::clone(&entry));
11561 entry
11562 }
11563
11564 fn cached_rule_first_set(
11565 &mut self,
11566 atn: &Atn,
11567 target: usize,
11568 child_stop: usize,
11569 ) -> Rc<FirstSet> {
11570 if self.rule_first_set_cache.len() <= target {
11571 self.rule_first_set_cache
11572 .resize_with(atn.states().len().max(target + 1), || None);
11573 }
11574 if let Some(cached) = self
11575 .rule_first_set_cache
11576 .get(target)
11577 .and_then(Option::as_ref)
11578 {
11579 return Rc::clone(cached);
11580 }
11581 let first = with_shared_first_set_cache(atn, |cache| {
11582 rule_first_set(atn, target, child_stop, cache)
11583 });
11584 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
11585 first
11586 }
11587
11588 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
11589 let atn_key = SharedAtnCacheKey::for_atn(atn);
11590 if self.empty_cycle_cache_atn != Some(atn_key) {
11591 self.empty_cycle_cache.clear();
11592 self.empty_cycle_cache_atn = Some(atn_key);
11593 }
11594 if self.empty_cycle_cache.len() <= state_number {
11595 self.empty_cycle_cache
11596 .resize_with(atn.state_count().max(state_number + 1), || None);
11597 }
11598 if let Some(cached) = self.empty_cycle_cache[state_number] {
11599 return cached;
11600 }
11601 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
11602 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
11603 self.empty_cycle_cache[state_number] = Some(result);
11604 result
11605 }
11606
11607 fn empty_path_reaches_state(
11608 &mut self,
11609 atn: &Atn,
11610 state_number: usize,
11611 target_state: usize,
11612 visited: &mut FxHashSet<usize>,
11613 ) -> bool {
11614 enum Work {
11615 Visit(usize),
11616 RuleFollow {
11617 target: usize,
11618 rule_index: usize,
11619 follow_state: usize,
11620 },
11621 }
11622
11623 let mut work = vec![Work::Visit(state_number)];
11624 while let Some(item) = work.pop() {
11625 match item {
11626 Work::Visit(state_number) => {
11627 if !visited.insert(state_number) {
11628 continue;
11629 }
11630 let Some(state) = atn.state(state_number) else {
11631 continue;
11632 };
11633 let transitions = state.transitions();
11634 for transition_index in (0..transitions.len()).rev() {
11635 let transition = transitions
11636 .get(transition_index)
11637 .expect("in-bounds parser transition");
11638 let kind = transition.kind();
11639 let target = transition.target();
11640 match kind {
11641 ParserTransitionKind::Atom
11642 | ParserTransitionKind::Range
11643 | ParserTransitionKind::Set
11644 | ParserTransitionKind::NotSet
11645 | ParserTransitionKind::Wildcard => {}
11646 ParserTransitionKind::Rule => {
11647 if target == target_state {
11648 return true;
11649 }
11650 work.push(Work::RuleFollow {
11651 target,
11652 rule_index: transition.arg0() as usize,
11653 follow_state: transition.arg1() as usize,
11654 });
11655 work.push(Work::Visit(target));
11656 }
11657 ParserTransitionKind::Epsilon
11658 | ParserTransitionKind::Predicate
11659 | ParserTransitionKind::Action
11660 | ParserTransitionKind::Precedence => {
11661 if target == target_state {
11662 return true;
11663 }
11664 work.push(Work::Visit(target));
11665 }
11666 }
11667 }
11668 }
11669 Work::RuleFollow {
11670 target,
11671 rule_index,
11672 follow_state,
11673 } => {
11674 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
11675 continue;
11676 };
11677 if self.cached_rule_first_set(atn, target, child_stop).nullable {
11678 if follow_state == target_state {
11679 return true;
11680 }
11681 work.push(Work::Visit(follow_state));
11682 }
11683 }
11684 }
11685 }
11686 false
11687 }
11688
11689 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
11692 match self.clean_memo_mode {
11693 CleanMemoMode::Promote => true,
11694 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
11695 CleanMemoMode::Sparse => {
11696 self.clean_memo_sparse_samples += 1;
11697 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
11698 return false;
11699 }
11700 self.clean_memo_sparse_samples = 0;
11701 self.clean_memo_mode = CleanMemoMode::Probe;
11702 self.clean_memo_probe_samples = 0;
11703 self.clean_memo_probe_repeats = 0;
11704 self.clean_memo_probe_seen.clear();
11705 self.observe_clean_memo_probe(key)
11706 }
11707 }
11708 }
11709
11710 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
11711 self.clean_memo_probe_samples += 1;
11712 if !self.clean_memo_probe_seen.insert(key.clone()) {
11713 self.clean_memo_probe_repeats += 1;
11714 }
11715 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
11716 self.clean_memo_mode = CleanMemoMode::Promote;
11717 self.clean_memo_probe_seen.clear();
11718 return true;
11719 }
11720 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
11721 self.clean_memo_mode = CleanMemoMode::Sparse;
11722 self.clean_memo_sparse_samples = 0;
11723 self.clean_memo_probe_seen.clear();
11724 return false;
11725 }
11726 true
11727 }
11728
11729 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
11731 self.input.get(index)
11732 }
11733
11734 fn token_id_at(&self, index: usize) -> Option<TokenId> {
11736 self.input.get_id(index)
11737 }
11738
11739 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
11740 let token = self
11741 .token_id_at(index)
11742 .expect("recognized token index must exist in the token store");
11743 let node = if error {
11744 ArenaRecognizedNode::ErrorToken { token }
11745 } else {
11746 ArenaRecognizedNode::Token { token }
11747 };
11748 self.recognition_arena.push_node(node)
11749 }
11750
11751 fn arena_missing_token_node(
11752 &mut self,
11753 token_type: i32,
11754 at_index: usize,
11755 text: String,
11756 ) -> RecognizedNodeId {
11757 let extra = self
11758 .recognition_arena
11759 .push_extra(RecognitionExtra::MissingToken {
11760 token_type,
11761 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
11762 text,
11763 });
11764 self.recognition_arena
11765 .push_node(ArenaRecognizedNode::MissingToken { extra })
11766 }
11767
11768 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
11769 let ArenaRuleSpec {
11770 rule_index,
11771 invoking_state,
11772 alt_number,
11773 start_index,
11774 stop_index,
11775 return_values,
11776 children,
11777 } = spec;
11778 let return_values = (!return_values.is_empty()).then(|| {
11779 self.recognition_arena
11780 .push_extra(RecognitionExtra::ReturnValues(return_values))
11781 });
11782 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
11783 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11784 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
11785 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11786 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
11787 stop_index: stop_index
11788 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
11789 return_values,
11790 children,
11791 })
11792 }
11793
11794 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
11795 self.recognition_arena
11796 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
11797 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11798 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11799 })
11800 }
11801
11802 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
11803 *sequence = self.recognition_arena.prepend(*sequence, node);
11804 }
11805
11806 #[allow(clippy::missing_const_for_fn)]
11809 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
11810 self.last_recognition_arena_root = root;
11811 self.last_recognition_arena_diagnostics = diagnostics;
11812 #[cfg(feature = "perf-counters")]
11813 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
11814 let stats = self.recognition_arena_stats();
11815 #[allow(clippy::print_stderr)]
11816 {
11817 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
11818 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
11819 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
11820 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
11821 eprintln!("perf recognition_links_total={}", stats.total_links);
11822 eprintln!("perf recognition_links_live={}", stats.live_links);
11823 eprintln!("perf recognition_links_dead={}", stats.dead_links);
11824 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
11825 eprintln!("perf recognition_extras_total={}", stats.total_extras);
11826 eprintln!("perf recognition_extras_live={}", stats.live_extras);
11827 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
11828 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
11829 }
11830 }
11831 }
11832
11833 fn reset_recognition_arena(&mut self) {
11834 self.recognition_arena.reset();
11835 self.last_recognition_arena_root = NodeSeqId::EMPTY;
11836 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
11837 }
11838
11839 fn current_visible_index(&mut self) -> usize {
11842 let index = self.input.index();
11843 self.input.seek(index);
11844 self.input.index()
11845 }
11846
11847 fn child_expected_reaches_clean_eof(
11850 &mut self,
11851 children: &[RecognizeOutcome],
11852 expected: &ExpectedTokens,
11853 ) -> bool {
11854 let Some(index) = expected.index else {
11855 return false;
11856 };
11857 self.token_type_at(index) == TOKEN_EOF
11858 && children
11859 .iter()
11860 .any(|child| child.diagnostics.is_empty() && child.index == index)
11861 }
11862
11863 fn previous_token_index(&self, index: usize) -> Option<usize> {
11870 self.input.previous_visible_token_index(index)
11871 }
11872
11873 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
11878 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
11879 Some(index)
11880 } else {
11881 self.previous_token_index(index)
11882 }
11883 }
11884
11885 #[must_use]
11902 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
11903 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
11904 self.rule_stop_token_index(current_index, consumed_eof)
11905 }
11906
11907 #[must_use]
11916 pub fn after_action_stop_index_for_tree(
11917 &mut self,
11918 tree: ParseTree,
11919 current_index: usize,
11920 ) -> Option<usize> {
11921 if let Some(stop) = self
11922 .node(tree)
11923 .as_rule()
11924 .and_then(crate::tree::RuleNodeView::stop_id)
11925 {
11926 return Some(stop.index());
11927 }
11928 self.after_action_stop_index(current_index)
11929 }
11930
11931 #[must_use]
11941 pub fn after_action_start_index_for_tree(
11942 &self,
11943 tree: ParseTree,
11944 fallback_index: usize,
11945 ) -> usize {
11946 if let Some(start) = self
11947 .node(tree)
11948 .as_rule()
11949 .and_then(crate::tree::RuleNodeView::start_id)
11950 {
11951 return start.index();
11952 }
11953 fallback_index
11954 }
11955
11956 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
11961 self.rule_stop_token_index(index, consumed_eof)
11962 .and_then(|token_index| self.token_id_at(token_index))
11963 }
11964
11965 fn predicate_failure_recovery(
11972 &mut self,
11973 request: PredicateFailureRecovery<'_>,
11974 ) -> RecognizeOutcome {
11975 let PredicateFailureRecovery {
11976 rule_index,
11977 index,
11978 message,
11979 member_values,
11980 return_values,
11981 rule_alt_number,
11982 } = request;
11983 let rule_name = self
11984 .rule_names()
11985 .get(rule_index)
11986 .map_or_else(|| rule_index.to_string(), Clone::clone);
11987 let diagnostic = diagnostic_for_token(
11988 self.token_at(index).as_ref(),
11989 format!("rule {rule_name} {message}"),
11990 );
11991 let mut reversed_nodes = NodeSeqId::EMPTY;
11992 let mut next_index = index;
11993 loop {
11994 let symbol = self.token_type_at(next_index);
11995 if symbol == TOKEN_EOF {
11996 break;
11997 }
11998 let error = self.arena_token_node(next_index, true);
11999 self.arena_prepend(&mut reversed_nodes, error);
12000 let after = self.consume_index(next_index, symbol);
12001 if after == next_index {
12002 break;
12003 }
12004 next_index = after;
12005 }
12006 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
12007 let diagnostics = self
12008 .recognition_arena
12009 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
12010 RecognizeOutcome {
12011 index: next_index,
12012 consumed_eof: false,
12013 alt_number: rule_alt_number,
12014 member_values,
12015 return_values,
12016 diagnostics,
12017 decisions: Vec::new(),
12018 actions: Vec::new(),
12019 nodes,
12020 }
12021 }
12022
12023 fn parser_semantic_hook_result(
12026 &mut self,
12027 request: ParserSemanticHookRequest<'_>,
12028 ) -> Option<bool> {
12029 let ParserSemanticHookRequest {
12030 index,
12031 rule_index,
12032 pred_index,
12033 context,
12034 local_int_arg,
12035 member_values,
12036 } = request;
12037 let rule_name = self.rule_names().get(rule_index).cloned();
12038 self.input.seek(index);
12039 let input = &mut self.input;
12040 let semantic_hooks = &mut self.semantic_hooks;
12041 let mut ctx = ParserSemCtx {
12042 input,
12043 tree_storage: &self.tree,
12044 rule_index,
12045 coordinate_index: pred_index,
12046 rule_name,
12047 context,
12048 tree: None,
12049 local_int_arg,
12050 member_values,
12051 action: None,
12052 };
12053 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
12054 }
12055
12056 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
12061 if prior.is_empty() {
12062 return;
12063 }
12064 let mut merged = prior;
12065 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
12066 if !merged.contains(&coordinate) {
12067 merged.push(coordinate);
12068 }
12069 }
12070 self.unknown_predicate_hits = merged;
12071 }
12072
12073 fn restore_prior_unhandled_action_hits(&mut self, prior: Vec<(usize, usize)>) {
12076 if prior.is_empty() {
12077 return;
12078 }
12079 let mut merged = prior;
12080 for coordinate in std::mem::take(&mut self.unhandled_action_hits) {
12081 if !merged.contains(&coordinate) {
12082 merged.push(coordinate);
12083 }
12084 }
12085 self.unhandled_action_hits = merged;
12086 }
12087
12088 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
12097 apply_unknown_predicate_policy(
12098 self.unknown_predicate_policy,
12099 rule_index,
12100 pred_index,
12101 &mut self.unknown_predicate_hits,
12102 )
12103 }
12104
12105 fn unknown_semantic_error(&self) -> Option<AntlrError> {
12108 use std::fmt::Write as _;
12109 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
12110 return None;
12111 }
12112 let mut message = String::new();
12113 for (rule_index, pred_index) in &self.unknown_predicate_hits {
12114 if !message.is_empty() {
12115 message.push_str("; ");
12116 }
12117 let _ = match self.rule_names().get(*rule_index) {
12118 Some(rule_name) => write!(
12119 message,
12120 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
12121 ),
12122 None => write!(
12123 message,
12124 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
12125 ),
12126 };
12127 }
12128 for (rule_index, source_state) in &self.unhandled_action_hits {
12129 if !message.is_empty() {
12130 message.push_str("; ");
12131 }
12132 let _ = match self.rule_names().get(*rule_index) {
12133 Some(rule_name) => write!(
12134 message,
12135 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
12136 ),
12137 None => write!(
12138 message,
12139 "unhandled semantic action: rule_index={rule_index} state={source_state}"
12140 ),
12141 };
12142 }
12143 Some(AntlrError::Unsupported(message))
12144 }
12145
12146 fn parser_semir_predicate_matches(
12154 &mut self,
12155 semantics: &ParserSemantics,
12156 predicate: &ParserSemanticPredicate,
12157 request: ParserSemanticHookRequest<'_>,
12158 ) -> bool {
12159 self.input.seek(request.index);
12160 let rule_name = self
12161 .data
12162 .rule_names()
12163 .get(request.rule_index)
12164 .map(String::as_str);
12165 let unknown_predicate_policy = self.unknown_predicate_policy;
12166 let mut ctx = ParserSemIrCtx {
12167 input: &mut self.input,
12168 tree_storage: &self.tree,
12169 semantic_hooks: &mut self.semantic_hooks,
12170 rule_index: request.rule_index,
12171 coordinate_index: request.pred_index,
12172 rule_name,
12173 context: request.context,
12174 local_int_arg: request.local_int_arg,
12175 member_values: request.member_values,
12176 invoked_predicates: &mut self.invoked_predicates,
12177 unknown_predicate_policy,
12178 unknown_predicate_hits: &mut self.unknown_predicate_hits,
12179 };
12180 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
12181 }
12182
12183 fn fast_parser_predicate_matches(
12184 &mut self,
12185 context: Option<FastPredicateContext<'_>>,
12186 transition: ParserTransition<'_>,
12187 index: usize,
12188 ) -> bool {
12189 let Some(context) = context else {
12190 return true;
12191 };
12192 let rule_index = transition.arg0() as usize;
12193 let pred_index = transition.arg1() as usize;
12194 let key = (index, rule_index, pred_index);
12195 if let Some(result) = self.fast_predicate_cache.get(&key) {
12196 return *result;
12197 }
12198 let result = self.parser_predicate_matches(PredicateEval {
12199 index,
12200 rule_index,
12201 pred_index,
12202 predicates: context.predicates,
12203 semantics: context.semantics,
12204 context: None,
12205 local_int_arg: None,
12206 member_values: context.member_values,
12207 });
12208 self.fast_predicate_cache.insert(key, result);
12209 result
12210 }
12211
12212 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
12213 let PredicateEval {
12214 index,
12215 rule_index,
12216 pred_index,
12217 predicates,
12218 semantics,
12219 context,
12220 local_int_arg,
12221 member_values,
12222 } = eval;
12223 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
12224 semantics
12225 .predicates
12226 .iter()
12227 .find(|predicate| {
12228 predicate.rule_index == rule_index && predicate.pred_index == pred_index
12229 })
12230 .map(|predicate| (semantics, predicate))
12231 }) {
12232 return self.parser_semir_predicate_matches(
12233 semantics,
12234 predicate,
12235 ParserSemanticHookRequest {
12236 index,
12237 rule_index,
12238 pred_index,
12239 context,
12240 local_int_arg,
12241 member_values,
12242 },
12243 );
12244 }
12245 let Some((_, _, predicate)) = predicates
12246 .iter()
12247 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
12248 else {
12249 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
12250 index,
12251 rule_index,
12252 pred_index,
12253 context,
12254 local_int_arg,
12255 member_values,
12256 }) {
12257 return result;
12258 }
12259 return self.unknown_predicate_result(rule_index, pred_index);
12260 };
12261 self.input.seek(index);
12262 match predicate {
12263 ParserPredicate::True => true,
12264 ParserPredicate::False => false,
12265 ParserPredicate::FalseWithMessage { .. } => false,
12266 ParserPredicate::Invoke { value } => {
12267 let key = (rule_index, pred_index);
12268 if !self.invoked_predicates.contains(&key) {
12269 self.invoked_predicates.push(key);
12270 use std::io::Write as _;
12271 let mut stdout = std::io::stdout().lock();
12272 let _ = writeln!(stdout, "eval={value}");
12273 }
12274 *value
12275 }
12276 ParserPredicate::LookaheadTextEquals { offset, text } => self
12277 .input
12278 .lt(*offset)
12279 .is_some_and(|token| Token::text(&token) == Some(*text)),
12280 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
12281 self.la(*offset) != *token_type
12282 }
12283 ParserPredicate::TokenPairAdjacent => {
12284 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
12285 return false;
12286 };
12287 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
12288 return false;
12289 };
12290 first + 1 == second
12291 }
12292 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
12293 .and_then(|context| {
12294 context
12295 .child_rules(&self.tree, self.input.token_store(), *rule_index)
12296 .next()
12297 .map(crate::tree::RuleNodeView::text)
12298 })
12299 .is_none_or(|actual| actual != *text),
12300 ParserPredicate::LocalIntEquals { value } => {
12301 local_int_arg.is_none_or(|(_, actual)| actual == *value)
12302 }
12303 ParserPredicate::LocalIntLessOrEqual { value } => {
12304 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
12305 }
12306 ParserPredicate::MemberModuloEquals {
12307 member,
12308 modulus,
12309 value,
12310 equals,
12311 } => {
12312 if *modulus == 0 {
12313 return false;
12314 }
12315 let actual = member_values.scalar(*member).unwrap_or_default() % *modulus;
12316 (actual == *value) == *equals
12317 }
12318 ParserPredicate::MemberEquals {
12319 member,
12320 value,
12321 equals,
12322 } => {
12323 let actual = member_values.scalar(*member).unwrap_or_default();
12324 (actual == *value) == *equals
12325 }
12326 }
12327 }
12328
12329 fn parser_predicate_failure_message(
12331 &self,
12332 rule_index: usize,
12333 pred_index: usize,
12334 predicates: &[(usize, usize, ParserPredicate)],
12335 ) -> Option<&'static str> {
12336 predicates
12337 .iter()
12338 .find_map(|(rule, pred, predicate)| match predicate {
12339 ParserPredicate::FalseWithMessage { message }
12340 if *rule == rule_index && *pred == pred_index =>
12341 {
12342 Some(*message)
12343 }
12344 _ => None,
12345 })
12346 }
12347
12348 pub fn parser_semantic_ir_predicate_failure_message(
12351 &self,
12352 rule_index: usize,
12353 pred_index: usize,
12354 semantics: &ParserSemantics,
12355 ) -> Option<&'static str> {
12356 semantics
12357 .predicates
12358 .iter()
12359 .find(|predicate| {
12360 predicate.rule_index == rule_index && predicate.pred_index == pred_index
12361 })
12362 .and_then(|predicate| predicate.failure_message)
12363 }
12364
12365 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
12374 if symbol == TOKEN_EOF {
12375 return index;
12376 }
12377 self.input.next_visible_after(index)
12378 }
12379
12380 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
12383 let text = display_input_text(&self.input.text(start_index, error_index));
12384 diagnostic_for_token(
12385 self.token_at(error_index).as_ref(),
12386 format!("no viable alternative at input '{text}'"),
12387 )
12388 }
12389
12390 fn recovery_failure_diagnostic(
12393 &self,
12394 index: usize,
12395 decision_start_index: Option<usize>,
12396 expected_symbols: &BTreeSet<i32>,
12397 ) -> ParserDiagnostic {
12398 if expected_symbols.len() > 1 {
12399 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
12400 return self.no_viable_alternative(decision_start, index);
12401 }
12402 }
12403 diagnostic_for_token(
12404 self.token_at(index).as_ref(),
12405 format!(
12406 "mismatched input {} expecting {}",
12407 self.token_at(index)
12408 .as_ref()
12409 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
12410 self.expected_symbols_display(expected_symbols)
12411 ),
12412 )
12413 }
12414
12415 fn eof_rule_recovery_diagnostic(
12418 &self,
12419 index: usize,
12420 expected_symbols: &BTreeSet<i32>,
12421 expected: &ExpectedTokens,
12422 ) -> ParserDiagnostic {
12423 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
12424 &expected.symbols
12425 } else {
12426 expected_symbols
12427 };
12428 diagnostic_for_token(
12429 self.token_at(index).as_ref(),
12430 format!(
12431 "mismatched input {} expecting {}",
12432 self.token_at(index)
12433 .as_ref()
12434 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
12435 self.expected_symbols_display(symbols)
12436 ),
12437 )
12438 }
12439
12440 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
12446 let Some(stop) = stop else {
12447 return String::new();
12448 };
12449 let stop = if self
12450 .token_at(stop)
12451 .is_some_and(|token| token.token_type() == TOKEN_EOF)
12452 {
12453 let Some(previous) = self.previous_token_index(stop) else {
12454 return String::new();
12455 };
12456 previous
12457 } else {
12458 stop
12459 };
12460 self.input.text(start, stop)
12461 }
12462
12463 fn clear_prediction_diagnostics(&mut self) {
12466 self.prediction_diagnostics.clear();
12467 self.reported_prediction_diagnostics.clear();
12468 }
12469
12470 fn reset_per_parse_caches(&mut self) {
12494 self.rule_first_set_cache.clear();
12495 self.decision_lookahead_cache.clear();
12496 self.ll1_decision_cache.clear();
12497 self.fast_predicate_cache.clear();
12498 self.rule_stop_reach_cache.clear();
12499 self.clean_memo_mode = CleanMemoMode::Probe;
12500 self.clean_memo_probe_seen.clear();
12501 self.clean_memo_probe_samples = 0;
12502 self.clean_memo_probe_repeats = 0;
12503 self.clean_memo_sparse_samples = 0;
12504 self.recovery_symbols_intern.clear();
12505 self.state_expected_cache.clear();
12506 self.state_expected_token_cache.clear();
12507 }
12508
12509 fn record_prediction_diagnostics(
12512 &mut self,
12513 atn: &Atn,
12514 state: AtnState<'_>,
12515 start_index: usize,
12516 outcomes: &[RecognizeOutcome],
12517 ) {
12518 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
12519 return;
12520 }
12521 let Some(decision) = atn
12522 .decision_to_state()
12523 .iter()
12524 .position(|state_number| state_number == state.state_number())
12525 else {
12526 return;
12527 };
12528 let Some(rule_index) = state.rule_index() else {
12529 return;
12530 };
12531 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
12532 for outcome in outcomes
12533 .iter()
12534 .filter(|outcome| outcome.diagnostics.is_empty())
12535 {
12536 let Some(alt) = outcome.decisions.first() else {
12537 continue;
12538 };
12539 alts_by_end
12540 .entry(outcome.index)
12541 .or_default()
12542 .insert(alt + 1);
12543 }
12544 let Some((&end_index, ambig_alts)) = alts_by_end
12545 .iter()
12546 .filter(|(_, alts)| alts.len() > 1)
12547 .max_by_key(|(end, _)| *end)
12548 else {
12549 return;
12550 };
12551 let rule_name = self
12552 .rule_names()
12553 .get(rule_index)
12554 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
12555 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
12556 let input = display_input_text(&self.input.text(start_index, stop_index));
12557 let alts = ambig_alts
12558 .iter()
12559 .map(usize::to_string)
12560 .collect::<Vec<_>>()
12561 .join(", ");
12562 let key = (decision, start_index, format!("{alts}:{input}"));
12563 if !self.reported_prediction_diagnostics.insert(key) {
12564 return;
12565 }
12566 let start_diagnostic = diagnostic_for_token(
12567 self.token_at(start_index),
12568 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
12569 );
12570 let stop_diagnostic = diagnostic_for_token(
12571 self.token_at(stop_index),
12572 format!(
12573 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
12574 ),
12575 );
12576 self.prediction_diagnostics.push(start_diagnostic);
12577 self.prediction_diagnostics.push(stop_diagnostic);
12578 }
12579
12580 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
12582 expected_symbols_display(
12583 &state_expected_symbols(atn, state_number),
12584 self.vocabulary(),
12585 )
12586 }
12587
12588 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
12593 let state = usize::try_from(self.data().state()).unwrap_or(0);
12594 ExpectedTokenSet {
12595 symbols: state_expected_symbols(atn, state),
12596 }
12597 }
12598
12599 pub const fn set_bail_on_error(&mut self, bail: bool) {
12602 self.bail_on_error = bail;
12603 }
12604
12605 #[must_use]
12607 pub const fn bail_on_error(&self) -> bool {
12608 self.bail_on_error
12609 }
12610
12611 pub fn rule_invocation_stack(&self) -> Vec<String> {
12614 self.rule_context_stack
12615 .iter()
12616 .rev()
12617 .map(|frame| {
12618 self.data()
12619 .rule_names()
12620 .get(frame.rule_index)
12621 .cloned()
12622 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
12623 })
12624 .collect()
12625 }
12626
12627 pub fn active_invocation_states(&self) -> Vec<isize> {
12631 self.rule_context_stack
12632 .iter()
12633 .skip(1)
12634 .rev()
12635 .map(|frame| frame.invoking_state)
12636 .collect()
12637 }
12638
12639 pub fn token_display_at(&self, index: usize) -> Option<String> {
12641 self.token_at(index).map(|token| format!("{token}"))
12642 }
12643}
12644
12645impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
12646where
12647 S: TokenSource,
12648 H: SemanticHooks,
12649{
12650 fn parse_rule(
12651 &mut self,
12652 rule_index: usize,
12653 invoking_state: isize,
12654 precedence: i32,
12655 ) -> DirectAdaptiveParseResult<ParseTree> {
12656 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
12657 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
12658 )?;
12659 let stop_state = self
12660 .atn
12661 .rule_to_stop_state()
12662 .get(rule_index)
12663 .filter(|state| *state != usize::MAX)
12664 .ok_or(DirectAdaptiveParseControl::Fallback(
12665 DirectAdaptiveFallback::MissingAtn,
12666 ))?;
12667 let start_index = self.parser.current_visible_index();
12668 let mut context = ParserRuleContext::new(rule_index, invoking_state);
12669 if let Some(token) = self.parser.token_id_at(start_index) {
12670 self.parser.set_context_start(&mut context, token);
12671 }
12672 let mut state_number = start_state;
12673 let mut consumed_eof = false;
12674 while state_number != stop_state {
12675 self.step()?;
12676 let (transition, boundary) = self.next_transition(state_number, precedence)?;
12677 if boundary.is_some() {
12678 return Err(DirectAdaptiveParseControl::Fallback(
12679 DirectAdaptiveFallback::LeftRecursiveBoundary,
12680 ));
12681 }
12682 match transition.data() {
12683 Transition::Epsilon { target } => {
12684 state_number = target;
12685 }
12686 Transition::Precedence {
12687 target,
12688 precedence: transition_precedence,
12689 } => {
12690 if transition_precedence < precedence {
12691 return Err(DirectAdaptiveParseControl::Fallback(
12692 DirectAdaptiveFallback::Precedence,
12693 ));
12694 }
12695 state_number = target;
12696 }
12697 Transition::Rule {
12698 rule_index,
12699 follow_state,
12700 precedence: rule_precedence,
12701 ..
12702 } => {
12703 let child = self.parse_rule(
12704 rule_index,
12705 invoking_state_number(state_number),
12706 rule_precedence,
12707 )?;
12708 if self.parser.build_parse_trees {
12709 self.parser.tree.add_child(&mut context, child);
12710 }
12711 state_number = follow_state;
12712 }
12713 Transition::Atom { .. }
12714 | Transition::Range { .. }
12715 | Transition::Set { .. }
12716 | Transition::NotSet { .. }
12717 | Transition::Wildcard { .. } => {
12718 let (matched_eof, child) = self.consume_transition(transition)?;
12719 consumed_eof |= matched_eof;
12720 if let Some(child) = child {
12721 self.parser.tree.add_child(&mut context, child);
12722 }
12723 state_number = transition.target();
12724 }
12725 Transition::Predicate { .. } => {
12726 return Err(DirectAdaptiveParseControl::Fallback(
12727 DirectAdaptiveFallback::Predicate,
12728 ));
12729 }
12730 Transition::Action { .. } => {
12731 return Err(DirectAdaptiveParseControl::Fallback(
12732 DirectAdaptiveFallback::Action,
12733 ));
12734 }
12735 }
12736 }
12737
12738 let stop_index = self
12739 .parser
12740 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
12741 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
12742 self.parser.set_context_stop(&mut context, token);
12743 }
12744 Ok(self.parser.rule_node(context))
12745 }
12746
12747 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
12748 self.steps += 1;
12749 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
12750 return Err(DirectAdaptiveParseControl::Fallback(
12751 DirectAdaptiveFallback::StepLimit,
12752 ));
12753 }
12754 Ok(())
12755 }
12756
12757 fn next_transition(
12758 &mut self,
12759 state_number: usize,
12760 precedence: i32,
12761 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
12762 let state = self
12763 .atn
12764 .state(state_number)
12765 .ok_or(DirectAdaptiveParseControl::Fallback(
12766 DirectAdaptiveFallback::MissingAtn,
12767 ))?;
12768 if state.is_rule_stop() {
12769 return Err(DirectAdaptiveParseControl::Fallback(
12770 DirectAdaptiveFallback::RuleStop,
12771 ));
12772 }
12773 let transition_index =
12774 self.transition_index(state_number, state.transitions().len(), precedence)?;
12775 let transition = state.transitions().get(transition_index).ok_or(
12776 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
12777 )?;
12778 let boundary = match &transition.data() {
12779 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
12780 left_recursive_boundary(self.atn, state, *target)
12781 }
12782 _ => None,
12783 };
12784 Ok((transition, boundary))
12785 }
12786
12787 fn transition_index(
12788 &mut self,
12789 state_number: usize,
12790 transition_count: usize,
12791 precedence: i32,
12792 ) -> DirectAdaptiveParseResult<usize> {
12793 match transition_count {
12794 0 => Err(DirectAdaptiveParseControl::Fallback(
12795 DirectAdaptiveFallback::NoTransition,
12796 )),
12797 1 => Ok(0),
12798 _ => {
12799 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
12800 return Ok(alt);
12801 }
12802 let decision = self
12803 .decision_by_state
12804 .get(state_number)
12805 .and_then(|decision| *decision)
12806 .ok_or(DirectAdaptiveParseControl::Fallback(
12807 DirectAdaptiveFallback::UnknownDecision,
12808 ))?;
12809 let prediction = self
12810 .simulator
12811 .adaptive_predict_stream_info_with_precedence(
12812 decision,
12813 direct_precedence(precedence),
12814 &mut self.parser.input,
12815 )
12816 .map_err(|_| {
12817 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
12818 })?;
12819 if prediction.has_semantic_context {
12820 return Err(DirectAdaptiveParseControl::Fallback(
12821 DirectAdaptiveFallback::SemanticContext,
12822 ));
12823 }
12824 prediction
12825 .alt
12826 .checked_sub(1)
12827 .filter(|index| *index < transition_count)
12828 .ok_or(DirectAdaptiveParseControl::Fallback(
12829 DirectAdaptiveFallback::InvalidAlt,
12830 ))
12831 }
12832 }
12833 }
12834
12835 fn ll1_transition_index(
12836 &mut self,
12837 state_number: usize,
12838 transition_count: usize,
12839 ) -> DirectAdaptiveParseResult<Option<usize>> {
12840 let state = self
12841 .atn
12842 .state(state_number)
12843 .ok_or(DirectAdaptiveParseControl::Fallback(
12844 DirectAdaptiveFallback::MissingAtn,
12845 ))?;
12846 if state.precedence_rule_decision() {
12847 return Ok(None);
12848 }
12849 let Some(rule_stop) = state
12850 .rule_index()
12851 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
12852 else {
12853 return Ok(None);
12854 };
12855 let symbol = self.parser.input.la_token(1);
12856 let entry = self
12857 .parser
12858 .cached_decision_lookahead(self.atn, state, rule_stop);
12859 Ok(
12860 ll1_greedy_alt(&entry, symbol, state.non_greedy())
12861 .filter(|alt| *alt < transition_count),
12862 )
12863 }
12864
12865 fn consume_transition(
12866 &mut self,
12867 transition: ParserTransition<'_>,
12868 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
12869 let symbol = self.parser.input.la_token(1);
12870 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
12871 return Err(DirectAdaptiveParseControl::Fallback(
12872 DirectAdaptiveFallback::TokenMismatch,
12873 ));
12874 }
12875 let token = self
12876 .parser
12877 .input
12878 .lt_id(1)
12879 .ok_or(DirectAdaptiveParseControl::Fallback(
12880 DirectAdaptiveFallback::TokenMismatch,
12881 ))?;
12882 let matched_eof = symbol == TOKEN_EOF;
12883 if !matched_eof {
12884 self.parser.consume();
12885 }
12886 let child = self
12887 .parser
12888 .build_parse_trees
12889 .then(|| self.parser.terminal_tree(token));
12890 Ok((matched_eof, child))
12891 }
12892}
12893
12894impl<S, H> CommittedAtnParser<'_, '_, '_, S, H>
12895where
12896 S: TokenSource,
12897 H: SemanticHooks,
12898{
12899 fn parse_rule(
12900 &mut self,
12901 rule_index: usize,
12902 precedence: i32,
12903 inherited_local_int_arg: Option<(usize, i64)>,
12904 init_expected_state: Option<usize>,
12905 ) -> Result<CommittedRuleOutcome, AntlrError> {
12906 let start_state = self
12907 .atn
12908 .rule_to_start_state()
12909 .get(rule_index)
12910 .ok_or_else(|| {
12911 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
12912 })?;
12913 let stop_state = self
12914 .atn
12915 .rule_to_stop_state()
12916 .get(rule_index)
12917 .filter(|state| *state != usize::MAX)
12918 .ok_or_else(|| {
12919 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
12920 })?;
12921 let left_recursive = self
12922 .atn
12923 .state(start_state)
12924 .is_some_and(AtnState::left_recursive_rule);
12925 if let Some(error) = self.parser.rule_depth_cap_violation() {
12926 return Err(error);
12927 }
12928 if let Some(error) = self.parser.parse_listener_enter_rule(rule_index) {
12929 return Err(error);
12930 }
12931 let mut context = if left_recursive {
12932 self.parser.enter_recursion_rule(
12933 invoking_state_number(start_state),
12934 rule_index,
12935 precedence,
12936 )
12937 } else {
12938 self.parser
12939 .enter_rule(invoking_state_number(start_state), rule_index)
12940 };
12941 let rule_start_index = self.parser.current_visible_index();
12942 let local_int_arg =
12943 usize::try_from(context.invoking_state())
12944 .ok()
12945 .and_then(|source_state| {
12946 rule_local_int_arg(
12947 self.options.rule_args,
12948 source_state,
12949 rule_index,
12950 inherited_local_int_arg,
12951 )
12952 });
12953 if self.options.init_action_rules.contains(&rule_index) {
12954 let action = ParserAction::new_rule_init(
12955 rule_index,
12956 rule_start_index,
12957 init_expected_state.or(Some(start_state)),
12958 );
12959 if !self
12960 .parser
12961 .parser_rule_init_hook_with_context(action, &context, local_int_arg)
12962 {
12963 self.deferred_actions.push(action);
12964 }
12965 }
12966 let mut consumed_eof = false;
12967 let result = self.walk_rule(
12968 rule_index,
12969 start_state,
12970 stop_state,
12971 precedence,
12972 rule_start_index,
12973 local_int_arg,
12974 left_recursive,
12975 &mut context,
12976 &mut consumed_eof,
12977 );
12978
12979 let result = match result {
12980 Ok(()) => Ok(if left_recursive {
12981 self.parser.finish_recursion_rule(context, consumed_eof)
12982 } else {
12983 self.parser.finish_rule(context, consumed_eof)
12984 }),
12985 Err(error) if self.parser.bail_on_error() => {
12986 if left_recursive {
12987 self.parser.unroll_recursion_context();
12988 } else {
12989 self.parser.exit_rule();
12990 }
12991 Err(error)
12992 }
12993 Err(error) => {
12994 self.parser
12995 .recover_generated_rule(&mut context, self.atn, error);
12996 Ok(if left_recursive {
12997 self.parser.finish_recursion_rule(context, consumed_eof)
12998 } else {
12999 self.parser.finish_rule(context, consumed_eof)
13000 })
13001 }
13002 };
13003 self.parser.parse_listener_exit_rule(rule_index);
13004 result.map(|tree| CommittedRuleOutcome { tree, consumed_eof })
13005 }
13006
13007 #[allow(clippy::too_many_arguments)]
13008 fn walk_rule(
13009 &mut self,
13010 rule_index: usize,
13011 mut state_number: usize,
13012 stop_state: usize,
13013 precedence: i32,
13014 rule_start_index: usize,
13015 local_int_arg: Option<(usize, i64)>,
13016 left_recursive: bool,
13017 context: &mut ParserRuleContext,
13018 consumed_eof: &mut bool,
13019 ) -> Result<(), AntlrError> {
13020 let mut entered_loops = BTreeSet::new();
13021 let mut visited_coordinates = FxHashSet::default();
13022 let mut guarded_input_index = self.parser.input.index();
13023 while state_number != stop_state {
13024 let input_index = self.parser.input.index();
13025 if input_index != guarded_input_index {
13026 visited_coordinates.clear();
13027 guarded_input_index = input_index;
13028 }
13029 if !visited_coordinates.insert((state_number, input_index)) {
13030 return Err(AntlrError::Unsupported(format!(
13031 "committed parser encountered a non-consuming ATN cycle at state \
13032 {state_number}"
13033 )));
13034 }
13035 let state = self.atn.state(state_number).ok_or_else(|| {
13036 AntlrError::Unsupported(format!("missing parser ATN state {state_number}"))
13037 })?;
13038 if state.is_rule_stop() {
13039 return Err(AntlrError::Unsupported(format!(
13040 "rule {rule_index} reached unexpected stop state {state_number}"
13041 )));
13042 }
13043 let transition_index = {
13044 let mut decision_context = CommittedDecisionContext {
13045 precedence,
13046 local_int_arg,
13047 context,
13048 entered_loops: &mut entered_loops,
13049 };
13050 self.transition_index(state, &mut decision_context)?
13051 };
13052 let transition = state.transitions().get(transition_index).ok_or_else(|| {
13053 AntlrError::Unsupported(format!(
13054 "missing transition {transition_index} from parser ATN state {state_number}"
13055 ))
13056 })?;
13057
13058 let next_alt = next_alt_number(
13059 state,
13060 state.transitions().len(),
13061 transition_index,
13062 context.alt_number(),
13063 self.options.track_alt_numbers,
13064 );
13065 if self.options.track_alt_numbers && context.alt_number() == 0 && next_alt != 0 {
13066 context.set_alt_number(next_alt);
13067 }
13068 let next_context_alt = next_alt_number(
13069 state,
13070 state.transitions().len(),
13071 transition_index,
13072 context.context_alt_number(),
13073 self.options.track_context_alt_numbers,
13074 );
13075 if self.options.track_context_alt_numbers
13076 && context.context_alt_number() == 0
13077 && next_context_alt != 0
13078 {
13079 context.set_context_alt_number(next_context_alt);
13080 }
13081
13082 if left_recursive
13083 && left_recursive_boundary(self.atn, state, transition.target()).is_some()
13084 {
13085 if let Some(error) = self.parser.rule_depth_cap_violation() {
13086 return Err(error);
13087 }
13088 self.parser.parse_listener_exit_rule(rule_index);
13089 self.parser.push_new_recursion_context_with_previous(
13090 invoking_state_number(
13091 self.atn
13092 .rule_to_start_state()
13093 .get(rule_index)
13094 .unwrap_or(state_number),
13095 ),
13096 rule_index,
13097 context,
13098 );
13099 if let Some(error) = self.parser.parse_listener_enter_rule(rule_index) {
13100 return Err(error);
13101 }
13102 }
13103 state_number = self.apply_transition(
13104 state_number,
13105 transition,
13106 precedence,
13107 rule_start_index,
13108 local_int_arg,
13109 context,
13110 consumed_eof,
13111 )?;
13112 }
13113 Ok(())
13114 }
13115
13116 fn transition_index(
13117 &mut self,
13118 state: AtnState<'_>,
13119 decision_context: &mut CommittedDecisionContext<'_>,
13120 ) -> Result<usize, AntlrError> {
13121 let transition_count = state.transitions().len();
13122 if transition_count == 1 {
13123 return Ok(0);
13124 }
13125 let Some(decision) = self
13126 .decision_by_state
13127 .get(state.state_number())
13128 .copied()
13129 .flatten()
13130 else {
13131 return Err(AntlrError::Unsupported(format!(
13132 "parser ATN state {} has {transition_count} transitions but is not a decision",
13133 state.state_number()
13134 )));
13135 };
13136
13137 let decision_start = self.parser.input.index();
13138 let overridden_transition = if self.parser.semantic_hooks.observes_parser_decisions() {
13139 self.parser
13140 .semantic_hooks
13141 .parser_decision_override(decision, decision_start, transition_count)
13142 .and_then(|alternative| alternative.checked_sub(1))
13143 .filter(|alternative| *alternative < transition_count)
13144 } else {
13145 None
13146 };
13147 if let Some(selected) = overridden_transition {
13148 self.update_loop_selection(state, selected, decision_context);
13149 return Ok(selected);
13150 }
13151
13152 if !state.precedence_rule_decision() {
13153 let loop_back = match state.kind() {
13154 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack => true,
13155 AtnStateKind::StarLoopEntry => decision_context
13156 .entered_loops
13157 .contains(&state.state_number()),
13158 _ => false,
13159 };
13160 let children = self.parser.sync_decision(
13161 self.atn,
13162 state.state_number(),
13163 !decision_context.context.has_matched_child(),
13164 loop_back,
13165 )?;
13166 for child in children {
13167 self.parser.add_parse_child(decision_context.context, child);
13168 }
13169 }
13170
13171 let prediction_precedence = if state.precedence_rule_decision() {
13172 usize::try_from(decision_context.precedence.max(0)).unwrap_or_default()
13173 } else {
13174 0
13175 };
13176 let prediction_context = {
13177 let return_states = self
13178 .parser
13179 .prediction_context_return_states(self.atn)
13180 .collect::<Vec<_>>();
13181 self.simulator
13182 .intern_prediction_context(self.parser.rule_context_version(), return_states)
13183 };
13184 self.simulator.set_exact_ambig_detection(
13185 self.parser.prediction_mode() == PredictionMode::LlExactAmbigDetection,
13186 );
13187 let prediction_mode = self.parser.prediction_mode();
13188 let prediction = match self.simulator.adaptive_predict_stream_info_sll_probe(
13189 decision,
13190 prediction_precedence,
13191 &mut self.parser.input,
13192 ) {
13193 Ok(prediction)
13194 if prediction.requires_full_context && prediction_mode != PredictionMode::Sll =>
13195 {
13196 self.simulator.adaptive_predict_stream_info_with_context(
13197 decision,
13198 prediction_precedence,
13199 &mut self.parser.input,
13200 prediction_context,
13201 )
13202 }
13203 prediction => prediction,
13204 };
13205 let mut prediction = match prediction {
13206 Ok(prediction) => prediction,
13207 Err(ParserAtnSimulatorError::NoViableAlt { index, .. })
13208 if state.precedence_rule_decision() =>
13209 {
13210 let enter_alt = state.transitions().iter().position(|transition| {
13211 self.atn
13212 .state(transition.target())
13213 .is_some_and(|target| target.kind() != AtnStateKind::LoopEnd)
13214 });
13215 let exit_alt = state.transitions().iter().position(|transition| {
13216 self.atn
13217 .state(transition.target())
13218 .is_some_and(|target| target.kind() == AtnStateKind::LoopEnd)
13219 });
13220 let selected = if self.parser.left_recursive_loop_enter_matches(
13221 self.atn,
13222 state.state_number(),
13223 decision_context.precedence,
13224 ) {
13225 enter_alt
13226 } else {
13227 exit_alt
13228 };
13229 let Some(selected) = selected else {
13230 return Err(self
13231 .parser
13232 .no_viable_alternative_error_at(decision_start, index));
13233 };
13234 ParserAtnPrediction {
13235 alt: selected + 1,
13236 requires_full_context: true,
13237 has_semantic_context: true,
13238 diagnostic: None,
13239 }
13240 }
13241 Err(ParserAtnSimulatorError::NoViableAlt { index, .. }) => {
13242 return Err(self
13243 .parser
13244 .no_viable_alternative_error_at(decision_start, index));
13245 }
13246 Err(ParserAtnSimulatorError::PredictionRequiresMoreLookahead) => {
13247 return Err(self.parser.no_viable_alternative_error(decision_start));
13248 }
13249 Err(error) => {
13250 return Err(AntlrError::Unsupported(format!(
13251 "committed parser prediction failed at decision {decision}: {error:?}"
13252 )));
13253 }
13254 };
13255 let mut selected = prediction
13256 .alt
13257 .checked_sub(1)
13258 .filter(|index| *index < transition_count)
13259 .ok_or_else(|| self.parser.no_viable_alternative_error(decision_start))?;
13260
13261 let semantic_candidates = self.simulator.prediction_semantic_candidates();
13262 if !semantic_candidates.is_empty() {
13263 let predicted_alt = prediction.alt;
13264 let mut semantic_results = BTreeMap::new();
13265 let selected_alt = selected + 1;
13266 let selected_matches = self.semantic_alternative_matches(
13267 selected_alt,
13268 decision_context,
13269 &semantic_candidates,
13270 );
13271 semantic_results.insert(selected_alt, selected_matches);
13272 if !selected_matches {
13273 let alternatives = semantic_candidates
13274 .iter()
13275 .map(|candidate| candidate.alt)
13276 .filter(|alternative| *alternative != 0 && *alternative <= transition_count)
13277 .collect::<BTreeSet<_>>();
13278 selected = alternatives
13279 .into_iter()
13280 .find(|alternative| {
13281 let matches = self.semantic_alternative_matches(
13282 *alternative,
13283 decision_context,
13284 &semantic_candidates,
13285 );
13286 semantic_results.insert(*alternative, matches);
13287 matches
13288 })
13289 .and_then(|alternative| alternative.checked_sub(1))
13290 .ok_or_else(|| self.parser.no_viable_alternative_error(decision_start))?;
13291 }
13292 if self.parser.report_diagnostic_errors
13293 && let Some(diagnostic) = prediction.diagnostic.as_ref()
13294 {
13295 for alternative in diagnostic.conflicting_alts.clone() {
13296 if semantic_results.contains_key(&alternative)
13297 || !semantic_candidates
13298 .iter()
13299 .any(|candidate| candidate.alt == alternative)
13300 {
13301 continue;
13302 }
13303 let matches = self.semantic_alternative_matches(
13304 alternative,
13305 decision_context,
13306 &semantic_candidates,
13307 );
13308 semantic_results.insert(alternative, matches);
13309 }
13310 }
13311 Self::filter_prediction_diagnostic(
13312 &mut prediction,
13313 predicted_alt,
13314 selected + 1,
13315 &semantic_results,
13316 );
13317 }
13318 self.parser.record_generated_prediction_diagnostic(
13319 self.atn,
13320 state.state_number(),
13321 &prediction,
13322 );
13323
13324 self.update_loop_selection(state, selected, decision_context);
13325 Ok(selected)
13326 }
13327
13328 fn semantic_alternative_matches(
13329 &mut self,
13330 alternative: usize,
13331 decision_context: &CommittedDecisionContext<'_>,
13332 candidates: &[ParserSemanticCandidate],
13333 ) -> bool {
13334 candidates
13335 .iter()
13336 .filter(|candidate| candidate.alt == alternative)
13337 .any(|candidate| {
13338 self.semantic_context_matches(&candidate.context, decision_context, candidate)
13339 })
13340 }
13341
13342 fn filter_prediction_diagnostic(
13343 prediction: &mut ParserAtnPrediction,
13344 predicted_alt: usize,
13345 selected_alt: usize,
13346 semantic_results: &BTreeMap<usize, bool>,
13347 ) {
13348 prediction.alt = selected_alt;
13349 if selected_alt != predicted_alt {
13350 prediction.diagnostic = None;
13351 return;
13352 }
13353 if let Some(diagnostic) = prediction.diagnostic.as_mut() {
13354 diagnostic
13355 .conflicting_alts
13356 .retain(|alternative| semantic_results.get(alternative).copied().unwrap_or(true));
13357 if diagnostic.conflicting_alts.len() < 2 {
13358 prediction.diagnostic = None;
13359 }
13360 }
13361 }
13362
13363 fn semantic_context_matches(
13364 &mut self,
13365 semantic_context: &SemanticContext,
13366 decision_context: &CommittedDecisionContext<'_>,
13367 candidate: &ParserSemanticCandidate,
13368 ) -> bool {
13369 match semantic_context {
13370 SemanticContext::None => true,
13371 SemanticContext::Predicate {
13372 rule_index,
13373 pred_index,
13374 ..
13375 } => {
13376 let mut matched_provenance = false;
13377 for predicate_call in candidate
13378 .predicate_calls
13379 .iter()
13380 .filter(|call| call.rule_index == *rule_index && call.pred_index == *pred_index)
13381 {
13382 matched_provenance = true;
13383 let mut local_int_arg = decision_context.local_int_arg;
13384 for rule_call in &predicate_call.rule_calls {
13385 local_int_arg = rule_local_int_arg(
13386 self.options.rule_args,
13387 rule_call.source_state,
13388 rule_call.rule_index,
13389 local_int_arg,
13390 );
13391 }
13392 if !self.semantic_predicate_matches(
13393 *rule_index,
13394 *pred_index,
13395 decision_context,
13396 local_int_arg,
13397 ) {
13398 return false;
13399 }
13400 }
13401 if matched_provenance {
13402 true
13403 } else {
13404 self.semantic_predicate_matches(
13405 *rule_index,
13406 *pred_index,
13407 decision_context,
13408 decision_context.local_int_arg,
13409 )
13410 }
13411 }
13412 SemanticContext::Precedence { precedence } => {
13413 *precedence >= decision_context.precedence
13414 }
13415 SemanticContext::And(children) => {
13416 for child in children {
13417 if !self.semantic_context_matches(child, decision_context, candidate) {
13418 return false;
13419 }
13420 }
13421 true
13422 }
13423 SemanticContext::Or(children) => {
13424 for child in children {
13425 if self.semantic_context_matches(child, decision_context, candidate) {
13426 return true;
13427 }
13428 }
13429 false
13430 }
13431 }
13432 }
13433
13434 fn semantic_predicate_matches(
13435 &mut self,
13436 rule_index: usize,
13437 pred_index: usize,
13438 decision_context: &CommittedDecisionContext<'_>,
13439 local_int_arg: Option<(usize, i64)>,
13440 ) -> bool {
13441 let member_values = self.parser.int_members.clone();
13442 self.parser.parser_predicate_matches(PredicateEval {
13443 index: self.parser.input.index(),
13444 rule_index,
13445 pred_index,
13446 predicates: self.options.predicates,
13447 semantics: self.options.semantics,
13448 context: Some(&*decision_context.context),
13449 local_int_arg,
13450 member_values: &member_values,
13451 })
13452 }
13453
13454 fn update_loop_selection(
13455 &self,
13456 state: AtnState<'_>,
13457 selected: usize,
13458 decision_context: &mut CommittedDecisionContext<'_>,
13459 ) {
13460 if state.kind() == AtnStateKind::StarLoopEntry {
13461 let enters = self
13462 .atn
13463 .state(
13464 state
13465 .transitions()
13466 .get(selected)
13467 .expect("selected transition is in bounds")
13468 .target(),
13469 )
13470 .is_some_and(|target| target.kind() != AtnStateKind::LoopEnd);
13471 if enters {
13472 decision_context.entered_loops.insert(state.state_number());
13473 } else {
13474 decision_context.entered_loops.remove(&state.state_number());
13475 }
13476 }
13477 }
13478
13479 #[allow(clippy::too_many_arguments)]
13480 fn apply_transition(
13481 &mut self,
13482 source_state: usize,
13483 transition: ParserTransition<'_>,
13484 precedence: i32,
13485 rule_start_index: usize,
13486 local_int_arg: Option<(usize, i64)>,
13487 context: &mut ParserRuleContext,
13488 consumed_eof: &mut bool,
13489 ) -> Result<usize, AntlrError> {
13490 self.parser.set_state(invoking_state_number(source_state));
13491 match transition.data() {
13492 Transition::Epsilon { target } => Ok(target),
13493 Transition::Atom { target, label } => {
13494 let matched = self
13495 .parser
13496 .match_token_recovering(label, target, self.atn)?;
13497 *consumed_eof |= matched.consumed_eof();
13498 for child in matched.into_child_iter() {
13499 self.parser.add_parse_child(context, child);
13500 }
13501 Ok(target)
13502 }
13503 Transition::Range {
13504 target,
13505 start,
13506 stop,
13507 } => {
13508 let matched =
13509 self.parser
13510 .match_set_recovering(&[(start, stop)], target, self.atn)?;
13511 *consumed_eof |= matched.consumed_eof();
13512 for child in matched.into_child_iter() {
13513 self.parser.add_parse_child(context, child);
13514 }
13515 Ok(target)
13516 }
13517 Transition::Set { target, set } => {
13518 let matched = self
13519 .parser
13520 .match_token_set_recovering(set, target, self.atn)?;
13521 *consumed_eof |= matched.consumed_eof();
13522 for child in matched.into_child_iter() {
13523 self.parser.add_parse_child(context, child);
13524 }
13525 Ok(target)
13526 }
13527 Transition::NotSet { target, set } => {
13528 let matched = self.parser.match_not_token_set_recovering(
13529 set,
13530 1,
13531 self.atn.max_token_type(),
13532 target,
13533 self.atn,
13534 )?;
13535 *consumed_eof |= matched.consumed_eof();
13536 for child in matched.into_child_iter() {
13537 self.parser.add_parse_child(context, child);
13538 }
13539 Ok(target)
13540 }
13541 Transition::Wildcard { target } => {
13542 let matched = self.parser.match_not_set_recovering(
13543 &[],
13544 1,
13545 self.atn.max_token_type(),
13546 target,
13547 self.atn,
13548 )?;
13549 *consumed_eof |= matched.consumed_eof();
13550 for child in matched.into_child_iter() {
13551 self.parser.add_parse_child(context, child);
13552 }
13553 Ok(target)
13554 }
13555 Transition::Rule {
13556 rule_index,
13557 follow_state,
13558 precedence: rule_precedence,
13559 ..
13560 } => {
13561 let marker = self
13562 .parser
13563 .push_invoking_state(invoking_state_number(source_state));
13564 let child = if self.parser.generated_rule_stack_check_due() {
13565 grow_generated_rule_stack(|| {
13566 self.parse_rule(
13567 rule_index,
13568 rule_precedence,
13569 local_int_arg,
13570 Some(follow_state),
13571 )
13572 })
13573 } else {
13574 self.parse_rule(
13575 rule_index,
13576 rule_precedence,
13577 local_int_arg,
13578 Some(follow_state),
13579 )
13580 };
13581 self.parser.discard_invoking_state(marker);
13582 let child = child?;
13583 *consumed_eof |= child.consumed_eof;
13584 self.parser.add_parse_child(context, child.tree);
13585 Ok(follow_state)
13586 }
13587 Transition::Predicate {
13588 target,
13589 rule_index,
13590 pred_index,
13591 ..
13592 } => {
13593 let member_values = self.parser.int_members.clone();
13594 if self.parser.parser_predicate_matches(PredicateEval {
13595 index: self.parser.input.index(),
13596 rule_index,
13597 pred_index,
13598 predicates: self.options.predicates,
13599 semantics: self.options.semantics,
13600 context: Some(context),
13601 local_int_arg,
13602 member_values: &member_values,
13603 }) {
13604 return Ok(target);
13605 }
13606 if let Some(message) = self
13607 .options
13608 .semantics
13609 .and_then(|semantics| {
13610 self.parser.parser_semantic_ir_predicate_failure_message(
13611 rule_index, pred_index, semantics,
13612 )
13613 })
13614 .or_else(|| {
13615 self.parser.parser_predicate_failure_message(
13616 rule_index,
13617 pred_index,
13618 self.options.predicates,
13619 )
13620 })
13621 {
13622 return Err(self
13623 .parser
13624 .failed_predicate_option_error(rule_index, message));
13625 }
13626 Err(self.parser.failed_predicate_error("semantic predicate"))
13627 }
13628 Transition::Action {
13629 target, rule_index, ..
13630 } => {
13631 self.apply_translated_actions(source_state, rule_index, context);
13632 if let Some(action_index) = self.action_index(source_state) {
13633 let action = self.parser.parser_action_at_current_indexed(
13634 source_state,
13635 rule_index,
13636 action_index,
13637 rule_start_index,
13638 *consumed_eof,
13639 );
13640 let _ = self.parser.parser_action_hook_inner(
13641 action,
13642 Some(context),
13643 None,
13644 local_int_arg,
13645 true,
13646 );
13647 }
13648 Ok(target)
13649 }
13650 Transition::Precedence {
13651 target,
13652 precedence: transition_precedence,
13653 } => {
13654 if transition_precedence >= precedence {
13655 Ok(target)
13656 } else {
13657 Err(self
13658 .parser
13659 .failed_predicate_error(format!("precpred(_ctx, {transition_precedence})")))
13660 }
13661 }
13662 }
13663 }
13664
13665 fn apply_translated_actions(
13666 &mut self,
13667 source_state: usize,
13668 rule_index: usize,
13669 context: &mut ParserRuleContext,
13670 ) {
13671 apply_member_actions(
13672 source_state,
13673 self.options.member_actions,
13674 self.options.semantics,
13675 &mut self.parser.int_members,
13676 );
13677 let return_values = return_values_after_action(
13678 source_state,
13679 rule_index,
13680 self.options.return_actions,
13681 self.options.semantics,
13682 &BTreeMap::new(),
13683 );
13684 for (name, value) in return_values {
13685 context.set_int_return(name, value);
13686 }
13687 }
13688
13689 fn action_index(&self, source_state: usize) -> Option<usize> {
13690 self.action_index_by_state.get(&source_state).copied()
13691 }
13692}
13693
13694fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
13697 if !state.precedence_rule_decision() {
13698 return None;
13699 }
13700 let target_state = atn.state(target)?;
13701 if target_state.kind() == AtnStateKind::LoopEnd {
13702 return None;
13703 }
13704 state.rule_index()
13705}
13706
13707fn next_alt_number(
13714 state: AtnState<'_>,
13715 transition_count: usize,
13716 transition_index: usize,
13717 current_alt_number: usize,
13718 track_alt_numbers: bool,
13719) -> usize {
13720 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
13721 return current_alt_number;
13722 }
13723 if matches!(
13724 state.kind(),
13725 AtnStateKind::Basic
13726 | AtnStateKind::BlockStart
13727 | AtnStateKind::PlusBlockStart
13728 | AtnStateKind::StarBlockStart
13729 | AtnStateKind::StarLoopEntry
13730 ) && !state.precedence_rule_decision()
13731 {
13732 return transition_index + 1;
13733 }
13734 current_alt_number
13735}
13736
13737fn invoking_state_number(state_number: usize) -> isize {
13740 isize::try_from(state_number).unwrap_or(isize::MAX)
13741}
13742
13743const fn packed_i32(value: u32) -> i32 {
13744 i32::from_le_bytes(value.to_le_bytes())
13745}
13746
13747fn direct_precedence(precedence: i32) -> usize {
13748 usize::try_from(precedence.max(0)).unwrap_or_default()
13749}
13750
13751fn token_input_display(token: &impl Token) -> String {
13752 format!("'{}'", token.text().unwrap_or("<EOF>"))
13753}
13754
13755fn display_input_text(text: &str) -> String {
13756 let mut out = String::new();
13757 for ch in text.chars() {
13758 match ch {
13759 '\n' => out.push_str("\\n"),
13760 '\r' => out.push_str("\\r"),
13761 '\t' => out.push_str("\\t"),
13762 other => out.push(other),
13763 }
13764 }
13765 out
13766}
13767
13768fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
13769 let (line, column, offending) = token.map_or((0, 0, None), |token| {
13770 (token.line(), token.column(), Some(token.token_id()))
13771 });
13772 ParserDiagnostic {
13773 line,
13774 column,
13775 message,
13776 offending,
13777 }
13778}
13779
13780fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
13781 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
13782}
13783
13784fn expected_symbols_display_iter(
13785 symbols: impl IntoIterator<Item = i32>,
13786 vocabulary: &Vocabulary,
13787) -> String {
13788 let items = symbols
13789 .into_iter()
13790 .map(|symbol| expected_symbol_display(symbol, vocabulary))
13791 .collect::<Vec<_>>();
13792 if let [single] = items.as_slice() {
13793 return single.clone();
13794 }
13795 format!("{{{}}}", items.join(", "))
13796}
13797
13798fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
13799 if symbol == TOKEN_EOF {
13800 return "<EOF>".to_owned();
13801 }
13802 vocabulary.display_name(symbol)
13803}
13804
13805fn caller_follow_token_info_for_stream<S: TokenSource>(
13806 input: &mut CommonTokenStream<S>,
13807 index: usize,
13808) -> (i32, bool, bool) {
13809 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
13812 input.fill();
13813 }
13814 let token_type = input.token_type_at_index(index);
13815 let visible_channel = input.channel();
13816 let token = input.get(index);
13817 let is_boundary = token
13818 .as_ref()
13819 .and_then(Token::text)
13820 .is_some_and(is_caller_follow_boundary_text);
13821 let is_boundary_gap = token.as_ref().is_some_and(|token| {
13822 token.channel() != visible_channel
13823 || is_caller_follow_boundary_gap_text(token.text_or_empty())
13824 });
13825 (token_type, is_boundary, is_boundary_gap)
13826}
13827
13828fn is_caller_follow_boundary_text(text: &str) -> bool {
13829 text.chars().any(|ch| ch == ';' || ch == '\n')
13830 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
13831}
13832
13833fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
13834 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
13835}
13836
13837fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
13841 let Some(rule_index) = state.rule_index() else {
13842 return false;
13843 };
13844 atn.rule_to_start_state()
13845 .get(rule_index)
13846 .and_then(|state_number| atn.state(state_number))
13847 .is_some_and(AtnState::left_recursive_rule)
13848}
13849
13850fn select_better_top_outcome(
13857 first: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
13858 second: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
13859 arena: &RecognitionArena,
13860) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
13861 match (first, second) {
13862 (Ok(first), Ok(second)) => {
13863 if arena.diagnostics(first.0.diagnostics).next().is_none() {
13864 Ok(first)
13865 } else {
13866 Ok(second)
13867 }
13868 }
13869 (Ok(first), Err(_)) => Ok(first),
13870 (Err(_), Ok(second)) => Ok(second),
13871 (Err(_), Err(second_expected)) => Err(second_expected),
13872 }
13873}
13874
13875fn select_best_fast_outcome(
13881 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
13882 prediction_mode: PredictionMode,
13883 caller_follow: Option<&TokenBitSet>,
13884 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
13885 arena: &RecognitionArena,
13886) -> Option<FastRecognizeOutcome> {
13887 let mut best = None;
13888 let mut best_caller_follow = None;
13889 for outcome in outcomes {
13890 if matches!(
13891 prediction_mode,
13892 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
13893 ) && outcome.diagnostics.is_empty()
13894 && let Some(follow) = caller_follow
13895 {
13896 let (token_type, is_boundary, _) = token_info_at(outcome.index);
13897 if is_boundary && follow.contains(token_type) {
13898 let replace =
13899 best_caller_follow
13900 .as_ref()
13901 .is_none_or(|existing: &FastRecognizeOutcome| {
13902 (outcome.index, outcome.consumed_eof)
13903 < (existing.index, existing.consumed_eof)
13904 });
13905 if replace {
13906 best_caller_follow = Some(outcome);
13907 }
13908 }
13909 }
13910 let Some(existing) = best else {
13911 best = Some(outcome);
13912 continue;
13913 };
13914 let outcome_position = (outcome.index, outcome.consumed_eof);
13915 let best_position = (existing.index, existing.consumed_eof);
13916 let better = match prediction_mode {
13917 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
13918 outcome_position,
13919 outcome.diagnostics,
13920 best_position,
13921 existing.diagnostics,
13922 arena,
13923 ),
13924 PredictionMode::Sll => outcome.index > existing.index,
13925 };
13926 best = Some(if better { outcome } else { existing });
13927 }
13928 let should_use_caller_follow =
13929 best_caller_follow
13930 .as_ref()
13931 .zip(best.as_ref())
13932 .is_some_and(|(candidate, selected)| {
13933 if !selected.diagnostics.is_empty() {
13934 return true;
13935 }
13936 candidate.index < selected.index
13937 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
13938 });
13939 if should_use_caller_follow {
13940 best_caller_follow
13941 } else {
13942 best
13943 }
13944}
13945
13946fn select_best_outcome(
13947 outcomes: impl Iterator<Item = RecognizeOutcome>,
13948 prediction_mode: PredictionMode,
13949 arena: &RecognitionArena,
13950) -> Option<RecognizeOutcome> {
13951 let outcomes = outcomes.collect::<Vec<_>>();
13952 let prefer_first_tie = outcomes
13953 .iter()
13954 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
13955 outcomes.into_iter().reduce(|best, outcome| {
13956 let outcome_position = (outcome.index, outcome.consumed_eof);
13957 let best_position = (best.index, best.consumed_eof);
13958 let better = match prediction_mode {
13959 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
13960 outcome_is_better(
13961 outcome_position,
13962 outcome.diagnostics,
13963 best_position,
13964 best.diagnostics,
13965 arena,
13966 ) || (outcome_position == best_position
13967 && arena.diagnostics_len(outcome.diagnostics)
13968 == arena.diagnostics_len(best.diagnostics)
13969 && arena.diagnostics_recovery_rank(outcome.diagnostics)
13970 == arena.diagnostics_recovery_rank(best.diagnostics)
13971 && (outcome.decisions < best.decisions
13972 || (!prefer_first_tie
13973 && outcome.decisions == best.decisions
13974 && outcome.actions > best.actions)))
13975 }
13976 PredictionMode::Sll => {
13977 outcome_position > best_position
13978 || (outcome_position == best_position
13979 && !prefer_first_tie
13980 && (outcome.decisions < best.decisions
13981 || (outcome.decisions == best.decisions
13982 && outcome_is_better(
13983 outcome_position,
13984 outcome.diagnostics,
13985 best_position,
13986 best.diagnostics,
13987 arena,
13988 ))))
13989 }
13990 };
13991 if better {
13992 return outcome;
13993 }
13994 best
13995 })
13996}
13997
13998fn transition_decision(
14005 atn: &Atn,
14006 state: AtnState<'_>,
14007 transition_count: usize,
14008 transition_index: usize,
14009 predicates: &[(usize, usize, ParserPredicate)],
14010) -> Option<usize> {
14011 if transition_count <= 1 || decision_reaches_unsupported_predicate(atn, state, predicates) {
14012 return None;
14013 }
14014 Some(transition_index)
14015}
14016
14017fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
14023 transition_count > 1
14024 && !matches!(
14025 state.kind(),
14026 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
14027 )
14028}
14029
14030fn record_no_viable_if_ambiguous(
14033 expected: &mut ExpectedTokens,
14034 decision_start_index: Option<usize>,
14035 index: usize,
14036) {
14037 if expected.index == Some(index) && expected.symbols.len() > 1 {
14038 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
14039 expected.record_no_viable(decision_start, index);
14040 }
14041 }
14042}
14043
14044const fn record_predicate_no_viable(
14047 expected: &mut ExpectedTokens,
14048 decision_start_index: Option<usize>,
14049 index: usize,
14050) {
14051 if let Some(decision_start) = decision_start_index {
14052 expected.record_no_viable(decision_start, index);
14053 }
14054}
14055
14056const fn no_viable_decision_start(
14058 decision_start_index: Option<usize>,
14059 index: usize,
14060) -> Option<usize> {
14061 match decision_start_index {
14062 Some(start) if index > start => Some(start),
14063 _ => None,
14064 }
14065}
14066
14067fn restore_expected(
14071 children: &[RecognizeOutcome],
14072 child_start_index: usize,
14073 expected: &mut ExpectedTokens,
14074 snapshot: ExpectedTokens,
14075 preserve_child_expected: bool,
14076) {
14077 if preserve_child_expected {
14078 return;
14079 }
14080 if children
14081 .iter()
14082 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
14083 {
14084 *expected = snapshot;
14085 }
14086}
14087
14088fn decision_reaches_unsupported_predicate(
14091 atn: &Atn,
14092 state: AtnState<'_>,
14093 predicates: &[(usize, usize, ParserPredicate)],
14094) -> bool {
14095 state.transitions().iter().any(|transition| {
14096 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
14097 })
14098}
14099
14100fn transition_reaches_unsupported_predicate(
14102 atn: &Atn,
14103 transition: ParserTransition<'_>,
14104 predicates: &[(usize, usize, ParserPredicate)],
14105 visited: &mut BTreeSet<usize>,
14106) -> bool {
14107 match &transition.data() {
14108 Transition::Predicate {
14109 rule_index,
14110 pred_index,
14111 ..
14112 } => !predicates
14113 .iter()
14114 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
14115 Transition::Epsilon { target }
14116 | Transition::Action { target, .. }
14117 | Transition::Rule { target, .. } => {
14118 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
14119 }
14120 Transition::Precedence { .. }
14121 | Transition::Atom { .. }
14122 | Transition::Range { .. }
14123 | Transition::Set { .. }
14124 | Transition::NotSet { .. }
14125 | Transition::Wildcard { .. } => false,
14126 }
14127}
14128
14129fn state_reaches_unsupported_predicate(
14131 atn: &Atn,
14132 state_number: usize,
14133 predicates: &[(usize, usize, ParserPredicate)],
14134 visited: &mut BTreeSet<usize>,
14135) -> bool {
14136 if !visited.insert(state_number) {
14137 return false;
14138 }
14139 let Some(state) = atn.state(state_number) else {
14140 return false;
14141 };
14142 state.transitions().iter().any(|transition| {
14143 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
14144 })
14145}
14146
14147fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
14149 if let Some(decision) = decision {
14150 outcome.decisions.insert(0, decision);
14151 }
14152}
14153
14154fn outcome_is_better(
14155 outcome_position: (usize, bool),
14156 outcome_diagnostics: DiagnosticSeqId,
14157 best_position: (usize, bool),
14158 best_diagnostics: DiagnosticSeqId,
14159 arena: &RecognitionArena,
14160) -> bool {
14161 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
14162 let best_len = arena.diagnostics_len(best_diagnostics);
14163 outcome_position > best_position
14164 || (outcome_position == best_position
14165 && (outcome_len < best_len
14166 || (outcome_len == best_len
14167 && arena.diagnostics_recovery_rank(outcome_diagnostics)
14168 < arena.diagnostics_recovery_rank(best_diagnostics))))
14169}
14170
14171fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
14172 if outcomes
14173 .iter()
14174 .any(|outcome| outcome.diagnostics.is_empty())
14175 {
14176 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
14177 }
14178}
14179
14180fn discard_recovered_outcomes_if_clean_path_exists(
14181 outcomes: &mut Vec<RecognizeOutcome>,
14182 arena: &RecognitionArena,
14183) {
14184 if outcomes
14185 .iter()
14186 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
14187 {
14188 return;
14189 }
14190 if outcomes
14191 .iter()
14192 .any(|outcome| outcome.diagnostics.is_empty())
14193 {
14194 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
14195 }
14196}
14197
14198fn outcome_has_rule_failure_diagnostic(
14201 outcome: &RecognizeOutcome,
14202 arena: &RecognitionArena,
14203) -> bool {
14204 arena
14205 .diagnostics(outcome.diagnostics)
14206 .any(|diagnostic| diagnostic.message.starts_with("rule "))
14207}
14208
14209fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
14223 if outcomes.len() < 2 {
14224 return;
14225 }
14226 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
14227 outcomes.retain(|outcome| {
14228 seen.insert((
14229 outcome.index,
14230 outcome.consumed_eof,
14231 arena.diagnostics_len(outcome.diagnostics),
14232 arena.diagnostics_recovery_rank(outcome.diagnostics),
14233 ))
14234 });
14235}
14236
14237const FAST_OUTCOME_INLINE_KEYS: usize = 8;
14238const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
14239const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
14240const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
14241
14242#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14243enum FastOutcomeDedupStrategy {
14244 Inline,
14245 Dense,
14246 Sparse,
14247}
14248
14249impl FastOutcomeDedupScratch {
14250 fn prepare_dense(&mut self, word_count: usize) {
14251 while let Some(word_index) = self.touched_dense_words.pop() {
14252 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
14253 }
14254 if self.dense_words.len() < word_count {
14255 self.dense_words.resize(word_count, 0);
14256 }
14257 }
14258}
14259
14260fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
14261 let first_index = outcomes.first()?.index;
14262 let (min_index, max_index) = outcomes[1..].iter().fold(
14263 (first_index, first_index),
14264 |(min_index, max_index), outcome| {
14265 (min_index.min(outcome.index), max_index.max(outcome.index))
14266 },
14267 );
14268 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
14269 let bit_count = index_span.checked_mul(2)?;
14270 let word_count =
14271 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
14272 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
14273 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
14274 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
14275 .then_some((min_index, word_count))
14276}
14277
14278#[cfg(feature = "perf-counters")]
14279fn record_clean_fast_outcome_dedup(
14280 strategy: FastOutcomeDedupStrategy,
14281 input_len: usize,
14282 output_len: usize,
14283 dense_words: usize,
14284) {
14285 let counter = match strategy {
14286 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
14287 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
14288 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
14289 };
14290 perf_counters::inc(
14291 &perf_counters::OUTCOME_DEDUPE_INPUTS,
14292 u64::try_from(input_len).unwrap_or(u64::MAX),
14293 );
14294 perf_counters::inc(
14295 &perf_counters::OUTCOME_DEDUPE_REMOVED,
14296 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
14297 );
14298 perf_counters::inc(counter, 1);
14299 perf_counters::inc(
14300 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
14301 u64::try_from(dense_words).unwrap_or(u64::MAX),
14302 );
14303}
14304
14305fn dedupe_clean_fast_outcomes(
14309 outcomes: &mut Vec<FastRecognizeOutcome>,
14310 scratch: &mut FastOutcomeDedupScratch,
14311) -> FastOutcomeDedupStrategy {
14312 #[cfg(feature = "perf-counters")]
14313 let input_len = outcomes.len();
14314 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
14315 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
14316 let mut inline_len = 0_usize;
14317 outcomes.retain(|outcome| {
14318 let key = (outcome.index, outcome.consumed_eof);
14319 if inline_keys[..inline_len].contains(&key) {
14320 return false;
14321 }
14322 inline_keys[inline_len] = key;
14323 inline_len += 1;
14324 true
14325 });
14326 #[cfg(feature = "perf-counters")]
14327 record_clean_fast_outcome_dedup(
14328 FastOutcomeDedupStrategy::Inline,
14329 input_len,
14330 outcomes.len(),
14331 0,
14332 );
14333 return FastOutcomeDedupStrategy::Inline;
14334 }
14335
14336 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
14337 scratch.prepare_dense(word_count);
14338 outcomes.retain(|outcome| {
14339 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
14340 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
14341 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
14342 let word = &mut scratch.dense_words[word_index];
14343 if *word & bit != 0 {
14344 return false;
14345 }
14346 if *word == 0 {
14347 scratch
14348 .touched_dense_words
14349 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
14350 }
14351 *word |= bit;
14352 true
14353 });
14354 #[cfg(feature = "perf-counters")]
14355 record_clean_fast_outcome_dedup(
14356 FastOutcomeDedupStrategy::Dense,
14357 input_len,
14358 outcomes.len(),
14359 word_count,
14360 );
14361 return FastOutcomeDedupStrategy::Dense;
14362 }
14363
14364 scratch.sparse_keys.clear();
14365 scratch.sparse_keys.reserve(outcomes.len());
14366 outcomes.retain(|outcome| {
14367 scratch
14368 .sparse_keys
14369 .insert((outcome.index, outcome.consumed_eof))
14370 });
14371 #[cfg(feature = "perf-counters")]
14372 record_clean_fast_outcome_dedup(
14373 FastOutcomeDedupStrategy::Sparse,
14374 input_len,
14375 outcomes.len(),
14376 0,
14377 );
14378 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
14379 scratch.sparse_keys = FxHashSet::default();
14380 }
14381 FastOutcomeDedupStrategy::Sparse
14382}
14383
14384fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
14387 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
14388 outcomes
14389 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
14390}
14391
14392fn compare_recognize_outcomes(
14393 left: &RecognizeOutcome,
14394 right: &RecognizeOutcome,
14395 arena: &RecognitionArena,
14396) -> Ordering {
14397 left.index
14398 .cmp(&right.index)
14399 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
14400 .then_with(|| left.alt_number.cmp(&right.alt_number))
14401 .then_with(|| left.member_values.cmp(&right.member_values))
14402 .then_with(|| left.return_values.cmp(&right.return_values))
14403 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
14404 .then_with(|| left.decisions.cmp(&right.decisions))
14405 .then_with(|| left.actions.cmp(&right.actions))
14406 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
14407}
14408
14409impl<S, H> Recognizer for BaseParser<S, H>
14410where
14411 S: TokenSource,
14412 H: SemanticHooks,
14413{
14414 fn data(&self) -> &RecognizerData {
14415 &self.data
14416 }
14417
14418 fn data_mut(&mut self) -> &mut RecognizerData {
14419 &mut self.data
14420 }
14421}
14422
14423impl<S, H> Parser for BaseParser<S, H>
14424where
14425 S: TokenSource,
14426 H: SemanticHooks,
14427{
14428 fn build_parse_trees(&self) -> bool {
14429 self.build_parse_trees
14430 }
14431
14432 fn set_build_parse_trees(&mut self, build: bool) {
14433 self.build_parse_trees = build;
14434 }
14435
14436 fn number_of_syntax_errors(&self) -> usize {
14437 Self::number_of_syntax_errors(self)
14438 }
14439
14440 fn report_diagnostic_errors(&self) -> bool {
14441 self.report_diagnostic_errors
14442 }
14443
14444 fn set_report_diagnostic_errors(&mut self, report: bool) {
14445 self.report_diagnostic_errors = report;
14446 }
14447
14448 fn prediction_mode(&self) -> PredictionMode {
14449 self.prediction_mode
14450 }
14451
14452 fn set_prediction_mode(&mut self, mode: PredictionMode) {
14453 self.prediction_mode = mode;
14454 }
14455
14456 fn max_rule_depth(&self) -> Option<usize> {
14457 self.max_rule_depth
14458 }
14459
14460 fn set_max_rule_depth(&mut self, depth: Option<usize>) {
14461 self.max_rule_depth = depth;
14462 }
14463
14464 fn add_parse_listener(&mut self, listener: Box<dyn ParseListener>) {
14465 self.parse_listeners.push(ParseListenerSlot(listener));
14466 }
14467
14468 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
14469 Self::remove_parse_listeners(self)
14470 }
14471}
14472
14473#[cfg(test)]
14474#[allow(clippy::disallowed_methods)] mod tests {
14476 use super::*;
14477 use crate::atn::parser::{
14478 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
14479 };
14480 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
14481 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
14482 use crate::token_stream::CommonTokenStream;
14483 use crate::tree::{NodeKind, ParseTreeStats};
14484 use crate::vocabulary::Vocabulary;
14485 use std::cell::RefCell;
14486 use std::mem::size_of;
14487 use std::rc::Rc;
14488 use std::sync::{Arc, Mutex};
14489
14490 #[test]
14491 fn fx_hasher_write_matches_typed_methods_for_full_words() {
14492 let value: u64 = 0x0102_0304_0506_0708;
14499 let mut typed = FxHasher::default();
14500 typed.write_u64(value);
14501 let mut bytewise = FxHasher::default();
14502 bytewise.write(&value.to_le_bytes());
14503 assert_eq!(typed.finish(), bytewise.finish());
14504 }
14505
14506 #[derive(Clone, Debug)]
14507 struct TestToken {
14508 spec: TokenSpec,
14509 id: TokenId,
14510 source_name: String,
14511 }
14512
14513 impl TestToken {
14514 fn new(token_type: i32) -> Self {
14515 Self {
14516 spec: TokenSpec::explicit(token_type, ""),
14517 id: TokenId::try_from(0).expect("zero token ID"),
14518 source_name: String::new(),
14519 }
14520 }
14521
14522 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
14523 Self {
14524 spec: TokenSpec::eof(index, index, line, column),
14525 id: TokenId::try_from(0).expect("zero token ID"),
14526 source_name: source_name.to_owned(),
14527 }
14528 }
14529
14530 fn with_text(mut self, text: impl Into<String>) -> Self {
14531 self.spec.text = Some(text.into());
14532 self
14533 }
14534
14535 const fn with_channel(mut self, channel: i32) -> Self {
14536 self.spec.channel = channel;
14537 self
14538 }
14539
14540 fn with_span(mut self, start: usize, stop: usize) -> Self {
14541 self.spec = self.spec.with_span(start, stop);
14542 self
14543 }
14544
14545 fn with_byte_span(mut self, start: usize, stop: usize) -> Self {
14546 self.spec = self.spec.with_byte_span(start, stop);
14547 self
14548 }
14549
14550 const fn with_position(mut self, line: usize, column: usize) -> Self {
14551 self.spec.line = line;
14552 self.spec.column = column;
14553 self
14554 }
14555
14556 fn set_token_index(&mut self, index: isize) {
14557 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
14558 }
14559 }
14560
14561 impl Token for TestToken {
14562 fn token_id(&self) -> TokenId {
14563 self.id
14564 }
14565
14566 fn token_type(&self) -> i32 {
14567 self.spec.token_type
14568 }
14569
14570 fn channel(&self) -> i32 {
14571 self.spec.channel
14572 }
14573
14574 fn start(&self) -> usize {
14575 self.spec.start
14576 }
14577
14578 fn stop(&self) -> usize {
14579 self.spec.stop
14580 }
14581
14582 fn line(&self) -> usize {
14583 self.spec.line
14584 }
14585
14586 fn column(&self) -> usize {
14587 self.spec.column
14588 }
14589
14590 fn text(&self) -> Option<&str> {
14591 self.spec.text.as_deref()
14592 }
14593
14594 fn source_name(&self) -> &str {
14595 &self.source_name
14596 }
14597
14598 fn start_byte(&self) -> Option<usize> {
14599 (self.spec.start_byte != usize::MAX).then_some(self.spec.start_byte)
14600 }
14601
14602 fn stop_byte(&self) -> Option<usize> {
14603 (self.spec.stop_byte != usize::MAX).then_some(self.spec.stop_byte)
14604 }
14605 }
14606
14607 #[derive(Debug)]
14608 struct Source {
14609 tokens: Vec<TestToken>,
14610 index: usize,
14611 }
14612
14613 impl TokenSource for Source {
14614 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
14615 let token = self
14616 .tokens
14617 .get(self.index)
14618 .cloned()
14619 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
14620 self.index += 1;
14621 sink.push(token.spec)
14622 }
14623
14624 fn line(&self) -> usize {
14625 1
14626 }
14627
14628 fn column(&self) -> usize {
14629 self.index
14630 }
14631
14632 fn source_name(&self) -> &'static str {
14633 "parser-test"
14634 }
14635 }
14636
14637 #[derive(Clone, Debug, Eq, PartialEq)]
14638 struct RecordedDiagnostic {
14639 grammar_file_name: String,
14640 offending_text: Option<String>,
14641 line: usize,
14642 column: usize,
14643 span: Option<std::ops::Range<usize>>,
14644 message: String,
14645 error: Option<AntlrError>,
14646 }
14647
14648 #[derive(Clone, Debug)]
14649 struct RecordingErrorListener {
14650 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
14651 }
14652
14653 impl<R> crate::ErrorListener<R> for RecordingErrorListener
14654 where
14655 R: Recognizer + ?Sized,
14656 {
14657 fn syntax_error(&mut self, recognizer: &R, event: &SyntaxErrorEvent<'_>) {
14658 self.diagnostics
14659 .lock()
14660 .expect("recorded diagnostics lock")
14661 .push(RecordedDiagnostic {
14662 grammar_file_name: recognizer.grammar_file_name().to_owned(),
14663 offending_text: event
14664 .offending
14665 .and_then(|token| token.text().map(str::to_owned)),
14666 line: event.line,
14667 column: event.column,
14668 span: event.span.clone(),
14669 message: event.message.to_owned(),
14670 error: event.error.cloned(),
14671 });
14672 }
14673 }
14674
14675 #[derive(Debug)]
14676 struct ReportingSource {
14677 source: Source,
14678 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
14679 }
14680
14681 impl TokenSource for ReportingSource {
14682 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
14683 self.source.next_token(sink)
14684 }
14685
14686 fn line(&self) -> usize {
14687 self.source.line()
14688 }
14689
14690 fn column(&self) -> usize {
14691 self.source.column()
14692 }
14693
14694 fn source_name(&self) -> &str {
14695 self.source.source_name()
14696 }
14697
14698 fn report_error(&self, error: &TokenSourceError) -> bool {
14699 self.diagnostics.borrow_mut().push(error.clone());
14700 true
14701 }
14702 }
14703
14704 fn mini_parser_data() -> RecognizerData {
14705 RecognizerData::new(
14706 "Mini.g4",
14707 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14708 )
14709 .with_rule_names(["s"])
14710 }
14711
14712 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
14713 let data = mini_parser_data();
14714 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
14715 }
14716
14717 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
14718 where
14719 H: SemanticHooks,
14720 {
14721 BaseParser::with_semantic_hooks(
14722 CommonTokenStream::new(Source { tokens, index: 0 }),
14723 mini_parser_data(),
14724 hooks,
14725 )
14726 }
14727
14728 #[test]
14729 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
14730 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
14731 parser.remove_error_listeners();
14732 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14733 parser.add_error_listener(RecordingErrorListener {
14734 diagnostics: Arc::clone(&diagnostics),
14735 });
14736 let parser_diagnostics = [ParserDiagnostic {
14737 line: 1,
14738 column: 2,
14739 message: "missing 'x' at 'y'".to_owned(),
14740 offending: None,
14741 }];
14742 let token_errors = [
14743 TokenSourceError::new(1, 1, "token recognition error at: '@'").with_span(1..2),
14744 TokenSourceError::new(1, 3, "token recognition error at: '#'").with_span(3..4),
14745 ];
14746
14747 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
14748
14749 insta::assert_debug_snapshot!(
14752 "parser_dispatches_recovery_diagnostics_through_registered_listeners",
14753 *diagnostics.lock().expect("recorded diagnostics lock")
14754 );
14755
14756 parser.remove_error_listeners();
14757 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
14758 assert_eq!(
14759 diagnostics.lock().expect("recorded diagnostics lock").len(),
14760 3
14761 );
14762 }
14763
14764 #[test]
14765 fn recovery_diagnostics_expose_the_offending_token_to_listeners() {
14766 let mut parser = mini_parser(vec![
14767 TestToken::new(7)
14768 .with_text("oops")
14769 .with_span(0, 3)
14770 .with_byte_span(0, 4)
14771 .with_position(1, 2),
14772 TestToken::eof("parser-test", 4, 1, 6),
14773 ]);
14774 parser.remove_error_listeners();
14775 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14776 parser.add_error_listener(RecordingErrorListener {
14777 diagnostics: Arc::clone(&diagnostics),
14778 });
14779 let offending = parser.input.lt_id(1);
14780 assert!(offending.is_some(), "current token should be buffered");
14781 let parser_diagnostics = [ParserDiagnostic {
14782 line: 1,
14783 column: 2,
14784 message: "extraneous input 'oops'".to_owned(),
14785 offending,
14786 }];
14787
14788 parser.dispatch_generated_diagnostics(&parser_diagnostics, &[]);
14789
14790 let recorded = diagnostics
14794 .lock()
14795 .expect("recorded diagnostics lock")
14796 .clone();
14797 insta::assert_debug_snapshot!(
14798 "recovery_diagnostics_expose_the_offending_token_to_listeners",
14799 recorded
14800 );
14801 }
14802
14803 #[test]
14804 fn recovery_diagnostics_preserve_unknown_custom_token_span() {
14805 let mut parser = mini_parser(vec![
14806 TestToken::new(7)
14807 .with_text("oops")
14808 .with_span(0, 3)
14809 .with_position(1, 2),
14810 TestToken::eof("parser-test", 4, 1, 6),
14811 ]);
14812 parser.remove_error_listeners();
14813 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14814 parser.add_error_listener(RecordingErrorListener {
14815 diagnostics: Arc::clone(&diagnostics),
14816 });
14817 let offending = parser.input.lt_id(1);
14818 assert!(offending.is_some(), "current token should be buffered");
14819
14820 parser.dispatch_parser_diagnostic(&ParserDiagnostic {
14821 line: 1,
14822 column: 2,
14823 message: "extraneous input 'oops'".to_owned(),
14824 offending,
14825 });
14826
14827 let span = {
14828 let diagnostics = diagnostics.lock().expect("recorded diagnostics lock");
14829 assert_eq!(diagnostics.len(), 1);
14830 diagnostics[0].span.clone()
14831 };
14832 assert_eq!(span, None);
14833 }
14834
14835 #[test]
14836 fn parser_leaves_token_errors_to_source_owned_listeners() {
14837 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
14838 let source = ReportingSource {
14839 source: Source {
14840 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
14841 index: 0,
14842 },
14843 diagnostics: Rc::clone(&source_diagnostics),
14844 };
14845 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
14846 parser.remove_error_listeners();
14847 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
14848 parser.add_error_listener(RecordingErrorListener {
14849 diagnostics: Arc::clone(&parser_diagnostics),
14850 });
14851 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
14852
14853 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
14854
14855 assert_eq!(*source_diagnostics.borrow(), [source_error]);
14856 assert!(
14857 parser_diagnostics
14858 .lock()
14859 .expect("recorded diagnostics lock")
14860 .is_empty()
14861 );
14862 }
14863
14864 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
14865 builder.finish().expect("valid packed parser ATN")
14866 }
14867
14868 fn nested_rule_chain_atn(depth: usize) -> Atn {
14869 nested_rule_graph_atn(depth, false, false)
14870 }
14871
14872 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
14873 assert!(depth > 0);
14874 let mut atn = ParserAtnBuilder::new(2);
14875 let mut starts = Vec::with_capacity(depth);
14876 let mut stops = Vec::with_capacity(depth);
14877 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
14878 for rule_index in 0..depth {
14879 starts.push(
14880 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
14881 .expect("rule start")
14882 .index(),
14883 );
14884 }
14885 for rule_index in 0..depth {
14886 stops.push(
14887 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
14888 .expect("rule stop")
14889 .index(),
14890 );
14891 }
14892 if consuming_follows {
14893 for rule_index in 0..depth - 1 {
14894 follows.push(
14895 atn.add_state(AtnStateKind::Basic, Some(rule_index))
14896 .expect("rule follow")
14897 .index(),
14898 );
14899 }
14900 }
14901 atn.set_rule_to_start_state(starts.clone())
14902 .expect("rule start states");
14903 atn.set_rule_to_stop_state(stops.clone())
14904 .expect("rule stop states");
14905 for rule_index in 0..depth - 1 {
14906 let follow_state = if consuming_follows {
14907 follows[rule_index]
14908 } else {
14909 stops[rule_index]
14910 };
14911 atn.add_transition(
14912 starts[rule_index],
14913 ParserTransitionSpec::Rule {
14914 target: starts[rule_index + 1],
14915 rule_index: rule_index + 1,
14916 follow_state,
14917 precedence: 0,
14918 },
14919 )
14920 .expect("nested rule transition");
14921 if branching {
14922 atn.add_transition(
14923 starts[rule_index],
14924 ParserTransitionSpec::Atom {
14925 target: stops[rule_index],
14926 label: 2,
14927 },
14928 )
14929 .expect("dead branch transition");
14930 }
14931 if consuming_follows {
14932 atn.add_transition(
14933 follow_state,
14934 ParserTransitionSpec::Atom {
14935 target: stops[rule_index],
14936 label: 1,
14937 },
14938 )
14939 .expect("consuming follow transition");
14940 }
14941 }
14942 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
14943 atn.add_transition(
14944 starts[depth - 1],
14945 ParserTransitionSpec::Set {
14946 target: stops[depth - 1],
14947 set: token_set,
14948 },
14949 )
14950 .expect("terminal set transition");
14951 if branching {
14952 atn.add_transition(
14953 starts[depth - 1],
14954 ParserTransitionSpec::Atom {
14955 target: stops[depth - 1],
14956 label: 2,
14957 },
14958 )
14959 .expect("dead leaf branch transition");
14960 }
14961 finish_atn(atn)
14962 }
14963
14964 fn ordinary_star_loop_atn() -> Atn {
14965 let mut atn = ParserAtnBuilder::new(2);
14966 for (state_number, kind, rule_index) in [
14967 (0, AtnStateKind::RuleStart, 0),
14968 (1, AtnStateKind::StarLoopEntry, 0),
14969 (2, AtnStateKind::Basic, 0),
14970 (3, AtnStateKind::StarLoopBack, 0),
14971 (4, AtnStateKind::LoopEnd, 0),
14972 (5, AtnStateKind::Basic, 0),
14973 (6, AtnStateKind::RuleStop, 0),
14974 (7, AtnStateKind::RuleStart, 1),
14975 (8, AtnStateKind::Basic, 1),
14976 (9, AtnStateKind::RuleStop, 1),
14977 ] {
14978 assert_eq!(
14979 atn.add_state(kind, Some(rule_index))
14980 .expect("state")
14981 .index(),
14982 state_number
14983 );
14984 }
14985 atn.set_rule_to_start_state(vec![0, 7])
14986 .expect("rule start states");
14987 atn.set_rule_to_stop_state(vec![6, 9])
14988 .expect("rule stop states");
14989 atn.add_decision_state(1).expect("decision state");
14990 atn.set_loop_back_state(4, 3).expect("loop back state");
14991 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14992 .expect("transition");
14993 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14994 .expect("transition");
14995 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
14996 .expect("transition");
14997 atn.add_transition(
14998 2,
14999 ParserTransitionSpec::Rule {
15000 target: 7,
15001 rule_index: 1,
15002 follow_state: 3,
15003 precedence: 0,
15004 },
15005 )
15006 .expect("transition");
15007 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
15008 .expect("transition");
15009 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15010 .expect("transition");
15011 atn.add_transition(
15012 5,
15013 ParserTransitionSpec::Atom {
15014 target: 6,
15015 label: TOKEN_EOF,
15016 },
15017 )
15018 .expect("transition");
15019 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
15020 .expect("transition");
15021 atn.add_transition(
15022 8,
15023 ParserTransitionSpec::Atom {
15024 target: 9,
15025 label: 1,
15026 },
15027 )
15028 .expect("transition");
15029 finish_atn(atn)
15030 }
15031
15032 fn ambiguous_ordinary_star_loop_atn() -> Atn {
15034 let mut atn = ParserAtnBuilder::new(1);
15035 for (state_number, kind) in [
15036 (0, AtnStateKind::RuleStart),
15037 (1, AtnStateKind::StarLoopEntry),
15038 (2, AtnStateKind::StarBlockStart),
15039 (3, AtnStateKind::Basic),
15040 (4, AtnStateKind::BlockEnd),
15041 (5, AtnStateKind::StarLoopBack),
15042 (6, AtnStateKind::LoopEnd),
15043 (7, AtnStateKind::Basic),
15044 (8, AtnStateKind::RuleStop),
15045 ] {
15046 assert_eq!(
15047 atn.add_state(kind, Some(0)).expect("state").index(),
15048 state_number
15049 );
15050 }
15051 atn.set_rule_to_start_state(vec![0])
15052 .expect("rule start states");
15053 atn.set_rule_to_stop_state(vec![8])
15054 .expect("rule stop states");
15055 atn.set_end_state(2, 4).expect("block end state");
15056 atn.set_loop_back_state(6, 5).expect("loop back state");
15057 atn.add_decision_state(1).expect("decision state");
15058 atn.add_decision_state(2).expect("decision state");
15059 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15060 .expect("transition");
15061 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15062 .expect("transition");
15063 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
15064 .expect("transition");
15065 atn.add_transition(
15066 2,
15067 ParserTransitionSpec::Atom {
15068 target: 4,
15069 label: 1,
15070 },
15071 )
15072 .expect("transition");
15073 atn.add_transition(
15074 2,
15075 ParserTransitionSpec::Atom {
15076 target: 3,
15077 label: 1,
15078 },
15079 )
15080 .expect("transition");
15081 atn.add_transition(
15082 3,
15083 ParserTransitionSpec::Atom {
15084 target: 4,
15085 label: 1,
15086 },
15087 )
15088 .expect("transition");
15089 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15090 .expect("transition");
15091 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
15092 .expect("transition");
15093 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15094 .expect("transition");
15095 atn.add_transition(
15096 7,
15097 ParserTransitionSpec::Atom {
15098 target: 8,
15099 label: TOKEN_EOF,
15100 },
15101 )
15102 .expect("transition");
15103 finish_atn(atn)
15104 }
15105
15106 fn ordinary_plus_loop_atn() -> Atn {
15107 let mut atn = ParserAtnBuilder::new(2);
15108 for (state_number, kind, rule_index) in [
15109 (0, AtnStateKind::RuleStart, 0),
15110 (1, AtnStateKind::Basic, 0),
15111 (2, AtnStateKind::PlusLoopBack, 0),
15112 (3, AtnStateKind::LoopEnd, 0),
15113 (4, AtnStateKind::Basic, 0),
15114 (5, AtnStateKind::RuleStop, 0),
15115 (6, AtnStateKind::RuleStart, 1),
15116 (7, AtnStateKind::Basic, 1),
15117 (8, AtnStateKind::RuleStop, 1),
15118 ] {
15119 assert_eq!(
15120 atn.add_state(kind, Some(rule_index))
15121 .expect("state")
15122 .index(),
15123 state_number
15124 );
15125 }
15126 atn.set_rule_to_start_state(vec![0, 6])
15127 .expect("rule start states");
15128 atn.set_rule_to_stop_state(vec![5, 8])
15129 .expect("rule stop states");
15130 atn.add_decision_state(2).expect("decision state");
15131 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15132 .expect("transition");
15133 atn.add_transition(
15134 1,
15135 ParserTransitionSpec::Rule {
15136 target: 6,
15137 rule_index: 1,
15138 follow_state: 2,
15139 precedence: 0,
15140 },
15141 )
15142 .expect("transition");
15143 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
15144 .expect("transition");
15145 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15146 .expect("transition");
15147 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15148 .expect("transition");
15149 atn.add_transition(
15150 4,
15151 ParserTransitionSpec::Atom {
15152 target: 5,
15153 label: TOKEN_EOF,
15154 },
15155 )
15156 .expect("transition");
15157 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15158 .expect("transition");
15159 atn.add_transition(
15160 7,
15161 ParserTransitionSpec::Atom {
15162 target: 8,
15163 label: 1,
15164 },
15165 )
15166 .expect("transition");
15167 finish_atn(atn)
15168 }
15169
15170 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
15171 let mut tokens = (0..count)
15172 .map(|_| TestToken::new(1).with_text("x"))
15173 .collect::<Vec<_>>();
15174 tokens.push(TestToken::eof("parser-test", count, 1, count));
15175 tokens
15176 }
15177
15178 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
15179 let mut atn = ParserAtnBuilder::new(2);
15180 assert_eq!(
15181 atn.add_state(AtnStateKind::RuleStart, Some(0))
15182 .expect("state")
15183 .index(),
15184 0
15185 );
15186 assert_eq!(
15187 atn.add_state(AtnStateKind::Basic, Some(0))
15188 .expect("state")
15189 .index(),
15190 1
15191 );
15192 assert_eq!(
15193 atn.add_state(AtnStateKind::Basic, Some(0))
15194 .expect("state")
15195 .index(),
15196 2
15197 );
15198 assert_eq!(
15199 atn.add_state(AtnStateKind::RuleStart, Some(1))
15200 .expect("state")
15201 .index(),
15202 3
15203 );
15204 atn.set_left_recursive_rule(3)
15205 .expect("left-recursive rule start");
15206 assert_eq!(
15207 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
15208 .expect("state")
15209 .index(),
15210 4
15211 );
15212 atn.set_precedence_rule_decision(4)
15213 .expect("precedence decision");
15214 assert_eq!(
15215 atn.add_state(AtnStateKind::Basic, Some(1))
15216 .expect("state")
15217 .index(),
15218 5
15219 );
15220 assert_eq!(
15221 atn.add_state(AtnStateKind::Basic, Some(1))
15222 .expect("state")
15223 .index(),
15224 6
15225 );
15226 assert_eq!(
15227 atn.add_state(AtnStateKind::LoopEnd, Some(1))
15228 .expect("state")
15229 .index(),
15230 7
15231 );
15232 assert_eq!(
15233 atn.add_state(AtnStateKind::RuleStop, Some(1))
15234 .expect("state")
15235 .index(),
15236 8
15237 );
15238 assert_eq!(
15239 atn.add_state(AtnStateKind::RuleStop, Some(0))
15240 .expect("state")
15241 .index(),
15242 9
15243 );
15244 atn.set_rule_to_start_state(vec![0, 3])
15245 .expect("rule start states");
15246 atn.set_rule_to_stop_state(vec![9, 8])
15247 .expect("rule stop states");
15248 atn.add_transition(
15249 1,
15250 ParserTransitionSpec::Rule {
15251 target: 3,
15252 rule_index: 1,
15253 follow_state: 2,
15254 precedence: 0,
15255 },
15256 )
15257 .expect("transition");
15258 atn.add_transition(
15259 2,
15260 ParserTransitionSpec::Atom {
15261 target: 9,
15262 label: caller_symbol,
15263 },
15264 )
15265 .expect("transition");
15266 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15267 .expect("transition");
15268 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
15269 .expect("transition");
15270 atn.add_transition(
15271 5,
15272 ParserTransitionSpec::Precedence {
15273 target: 6,
15274 precedence: 1,
15275 },
15276 )
15277 .expect("transition");
15278 atn.add_transition(
15279 6,
15280 ParserTransitionSpec::Atom {
15281 target: 4,
15282 label: 1,
15283 },
15284 )
15285 .expect("transition");
15286 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
15287 .expect("transition");
15288 finish_atn(atn)
15289 }
15290
15291 fn labeled_left_recursive_operator_atn() -> Atn {
15292 let mut atn = ParserAtnBuilder::new(4);
15293 for (state, kind) in [
15294 (0, AtnStateKind::RuleStart),
15295 (1, AtnStateKind::BlockStart),
15296 (2, AtnStateKind::StarLoopEntry),
15297 (3, AtnStateKind::StarBlockStart),
15298 (4, AtnStateKind::Basic),
15299 (5, AtnStateKind::Basic),
15300 (6, AtnStateKind::Basic),
15301 (7, AtnStateKind::StarLoopBack),
15302 (8, AtnStateKind::LoopEnd),
15303 (9, AtnStateKind::RuleStop),
15304 ] {
15305 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15306 }
15307 atn.set_left_recursive_rule(0)
15308 .expect("left-recursive rule start");
15309 atn.set_precedence_rule_decision(2)
15310 .expect("precedence decision");
15311 atn.set_loop_back_state(8, 7).expect("loop-back state");
15312 atn.set_rule_to_start_state(vec![0])
15313 .expect("rule start states");
15314 atn.set_rule_to_stop_state(vec![9])
15315 .expect("rule stop states");
15316 for state in [1, 2, 3] {
15317 atn.add_decision_state(state).expect("decision state");
15318 }
15319 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
15320 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
15321 .expect("epsilon transition");
15322 }
15323 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3), (6, 7, 1)] {
15324 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
15325 .expect("token transition");
15326 }
15327 for (target, precedence) in [(4, 2), (5, 1)] {
15328 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
15329 .expect("operator precedence");
15330 }
15331 finish_atn(atn)
15332 }
15333
15334 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
15335 let mut parser = mini_parser(vec![
15336 TestToken::new(symbol).with_text("lookahead"),
15337 TestToken::eof("parser-test", 1, 1, 1),
15338 ]);
15339 parser.rule_context_stack = vec![
15340 RuleContextFrame {
15341 rule_index: 0,
15342 invoking_state: -1,
15343 },
15344 RuleContextFrame {
15345 rule_index: 1,
15346 invoking_state: 1,
15347 },
15348 ];
15349 parser
15350 }
15351
15352 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
15353 let mut atn = ParserAtnBuilder::new(1);
15357 for (state, kind, rule) in [
15358 (0, AtnStateKind::RuleStart, 0),
15359 (1, AtnStateKind::StarLoopEntry, 0),
15360 (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),
15367 (9, AtnStateKind::RuleStop, 0),
15368 ] {
15369 assert_eq!(
15370 atn.add_state(kind, Some(rule)).expect("state").index(),
15371 state
15372 );
15373 if state == 0 {
15374 atn.set_left_recursive_rule(state)
15375 .expect("left-recursive rule start");
15376 } else if state == 1 {
15377 atn.set_precedence_rule_decision(state)
15378 .expect("precedence decision");
15379 }
15380 }
15381 atn.set_rule_to_start_state(vec![0])
15382 .expect("rule start states");
15383 atn.set_rule_to_stop_state(vec![9])
15384 .expect("rule stop states");
15385 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15386 .expect("ops");
15387 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
15388 .expect("exit");
15389 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15390 .expect("to shift");
15391 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15392 .expect("to rel");
15393 atn.add_transition(
15394 3,
15395 ParserTransitionSpec::Precedence {
15396 target: 4,
15397 precedence: 2,
15398 },
15399 )
15400 .expect("shift prec");
15401 atn.add_transition(
15402 4,
15403 ParserTransitionSpec::Atom {
15404 target: 5,
15405 label: 1,
15406 },
15407 )
15408 .expect("shift first >");
15409 atn.add_transition(
15410 5,
15411 ParserTransitionSpec::Atom {
15412 target: 1,
15413 label: 1,
15414 },
15415 )
15416 .expect("shift second >");
15417 atn.add_transition(
15418 6,
15419 ParserTransitionSpec::Precedence {
15420 target: 7,
15421 precedence: 1,
15422 },
15423 )
15424 .expect("rel prec");
15425 atn.add_transition(
15426 7,
15427 ParserTransitionSpec::Atom {
15428 target: 1,
15429 label: 1,
15430 },
15431 )
15432 .expect("rel >");
15433 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15434 .expect("loop end");
15435 finish_atn(atn)
15436 }
15437
15438 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
15439 let mut atn = ParserAtnBuilder::new(2);
15440 for (state, kind, rule) in [
15441 (0, AtnStateKind::RuleStart, 0),
15442 (1, AtnStateKind::StarLoopEntry, 0),
15443 (2, AtnStateKind::Basic, 0),
15444 (3, AtnStateKind::Basic, 0),
15445 (4, AtnStateKind::Basic, 0),
15446 (5, AtnStateKind::Basic, 0),
15447 (6, AtnStateKind::Basic, 0),
15448 (7, AtnStateKind::Basic, 0),
15449 (8, AtnStateKind::LoopEnd, 0),
15450 (9, AtnStateKind::RuleStop, 0),
15451 (10, AtnStateKind::RuleStart, 1),
15452 (11, AtnStateKind::Basic, 1),
15453 (12, AtnStateKind::RuleStop, 1),
15454 ] {
15455 assert_eq!(
15456 atn.add_state(kind, Some(rule)).expect("state").index(),
15457 state
15458 );
15459 if state == 0 {
15460 atn.set_left_recursive_rule(state)
15461 .expect("left-recursive rule start");
15462 } else if state == 1 {
15463 atn.set_precedence_rule_decision(state)
15464 .expect("precedence decision");
15465 }
15466 }
15467 atn.set_rule_to_start_state(vec![0, 10])
15468 .expect("rule start states");
15469 atn.set_rule_to_stop_state(vec![9, 12])
15470 .expect("rule stop states");
15471 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15472 .expect("ops");
15473 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
15474 .expect("exit");
15475 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15476 .expect("to shift");
15477 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15478 .expect("to relational");
15479 atn.add_transition(
15480 3,
15481 ParserTransitionSpec::Precedence {
15482 target: 4,
15483 precedence: 2,
15484 },
15485 )
15486 .expect("shift precedence");
15487 atn.add_transition(
15488 4,
15489 ParserTransitionSpec::Rule {
15490 target: 10,
15491 rule_index: 1,
15492 follow_state: 5,
15493 precedence: 0,
15494 },
15495 )
15496 .expect("first shift token helper");
15497 atn.add_transition(
15498 5,
15499 ParserTransitionSpec::Atom {
15500 target: 1,
15501 label: 1,
15502 },
15503 )
15504 .expect("second shift token");
15505 atn.add_transition(
15506 6,
15507 ParserTransitionSpec::Precedence {
15508 target: 7,
15509 precedence: 1,
15510 },
15511 )
15512 .expect("relational precedence");
15513 atn.add_transition(
15514 7,
15515 ParserTransitionSpec::Atom {
15516 target: 1,
15517 label: 1,
15518 },
15519 )
15520 .expect("relational token");
15521 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15522 .expect("loop end");
15523 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
15524 .expect("helper entry");
15525 atn.add_transition(
15526 11,
15527 ParserTransitionSpec::Atom {
15528 target: 12,
15529 label: 1,
15530 },
15531 )
15532 .expect("first shift token");
15533 finish_atn(atn)
15534 }
15535
15536 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
15537 let mut atn = ParserAtnBuilder::new(1);
15538 for (state, kind) in [
15539 (0, AtnStateKind::RuleStart),
15540 (1, AtnStateKind::StarLoopEntry),
15541 (2, AtnStateKind::Basic),
15542 (3, AtnStateKind::Basic),
15543 (4, AtnStateKind::Basic),
15544 (5, AtnStateKind::Basic),
15545 (6, AtnStateKind::Basic),
15546 (7, AtnStateKind::Basic),
15547 (8, AtnStateKind::Basic),
15548 (9, AtnStateKind::LoopEnd),
15549 (10, AtnStateKind::RuleStop),
15550 ] {
15551 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15552 if state == 0 {
15553 atn.set_left_recursive_rule(state)
15554 .expect("left-recursive rule start");
15555 } else if state == 1 {
15556 atn.set_precedence_rule_decision(state)
15557 .expect("precedence decision");
15558 }
15559 }
15560 atn.set_rule_to_start_state(vec![0])
15561 .expect("rule start states");
15562 atn.set_rule_to_stop_state(vec![10])
15563 .expect("rule stop states");
15564 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15565 .expect("ops");
15566 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
15567 .expect("exit");
15568 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15569 .expect("to multi-token operator");
15570 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15571 .expect("to predicate operator");
15572 atn.add_transition(
15573 3,
15574 ParserTransitionSpec::Precedence {
15575 target: 4,
15576 precedence: 2,
15577 },
15578 )
15579 .expect("multi-token precedence");
15580 atn.add_transition(
15581 4,
15582 ParserTransitionSpec::Atom {
15583 target: 5,
15584 label: 1,
15585 },
15586 )
15587 .expect("multi-token first");
15588 atn.add_transition(
15589 5,
15590 ParserTransitionSpec::Atom {
15591 target: 1,
15592 label: 1,
15593 },
15594 )
15595 .expect("multi-token second");
15596 atn.add_transition(
15597 6,
15598 ParserTransitionSpec::Precedence {
15599 target: 7,
15600 precedence: 2,
15601 },
15602 )
15603 .expect("predicate precedence");
15604 atn.add_transition(
15605 7,
15606 ParserTransitionSpec::Predicate {
15607 target: 8,
15608 rule_index: 0,
15609 pred_index: 0,
15610 context_dependent: false,
15611 },
15612 )
15613 .expect("operator predicate");
15614 atn.add_transition(
15615 8,
15616 ParserTransitionSpec::Atom {
15617 target: 1,
15618 label: 1,
15619 },
15620 )
15621 .expect("predicate single token");
15622 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15623 .expect("loop end");
15624 finish_atn(atn)
15625 }
15626
15627 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
15628 let mut atn = ParserAtnBuilder::new(2);
15629 for (state, kind, rule) in [
15630 (0, AtnStateKind::RuleStart, 0),
15631 (1, AtnStateKind::StarLoopEntry, 0),
15632 (2, AtnStateKind::Basic, 0),
15633 (3, AtnStateKind::Basic, 0),
15634 (4, AtnStateKind::Basic, 0),
15635 (5, AtnStateKind::LoopEnd, 0),
15636 (6, AtnStateKind::RuleStop, 0),
15637 (7, AtnStateKind::RuleStart, 1),
15638 (8, AtnStateKind::RuleStop, 1),
15639 (9, AtnStateKind::Basic, 1),
15640 ] {
15641 assert_eq!(
15642 atn.add_state(kind, Some(rule)).expect("state").index(),
15643 state
15644 );
15645 if state == 0 {
15646 atn.set_left_recursive_rule(state)
15647 .expect("left-recursive rule start");
15648 } else if state == 1 {
15649 atn.set_precedence_rule_decision(state)
15650 .expect("precedence decision");
15651 }
15652 }
15653 atn.set_rule_to_start_state(vec![0, 7])
15654 .expect("rule start states");
15655 atn.set_rule_to_stop_state(vec![6, 8])
15656 .expect("rule stop states");
15657 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15658 .expect("transition");
15659 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
15660 .expect("transition");
15661 atn.add_transition(
15662 2,
15663 ParserTransitionSpec::Precedence {
15664 target: 3,
15665 precedence: 3,
15666 },
15667 )
15668 .expect("transition");
15669 atn.add_transition(
15670 3,
15671 ParserTransitionSpec::Rule {
15672 target: 7,
15673 rule_index: 1,
15674 follow_state: 4,
15675 precedence: 0,
15676 },
15677 )
15678 .expect("transition");
15679 atn.add_transition(
15680 4,
15681 ParserTransitionSpec::Atom {
15682 target: 1,
15683 label: 1,
15684 },
15685 )
15686 .expect("transition");
15687 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15688 .expect("transition");
15689 atn.add_transition(
15690 7,
15691 ParserTransitionSpec::Precedence {
15692 target: 9,
15693 precedence: 1,
15694 },
15695 )
15696 .expect("transition");
15697 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
15698 .expect("transition");
15699 finish_atn(atn)
15700 }
15701
15702 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
15703 let mut atn = ParserAtnBuilder::new(2);
15704 for (state, kind) in [
15705 (0, AtnStateKind::RuleStart),
15706 (1, AtnStateKind::StarLoopEntry),
15707 (2, AtnStateKind::Basic),
15708 (3, AtnStateKind::Basic),
15709 (4, AtnStateKind::Basic),
15710 (5, AtnStateKind::LoopEnd),
15711 (6, AtnStateKind::RuleStop),
15712 ] {
15713 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15714 if state == 0 {
15715 atn.set_left_recursive_rule(state)
15716 .expect("left-recursive rule start");
15717 } else if state == 1 {
15718 atn.set_precedence_rule_decision(state)
15719 .expect("precedence decision");
15720 }
15721 }
15722 atn.set_rule_to_start_state(vec![0])
15723 .expect("rule start states");
15724 atn.set_rule_to_stop_state(vec![6])
15725 .expect("rule stop states");
15726 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15727 .expect("transition");
15728 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
15729 .expect("transition");
15730 atn.add_transition(
15731 2,
15732 ParserTransitionSpec::Precedence {
15733 target: 3,
15734 precedence: 1,
15735 },
15736 )
15737 .expect("transition");
15738 atn.add_transition(
15739 3,
15740 ParserTransitionSpec::Predicate {
15741 target: 4,
15742 rule_index: 0,
15743 pred_index: 0,
15744 context_dependent: false,
15745 },
15746 )
15747 .expect("transition");
15748 atn.add_transition(
15749 4,
15750 ParserTransitionSpec::Atom {
15751 target: 1,
15752 label: 1,
15753 },
15754 )
15755 .expect("transition");
15756 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15757 .expect("transition");
15758 finish_atn(atn)
15759 }
15760
15761 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
15762 let mut atn = ParserAtnBuilder::new(2);
15763 for (state, kind, rule) in [
15764 (0, AtnStateKind::RuleStart, 0),
15765 (1, AtnStateKind::Basic, 0),
15766 (2, AtnStateKind::Basic, 0),
15767 (3, AtnStateKind::Basic, 0),
15768 (4, AtnStateKind::RuleStop, 0),
15769 (5, AtnStateKind::RuleStart, 1),
15770 (6, AtnStateKind::StarLoopEntry, 1),
15771 (7, AtnStateKind::Basic, 1),
15772 (8, AtnStateKind::Basic, 1),
15773 (9, AtnStateKind::LoopEnd, 1),
15774 (10, AtnStateKind::RuleStop, 1),
15775 (11, AtnStateKind::RuleStart, 2),
15776 (12, AtnStateKind::RuleStop, 2),
15777 ] {
15778 assert_eq!(
15779 atn.add_state(kind, Some(rule)).expect("state").index(),
15780 state
15781 );
15782 if state == 5 {
15783 atn.set_left_recursive_rule(state)
15784 .expect("left-recursive rule start");
15785 } else if state == 6 {
15786 atn.set_precedence_rule_decision(state)
15787 .expect("precedence decision");
15788 }
15789 }
15790 atn.set_rule_to_start_state(vec![0, 5, 11])
15791 .expect("rule start states");
15792 atn.set_rule_to_stop_state(vec![4, 10, 12])
15793 .expect("rule stop states");
15794 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15795 .expect("transition");
15796 atn.add_transition(
15797 1,
15798 ParserTransitionSpec::Rule {
15799 target: 5,
15800 rule_index: 1,
15801 follow_state: 2,
15802 precedence: 0,
15803 },
15804 )
15805 .expect("transition");
15806 atn.add_transition(
15807 2,
15808 ParserTransitionSpec::Rule {
15809 target: 11,
15810 rule_index: 2,
15811 follow_state: 3,
15812 precedence: 0,
15813 },
15814 )
15815 .expect("transition");
15816 atn.add_transition(
15817 3,
15818 ParserTransitionSpec::Atom {
15819 target: 4,
15820 label: caller_symbol,
15821 },
15822 )
15823 .expect("transition");
15824 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15825 .expect("transition");
15826 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
15827 .expect("transition");
15828 atn.add_transition(
15829 7,
15830 ParserTransitionSpec::Precedence {
15831 target: 8,
15832 precedence: 1,
15833 },
15834 )
15835 .expect("transition");
15836 atn.add_transition(
15837 8,
15838 ParserTransitionSpec::Atom {
15839 target: 6,
15840 label: 1,
15841 },
15842 )
15843 .expect("transition");
15844 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15845 .expect("transition");
15846 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
15847 .expect("transition");
15848 finish_atn(atn)
15849 }
15850
15851 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
15852 let mut atn = ParserAtnBuilder::new(2);
15853 for (state, kind, rule) in [
15854 (0, AtnStateKind::RuleStart, 0),
15855 (1, AtnStateKind::Basic, 0),
15856 (2, AtnStateKind::Basic, 0),
15857 (3, AtnStateKind::RuleStop, 0),
15858 (4, AtnStateKind::RuleStart, 1),
15859 (5, AtnStateKind::Basic, 1),
15860 (6, AtnStateKind::Basic, 1),
15861 (7, AtnStateKind::RuleStop, 1),
15862 (8, AtnStateKind::RuleStart, 2),
15863 (9, AtnStateKind::StarLoopEntry, 2),
15864 (10, AtnStateKind::Basic, 2),
15865 (11, AtnStateKind::Basic, 2),
15866 (12, AtnStateKind::LoopEnd, 2),
15867 (13, AtnStateKind::RuleStop, 2),
15868 ] {
15869 assert_eq!(
15870 atn.add_state(kind, Some(rule)).expect("state").index(),
15871 state
15872 );
15873 if state == 8 {
15874 atn.set_left_recursive_rule(state)
15875 .expect("left-recursive rule start");
15876 } else if state == 9 {
15877 atn.set_precedence_rule_decision(state)
15878 .expect("precedence decision");
15879 }
15880 }
15881 atn.set_rule_to_start_state(vec![0, 4, 8])
15882 .expect("rule start states");
15883 atn.set_rule_to_stop_state(vec![3, 7, 13])
15884 .expect("rule stop states");
15885 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15886 .expect("transition");
15887 atn.add_transition(
15888 1,
15889 ParserTransitionSpec::Rule {
15890 target: 4,
15891 rule_index: 1,
15892 follow_state: 2,
15893 precedence: 0,
15894 },
15895 )
15896 .expect("transition");
15897 atn.add_transition(
15898 2,
15899 ParserTransitionSpec::Atom {
15900 target: 3,
15901 label: caller_symbol,
15902 },
15903 )
15904 .expect("transition");
15905 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15906 .expect("transition");
15907 atn.add_transition(
15908 5,
15909 ParserTransitionSpec::Rule {
15910 target: 8,
15911 rule_index: 2,
15912 follow_state: 6,
15913 precedence: 0,
15914 },
15915 )
15916 .expect("transition");
15917 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15918 .expect("transition");
15919 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15920 .expect("transition");
15921 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
15922 .expect("transition");
15923 atn.add_transition(
15924 10,
15925 ParserTransitionSpec::Precedence {
15926 target: 11,
15927 precedence: 1,
15928 },
15929 )
15930 .expect("transition");
15931 atn.add_transition(
15932 11,
15933 ParserTransitionSpec::Atom {
15934 target: 9,
15935 label: 1,
15936 },
15937 )
15938 .expect("transition");
15939 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
15940 .expect("transition");
15941 finish_atn(atn)
15942 }
15943
15944 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
15945 let mut atn = ParserAtnBuilder::new(2);
15946 for (state, kind, rule) in [
15947 (0, AtnStateKind::RuleStart, 0),
15948 (1, AtnStateKind::Basic, 0),
15949 (2, AtnStateKind::Basic, 0),
15950 (3, AtnStateKind::RuleStop, 0),
15951 (4, AtnStateKind::RuleStart, 1),
15952 (5, AtnStateKind::StarLoopEntry, 1),
15953 (6, AtnStateKind::Basic, 1),
15954 (7, AtnStateKind::Basic, 1),
15955 (8, AtnStateKind::Basic, 1),
15956 (9, AtnStateKind::Basic, 1),
15957 (10, AtnStateKind::LoopEnd, 1),
15958 (11, AtnStateKind::RuleStop, 1),
15959 ] {
15960 assert_eq!(
15961 atn.add_state(kind, Some(rule)).expect("state").index(),
15962 state
15963 );
15964 if state == 4 {
15965 atn.set_left_recursive_rule(state)
15966 .expect("left-recursive rule start");
15967 } else if state == 5 {
15968 atn.set_precedence_rule_decision(state)
15969 .expect("precedence decision");
15970 }
15971 }
15972 atn.set_rule_to_start_state(vec![0, 4])
15973 .expect("rule start states");
15974 atn.set_rule_to_stop_state(vec![3, 11])
15975 .expect("rule stop states");
15976 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15977 .expect("transition");
15978 atn.add_transition(
15979 1,
15980 ParserTransitionSpec::Rule {
15981 target: 4,
15982 rule_index: 1,
15983 follow_state: 2,
15984 precedence: 0,
15985 },
15986 )
15987 .expect("transition");
15988 atn.add_transition(
15989 2,
15990 ParserTransitionSpec::Atom {
15991 target: 3,
15992 label: caller_symbol,
15993 },
15994 )
15995 .expect("transition");
15996 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15997 .expect("transition");
15998 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
15999 .expect("transition");
16000 atn.add_transition(
16001 6,
16002 ParserTransitionSpec::Precedence {
16003 target: 7,
16004 precedence: 1,
16005 },
16006 )
16007 .expect("transition");
16008 atn.add_transition(
16009 7,
16010 ParserTransitionSpec::Atom {
16011 target: 8,
16012 label: 1,
16013 },
16014 )
16015 .expect("transition");
16016 atn.add_transition(
16017 8,
16018 ParserTransitionSpec::Rule {
16019 target: 4,
16020 rule_index: 1,
16021 follow_state: 9,
16022 precedence: 2,
16023 },
16024 )
16025 .expect("transition");
16026 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
16027 .expect("transition");
16028 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
16029 .expect("transition");
16030 finish_atn(atn)
16031 }
16032
16033 #[test]
16034 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
16035 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
16036 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
16037
16038 let mut overlapping = parser_inside_left_recursive_callee(1);
16039 assert_eq!(
16040 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
16041 None
16042 );
16043
16044 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
16045 assert_eq!(
16046 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
16047 Some(true)
16048 );
16049
16050 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
16051 assert_eq!(
16052 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
16053 Some(false)
16054 );
16055
16056 assert_eq!(
16057 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
16058 Some(true),
16059 "overlap results must not leak across ATNs"
16060 );
16061 }
16062
16063 #[test]
16064 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
16065 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
16066 let mut parser = mini_parser(vec![
16067 TestToken::new(1).with_text("operator"),
16068 TestToken::eof("parser-test", 1, 1, 1),
16069 ]);
16070 parser.rule_context_stack = vec![RuleContextFrame {
16071 rule_index: 0,
16072 invoking_state: -1,
16073 }];
16074
16075 assert_eq!(
16076 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16077 Some(true)
16078 );
16079 assert_eq!(
16080 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16081 Some(true),
16082 "cached operator lookahead must preserve the nullable prefix return path"
16083 );
16084 assert_eq!(
16085 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16086 Some(true),
16087 "the nullable child must use its rule-call precedence, not the caller precedence"
16088 );
16089 }
16090
16091 #[test]
16092 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
16093 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
16098 let mut parser = mini_parser(vec![
16099 TestToken::new(1).with_text(">"),
16100 TestToken::new(2).with_text("id"),
16101 TestToken::eof("parser-test", 1, 1, 1),
16102 ]);
16103 parser.rule_context_stack = vec![RuleContextFrame {
16104 rule_index: 0,
16105 invoking_state: -1,
16106 }];
16107
16108 assert_eq!(
16109 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16110 Some(true),
16111 "at low precedence relational `>` is a single-token operator"
16112 );
16113 assert_eq!(
16114 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
16115 Some(true),
16116 "relational remains single-token at its own precedence"
16117 );
16118 assert_eq!(
16119 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16120 None,
16121 "at shift precedence, bare `>` must not force enter"
16122 );
16123 }
16124
16125 #[test]
16126 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
16127 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
16128 let mut parser = mini_parser(vec![
16129 TestToken::new(1).with_text(">"),
16130 TestToken::new(2).with_text("id"),
16131 TestToken::eof("parser-test", 1, 1, 1),
16132 ]);
16133 parser.rule_context_stack = vec![RuleContextFrame {
16134 rule_index: 0,
16135 invoking_state: -1,
16136 }];
16137
16138 assert_eq!(
16139 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16140 Some(true),
16141 "the direct relational alternative remains a one-token operator"
16142 );
16143 assert_eq!(
16144 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16145 None,
16146 "a token matched in the helper rule must return to the second shift token"
16147 );
16148 }
16149
16150 #[test]
16151 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
16152 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
16153 let mut parser = mini_parser(vec![
16154 TestToken::new(1).with_text(">"),
16155 TestToken::new(2).with_text("id"),
16156 TestToken::eof("parser-test", 1, 1, 1),
16157 ]);
16158 parser.rule_context_stack = vec![RuleContextFrame {
16159 rule_index: 0,
16160 invoking_state: -1,
16161 }];
16162
16163 assert_eq!(
16164 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
16165 None,
16166 "a predicate-gated single-token path must not be hidden by a multi-token path"
16167 );
16168 }
16169
16170 #[test]
16171 fn left_recursive_loop_defers_predicate_guarded_operator() {
16172 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
16173 let mut parser = mini_parser_with_hooks(
16174 vec![
16175 TestToken::new(1).with_text("operator"),
16176 TestToken::eof("parser-test", 1, 1, 1),
16177 ],
16178 RejectingPredicateHooks::default(),
16179 );
16180 parser.rule_context_stack = vec![RuleContextFrame {
16181 rule_index: 0,
16182 invoking_state: -1,
16183 }];
16184
16185 assert_eq!(
16186 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16187 None,
16188 "a false predicate must be evaluated before entering the operator alternative"
16189 );
16190 assert_eq!(
16191 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
16192 None,
16193 "cached predicate-dependent lookahead must keep deferring"
16194 );
16195 }
16196
16197 #[test]
16198 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
16199 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
16200 let mut parser = parser_inside_left_recursive_callee(1);
16201
16202 assert_eq!(
16203 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
16204 None
16205 );
16206 assert_eq!(
16207 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
16208 None,
16209 "the cached overlap must preserve the nullable child return path"
16210 );
16211 }
16212
16213 #[test]
16214 fn left_recursive_loop_defers_through_nullable_parent_return() {
16215 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
16216 let mut parser = mini_parser(vec![
16217 TestToken::new(1).with_text("lookahead"),
16218 TestToken::eof("parser-test", 1, 1, 1),
16219 ]);
16220 parser.rule_context_stack = vec![
16221 RuleContextFrame {
16222 rule_index: 0,
16223 invoking_state: -1,
16224 },
16225 RuleContextFrame {
16226 rule_index: 1,
16227 invoking_state: 1,
16228 },
16229 RuleContextFrame {
16230 rule_index: 2,
16231 invoking_state: 5,
16232 },
16233 ];
16234
16235 assert_eq!(
16236 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
16237 None,
16238 "a nullable caller must unwind to its parent's consuming follow path"
16239 );
16240 assert_eq!(
16241 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
16242 None,
16243 "the caller-overlap cache must not retain a false negative"
16244 );
16245 }
16246
16247 #[test]
16248 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
16249 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
16250 let mut parser = mini_parser(vec![
16251 TestToken::new(1).with_text("lookahead"),
16252 TestToken::eof("parser-test", 1, 1, 1),
16253 ]);
16254 parser.rule_context_stack = vec![
16255 RuleContextFrame {
16256 rule_index: 0,
16257 invoking_state: -1,
16258 },
16259 RuleContextFrame {
16260 rule_index: 1,
16261 invoking_state: 1,
16262 },
16263 RuleContextFrame {
16264 rule_index: 1,
16265 invoking_state: 8,
16266 },
16267 ];
16268
16269 assert_eq!(
16270 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
16271 None,
16272 "a recursive operand return must preserve its parent caller context"
16273 );
16274 assert_eq!(
16275 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
16276 None,
16277 "the caller-overlap cache must preserve the loop-boundary return"
16278 );
16279 }
16280
16281 fn token_then_eof_atn() -> Atn {
16282 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16283 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, ]))
16299 .deserialize_parser()
16300 .expect("artificial parser ATN should deserialize")
16301 }
16302
16303 fn epsilon_cycle_atn() -> Atn {
16304 let mut atn = ParserAtnBuilder::new(1);
16305 for (state_number, kind) in [
16306 (0, AtnStateKind::RuleStart),
16307 (1, AtnStateKind::Basic),
16308 (2, AtnStateKind::RuleStop),
16309 ] {
16310 assert_eq!(
16311 atn.add_state(kind, Some(0)).expect("state").index(),
16312 state_number
16313 );
16314 }
16315 atn.set_rule_to_start_state(vec![0])
16316 .expect("rule start states");
16317 atn.set_rule_to_stop_state(vec![2])
16318 .expect("rule stop states");
16319 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16320 .expect("transition");
16321 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
16322 .expect("self-cycle transition");
16323 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16324 .expect("exit transition");
16325 finish_atn(atn)
16326 }
16327
16328 fn committed_non_consuming_cycle_atn() -> Atn {
16329 let mut atn = ParserAtnBuilder::new(1);
16330 for (state_number, kind) in [
16331 (0, AtnStateKind::RuleStart),
16332 (1, AtnStateKind::Basic),
16333 (2, AtnStateKind::RuleStop),
16334 ] {
16335 assert_eq!(
16336 atn.add_state(kind, Some(0)).expect("state").index(),
16337 state_number
16338 );
16339 }
16340 atn.set_rule_to_start_state(vec![0])
16341 .expect("rule start states");
16342 atn.set_rule_to_stop_state(vec![2])
16343 .expect("rule stop states");
16344 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16345 .expect("cycle entry");
16346 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
16347 .expect("self-cycle transition");
16348 finish_atn(atn)
16349 }
16350
16351 fn eof_then_action_atn() -> Atn {
16352 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16353 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, ]))
16369 .deserialize_parser()
16370 .expect("artificial parser ATN should deserialize")
16371 }
16372
16373 fn noop_action_then_token_then_eof_atn() -> Atn {
16374 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16375 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, ]))
16393 .deserialize_parser()
16394 .expect("artificial no-op action ATN should deserialize")
16395 }
16396
16397 fn committed_action_then_predicate_atn() -> Atn {
16398 let mut atn = ParserAtnBuilder::new(1);
16399 for (state_number, kind) in [
16400 (0, AtnStateKind::RuleStart),
16401 (1, AtnStateKind::Basic),
16402 (2, AtnStateKind::Basic),
16403 (3, AtnStateKind::Basic),
16404 (4, AtnStateKind::RuleStop),
16405 ] {
16406 assert_eq!(
16407 atn.add_state(kind, Some(0)).expect("state").index(),
16408 state_number
16409 );
16410 }
16411 atn.set_rule_to_start_state(vec![0])
16412 .expect("rule start states");
16413 atn.set_rule_to_stop_state(vec![4])
16414 .expect("rule stop states");
16415 atn.add_transition(
16416 0,
16417 ParserTransitionSpec::Action {
16418 target: 1,
16419 rule_index: 0,
16420 action_index: None,
16421 context_dependent: false,
16422 },
16423 )
16424 .expect("action transition");
16425 atn.add_transition(
16426 1,
16427 ParserTransitionSpec::Predicate {
16428 target: 2,
16429 rule_index: 0,
16430 pred_index: 0,
16431 context_dependent: false,
16432 },
16433 )
16434 .expect("predicate transition");
16435 atn.add_transition(
16436 2,
16437 ParserTransitionSpec::Atom {
16438 target: 3,
16439 label: 1,
16440 },
16441 )
16442 .expect("token transition");
16443 atn.add_transition(
16444 3,
16445 ParserTransitionSpec::Atom {
16446 target: 4,
16447 label: TOKEN_EOF,
16448 },
16449 )
16450 .expect("EOF transition");
16451 finish_atn(atn)
16452 }
16453
16454 fn parameterized_child_action_eof_atn() -> Atn {
16456 let mut atn = ParserAtnBuilder::new(1);
16457 for (state_number, kind, rule_index) in [
16458 (0, AtnStateKind::RuleStart, 0),
16459 (1, AtnStateKind::Basic, 0),
16460 (2, AtnStateKind::Basic, 0),
16461 (3, AtnStateKind::RuleStop, 0),
16462 (4, AtnStateKind::RuleStart, 1),
16463 (5, AtnStateKind::Basic, 1),
16464 (6, AtnStateKind::RuleStop, 1),
16465 ] {
16466 assert_eq!(
16467 atn.add_state(kind, Some(rule_index))
16468 .expect("state")
16469 .index(),
16470 state_number
16471 );
16472 }
16473 atn.set_rule_to_start_state(vec![0, 4])
16474 .expect("rule start states");
16475 atn.set_rule_to_stop_state(vec![3, 6])
16476 .expect("rule stop states");
16477 atn.add_transition(
16478 0,
16479 ParserTransitionSpec::Rule {
16480 target: 4,
16481 rule_index: 1,
16482 follow_state: 1,
16483 precedence: 0,
16484 },
16485 )
16486 .expect("parameterized child call");
16487 atn.add_transition(
16488 1,
16489 ParserTransitionSpec::Action {
16490 target: 2,
16491 rule_index: 0,
16492 action_index: None,
16493 context_dependent: false,
16494 },
16495 )
16496 .expect("parent action");
16497 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
16498 .expect("parent stop");
16499 atn.add_transition(
16500 4,
16501 ParserTransitionSpec::Action {
16502 target: 5,
16503 rule_index: 1,
16504 action_index: None,
16505 context_dependent: false,
16506 },
16507 )
16508 .expect("child action");
16509 atn.add_transition(
16510 5,
16511 ParserTransitionSpec::Atom {
16512 target: 6,
16513 label: TOKEN_EOF,
16514 },
16515 )
16516 .expect("child EOF");
16517 finish_atn(atn)
16518 }
16519
16520 fn action_then_nested_rule_atn() -> Atn {
16521 let mut atn = ParserAtnBuilder::new(1);
16522 for (state_number, kind, rule_index) in [
16523 (0, AtnStateKind::RuleStart, 0),
16524 (1, AtnStateKind::Basic, 0),
16525 (2, AtnStateKind::Basic, 0),
16526 (3, AtnStateKind::RuleStop, 0),
16527 (4, AtnStateKind::RuleStart, 1),
16528 (5, AtnStateKind::RuleStop, 1),
16529 ] {
16530 assert_eq!(
16531 atn.add_state(kind, Some(rule_index))
16532 .expect("state")
16533 .index(),
16534 state_number
16535 );
16536 }
16537 atn.set_rule_to_start_state(vec![0, 4])
16538 .expect("rule start states");
16539 atn.set_rule_to_stop_state(vec![3, 5])
16540 .expect("rule stop states");
16541 atn.add_transition(
16542 0,
16543 ParserTransitionSpec::Action {
16544 target: 1,
16545 rule_index: 0,
16546 action_index: None,
16547 context_dependent: false,
16548 },
16549 )
16550 .expect("parent action");
16551 atn.add_transition(
16552 1,
16553 ParserTransitionSpec::Rule {
16554 target: 4,
16555 rule_index: 1,
16556 follow_state: 2,
16557 precedence: 0,
16558 },
16559 )
16560 .expect("nested rule call");
16561 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
16562 .expect("parent stop");
16563 atn.add_transition(
16564 4,
16565 ParserTransitionSpec::Atom {
16566 target: 5,
16567 label: TOKEN_EOF,
16568 },
16569 )
16570 .expect("child EOF");
16571 finish_atn(atn)
16572 }
16573
16574 fn losing_alternative_action_atn() -> Atn {
16575 let mut atn = ParserAtnBuilder::new(2);
16576 for (state_number, kind) in [
16577 (0, AtnStateKind::RuleStart),
16578 (1, AtnStateKind::BlockStart),
16579 (2, AtnStateKind::Basic),
16580 (3, AtnStateKind::Basic),
16581 (4, AtnStateKind::BlockEnd),
16582 (5, AtnStateKind::RuleStop),
16583 ] {
16584 assert_eq!(
16585 atn.add_state(kind, Some(0)).expect("state").index(),
16586 state_number
16587 );
16588 }
16589 atn.set_rule_to_start_state(vec![0])
16590 .expect("rule start states");
16591 atn.set_rule_to_stop_state(vec![5])
16592 .expect("rule stop states");
16593 atn.set_end_state(1, 4).expect("block end state");
16594 atn.add_decision_state(1).expect("decision state");
16595 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16596 .expect("entry transition");
16597 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16598 .expect("first alternative");
16599 atn.add_transition(
16600 1,
16601 ParserTransitionSpec::Atom {
16602 target: 4,
16603 label: 2,
16604 },
16605 )
16606 .expect("second alternative");
16607 atn.add_transition(
16608 2,
16609 ParserTransitionSpec::Action {
16610 target: 3,
16611 rule_index: 0,
16612 action_index: None,
16613 context_dependent: false,
16614 },
16615 )
16616 .expect("losing action");
16617 atn.add_transition(
16618 3,
16619 ParserTransitionSpec::Atom {
16620 target: 4,
16621 label: 1,
16622 },
16623 )
16624 .expect("first alternative token");
16625 atn.add_transition(
16626 4,
16627 ParserTransitionSpec::Atom {
16628 target: 5,
16629 label: TOKEN_EOF,
16630 },
16631 )
16632 .expect("EOF transition");
16633 finish_atn(atn)
16634 }
16635
16636 fn committed_action_star_loop_atn() -> Atn {
16637 let mut atn = ParserAtnBuilder::new(1);
16638 for (state_number, kind) in [
16639 (0, AtnStateKind::RuleStart),
16640 (1, AtnStateKind::StarLoopEntry),
16641 (2, AtnStateKind::Basic),
16642 (3, AtnStateKind::Basic),
16643 (4, AtnStateKind::StarLoopBack),
16644 (5, AtnStateKind::LoopEnd),
16645 (6, AtnStateKind::RuleStop),
16646 ] {
16647 assert_eq!(
16648 atn.add_state(kind, Some(0)).expect("state").index(),
16649 state_number
16650 );
16651 }
16652 atn.set_rule_to_start_state(vec![0])
16653 .expect("rule start states");
16654 atn.set_rule_to_stop_state(vec![6])
16655 .expect("rule stop states");
16656 atn.add_decision_state(1).expect("decision state");
16657 atn.set_loop_back_state(5, 4).expect("loop back state");
16658 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16659 .expect("entry transition");
16660 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16661 .expect("loop body");
16662 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
16663 .expect("loop exit");
16664 atn.add_transition(
16665 2,
16666 ParserTransitionSpec::Action {
16667 target: 3,
16668 rule_index: 0,
16669 action_index: None,
16670 context_dependent: false,
16671 },
16672 )
16673 .expect("loop action");
16674 atn.add_transition(
16675 3,
16676 ParserTransitionSpec::Atom {
16677 target: 4,
16678 label: 1,
16679 },
16680 )
16681 .expect("loop token");
16682 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
16683 .expect("loop back");
16684 atn.add_transition(
16685 5,
16686 ParserTransitionSpec::Atom {
16687 target: 6,
16688 label: TOKEN_EOF,
16689 },
16690 )
16691 .expect("EOF transition");
16692 finish_atn(atn)
16693 }
16694
16695 fn committed_action_left_recursive_atn() -> Atn {
16696 let mut atn = ParserAtnBuilder::new(4);
16697 for (state, kind) in [
16698 (0, AtnStateKind::RuleStart),
16699 (1, AtnStateKind::BlockStart),
16700 (2, AtnStateKind::StarLoopEntry),
16701 (3, AtnStateKind::StarBlockStart),
16702 (4, AtnStateKind::Basic),
16703 (5, AtnStateKind::Basic),
16704 (6, AtnStateKind::Basic),
16705 (7, AtnStateKind::StarLoopBack),
16706 (8, AtnStateKind::LoopEnd),
16707 (9, AtnStateKind::RuleStop),
16708 (10, AtnStateKind::Basic),
16709 ] {
16710 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
16711 }
16712 atn.set_left_recursive_rule(0)
16713 .expect("left-recursive rule start");
16714 atn.set_precedence_rule_decision(2)
16715 .expect("precedence decision");
16716 atn.set_loop_back_state(8, 7).expect("loop-back state");
16717 atn.set_rule_to_start_state(vec![0])
16718 .expect("rule start states");
16719 atn.set_rule_to_stop_state(vec![9])
16720 .expect("rule stop states");
16721 for state in [1, 2, 3] {
16722 atn.add_decision_state(state).expect("decision state");
16723 }
16724 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
16725 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
16726 .expect("epsilon transition");
16727 }
16728 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3)] {
16729 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
16730 .expect("token transition");
16731 }
16732 for (target, precedence) in [(4, 2), (5, 1)] {
16733 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
16734 .expect("operator precedence");
16735 }
16736 atn.add_transition(
16737 6,
16738 ParserTransitionSpec::Action {
16739 target: 10,
16740 rule_index: 0,
16741 action_index: None,
16742 context_dependent: false,
16743 },
16744 )
16745 .expect("operator action");
16746 atn.add_transition(
16747 10,
16748 ParserTransitionSpec::Atom {
16749 target: 7,
16750 label: 1,
16751 },
16752 )
16753 .expect("right operand");
16754 finish_atn(atn)
16755 }
16756
16757 fn two_alt_decision_atn() -> Atn {
16758 let mut atn = ParserAtnBuilder::new(2);
16759 assert_eq!(
16760 atn.add_state(AtnStateKind::RuleStart, Some(0))
16761 .expect("state")
16762 .index(),
16763 0
16764 );
16765 assert_eq!(
16766 atn.add_state(AtnStateKind::BlockStart, Some(0))
16767 .expect("state")
16768 .index(),
16769 1
16770 );
16771 assert_eq!(
16772 atn.add_state(AtnStateKind::Basic, Some(0))
16773 .expect("state")
16774 .index(),
16775 2
16776 );
16777 assert_eq!(
16778 atn.add_state(AtnStateKind::Basic, Some(0))
16779 .expect("state")
16780 .index(),
16781 3
16782 );
16783 assert_eq!(
16784 atn.add_state(AtnStateKind::BlockEnd, Some(0))
16785 .expect("state")
16786 .index(),
16787 4
16788 );
16789 assert_eq!(
16790 atn.add_state(AtnStateKind::RuleStop, Some(0))
16791 .expect("state")
16792 .index(),
16793 5
16794 );
16795 atn.set_rule_to_start_state(vec![0])
16796 .expect("rule start states");
16797 atn.set_rule_to_stop_state(vec![5])
16798 .expect("rule stop states");
16799 atn.add_decision_state(1).expect("decision state");
16800 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16801 .expect("transition");
16802 atn.add_transition(
16803 1,
16804 ParserTransitionSpec::Atom {
16805 target: 2,
16806 label: 1,
16807 },
16808 )
16809 .expect("transition");
16810 atn.add_transition(
16811 1,
16812 ParserTransitionSpec::Atom {
16813 target: 3,
16814 label: 2,
16815 },
16816 )
16817 .expect("transition");
16818 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
16819 .expect("transition");
16820 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
16821 .expect("transition");
16822 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
16823 .expect("transition");
16824 finish_atn(atn)
16825 }
16826
16827 fn optional_then_b_eof_atn() -> Atn {
16830 let mut atn = ParserAtnBuilder::new(3);
16831 assert_eq!(
16832 atn.add_state(AtnStateKind::RuleStart, Some(0))
16833 .expect("state")
16834 .index(),
16835 0
16836 );
16837 assert_eq!(
16838 atn.add_state(AtnStateKind::BlockStart, Some(0))
16839 .expect("state")
16840 .index(),
16841 1
16842 );
16843 assert_eq!(
16844 atn.add_state(AtnStateKind::Basic, Some(0))
16845 .expect("state")
16846 .index(),
16847 2
16848 );
16849 assert_eq!(
16850 atn.add_state(AtnStateKind::Basic, Some(0))
16851 .expect("state")
16852 .index(),
16853 3
16854 );
16855 assert_eq!(
16856 atn.add_state(AtnStateKind::Basic, Some(0))
16857 .expect("state")
16858 .index(),
16859 4
16860 );
16861 assert_eq!(
16862 atn.add_state(AtnStateKind::RuleStop, Some(0))
16863 .expect("state")
16864 .index(),
16865 5
16866 );
16867 atn.set_rule_to_start_state(vec![0])
16868 .expect("rule start states");
16869 atn.set_rule_to_stop_state(vec![5])
16870 .expect("rule stop states");
16871 atn.add_decision_state(1).expect("decision state");
16872 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16873 .expect("transition");
16874 atn.add_transition(
16876 1,
16877 ParserTransitionSpec::Atom {
16878 target: 3,
16879 label: 1,
16880 },
16881 )
16882 .expect("transition");
16883 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
16884 .expect("transition");
16885 atn.add_transition(
16887 3,
16888 ParserTransitionSpec::Atom {
16889 target: 4,
16890 label: 2,
16891 },
16892 )
16893 .expect("transition");
16894 atn.add_transition(
16895 4,
16896 ParserTransitionSpec::Atom {
16897 target: 5,
16898 label: TOKEN_EOF,
16899 },
16900 )
16901 .expect("transition");
16902 finish_atn(atn)
16903 }
16904
16905 #[test]
16906 fn sync_decision_deletes_only_a_single_token() {
16907 let atn = optional_then_b_eof_atn();
16915
16916 let mut single = mini_parser(vec![
16917 TestToken::new(3).with_text("c"),
16918 TestToken::new(2).with_text("b"),
16919 TestToken::eof("parser-test", 1, 2, 2),
16920 ]);
16921 single.rule_context_stack = vec![RuleContextFrame {
16922 rule_index: 0,
16923 invoking_state: 0,
16924 }];
16925 let children = single
16926 .sync_decision(&atn, 1, true, false)
16927 .expect("single extraneous token recovers");
16928 assert_eq!(children.len(), 1);
16929 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
16930 assert_eq!(single.number_of_syntax_errors(), 1);
16931 assert_eq!(single.la(1), 2);
16933
16934 let mut double = mini_parser(vec![
16935 TestToken::new(3).with_text("c"),
16936 TestToken::new(3).with_text("c"),
16937 TestToken::new(2).with_text("b"),
16938 TestToken::eof("parser-test", 1, 3, 3),
16939 ]);
16940 double.rule_context_stack = vec![RuleContextFrame {
16941 rule_index: 0,
16942 invoking_state: 0,
16943 }];
16944 let result = double.sync_decision(&atn, 1, true, false);
16945 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
16950 match error {
16951 AntlrError::ParserError { message, .. } => {
16952 assert!(message.starts_with("mismatched input"), "got: {message}");
16953 }
16954 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
16955 }
16956 assert_eq!(double.la(1), 3);
16957 }
16958
16959 fn star_loop_then_eof_atn() -> Atn {
16963 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16964 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,
16965 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,
16966 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,
16967 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
16968 ]))
16969 .deserialize_parser()
16970 .expect("star-loop-then-EOF ATN should deserialize")
16971 }
16972
16973 fn nested_star_rule_atn() -> Atn {
16977 let mut atn = ParserAtnBuilder::new(2);
16978 for (state_number, kind, rule_index) in [
16979 (0, AtnStateKind::RuleStart, 0),
16980 (1, AtnStateKind::Basic, 0),
16981 (2, AtnStateKind::Basic, 0),
16982 (3, AtnStateKind::RuleStop, 0),
16983 (4, AtnStateKind::RuleStart, 1),
16984 (5, AtnStateKind::StarLoopEntry, 1),
16985 (6, AtnStateKind::Basic, 1),
16986 (7, AtnStateKind::StarLoopBack, 1),
16987 (8, AtnStateKind::LoopEnd, 1),
16988 (9, AtnStateKind::RuleStop, 1),
16989 ] {
16990 assert_eq!(
16991 atn.add_state(kind, Some(rule_index))
16992 .expect("state")
16993 .index(),
16994 state_number
16995 );
16996 }
16997 atn.set_rule_to_start_state(vec![0, 4])
16998 .expect("rule start states");
16999 atn.set_rule_to_stop_state(vec![3, 9])
17000 .expect("rule stop states");
17001 atn.add_decision_state(5).expect("decision state");
17002 atn.set_loop_back_state(8, 7).expect("loop back state");
17003 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17004 .expect("transition");
17005 atn.add_transition(
17006 1,
17007 ParserTransitionSpec::Rule {
17008 target: 4,
17009 rule_index: 1,
17010 follow_state: 2,
17011 precedence: 0,
17012 },
17013 )
17014 .expect("transition");
17015 atn.add_transition(
17016 2,
17017 ParserTransitionSpec::Atom {
17018 target: 3,
17019 label: TOKEN_EOF,
17020 },
17021 )
17022 .expect("transition");
17023 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
17024 .expect("transition");
17025 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
17026 .expect("transition");
17027 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 8 })
17028 .expect("transition");
17029 atn.add_transition(
17030 6,
17031 ParserTransitionSpec::Atom {
17032 target: 7,
17033 label: 1,
17034 },
17035 )
17036 .expect("transition");
17037 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 5 })
17038 .expect("transition");
17039 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17040 .expect("transition");
17041 finish_atn(atn)
17042 }
17043
17044 fn plus_loop_with_recovering_body_atn() -> Atn {
17050 let mut atn = ParserAtnBuilder::new(2);
17051 assert_eq!(
17052 atn.add_state(AtnStateKind::RuleStart, Some(0))
17053 .expect("state")
17054 .index(),
17055 0
17056 );
17057 assert_eq!(
17058 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
17059 .expect("state")
17060 .index(),
17061 1
17062 );
17063 assert_eq!(
17064 atn.add_state(AtnStateKind::Basic, Some(0))
17065 .expect("state")
17066 .index(),
17067 2
17068 );
17069 assert_eq!(
17070 atn.add_state(AtnStateKind::BlockEnd, Some(0))
17071 .expect("state")
17072 .index(),
17073 3
17074 );
17075 assert_eq!(
17076 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
17077 .expect("state")
17078 .index(),
17079 4
17080 );
17081 assert_eq!(
17082 atn.add_state(AtnStateKind::LoopEnd, Some(0))
17083 .expect("state")
17084 .index(),
17085 5
17086 );
17087 assert_eq!(
17088 atn.add_state(AtnStateKind::RuleStop, Some(0))
17089 .expect("state")
17090 .index(),
17091 6
17092 );
17093 assert_eq!(
17094 atn.add_state(AtnStateKind::RuleStart, Some(1))
17095 .expect("state")
17096 .index(),
17097 7
17098 );
17099 assert_eq!(
17100 atn.add_state(AtnStateKind::Basic, Some(1))
17101 .expect("state")
17102 .index(),
17103 8
17104 );
17105 assert_eq!(
17106 atn.add_state(AtnStateKind::RuleStop, Some(1))
17107 .expect("state")
17108 .index(),
17109 9
17110 );
17111 atn.set_rule_to_start_state(vec![0, 7])
17112 .expect("rule start states");
17113 atn.set_rule_to_stop_state(vec![6, 9])
17114 .expect("rule stop states");
17115 atn.set_end_state(1, 3).expect("block end state");
17116 atn.set_loop_back_state(5, 4).expect("loop back state");
17117 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17118 .expect("transition");
17119 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17120 .expect("transition");
17121 atn.add_transition(
17122 2,
17123 ParserTransitionSpec::Rule {
17124 target: 7,
17125 rule_index: 1,
17126 follow_state: 3,
17127 precedence: 0,
17128 },
17129 )
17130 .expect("transition");
17131 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
17132 .expect("transition");
17133 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
17134 .expect("transition");
17135 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
17136 .expect("transition");
17137 atn.add_transition(
17138 5,
17139 ParserTransitionSpec::Atom {
17140 target: 6,
17141 label: 2,
17142 },
17143 )
17144 .expect("transition");
17145 atn.add_transition(
17146 7,
17147 ParserTransitionSpec::Atom {
17148 target: 8,
17149 label: 1,
17150 },
17151 )
17152 .expect("transition");
17153 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17154 .expect("transition");
17155 finish_atn(atn)
17156 }
17157
17158 #[test]
17159 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
17160 let atn = plus_loop_with_recovering_body_atn();
17161 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17162
17163 let error = parser
17164 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17165 .expect_err("EOF recovery should report a bounded mismatch");
17166
17167 let AntlrError::ParserError { message, .. } = error else {
17168 panic!("expected ParserError, got {error:?}");
17169 };
17170 insta::assert_snapshot!(message, @"mismatched input '<EOF>' expecting {'x', 2}");
17171 assert_eq!(parser.number_of_syntax_errors(), 1);
17172 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
17173 }
17174
17175 #[test]
17176 fn sync_decision_deletes_token_before_eof_at_loop_back() {
17177 let atn = star_loop_then_eof_atn();
17183 let mut parser = mini_parser(vec![
17184 TestToken::new(2).with_text("c"),
17185 TestToken::eof("parser-test", 1, 1, 1),
17186 ]);
17187 parser.rule_context_stack = vec![RuleContextFrame {
17188 rule_index: 0,
17189 invoking_state: 0,
17190 }];
17191 let children = parser
17192 .sync_decision(&atn, 5, true, false)
17193 .expect("single token before EOF recovers");
17194 assert_eq!(children.len(), 1);
17195 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
17196 assert_eq!(parser.number_of_syntax_errors(), 1);
17197 assert_eq!(
17198 parser.la(1),
17199 TOKEN_EOF,
17200 "EOF is left for the rule's EOF match"
17201 );
17202 }
17203
17204 #[test]
17205 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
17206 let atn = star_loop_then_eof_atn();
17211 let mut parser = mini_parser(vec![
17212 TestToken::new(2).with_text("c"),
17213 TestToken::new(2).with_text("c"),
17214 TestToken::eof("parser-test", 1, 2, 2),
17215 ]);
17216 parser.rule_context_stack = vec![RuleContextFrame {
17217 rule_index: 0,
17218 invoking_state: 0,
17219 }];
17220 let error = parser
17221 .sync_decision(&atn, 5, true, false)
17222 .expect_err("two tokens at the loop entry must not be deleted");
17223 match error {
17224 AntlrError::ParserError { message, .. } => {
17225 assert!(message.starts_with("mismatched input"), "got: {message}");
17226 }
17227 other => panic!("expected mismatched-input ParserError, got {other:?}"),
17228 }
17229 assert_eq!(
17230 parser.la(1),
17231 2,
17232 "nothing consumed; cursor still on first `c`"
17233 );
17234 }
17235
17236 #[test]
17237 fn sync_decision_consumes_until_eof_at_loop_back() {
17238 let atn = star_loop_then_eof_atn();
17244 let mut parser = mini_parser(vec![
17245 TestToken::new(2).with_text("c"),
17246 TestToken::new(2).with_text("c"),
17247 TestToken::eof("parser-test", 1, 2, 2),
17248 ]);
17249 parser.rule_context_stack = vec![RuleContextFrame {
17250 rule_index: 0,
17251 invoking_state: 0,
17252 }];
17253 let children = parser
17254 .sync_decision(&atn, 5, false, true)
17255 .expect("loop-back multi-token deletion recovers onto EOF");
17256 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
17257 assert!(
17258 children
17259 .iter()
17260 .all(|child| parser.node(*child).kind() == NodeKind::Error)
17261 );
17262 assert_eq!(parser.number_of_syntax_errors(), 1);
17263 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
17264 }
17265
17266 #[test]
17267 fn sync_decision_returns_before_recovery_for_nullable_exit() {
17268 let atn = nested_star_rule_atn();
17269 for (current_context_empty, loop_back) in [(true, false), (false, true)] {
17270 let mut parser = mini_parser(vec![
17271 TestToken::new(2).with_text("c"),
17272 TestToken::new(1).with_text("a"),
17273 TestToken::eof("parser-test", 1, 2, 2),
17274 ]);
17275 parser.rule_context_stack = vec![
17276 RuleContextFrame {
17277 rule_index: 0,
17278 invoking_state: 0,
17279 },
17280 RuleContextFrame {
17281 rule_index: 1,
17282 invoking_state: 1,
17283 },
17284 ];
17285
17286 let children = parser
17287 .sync_decision(&atn, 5, current_context_empty, loop_back)
17288 .expect("nullable synchronization is a no-op");
17289
17290 assert!(children.is_empty());
17291 assert_eq!(parser.la(1), 2, "the caller must receive the current token");
17292 assert_eq!(parser.number_of_syntax_errors(), 0);
17293 assert_eq!(
17294 parser
17295 .generated_sync_expected
17296 .as_ref()
17297 .expect("nullable sync preserves expected symbols")
17298 .to_btree_set(),
17299 BTreeSet::from([TOKEN_EOF, 1])
17300 );
17301 }
17302 }
17303
17304 fn predicate_after_token_atn() -> Atn {
17305 let mut atn = ParserAtnBuilder::new(2);
17306 assert_eq!(
17307 atn.add_state(AtnStateKind::RuleStart, Some(0))
17308 .expect("state")
17309 .index(),
17310 0
17311 );
17312 assert_eq!(
17313 atn.add_state(AtnStateKind::Basic, Some(0))
17314 .expect("state")
17315 .index(),
17316 1
17317 );
17318 assert_eq!(
17319 atn.add_state(AtnStateKind::Basic, Some(0))
17320 .expect("state")
17321 .index(),
17322 2
17323 );
17324 assert_eq!(
17325 atn.add_state(AtnStateKind::Basic, Some(0))
17326 .expect("state")
17327 .index(),
17328 3
17329 );
17330 assert_eq!(
17331 atn.add_state(AtnStateKind::RuleStop, Some(0))
17332 .expect("state")
17333 .index(),
17334 4
17335 );
17336 atn.set_rule_to_start_state(vec![0])
17337 .expect("rule start states");
17338 atn.set_rule_to_stop_state(vec![4])
17339 .expect("rule stop states");
17340 atn.add_transition(
17341 0,
17342 ParserTransitionSpec::Atom {
17343 target: 1,
17344 label: 1,
17345 },
17346 )
17347 .expect("transition");
17348 atn.add_transition(
17349 1,
17350 ParserTransitionSpec::Predicate {
17351 target: 2,
17352 rule_index: 0,
17353 pred_index: 0,
17354 context_dependent: false,
17355 },
17356 )
17357 .expect("transition");
17358 atn.add_transition(
17359 2,
17360 ParserTransitionSpec::Atom {
17361 target: 3,
17362 label: 2,
17363 },
17364 )
17365 .expect("transition");
17366 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
17367 .expect("transition");
17368 finish_atn(atn)
17369 }
17370
17371 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
17372 let mut atn = ParserAtnBuilder::new(1);
17373 for (state_number, kind) in [
17374 (0, AtnStateKind::RuleStart),
17375 (1, AtnStateKind::BlockStart),
17376 (2, AtnStateKind::Basic),
17377 (3, AtnStateKind::Basic),
17378 (4, AtnStateKind::Basic),
17379 (5, AtnStateKind::Basic),
17380 (6, AtnStateKind::BlockEnd),
17381 (7, AtnStateKind::RuleStop),
17382 ] {
17383 assert_eq!(
17384 atn.add_state(kind, Some(0)).expect("state").index(),
17385 state_number
17386 );
17387 }
17388 atn.set_rule_to_start_state(vec![0])
17389 .expect("rule start states");
17390 atn.set_rule_to_stop_state(vec![7])
17391 .expect("rule stop states");
17392 atn.add_decision_state(1).expect("decision state");
17393 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17394 .expect("transition");
17395 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17396 .expect("transition");
17397 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17398 .expect("transition");
17399 atn.add_transition(
17400 2,
17401 ParserTransitionSpec::Predicate {
17402 target: 4,
17403 rule_index: 0,
17404 pred_index: pred_indexes[0],
17405 context_dependent: false,
17406 },
17407 )
17408 .expect("transition");
17409 atn.add_transition(
17410 3,
17411 ParserTransitionSpec::Predicate {
17412 target: 5,
17413 rule_index: 0,
17414 pred_index: pred_indexes[1],
17415 context_dependent: false,
17416 },
17417 )
17418 .expect("transition");
17419 atn.add_transition(
17420 4,
17421 ParserTransitionSpec::Atom {
17422 target: 6,
17423 label: 1,
17424 },
17425 )
17426 .expect("transition");
17427 atn.add_transition(
17428 5,
17429 ParserTransitionSpec::Atom {
17430 target: 6,
17431 label: 1,
17432 },
17433 )
17434 .expect("transition");
17435 atn.add_transition(
17436 6,
17437 ParserTransitionSpec::Atom {
17438 target: 7,
17439 label: TOKEN_EOF,
17440 },
17441 )
17442 .expect("transition");
17443 finish_atn(atn)
17444 }
17445
17446 fn semantic_fallback_viability_atn() -> Atn {
17448 let mut atn = ParserAtnBuilder::new(3);
17449 for (state_number, kind) in [
17450 (0, AtnStateKind::RuleStart),
17451 (1, AtnStateKind::BlockStart),
17452 (2, AtnStateKind::Basic),
17453 (3, AtnStateKind::Basic),
17454 (4, AtnStateKind::Basic),
17455 (5, AtnStateKind::Basic),
17456 (6, AtnStateKind::Basic),
17457 (7, AtnStateKind::Basic),
17458 (8, AtnStateKind::Basic),
17459 (9, AtnStateKind::BlockEnd),
17460 (10, AtnStateKind::RuleStop),
17461 ] {
17462 assert_eq!(
17463 atn.add_state(kind, Some(0)).expect("state").index(),
17464 state_number
17465 );
17466 }
17467 atn.set_rule_to_start_state(vec![0])
17468 .expect("rule start states");
17469 atn.set_rule_to_stop_state(vec![10])
17470 .expect("rule stop states");
17471 atn.set_end_state(1, 9).expect("block end state");
17472 atn.add_decision_state(1).expect("decision state");
17473 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17474 .expect("entry transition");
17475 atn.add_transition(
17476 1,
17477 ParserTransitionSpec::Atom {
17478 target: 2,
17479 label: 1,
17480 },
17481 )
17482 .expect("first alternative");
17483 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17484 .expect("second alternative");
17485 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
17486 .expect("third alternative");
17487 atn.add_transition(
17488 2,
17489 ParserTransitionSpec::Atom {
17490 target: 9,
17491 label: 2,
17492 },
17493 )
17494 .expect("first alternative suffix");
17495 for (source, target, pred_index) in [(3, 4, 0), (6, 7, 1)] {
17496 atn.add_transition(
17497 source,
17498 ParserTransitionSpec::Predicate {
17499 target,
17500 rule_index: 0,
17501 pred_index,
17502 context_dependent: false,
17503 },
17504 )
17505 .expect("predicate transition");
17506 }
17507 for (source, target, label) in [(4, 5, 1), (5, 9, 3), (7, 8, 1), (8, 9, 3)] {
17508 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
17509 .expect("predicate alternative token");
17510 }
17511 atn.add_transition(
17512 9,
17513 ParserTransitionSpec::Atom {
17514 target: 10,
17515 label: TOKEN_EOF,
17516 },
17517 )
17518 .expect("EOF transition");
17519 finish_atn(atn)
17520 }
17521
17522 fn rule_call_predicate_decision_atn() -> Atn {
17524 let mut atn = ParserAtnBuilder::new(1);
17525 for (state_number, kind, rule_index) in [
17526 (0, AtnStateKind::RuleStart, 0),
17527 (1, AtnStateKind::BlockStart, 0),
17528 (2, AtnStateKind::Basic, 0),
17529 (3, AtnStateKind::Basic, 0),
17530 (4, AtnStateKind::BlockEnd, 0),
17531 (5, AtnStateKind::RuleStop, 0),
17532 (6, AtnStateKind::RuleStart, 1),
17533 (7, AtnStateKind::Basic, 1),
17534 (8, AtnStateKind::RuleStop, 1),
17535 ] {
17536 assert_eq!(
17537 atn.add_state(kind, Some(rule_index))
17538 .expect("state")
17539 .index(),
17540 state_number
17541 );
17542 }
17543 atn.set_rule_to_start_state(vec![0, 6])
17544 .expect("rule start states");
17545 atn.set_rule_to_stop_state(vec![5, 8])
17546 .expect("rule stop states");
17547 atn.set_end_state(1, 4).expect("block end state");
17548 atn.add_decision_state(1).expect("decision state");
17549 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17550 .expect("entry transition");
17551 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17552 .expect("gated alternative entry");
17553 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17554 .expect("direct alternative entry");
17555 atn.add_transition(
17556 2,
17557 ParserTransitionSpec::Rule {
17558 target: 6,
17559 rule_index: 1,
17560 follow_state: 4,
17561 precedence: 0,
17562 },
17563 )
17564 .expect("gated alternative");
17565 atn.add_transition(
17566 3,
17567 ParserTransitionSpec::Atom {
17568 target: 4,
17569 label: 1,
17570 },
17571 )
17572 .expect("direct alternative");
17573 atn.add_transition(
17574 4,
17575 ParserTransitionSpec::Atom {
17576 target: 5,
17577 label: TOKEN_EOF,
17578 },
17579 )
17580 .expect("EOF transition");
17581 atn.add_transition(
17582 6,
17583 ParserTransitionSpec::Predicate {
17584 target: 7,
17585 rule_index: 1,
17586 pred_index: 0,
17587 context_dependent: false,
17588 },
17589 )
17590 .expect("callee predicate");
17591 atn.add_transition(
17592 7,
17593 ParserTransitionSpec::Atom {
17594 target: 8,
17595 label: 1,
17596 },
17597 )
17598 .expect("callee token");
17599 finish_atn(atn)
17600 }
17601
17602 fn predicate_gated_star_loop_atn() -> Atn {
17604 let mut atn = ParserAtnBuilder::new(2);
17605 for (state_number, kind) in [
17606 (0, AtnStateKind::RuleStart),
17607 (1, AtnStateKind::StarLoopEntry),
17608 (2, AtnStateKind::Basic),
17609 (3, AtnStateKind::Basic),
17610 (4, AtnStateKind::StarLoopBack),
17611 (5, AtnStateKind::LoopEnd),
17612 (6, AtnStateKind::RuleStop),
17613 ] {
17614 assert_eq!(
17615 atn.add_state(kind, Some(0)).expect("state").index(),
17616 state_number
17617 );
17618 }
17619 atn.set_rule_to_start_state(vec![0])
17620 .expect("rule start states");
17621 atn.set_rule_to_stop_state(vec![6])
17622 .expect("rule stop states");
17623 atn.add_decision_state(1).expect("decision state");
17624 atn.set_loop_back_state(5, 4).expect("loop back state");
17625 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17626 .expect("entry transition");
17627 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17628 .expect("loop enter");
17629 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
17630 .expect("loop exit");
17631 atn.add_transition(
17632 2,
17633 ParserTransitionSpec::Predicate {
17634 target: 3,
17635 rule_index: 0,
17636 pred_index: 0,
17637 context_dependent: false,
17638 },
17639 )
17640 .expect("loop predicate");
17641 atn.add_transition(
17642 3,
17643 ParserTransitionSpec::Atom {
17644 target: 4,
17645 label: 1,
17646 },
17647 )
17648 .expect("loop token");
17649 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
17650 .expect("loop back");
17651 atn.add_transition(
17652 5,
17653 ParserTransitionSpec::Atom {
17654 target: 6,
17655 label: TOKEN_EOF,
17656 },
17657 )
17658 .expect("EOF transition");
17659 finish_atn(atn)
17660 }
17661
17662 fn nested_nullable_context_atn() -> Atn {
17663 let mut atn = ParserAtnBuilder::new(1);
17664 for state_number in 0..=20 {
17665 let kind = match state_number {
17666 0 | 10 | 16 => AtnStateKind::RuleStart,
17667 9 | 15 | 20 => AtnStateKind::RuleStop,
17668 _ => AtnStateKind::Basic,
17669 };
17670 let rule_index = match state_number {
17671 0..=9 => 0,
17672 10..=15 => 1,
17673 _ => 2,
17674 };
17675 assert_eq!(
17676 atn.add_state(kind, Some(rule_index))
17677 .expect("state")
17678 .index(),
17679 state_number
17680 );
17681 }
17682 atn.set_rule_to_start_state(vec![0, 10, 16])
17683 .expect("rule start states");
17684 atn.set_rule_to_stop_state(vec![9, 15, 20])
17685 .expect("rule stop states");
17686 atn.add_transition(
17687 1,
17688 ParserTransitionSpec::Rule {
17689 target: 10,
17690 rule_index: 1,
17691 follow_state: 8,
17692 precedence: 0,
17693 },
17694 )
17695 .expect("transition");
17696 atn.add_transition(
17697 8,
17698 ParserTransitionSpec::Atom {
17699 target: 9,
17700 label: 1,
17701 },
17702 )
17703 .expect("transition");
17704 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17705 .expect("transition");
17706 atn.add_transition(
17707 2,
17708 ParserTransitionSpec::Rule {
17709 target: 16,
17710 rule_index: 2,
17711 follow_state: 14,
17712 precedence: 0,
17713 },
17714 )
17715 .expect("transition");
17716 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
17717 .expect("transition");
17718 finish_atn(atn)
17719 }
17720
17721 fn generated_match_recovery_atn() -> Atn {
17722 let mut atn = ParserAtnBuilder::new(2);
17723 assert_eq!(
17724 atn.add_state(AtnStateKind::RuleStart, Some(0))
17725 .expect("state")
17726 .index(),
17727 0
17728 );
17729 assert_eq!(
17730 atn.add_state(AtnStateKind::Basic, Some(0))
17731 .expect("state")
17732 .index(),
17733 1
17734 );
17735 assert_eq!(
17736 atn.add_state(AtnStateKind::Basic, Some(0))
17737 .expect("state")
17738 .index(),
17739 2
17740 );
17741 assert_eq!(
17742 atn.add_state(AtnStateKind::RuleStop, Some(0))
17743 .expect("state")
17744 .index(),
17745 3
17746 );
17747 assert_eq!(
17748 atn.add_state(AtnStateKind::RuleStart, Some(1))
17749 .expect("state")
17750 .index(),
17751 4
17752 );
17753 assert_eq!(
17754 atn.add_state(AtnStateKind::RuleStop, Some(1))
17755 .expect("state")
17756 .index(),
17757 5
17758 );
17759 atn.set_rule_to_start_state(vec![0, 4])
17760 .expect("rule start states");
17761 atn.set_rule_to_stop_state(vec![3, 5])
17762 .expect("rule stop states");
17763 atn.add_transition(
17764 1,
17765 ParserTransitionSpec::Rule {
17766 target: 4,
17767 rule_index: 1,
17768 follow_state: 2,
17769 precedence: 0,
17770 },
17771 )
17772 .expect("transition");
17773 atn.add_transition(
17774 2,
17775 ParserTransitionSpec::Atom {
17776 target: 3,
17777 label: TOKEN_EOF,
17778 },
17779 )
17780 .expect("transition");
17781 finish_atn(atn)
17782 }
17783
17784 fn complement_set_atn() -> Atn {
17785 let mut atn = ParserAtnBuilder::new(1);
17786 assert_eq!(
17787 atn.add_state(AtnStateKind::RuleStart, Some(0))
17788 .expect("state")
17789 .index(),
17790 0
17791 );
17792 assert_eq!(
17793 atn.add_state(AtnStateKind::RuleStop, Some(0))
17794 .expect("state")
17795 .index(),
17796 1
17797 );
17798 atn.set_rule_to_start_state(vec![0])
17799 .expect("rule start states");
17800 atn.set_rule_to_stop_state(vec![1])
17801 .expect("rule stop states");
17802 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
17803 atn.add_transition(
17804 0,
17805 ParserTransitionSpec::NotSet {
17806 target: 1,
17807 set: excluded,
17808 },
17809 )
17810 .expect("transition");
17811 finish_atn(atn)
17812 }
17813
17814 fn wildcard_then_eof_atn() -> Atn {
17817 let mut atn = ParserAtnBuilder::new(1);
17818 assert_eq!(
17819 atn.add_state(AtnStateKind::RuleStart, Some(0))
17820 .expect("state")
17821 .index(),
17822 0
17823 );
17824 assert_eq!(
17825 atn.add_state(AtnStateKind::RuleStop, Some(0))
17826 .expect("state")
17827 .index(),
17828 1
17829 );
17830 assert_eq!(
17831 atn.add_state(AtnStateKind::Basic, Some(0))
17832 .expect("state")
17833 .index(),
17834 2
17835 );
17836 atn.set_rule_to_start_state(vec![0])
17837 .expect("rule start states");
17838 atn.set_rule_to_stop_state(vec![1])
17839 .expect("rule stop states");
17840 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
17841 .expect("transition");
17842 atn.add_transition(
17843 2,
17844 ParserTransitionSpec::Atom {
17845 target: 1,
17846 label: TOKEN_EOF,
17847 },
17848 )
17849 .expect("transition");
17850 finish_atn(atn)
17851 }
17852
17853 #[test]
17854 fn parser_matches_token_and_reports_mismatch() {
17855 let source = Source {
17856 tokens: vec![
17857 TestToken::new(1).with_text("x"),
17858 TestToken::eof("parser-test", 1, 1, 1),
17859 ],
17860 index: 0,
17861 };
17862 let data = RecognizerData::new(
17863 "Mini.g4",
17864 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17865 );
17866 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17867 let matched = parser.match_token(1).expect("token 1 should match");
17868 assert_eq!(parser.node(matched).text(), "x");
17869 assert!(parser.match_token(1).is_err());
17870 }
17871
17872 #[test]
17873 fn parser_matches_token_sets() {
17874 let mut parser = mini_parser(vec![
17875 TestToken::new(1).with_text("x"),
17876 TestToken::eof("parser-test", 1, 1, 1),
17877 ]);
17878
17879 let matched = parser
17880 .match_set(&[(1, 1), (3, 4)])
17881 .expect("token set should match");
17882 assert_eq!(parser.node(matched).text(), "x");
17883 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
17884 }
17885
17886 #[test]
17887 fn generated_rule_api_tracks_state_and_precedence() {
17888 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17889
17890 let context = parser.enter_rule(7, 2);
17891 assert_eq!(context.rule_index(), 2);
17892 assert_eq!(parser.state(), 7);
17893 assert_eq!(
17894 parser.rule_context_stack,
17895 vec![RuleContextFrame {
17896 rule_index: 2,
17897 invoking_state: 7
17898 }]
17899 );
17900
17901 let recursive = parser.enter_recursion_rule(11, 3, 4);
17902 assert_eq!(recursive.rule_index(), 3);
17903 assert!(parser.precpred(4));
17904 assert!(parser.precpred(5));
17905 assert!(!parser.precpred(3));
17906
17907 let next = parser.push_new_recursion_context(13, 3);
17908 assert_eq!(next.invoking_state(), 13);
17909 parser.unroll_recursion_context();
17910 assert_eq!(parser.precedence_stack, vec![0]);
17911 assert_eq!(
17912 parser.rule_context_stack,
17913 vec![RuleContextFrame {
17914 rule_index: 2,
17915 invoking_state: 7
17916 }]
17917 );
17918
17919 parser.exit_rule();
17920 assert!(parser.rule_context_stack.is_empty());
17921 }
17922
17923 #[test]
17924 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
17925 let mut parser = mini_parser(vec![
17926 TestToken::new(1).with_text("x"),
17927 TestToken::eof("parser-test", 1, 1, 1),
17928 ]);
17929 let matched = parser.match_token(1).expect("token should match");
17930 assert_eq!(parser.node(matched).text(), "x");
17931 parser.record_generated_syntax_error();
17932 parser.set_int_member(7, 11);
17933 parser.set_build_parse_trees(false);
17934 parser.set_report_diagnostic_errors(true);
17935 parser.set_prediction_mode(PredictionMode::Sll);
17936 parser.set_bail_on_error(true);
17937 let _context = parser.enter_recursion_rule(9, 0, 4);
17938 parser.pending_invoking_states.push(5);
17939 parser.unknown_predicate_hits.push((0, 1));
17940 parser.unhandled_action_hits.push((0, 2));
17941
17942 parser.reset();
17943
17944 assert_eq!(parser.input.index(), 0);
17945 assert_eq!(parser.la(1), 1);
17946 assert_eq!(parser.state(), -1);
17947 assert_eq!(parser.number_of_syntax_errors(), 0);
17948 assert_eq!(parser.parse_tree_storage().node_count(), 0);
17949 assert!(parser.rule_context_stack.is_empty());
17950 assert!(parser.pending_invoking_states.is_empty());
17951 assert_eq!(parser.precedence_stack, [0]);
17952 assert!(parser.unknown_predicate_hits.is_empty());
17953 assert!(parser.unhandled_action_hits.is_empty());
17954 assert_eq!(parser.int_member(7), Some(11));
17955 assert!(!parser.build_parse_trees());
17956 assert!(parser.report_diagnostic_errors());
17957 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
17958 assert!(parser.bail_on_error());
17959 }
17960
17961 #[test]
17962 fn set_token_stream_replaces_input_and_resets_parser() {
17963 let mut parser = mini_parser(vec![
17964 TestToken::new(1).with_text("old"),
17965 TestToken::eof("parser-test", 1, 1, 1),
17966 ]);
17967 parser.consume();
17968 parser.record_generated_syntax_error();
17969 let replacement = CommonTokenStream::new(Source {
17970 tokens: vec![
17971 TestToken::new(2).with_text("new"),
17972 TestToken::eof("parser-test", 1, 1, 1),
17973 ],
17974 index: 0,
17975 });
17976
17977 parser.set_token_stream(replacement);
17978
17979 assert_eq!(parser.input.index(), 0);
17980 assert_eq!(parser.la(1), 2);
17981 assert_eq!(parser.input.text_all(), "new");
17982 assert_eq!(parser.number_of_syntax_errors(), 0);
17983 }
17984
17985 #[test]
17986 fn active_invocation_states_exclude_the_root_frame() {
17987 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17988
17989 let _root = parser.enter_rule(0, 0);
17990 assert!(parser.active_invocation_states().is_empty());
17991
17992 let marker = parser.push_invoking_state(6);
17993 let _child = parser.enter_rule(2, 1);
17994 parser.discard_invoking_state(marker);
17995 assert_eq!(parser.active_invocation_states(), [6]);
17996
17997 let marker = parser.push_invoking_state(13);
17998 let _grandchild = parser.enter_rule(4, 2);
17999 parser.discard_invoking_state(marker);
18000 assert_eq!(parser.active_invocation_states(), [13, 6]);
18001
18002 parser.exit_rule();
18003 parser.exit_rule();
18004 parser.exit_rule();
18005 }
18006
18007 #[test]
18008 fn parser_predicates_support_token_adjacency() {
18009 let mut parser = mini_parser(vec![
18010 TestToken::new(1).with_text("=").with_span(0, 0),
18011 TestToken::new(1).with_text(">").with_span(1, 1),
18012 TestToken::eof("parser-test", 2, 1, 2),
18013 ]);
18014 parser.consume();
18015 parser.consume();
18016
18017 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
18018
18019 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
18020
18021 let mut parser = mini_parser(vec![
18022 TestToken::new(1).with_text("=").with_span(0, 0),
18023 TestToken::new(1)
18024 .with_text(" ")
18025 .with_channel(HIDDEN_CHANNEL)
18026 .with_span(1, 1),
18027 TestToken::new(1).with_text(">").with_span(2, 2),
18028 TestToken::eof("parser-test", 3, 1, 3),
18029 ]);
18030 parser.consume();
18031 parser.consume();
18032
18033 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
18034 }
18035
18036 #[test]
18037 fn parser_predicates_support_context_child_text_checks() {
18038 let mut parser = mini_parser(vec![
18039 TestToken::new(1).with_text("var"),
18040 TestToken::eof("parser-test", 1, 1, 1),
18041 ]);
18042 let mut context = ParserRuleContext::new(1, 0);
18043 let mut child_context = ParserRuleContext::new(2, 0);
18044 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
18045 parser.tree.add_child(&mut child_context, terminal);
18046 let child = parser.rule_node(child_context);
18047 parser.tree.add_child(&mut context, child);
18048 let predicates = [(
18049 1,
18050 0,
18051 ParserPredicate::ContextChildRuleTextNotEquals {
18052 rule_index: 2,
18053 text: "var",
18054 },
18055 )];
18056
18057 assert!(
18058 !parser.parser_semantic_predicate_matches_with_context_and_local(
18059 &predicates,
18060 1,
18061 0,
18062 &context,
18063 0,
18064 )
18065 );
18066 }
18067
18068 #[test]
18069 fn context_expected_symbols_walks_nullable_parent_contexts() {
18070 let atn = nested_nullable_context_atn();
18071 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18072 parser.rule_context_stack = vec![
18073 RuleContextFrame {
18074 rule_index: 0,
18075 invoking_state: 0,
18076 },
18077 RuleContextFrame {
18078 rule_index: 1,
18079 invoking_state: 1,
18080 },
18081 RuleContextFrame {
18082 rule_index: 2,
18083 invoking_state: 2,
18084 },
18085 ];
18086
18087 let expected = parser.context_expected_symbols(&atn);
18088
18089 assert!(expected.contains(&1));
18090 assert!(expected.contains(&TOKEN_EOF));
18091 }
18092
18093 #[test]
18094 fn prediction_context_return_states_track_rule_stack_changes() {
18095 let atn = nested_nullable_context_atn();
18096 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18097 parser.rule_context_stack = vec![
18098 RuleContextFrame {
18099 rule_index: 0,
18100 invoking_state: 0,
18101 },
18102 RuleContextFrame {
18103 rule_index: 1,
18104 invoking_state: 1,
18105 },
18106 RuleContextFrame {
18107 rule_index: 2,
18108 invoking_state: 2,
18109 },
18110 ];
18111
18112 let initial_version = parser.rule_context_version();
18113 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
18114 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
18115 assert_eq!(first, second);
18116 assert_eq!(parser.rule_context_version(), initial_version);
18117
18118 parser.exit_rule();
18119 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
18120 assert_ne!(first, after_pop);
18121 assert_ne!(parser.rule_context_version(), initial_version);
18122 }
18123
18124 #[test]
18125 fn generated_match_token_recovers_missing_token_from_context_follow() {
18126 let atn = generated_match_recovery_atn();
18127 let data = RecognizerData::new(
18128 "Mini.g4",
18129 Vocabulary::new(
18130 [None, Some("'X'"), Some("'Y'")],
18131 [None, Some("X"), Some("Y")],
18132 [None::<&str>, None, None],
18133 ),
18134 );
18135 let mut parser = BaseParser::new(
18136 CommonTokenStream::new(Source {
18137 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
18138 index: 0,
18139 }),
18140 data,
18141 );
18142 parser.rule_context_stack = vec![
18143 RuleContextFrame {
18144 rule_index: 0,
18145 invoking_state: 0,
18146 },
18147 RuleContextFrame {
18148 rule_index: 1,
18149 invoking_state: 1,
18150 },
18151 ];
18152 assert_eq!(parser.number_of_syntax_errors(), 0);
18153
18154 let node = parser
18155 .match_token_recovering(2, 5, &atn)
18156 .expect("generated match should insert missing token");
18157
18158 assert_eq!(node.children().len(), 1);
18159 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
18160 assert_eq!(
18161 node.clone()
18162 .into_child_iter()
18163 .map(|child| parser.node(child).text())
18164 .collect::<Vec<_>>(),
18165 ["<missing 'Y'>"]
18166 );
18167 assert!(!node.consumed_eof());
18170 assert_eq!(parser.la(1), TOKEN_EOF);
18171 assert_eq!(parser.number_of_syntax_errors(), 1);
18172 assert_eq!(
18173 parser.generated_parser_diagnostics,
18174 [ParserDiagnostic {
18175 line: 1,
18176 column: 3,
18177 message: "missing 'Y' at '<EOF>'".to_owned(),
18178 offending: parser.input.lt_id(1),
18179 }]
18180 );
18181 }
18182
18183 #[test]
18184 fn generated_match_token_counts_single_token_deletion_recovery() {
18185 let atn = generated_match_recovery_atn();
18186 let data = RecognizerData::new(
18187 "Mini.g4",
18188 Vocabulary::new(
18189 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
18190 [None, Some("X"), Some("Y"), Some("Z")],
18191 [None::<&str>, None, None, None],
18192 ),
18193 );
18194 let mut parser = BaseParser::new(
18195 CommonTokenStream::new(Source {
18196 tokens: vec![
18197 TestToken::new(3).with_text("z"),
18198 TestToken::new(2).with_text("y"),
18199 TestToken::eof("parser-test", 3, 1, 3),
18200 ],
18201 index: 0,
18202 }),
18203 data,
18204 );
18205
18206 let node = parser
18207 .match_token_recovering(2, 5, &atn)
18208 .expect("generated match should delete the extraneous token");
18209
18210 assert_eq!(node.children().len(), 2);
18211 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
18212 assert_eq!(parser.node(node.children()[0]).text(), "z");
18213 assert_eq!(parser.node(node.children()[1]).text(), "y");
18214 assert_eq!(
18215 node.into_child_iter()
18216 .map(|child| parser.node(child).text())
18217 .collect::<Vec<_>>(),
18218 ["z", "y"]
18219 );
18220 assert_eq!(parser.number_of_syntax_errors(), 1);
18221 }
18222
18223 #[test]
18224 fn generated_match_token_iterates_single_success_without_a_children_vec() {
18225 let atn = generated_match_recovery_atn();
18226 let data = RecognizerData::new(
18227 "Mini.g4",
18228 Vocabulary::new(
18229 [None, Some("'X'"), Some("'Y'")],
18230 [None, Some("X"), Some("Y")],
18231 [None::<&str>, None, None],
18232 ),
18233 );
18234 let mut parser = BaseParser::new(
18235 CommonTokenStream::new(Source {
18236 tokens: vec![
18237 TestToken::new(2).with_text("y"),
18238 TestToken::eof("parser-test", 1, 1, 1),
18239 ],
18240 index: 0,
18241 }),
18242 data,
18243 );
18244
18245 let node = parser
18246 .match_token_recovering(2, 5, &atn)
18247 .expect("generated match should consume the expected token");
18248
18249 assert_eq!(
18250 node.into_child_iter()
18251 .map(|child| parser.node(child).text())
18252 .collect::<Vec<_>>(),
18253 ["y"]
18254 );
18255 assert_eq!(parser.number_of_syntax_errors(), 0);
18256 }
18257
18258 #[test]
18259 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
18260 let atn = generated_match_recovery_atn();
18261 let data = RecognizerData::new(
18262 "Mini.g4",
18263 Vocabulary::new(
18264 [None, Some("'X'"), Some("'Y'")],
18265 [None, Some("X"), Some("Y")],
18266 [None::<&str>, None, None],
18267 ),
18268 );
18269 let mut parser = BaseParser::new(
18270 CommonTokenStream::new(Source {
18271 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
18272 index: 0,
18273 }),
18274 data,
18275 );
18276 parser.rule_context_stack = vec![
18277 RuleContextFrame {
18278 rule_index: 0,
18279 invoking_state: 0,
18280 },
18281 RuleContextFrame {
18282 rule_index: 1,
18283 invoking_state: 1,
18284 },
18285 ];
18286 let marker = parser.generated_diagnostics_checkpoint();
18287
18288 let _ = parser
18289 .match_token_recovering(2, 5, &atn)
18290 .expect("generated match should insert missing token");
18291 assert_eq!(parser.number_of_syntax_errors(), 1);
18292
18293 parser.restore_generated_diagnostics(marker);
18294
18295 assert_eq!(parser.number_of_syntax_errors(), 0);
18296 assert!(parser.generated_parser_diagnostics.is_empty());
18297 }
18298
18299 #[test]
18300 fn generated_prediction_diagnostics_use_adaptive_context() {
18301 let atn = two_alt_decision_atn();
18302 let data = RecognizerData::new(
18303 "Mini.g4",
18304 Vocabulary::new(
18305 [None, Some("'x'"), Some("'y'")],
18306 [None, Some("X"), Some("Y")],
18307 [None::<&str>, None, None],
18308 ),
18309 )
18310 .with_rule_names(["s"]);
18311 let mut parser = BaseParser::new(
18312 CommonTokenStream::new(Source {
18313 tokens: vec![
18314 TestToken::new(1)
18315 .with_text("x")
18316 .with_position(1, 0)
18317 .with_span(0, 0),
18318 TestToken::new(2)
18319 .with_text("y")
18320 .with_position(1, 2)
18321 .with_span(1, 1),
18322 TestToken::eof("parser-test", 2, 1, 3),
18323 ],
18324 index: 0,
18325 }),
18326 data,
18327 );
18328 parser.set_report_diagnostic_errors(true);
18329
18330 parser.record_generated_prediction_diagnostic(
18331 &atn,
18332 1,
18333 &ParserAtnPrediction {
18334 alt: 1,
18335 requires_full_context: true,
18336 has_semantic_context: false,
18337 diagnostic: Some(ParserAtnPredictionDiagnostic {
18338 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
18339 start_index: 0,
18340 sll_stop_index: 1,
18341 ll_stop_index: 0,
18342 conflicting_alts: vec![1, 2],
18343 exact: false,
18344 }),
18345 },
18346 );
18347 parser.record_generated_prediction_diagnostic(
18352 &atn,
18353 1,
18354 &ParserAtnPrediction {
18355 alt: 1,
18356 requires_full_context: true,
18357 has_semantic_context: false,
18358 diagnostic: Some(ParserAtnPredictionDiagnostic {
18359 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
18360 start_index: 0,
18361 sll_stop_index: 1,
18362 ll_stop_index: 1,
18363 conflicting_alts: vec![1, 2],
18364 exact: false,
18365 }),
18366 },
18367 );
18368
18369 insta::assert_debug_snapshot!(
18372 "generated_prediction_diagnostics_use_adaptive_context",
18373 parser.generated_parser_diagnostics
18374 );
18375 }
18376
18377 #[test]
18378 fn generated_match_not_set_recovers_empty_complement_at_eof() {
18379 let atn = complement_set_atn();
18380 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18381 parser.rule_context_stack = vec![RuleContextFrame {
18382 rule_index: 0,
18383 invoking_state: 0,
18384 }];
18385
18386 let node = parser
18387 .match_not_token_set_recovering(
18388 atn.token_set(0).expect("excluded token set"),
18389 1,
18390 1,
18391 1,
18392 &atn,
18393 )
18394 .expect("empty complement should recover at EOF");
18395
18396 assert_eq!(node.children().len(), 1);
18397 assert!(!node.consumed_eof());
18400 assert_eq!(parser.la(1), TOKEN_EOF);
18401 assert_eq!(
18402 parser.generated_parser_diagnostics,
18403 [ParserDiagnostic {
18404 line: 1,
18405 column: 1,
18406 message: "missing {} at '<EOF>'".to_owned(),
18407 offending: parser.input.lt_id(1),
18408 }]
18409 );
18410 }
18411
18412 #[test]
18413 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
18414 let atn = wildcard_then_eof_atn();
18420 let data = RecognizerData::new(
18421 "Mini.g4",
18422 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18423 );
18424 let mut parser = BaseParser::new(
18425 CommonTokenStream::new(Source {
18426 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
18427 index: 0,
18428 }),
18429 data,
18430 );
18431 parser.rule_context_stack = vec![RuleContextFrame {
18432 rule_index: 0,
18433 invoking_state: 0,
18434 }];
18435
18436 let node = parser
18437 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
18438 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
18439
18440 assert_eq!(node.children().len(), 1);
18442 assert!(!node.consumed_eof());
18443 assert!(
18444 parser
18445 .node(node.children()[0])
18446 .text()
18447 .starts_with("<missing")
18448 );
18449 assert_eq!(parser.la(1), TOKEN_EOF);
18450 assert_eq!(
18451 parser.generated_parser_diagnostics,
18452 [ParserDiagnostic {
18453 line: 1,
18454 column: 1,
18455 message: "missing 'x' at '<EOF>'".to_owned(),
18456 offending: parser.input.lt_id(1),
18457 }]
18458 );
18459 }
18460
18461 #[test]
18462 fn generated_rule_recovery_consumes_to_parent_follow() {
18463 let atn = generated_match_recovery_atn();
18464 let data = RecognizerData::new(
18465 "Mini.g4",
18466 Vocabulary::new(
18467 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
18468 [None, Some("X"), Some("Y"), Some("Z")],
18469 [None::<&str>, None, None, None],
18470 ),
18471 );
18472 let mut parser = BaseParser::new(
18473 CommonTokenStream::new(Source {
18474 tokens: vec![
18475 TestToken::new(3).with_text("z"),
18476 TestToken::eof("parser-test", 1, 1, 1),
18477 ],
18478 index: 0,
18479 }),
18480 data,
18481 );
18482 let _parent = parser.enter_rule(0, 0);
18483 let marker = parser.push_invoking_state(1);
18484 let mut child = parser.enter_rule(4, 1);
18485 parser.discard_invoking_state(marker);
18486
18487 let offending = parser.input.lt_id(1);
18490 assert!(offending.is_some(), "the 'z' token should be buffered");
18491 parser.recover_generated_rule(
18492 &mut child,
18493 &atn,
18494 AntlrError::ParserError {
18495 line: 1,
18496 column: 0,
18497 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
18498 offending,
18499 },
18500 );
18501 let tree = parser.finish_rule(child, false);
18502
18503 assert_eq!(parser.la(1), TOKEN_EOF);
18504 assert_eq!(
18505 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
18506 "(a z)"
18507 );
18508 assert_eq!(parser.number_of_syntax_errors(), 1);
18509 assert_eq!(
18510 parser.generated_parser_diagnostics,
18511 [ParserDiagnostic {
18512 line: 1,
18513 column: 0,
18514 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
18515 offending,
18516 }]
18517 );
18518 parser.exit_rule();
18519 }
18520
18521 #[test]
18522 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
18523 let atn = nested_nullable_context_atn();
18524 let mut parser = mini_parser(vec![
18525 TestToken::new(1).with_text("x"),
18526 TestToken::eof("parser-test", 1, 1, 1),
18527 ]);
18528 parser.rule_context_stack = vec![
18529 RuleContextFrame {
18530 rule_index: 0,
18531 invoking_state: 0,
18532 },
18533 RuleContextFrame {
18534 rule_index: 1,
18535 invoking_state: 1,
18536 },
18537 RuleContextFrame {
18538 rule_index: 2,
18539 invoking_state: 2,
18540 },
18541 ];
18542 parser.set_state(20);
18543 let mut context = ParserRuleContext::new(2, 2);
18544
18545 parser.recover_generated_rule(
18546 &mut context,
18547 &atn,
18548 AntlrError::NoViableAlternative {
18549 input: "'x'".to_owned(),
18550 },
18551 );
18552 assert_eq!(parser.input.index(), 0);
18553
18554 parser.set_state(21);
18555 parser.recover_generated_rule(
18556 &mut context,
18557 &atn,
18558 AntlrError::NoViableAlternative {
18559 input: "'x'".to_owned(),
18560 },
18561 );
18562 assert_eq!(parser.input.index(), 0);
18563 assert_eq!(
18564 parser.generated_recovery_error_states,
18565 BTreeSet::from([20, 21])
18566 );
18567
18568 parser.set_state(20);
18569 parser.recover_generated_rule(
18570 &mut context,
18571 &atn,
18572 AntlrError::NoViableAlternative {
18573 input: "'x'".to_owned(),
18574 },
18575 );
18576
18577 assert_eq!(parser.input.index(), 1);
18578 assert_eq!(parser.la(1), TOKEN_EOF);
18579 assert!(context.has_matched_child());
18580 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
18581
18582 parser.match_eof().expect("EOF should match");
18583 assert_eq!(parser.generated_recovery_error_index, None);
18584 assert!(parser.generated_recovery_error_states.is_empty());
18585 }
18586
18587 #[test]
18588 fn greedy_ll1_alt_handles_nullable_loop_exit() {
18589 let mut body_symbols = TokenBitSet::default();
18590 body_symbols.insert(1);
18591 let entry = DecisionLookahead {
18592 transitions: vec![
18593 TransitionLookSet {
18594 symbols: body_symbols,
18595 nullable: false,
18596 },
18597 TransitionLookSet {
18598 symbols: TokenBitSet::default(),
18599 nullable: true,
18600 },
18601 ],
18602 };
18603
18604 assert_eq!(ll1_unique_alt(&entry, 2), None);
18605 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
18606 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
18607 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
18608 }
18609
18610 #[test]
18611 fn ordinary_repetition_builds_tree_in_input_order() {
18612 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18613 let mut parser = mini_parser(repeated_x_tokens(3));
18614 let tree = parser
18615 .parse_atn_rule(&atn, 0)
18616 .expect("ordinary repetition should parse");
18617
18618 let root = parser
18619 .node(tree)
18620 .as_rule()
18621 .expect("entry result should be a rule");
18622 let body_rules = root.child_rules(1).collect::<Vec<_>>();
18623 assert_eq!(root.text(), "xxx<EOF>");
18624 assert_eq!(body_rules.len(), 3);
18625 assert_eq!(
18626 body_rules
18627 .iter()
18628 .map(|rule| rule.start_id().expect("body start").index())
18629 .collect::<Vec<_>>(),
18630 [0, 1, 2]
18631 );
18632 assert_eq!(
18633 body_rules
18634 .iter()
18635 .map(|rule| rule.stop_id().expect("body stop").index())
18636 .collect::<Vec<_>>(),
18637 [0, 1, 2]
18638 );
18639 assert_eq!(parser.number_of_syntax_errors(), 0);
18640 }
18641 }
18642
18643 #[test]
18644 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
18645 const DEPTH: usize = 20_000;
18646
18647 std::thread::Builder::new()
18648 .name("deferred-rule-materialization".to_owned())
18649 .stack_size(256 * 1024)
18650 .spawn(|| {
18651 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
18652 let mut root = FastDeferredNodeId::EMPTY;
18653 for depth in 0..DEPTH {
18654 root = parser
18655 .recognition_arena
18656 .deferred_rule_node(FastDeferredRule {
18657 rule_index: u32::try_from(depth).expect("depth fits in u32"),
18658 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
18659 start_index: 0,
18660 stop_index: None,
18661 deferred_children: root,
18662 children: NodeSeqId::EMPTY,
18663 });
18664 }
18665
18666 let (mut children, alt_number) =
18667 parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
18668 assert_eq!(alt_number, 0);
18669 for expected_rule in (0..DEPTH).rev() {
18670 let mut nodes = parser.recognition_arena.iter(children);
18671 let node = nodes.next().expect("nested rule node");
18672 assert!(nodes.next().is_none(), "each rule has one child");
18673 let ArenaRecognizedNode::Rule {
18674 rule_index,
18675 children: nested,
18676 ..
18677 } = parser.recognition_arena.node(node)
18678 else {
18679 panic!("expected nested rule");
18680 };
18681 assert_eq!(rule_index as usize, expected_rule);
18682 children = nested;
18683 }
18684 assert!(children.is_empty());
18685 })
18686 .expect("small-stack thread should start")
18687 .join()
18688 .expect("deferred rules should materialize without recursion");
18689 }
18690
18691 #[test]
18692 fn deferred_alternatives_preserve_left_recursive_contexts() {
18693 let mut parser = mini_parser(vec![
18694 TestToken::new(1).with_text("1"),
18695 TestToken::new(2).with_text("+"),
18696 TestToken::new(1).with_text("2"),
18697 TestToken::eof("parser-test", 3, 1, 3),
18698 ]);
18699 let base = parser.arena_token_node(0, false);
18700 let operator = parser.arena_token_node(1, false);
18701 let right = parser.arena_token_node(2, false);
18702
18703 let base = parser.recognition_arena.prepend(NodeSeqId::EMPTY, base);
18704 let base = parser.recognition_arena.deferred_fragment(base);
18705 let operator = parser.recognition_arena.prepend(NodeSeqId::EMPTY, operator);
18706 let operator = parser.recognition_arena.deferred_fragment(operator);
18707 let right = parser.recognition_arena.prepend(NodeSeqId::EMPTY, right);
18708 let right = parser.recognition_arena.deferred_fragment(right);
18709 let base_alt = parser.recognition_arena.deferred_alternative(1);
18710 let boundary = parser.recognition_arena.deferred_left_recursive_boundary(0);
18711 let operator_alt = parser.recognition_arena.deferred_alternative(6);
18712
18713 let mut deferred = FastDeferredNodeId::EMPTY;
18714 for fragment in [base_alt, base, boundary, operator_alt, operator, right] {
18715 deferred = parser
18716 .recognition_arena
18717 .concat_deferred_nodes(deferred, fragment);
18718 }
18719 let (nodes, root_alt_number) =
18720 parser.materialize_fast_deferred_nodes(deferred, NodeSeqId::EMPTY);
18721 let nodes = parser
18722 .recognition_arena
18723 .fold_left_recursive_boundaries(nodes);
18724
18725 let mut root = ParserRuleContext::new(0, -1);
18726 root.set_context_alt_number(root_alt_number);
18727 let mut cursor = nodes;
18728 while let Some(link) = parser.recognition_arena.link(cursor) {
18729 let child = parser
18730 .arena_recognized_node_tree(link.head, false, true)
18731 .expect("materialized child should become a public tree");
18732 parser.tree.add_child(&mut root, child);
18733 cursor = link.tail;
18734 }
18735 let tree = parser.rule_node(root);
18736 let contexts = parser
18737 .node(tree)
18738 .descendants()
18739 .filter_map(Node::as_rule)
18740 .map(|rule| {
18741 (
18742 rule.rule_index(),
18743 rule.alt_number(),
18744 rule.context_alt_number(),
18745 rule.text(),
18746 )
18747 })
18748 .collect::<Vec<_>>();
18749
18750 insta::assert_debug_snapshot!(
18751 "deferred_alternatives_preserve_left_recursive_contexts",
18752 contexts
18753 );
18754 }
18755
18756 #[test]
18757 fn fast_recognizer_preserves_labeled_left_recursive_operator_context() {
18758 let atn = labeled_left_recursive_operator_atn();
18759 let mut parser = mini_parser(vec![
18760 TestToken::new(1).with_text("a"),
18761 TestToken::new(3).with_text("+"),
18762 TestToken::new(1).with_text("b"),
18763 TestToken::eof("parser-test", 3, 1, 3),
18764 ]);
18765
18766 let (tree, _) = parser
18767 .parse_atn_rule_with_runtime_options(
18768 &atn,
18769 0,
18770 ParserRuntimeOptions {
18771 track_context_alt_numbers: true,
18772 ..ParserRuntimeOptions::default()
18773 },
18774 )
18775 .expect("labeled left-recursive addition should parse");
18776 let contexts = parser
18777 .node(tree)
18778 .descendants()
18779 .filter_map(Node::as_rule)
18780 .map(|rule| {
18781 let operator = rule
18782 .children()
18783 .next()
18784 .and_then(Node::as_rule)
18785 .is_some_and(|child| child.rule_index() == rule.rule_index());
18786 (operator, rule.context_alt_number(), rule.text())
18787 })
18788 .collect::<Vec<_>>();
18789
18790 insta::assert_debug_snapshot!(
18791 "fast_recognizer_preserves_labeled_left_recursive_operator_context",
18792 contexts
18793 );
18794 assert!(!parser.recognition_arena.deferred_nodes.is_empty());
18795 assert_eq!(parser.number_of_syntax_errors(), 0);
18796 }
18797
18798 #[test]
18799 fn deeply_nested_rule_calls_grow_the_stack() {
18800 const DEPTH: usize = 4_096;
18801 const STACK_SIZE: usize = 256 * 1024;
18802 let atn = nested_rule_chain_atn(DEPTH);
18803 std::thread::Builder::new()
18804 .name("nested-adaptive-set-rules".to_owned())
18805 .stack_size(STACK_SIZE)
18806 .spawn(move || {
18807 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
18808 parser.set_build_parse_trees(false);
18809 parser.fast_first_set_prefilter = false;
18812 parser
18813 .parse_atn_rule(&atn, 0)
18814 .expect("nested rule chain should grow the native stack");
18815 assert_eq!(parser.input.index(), 1);
18816 })
18817 .expect("small-stack thread should start")
18818 .join()
18819 .expect("nested rule chain should not overflow its stack");
18820 }
18821
18822 #[test]
18823 fn deeply_nested_branching_rules_grow_the_stack() {
18824 const DEPTH: usize = 4_096;
18825 const STACK_SIZE: usize = 256 * 1024;
18826 let atn = nested_rule_graph_atn(DEPTH, true, false);
18827 std::thread::Builder::new()
18828 .name("nested-branching-rules".to_owned())
18829 .stack_size(STACK_SIZE)
18830 .spawn(move || {
18831 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
18832 parser.set_build_parse_trees(false);
18833 parser
18834 .parse_atn_rule(&atn, 0)
18835 .expect("branching rule chain should grow the native stack");
18836 assert_eq!(parser.input.index(), 1);
18837 })
18838 .expect("small-stack thread should start")
18839 .join()
18840 .expect("branching rule chain should not overflow its stack");
18841 }
18842
18843 #[test]
18844 fn deeply_nested_rule_follows_grow_the_stack() {
18845 const DEPTH: usize = 4_096;
18846 const STACK_SIZE: usize = 256 * 1024;
18847 let atn = nested_rule_graph_atn(DEPTH, false, true);
18848 std::thread::Builder::new()
18849 .name("nested-rule-follows".to_owned())
18850 .stack_size(STACK_SIZE)
18851 .spawn(move || {
18852 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
18853 parser.set_build_parse_trees(false);
18854 parser.fast_first_set_prefilter = false;
18855 parser
18856 .parse_atn_rule(&atn, 0)
18857 .expect("rule follow chain should grow the native stack");
18858 assert_eq!(parser.input.index(), DEPTH);
18859 })
18860 .expect("small-stack thread should start")
18861 .join()
18862 .expect("nested rule follow chain should not overflow its stack");
18863 }
18864
18865 #[test]
18866 fn deeply_nested_recovery_grows_the_stack() {
18867 const DEPTH: usize = 4_096;
18868 const STACK_SIZE: usize = 256 * 1024;
18869 let atn = nested_rule_chain_atn(DEPTH);
18870 std::thread::Builder::new()
18871 .name("nested-rule-recovery".to_owned())
18872 .stack_size(STACK_SIZE)
18873 .spawn(move || {
18874 let mut parser = mini_parser(vec![
18875 TestToken::new(2).with_text("z"),
18876 TestToken::new(1).with_text("x"),
18877 TestToken::eof("parser-test", 2, 1, 2),
18878 ]);
18879 parser.set_build_parse_trees(false);
18880 parser.fast_first_set_prefilter = false;
18881 parser
18882 .parse_atn_rule(&atn, 0)
18883 .expect("nested recovery should grow the native stack");
18884 assert_eq!(parser.input.index(), 2);
18885 assert_eq!(parser.number_of_syntax_errors(), 1);
18886 })
18887 .expect("small-stack thread should start")
18888 .join()
18889 .expect("nested rule recovery should not overflow its stack");
18890 }
18891
18892 #[test]
18893 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
18894 const REPETITIONS: usize = 64;
18895
18896 let atn = ambiguous_ordinary_star_loop_atn();
18897 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18898 let tree = parser
18899 .parse_atn_rule(&atn, 0)
18900 .expect("ambiguous ordinary repetition should parse");
18901
18902 let root = parser
18903 .node(tree)
18904 .as_rule()
18905 .expect("entry result should be a rule");
18906 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
18907 assert_eq!(parser.input.index(), REPETITIONS);
18908 assert!(
18909 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
18910 "equivalent segmentations should keep deferred storage linear"
18911 );
18912 assert_eq!(parser.number_of_syntax_errors(), 0);
18913 }
18914
18915 #[test]
18916 fn long_ordinary_repetition_does_not_consume_native_stack() {
18917 const REPETITIONS: usize = 20_000;
18918
18919 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18920 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18921 parser.set_build_parse_trees(false);
18922 parser
18923 .parse_atn_rule(&atn, 0)
18924 .expect("long ordinary repetition should parse");
18925
18926 assert_eq!(parser.input.index(), REPETITIONS);
18927 assert_eq!(parser.number_of_syntax_errors(), 0);
18928 }
18929 }
18930
18931 #[test]
18932 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
18933 const REPETITIONS: usize = 2_000;
18934 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
18935
18936 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18937 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18938 let tree = parser
18939 .parse_atn_rule(&atn, 0)
18940 .expect("long rule repetition should parse");
18941
18942 let root = parser
18943 .node(tree)
18944 .as_rule()
18945 .expect("entry result should be a rule");
18946 assert_eq!(root.text(), expected_text);
18947 assert_eq!(root.child_rules(1).count(), REPETITIONS);
18948 let first_body = root.child_rules(1).next().expect("first body rule");
18949 let last_body = root.child_rules(1).next_back().expect("last body rule");
18950 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
18951 assert_eq!(
18952 last_body.stop_id().expect("last body stop").index(),
18953 REPETITIONS - 1
18954 );
18955
18956 let stats = parser.recognition_arena_stats();
18957 assert_eq!(
18958 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18959 (REPETITIONS, REPETITIONS, 0)
18960 );
18961 assert_eq!(
18962 (stats.total_links, stats.live_links, stats.dead_links),
18963 (REPETITIONS, REPETITIONS, 0)
18964 );
18965 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
18966 assert_eq!(
18967 parser.recognition_arena.deferred_nodes.len(),
18968 REPETITIONS * 2 - 1
18969 );
18970 assert_eq!(parser.number_of_syntax_errors(), 0);
18971 }
18972 }
18973
18974 #[test]
18975 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
18976 let key = |state_number| FastRecognizeKey {
18977 state_number,
18978 stop_state: 10,
18979 index: state_number,
18980 rule_start_index: 0,
18981 decision_start_index: None,
18982 precedence: 0,
18983 recovery_symbols_id: 0,
18984 recovery_state: None,
18985 };
18986
18987 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18988 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
18989 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
18990 }
18991 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
18992 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
18993
18994 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18995 let repeated = key(1);
18996 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
18997 assert!(promote.clean_memo_enabled_for_key(&repeated));
18998 }
18999 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
19000
19001 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
19002 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
19003 }
19004 assert!(sparse.clean_memo_enabled_for_key(&repeated));
19005 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
19006 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
19007 assert!(sparse.clean_memo_enabled_for_key(&repeated));
19008 }
19009 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
19010 }
19011
19012 #[test]
19013 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
19014 assert_eq!(
19015 fast_recognize_memo_capacity(0),
19016 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
19017 );
19018 assert_eq!(
19019 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
19020 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
19021 );
19022 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
19023 assert_eq!(
19024 fast_recognize_memo_capacity(usize::MAX),
19025 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
19026 );
19027 }
19028
19029 #[test]
19030 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
19031 let mut scratch = FastRecognizeTopScratch::default();
19032 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
19033 let retained_capacity = scratch.memo.capacity();
19034 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
19035 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
19036
19037 let larger_capacity = retained_capacity + 1;
19038 scratch.prepare(larger_capacity);
19039 let grown_capacity = scratch.memo.capacity();
19040 assert!(grown_capacity >= larger_capacity);
19041 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
19042
19043 scratch.memo.insert(
19044 FastRecognizeKey {
19045 state_number: 0,
19046 stop_state: 0,
19047 index: 0,
19048 rule_start_index: 0,
19049 decision_start_index: None,
19050 precedence: 0,
19051 recovery_symbols_id: 0,
19052 recovery_state: None,
19053 },
19054 Rc::from([FastRecognizeOutcome {
19055 index: 0,
19056 consumed_eof: false,
19057 diagnostics: DiagnosticSeqId::EMPTY,
19058 deferred_nodes: FastDeferredNodeId::EMPTY,
19059 nodes: NodeSeqId::EMPTY,
19060 }]),
19061 );
19062 scratch.release_oversized_memo();
19063 assert!(scratch.memo.is_empty());
19064 assert_eq!(scratch.memo.capacity(), grown_capacity);
19065
19066 scratch
19067 .memo
19068 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
19069 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
19070
19071 scratch.release_oversized_memo();
19072 assert!(scratch.memo.is_empty());
19073 assert_eq!(scratch.memo.capacity(), 0);
19074 }
19075
19076 #[test]
19077 fn clean_empty_multi_alt_outcomes_are_memoized() {
19078 let mut atn = ParserAtnBuilder::new(2);
19079 assert_eq!(
19080 atn.add_state(AtnStateKind::RuleStart, Some(0))
19081 .expect("state")
19082 .index(),
19083 0
19084 );
19085 assert_eq!(
19086 atn.add_state(AtnStateKind::BlockStart, Some(0))
19087 .expect("state")
19088 .index(),
19089 1
19090 );
19091 assert_eq!(
19092 atn.add_state(AtnStateKind::RuleStop, Some(0))
19093 .expect("state")
19094 .index(),
19095 2
19096 );
19097 atn.set_rule_to_start_state(vec![0])
19098 .expect("rule start states");
19099 atn.set_rule_to_stop_state(vec![2])
19100 .expect("rule stop states");
19101 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
19102 .expect("transition");
19103 atn.add_transition(
19104 1,
19105 ParserTransitionSpec::Atom {
19106 target: 2,
19107 label: 1,
19108 },
19109 )
19110 .expect("transition");
19111 atn.add_transition(
19112 1,
19113 ParserTransitionSpec::Atom {
19114 target: 2,
19115 label: 2,
19116 },
19117 )
19118 .expect("transition");
19119 let atn = finish_atn(atn);
19120
19121 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
19122 parser.fast_recovery_enabled = false;
19123 let mut visiting = FxHashSet::default();
19124 let mut memo = FxHashMap::default();
19125 let mut expected = ExpectedTokens::default();
19126 let outcomes = parser.recognize_state_fast(
19127 &atn,
19128 FastRecognizeRequest {
19129 state_number: 1,
19130 stop_state: 2,
19131 index: 0,
19132 rule_start_index: 0,
19133 decision_start_index: None,
19134 precedence: 0,
19135 depth: 0,
19136 recovery_symbols: parser.empty_recovery_symbols(),
19137 recovery_state: None,
19138 },
19139 FastRecognizeScratch {
19140 predicate_context: None,
19141 visiting: &mut visiting,
19142 memo: &mut memo,
19143 expected: &mut expected,
19144 native_depth: 0,
19145 },
19146 );
19147
19148 assert!(outcomes.is_empty());
19149 assert_eq!(memo.len(), 1);
19150 assert!(memo.values().next().expect("memo entry").is_empty());
19151
19152 parser.clean_memo_mode = CleanMemoMode::Sparse;
19153 visiting.clear();
19154 memo.clear();
19155 expected = ExpectedTokens::default();
19156 let sparse_outcomes = parser.recognize_state_fast(
19157 &atn,
19158 FastRecognizeRequest {
19159 state_number: 1,
19160 stop_state: 2,
19161 index: 0,
19162 rule_start_index: 0,
19163 decision_start_index: None,
19164 precedence: 0,
19165 depth: 0,
19166 recovery_symbols: parser.empty_recovery_symbols(),
19167 recovery_state: None,
19168 },
19169 FastRecognizeScratch {
19170 predicate_context: None,
19171 visiting: &mut visiting,
19172 memo: &mut memo,
19173 expected: &mut expected,
19174 native_depth: 0,
19175 },
19176 );
19177
19178 assert!(sparse_outcomes.is_empty());
19179 assert!(memo.is_empty());
19180 }
19181
19182 #[test]
19183 fn wildcard_matches_non_eof_only() {
19184 let mut parser = mini_parser(vec![
19185 TestToken::new(1).with_text("x"),
19186 TestToken::eof("parser-test", 1, 1, 1),
19187 ]);
19188 let matched = parser.match_wildcard().expect("wildcard");
19189 assert_eq!(parser.node(matched).text(), "x");
19190 assert!(parser.match_wildcard().is_err());
19191 }
19192
19193 #[test]
19194 fn add_parse_child_records_match_even_without_tree_building() {
19195 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
19200 let token = TestToken::new(1).with_text("x");
19201
19202 parser.set_build_parse_trees(false);
19203 let mut ctx = ParserRuleContext::new(0, 0);
19204 assert!(!ctx.has_matched_child());
19205 let child = parser.terminal_tree(token.id);
19206 parser.add_parse_child(&mut ctx, child);
19207 assert_eq!(ctx.child_count(), 0);
19209 assert_eq!(parser.parse_tree_storage().node_count(), 0);
19210 assert!(ctx.has_matched_child());
19212
19213 parser.set_build_parse_trees(true);
19215 let mut ctx = ParserRuleContext::new(0, 0);
19216 let child = parser.terminal_tree(token.id);
19217 parser.add_parse_child(&mut ctx, child);
19218 assert_eq!(ctx.child_count(), 1);
19219 assert!(ctx.has_matched_child());
19220 }
19221
19222 #[test]
19223 fn disabled_tree_building_does_not_grow_flat_storage() {
19224 let mut parser = mini_parser(vec![
19225 TestToken::new(1).with_text("x"),
19226 TestToken::new(1).with_text("y"),
19227 TestToken::eof("parser-test", 2, 1, 2),
19228 ]);
19229 parser.set_build_parse_trees(false);
19230 let mut context = ParserRuleContext::new(0, -1);
19231
19232 for _ in 0..2 {
19233 let child = parser.match_token(1).expect("token should match");
19234 parser.add_parse_child(&mut context, child);
19235 }
19236 let current = parser.input.lt_id(1).expect("EOF token");
19237 let error = parser.error_tree(current);
19238 parser.add_parse_child(&mut context, error);
19239 let root = parser.rule_node(context);
19240
19241 assert_eq!(
19242 parser.parse_tree_storage().stats(),
19243 ParseTreeStats::default()
19244 );
19245 assert!(
19246 parser
19247 .parse_tree_storage()
19248 .node(parser.token_store(), root)
19249 .is_none(),
19250 "the no-tree sentinel must not resolve to stored data"
19251 );
19252 }
19253
19254 #[test]
19255 fn disabled_tree_building_skips_recognition_rule_node_storage() {
19256 let atn = ordinary_star_loop_atn();
19257 let mut parser = mini_parser(repeated_x_tokens(3));
19258 parser.set_build_parse_trees(false);
19259
19260 parser
19261 .parse_atn_rule(&atn, 0)
19262 .expect("ordinary repetition should parse without a tree");
19263
19264 assert_eq!(parser.input.index(), 3);
19265 assert!(parser.recognition_arena.nodes.is_empty());
19266 assert!(parser.recognition_arena.seq_links.is_empty());
19267 assert!(parser.recognition_arena.deferred_nodes.is_empty());
19268 assert!(parser.recognition_arena.deferred_rules.is_empty());
19269 assert!(!parser.fast_token_nodes_enabled);
19270 assert!(parser.fast_recognize_scratch.memo.is_empty());
19271 }
19272
19273 #[test]
19274 fn parser_interprets_simple_atn_rule() {
19275 let atn = token_then_eof_atn();
19276 let mut parser = mini_parser(vec![
19277 TestToken::new(1).with_text("x"),
19278 TestToken::eof("parser-test", 1, 1, 1),
19279 ]);
19280
19281 let tree = parser
19282 .parse_atn_rule(&atn, 0)
19283 .expect("artificial parser rule should parse");
19284 assert_eq!(parser.node(tree).text(), "x<EOF>");
19285 assert_eq!(parser.number_of_syntax_errors(), 0);
19286 assert_eq!(
19287 parser
19288 .node(tree)
19289 .first_rule_stop(0)
19290 .expect("rule should stop at EOF")
19291 .token_type(),
19292 TOKEN_EOF
19293 );
19294
19295 let mut parser = mini_parser(vec![
19296 TestToken::new(1).with_text("x"),
19297 TestToken::eof("parser-test", 1, 1, 1),
19298 ]);
19299 let (tree, actions) = parser
19300 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19301 .expect("runtime-option parser rule should parse");
19302 assert!(actions.is_empty());
19303 assert_eq!(
19304 parser
19305 .node(tree)
19306 .first_rule_stop(0)
19307 .expect("rule should stop at EOF")
19308 .token_type(),
19309 TOKEN_EOF
19310 );
19311 }
19312
19313 #[test]
19314 fn runtime_options_default_ignores_noop_action_transitions() {
19315 let atn = noop_action_then_token_then_eof_atn();
19316 let mut parser = mini_parser(vec![
19317 TestToken::new(1).with_text("x"),
19318 TestToken::eof("parser-test", 1, 1, 1),
19319 ]);
19320
19321 let (tree, actions) = parser
19322 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19323 .expect("no-op parser action should not force action replay");
19324
19325 assert_eq!(parser.node(tree).text(), "x<EOF>");
19326 assert!(
19327 actions.is_empty(),
19328 "action_index=None transitions are ANTLR metadata, not replay actions"
19329 );
19330 assert_eq!(parser.number_of_syntax_errors(), 0);
19331 }
19332
19333 #[test]
19334 fn parser_exposes_buffered_token_stream_after_parse() {
19335 let atn = token_then_eof_atn();
19336 let mut parser = mini_parser(vec![
19337 TestToken::new(1).with_text("x"),
19338 TestToken::eof("parser-test", 1, 1, 1),
19339 ]);
19340
19341 let tree = parser
19342 .parse_atn_rule(&atn, 0)
19343 .expect("artificial parser rule should parse");
19344 assert_eq!(parser.node(tree).text(), "x<EOF>");
19345
19346 let stream = parser.token_stream();
19347 let source_index_after_parse = stream.token_source().index;
19348 let buffered = stream.tokens().collect::<Vec<_>>();
19349 assert_eq!(buffered.len(), 2);
19350 assert_eq!(buffered[0].text(), Some("x"));
19351 assert_eq!(buffered[0].token_id().index(), 0);
19352 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
19353 assert_eq!(stream.token_source().index, source_index_after_parse);
19354 drop(buffered);
19355
19356 let stream = parser.into_token_stream();
19357 assert_eq!(stream.token_source().index, source_index_after_parse);
19358 assert_eq!(
19359 stream.tokens().next().expect("first token").text(),
19360 Some("x")
19361 );
19362 assert_eq!(
19363 stream.tokens().nth(1).expect("EOF token").token_type(),
19364 TOKEN_EOF
19365 );
19366 }
19367
19368 #[test]
19369 fn parsed_file_exposes_all_buffered_tokens() {
19370 let atn = token_then_eof_atn();
19371 let mut parser = mini_parser(vec![
19372 TestToken::new(99)
19373 .with_text(" comment")
19374 .with_channel(HIDDEN_CHANNEL),
19375 TestToken::new(1).with_text("x"),
19376 TestToken::eof("parser-test", 9, 1, 9),
19377 ]);
19378
19379 let tree = parser
19380 .parse_atn_rule(&atn, 0)
19381 .expect("artificial parser rule should parse");
19382 let parsed = parser.into_parsed_file(tree);
19383
19384 insta::assert_debug_snapshot!(
19387 "parsed_file_exposes_all_buffered_tokens",
19388 parsed
19389 .tokens()
19390 .iter()
19391 .map(|token| (token.token_type(), token.channel(), token.text()))
19392 .collect::<Vec<_>>()
19393 );
19394 assert_eq!(parsed.tokens().into_iter().count(), 3);
19395 }
19396
19397 #[test]
19398 fn parser_syntax_error_count_tracks_interpreted_recovery() {
19399 let atn = token_then_eof_atn();
19400 let mut parser = mini_parser(vec![
19401 TestToken::new(1).with_text("x"),
19402 TestToken::new(2).with_text("y"),
19403 TestToken::eof("parser-test", 2, 1, 2),
19404 ]);
19405
19406 let tree = parser
19407 .parse_atn_rule(&atn, 0)
19408 .expect("invalid token should recover into an error node");
19409
19410 assert_eq!(parser.number_of_syntax_errors(), 1);
19411 assert_eq!(
19412 parser
19413 .node(tree)
19414 .first_error_token()
19415 .expect("recovery should embed an error token")
19416 .text(),
19417 Some("y")
19418 );
19419 }
19420
19421 #[test]
19422 fn failed_interpreted_parse_notifies_error_listener() {
19423 let atn = token_then_eof_atn();
19424 let mut parser = mini_parser(vec![
19425 TestToken::new(2)
19426 .with_text("y")
19427 .with_span(0, 0)
19428 .with_byte_span(0, 1)
19429 .with_position(3, 5),
19430 TestToken::eof("parser-test", 1, 1, 1),
19431 ]);
19432 parser.remove_error_listeners();
19433 let diagnostics = Arc::new(Mutex::new(Vec::new()));
19434 parser.add_error_listener(RecordingErrorListener {
19435 diagnostics: Arc::clone(&diagnostics),
19436 });
19437
19438 let error = parser
19439 .parse_atn_rule(&atn, 0)
19440 .expect_err("start-rule mismatch should remain a parser error");
19441
19442 assert_eq!(parser.number_of_syntax_errors(), 1);
19443 assert!(matches!(&error, AntlrError::ParserError { .. }));
19444 insta::assert_debug_snapshot!(
19445 "failed_interpreted_parse_notifies_error_listener",
19446 *diagnostics.lock().expect("recorded diagnostics lock")
19447 );
19448 }
19449
19450 #[test]
19451 fn adaptive_direct_rule_uses_simulator_decision() {
19452 let atn = two_alt_decision_atn();
19453 let mut simulator = ParserAtnSimulator::new(&atn);
19454 let mut parser = mini_parser(vec![
19455 TestToken::new(2).with_text("y"),
19456 TestToken::eof("parser-test", 1, 1, 1),
19457 ]);
19458
19459 let tree = parser
19460 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
19461 .expect("direct adaptive rule should parse");
19462
19463 assert_eq!(parser.node(tree).text(), "y");
19464 assert_eq!(parser.input.index(), 1);
19465 }
19466
19467 #[test]
19468 fn adaptive_direct_rule_restores_input_on_fallback() {
19469 let atn = predicate_after_token_atn();
19470 let mut simulator = ParserAtnSimulator::new(&atn);
19471 let mut parser = mini_parser(vec![
19472 TestToken::new(1).with_text("x"),
19473 TestToken::new(2).with_text("y"),
19474 TestToken::eof("parser-test", 2, 1, 2),
19475 ]);
19476
19477 let tree = parser
19478 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
19479 .expect("fallback recognizer should parse");
19480
19481 assert_eq!(parser.node(tree).text(), "xy");
19482 assert_eq!(parser.input.index(), 2);
19483 let stats = parser.parse_tree_storage().stats();
19484 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
19485 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
19486 assert_eq!(stats.scratch_links, 0);
19487 }
19488
19489 #[test]
19490 fn unknown_predicate_policy_defaults_to_assume_true() {
19491 let atn = predicate_after_token_atn();
19492 let mut parser = mini_parser(vec![
19493 TestToken::new(1).with_text("x"),
19494 TestToken::new(2).with_text("y"),
19495 TestToken::eof("parser-test", 2, 1, 2),
19496 ]);
19497
19498 let (tree, _) = parser
19499 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19500 .expect("unknown predicate should pass under the default policy");
19501
19502 assert_eq!(parser.node(tree).text(), "xy");
19503 assert_eq!(parser.number_of_syntax_errors(), 0);
19504 }
19505
19506 #[test]
19507 fn private_context_alt_tracking_keeps_fast_predicate_recognition() {
19508 let atn = predicate_gated_same_lookahead_atn([0, 1]);
19509 let mut parser = mini_parser(vec![
19510 TestToken::new(1).with_text("x"),
19511 TestToken::eof("parser-test", 1, 1, 1),
19512 ]);
19513
19514 let (tree, _) = parser
19515 .parse_atn_rule_with_runtime_options(
19516 &atn,
19517 0,
19518 ParserRuntimeOptions {
19519 predicates: &[
19520 (0, 0, ParserPredicate::False),
19521 (0, 1, ParserPredicate::True),
19522 ],
19523 track_context_alt_numbers: true,
19524 ..ParserRuntimeOptions::default()
19525 },
19526 )
19527 .expect("the second predicate-gated alternative should match");
19528
19529 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19530 insta::assert_debug_snapshot!(
19531 "private_context_alt_tracking_keeps_fast_predicate_recognition",
19532 (root.alt_number(), root.context_alt_number(), root.text())
19533 );
19534 assert_eq!(parser.number_of_syntax_errors(), 0);
19535 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
19536 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
19537 }
19538
19539 #[test]
19540 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
19541 let atn = token_then_eof_atn();
19545 let mut parser = mini_parser(vec![
19546 TestToken::new(1).with_text("x"),
19547 TestToken::eof("parser-test", 1, 1, 1),
19548 ]);
19549
19550 parser.unknown_predicate_hits.push((7, 3));
19552
19553 parser
19555 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19556 .expect("child rule parses");
19557
19558 let error = parser
19560 .take_unknown_semantic_error()
19561 .expect("parent's recorded coordinate must survive the nested interpreted parse");
19562 let AntlrError::Unsupported(message) = error else {
19563 panic!("expected AntlrError::Unsupported, got {error:?}");
19564 };
19565 assert!(message.contains("pred_index=3"), "message: {message}");
19566 }
19567
19568 #[test]
19569 fn nested_committed_parse_preserves_prior_unhandled_action_hits() {
19570 let atn = token_then_eof_atn();
19571 let mut parser = mini_parser(vec![
19572 TestToken::new(1).with_text("x"),
19573 TestToken::eof("parser-test", 1, 1, 1),
19574 ]);
19575 parser.unhandled_action_hits.push((7, 42));
19576
19577 parser
19578 .parse_atn_rule_with_runtime_options(
19579 &atn,
19580 0,
19581 ParserRuntimeOptions {
19582 action_indices: &[(usize::MAX, 0)],
19583 ..ParserRuntimeOptions::default()
19584 },
19585 )
19586 .expect("a child with no action miss must not observe its parent's miss");
19587
19588 let error = parser
19589 .take_unknown_semantic_error()
19590 .expect("the parent's action miss must survive the nested committed parse");
19591 let AntlrError::Unsupported(message) = error else {
19592 panic!("expected AntlrError::Unsupported, got {error:?}");
19593 };
19594 assert!(
19595 message.contains("rule_index=7") && message.contains("state=42"),
19596 "message: {message}"
19597 );
19598 }
19599
19600 #[test]
19601 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
19602 let atn = predicate_after_token_atn();
19603 let mut parser = mini_parser(vec![
19604 TestToken::new(1).with_text("x"),
19605 TestToken::new(2).with_text("y"),
19606 TestToken::eof("parser-test", 2, 1, 2),
19607 ]);
19608
19609 let result = parser.parse_atn_rule_with_runtime_options(
19610 &atn,
19611 0,
19612 ParserRuntimeOptions {
19613 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
19614 ..ParserRuntimeOptions::default()
19615 },
19616 );
19617
19618 assert!(
19619 result.is_err(),
19620 "the only path is predicate-guarded, so assume-false must fail the parse"
19621 );
19622 }
19623
19624 #[test]
19625 fn predicate_failure_message_keeps_semantic_recovery_path() {
19626 let atn = predicate_after_token_atn();
19627 let mut parser = mini_parser(vec![
19628 TestToken::new(1).with_text("x"),
19629 TestToken::new(2).with_text("y"),
19630 TestToken::eof("parser-test", 2, 1, 2),
19631 ]);
19632
19633 let (tree, _) = parser
19634 .parse_atn_rule_with_runtime_options(
19635 &atn,
19636 0,
19637 ParserRuntimeOptions {
19638 predicates: &[(
19639 0,
19640 0,
19641 ParserPredicate::FalseWithMessage {
19642 message: "predicate rejected input",
19643 },
19644 )],
19645 ..ParserRuntimeOptions::default()
19646 },
19647 )
19648 .expect("failure-message predicates recover through the semantic interpreter");
19649
19650 assert_eq!(parser.node(tree).text(), "xy");
19651 assert_eq!(parser.number_of_syntax_errors(), 1);
19652 assert!(
19653 parser.fast_predicate_cache.is_empty(),
19654 "failure-message predicates need the semantic interpreter's recovery outcome"
19655 );
19656 }
19657
19658 #[test]
19659 fn unknown_predicate_policy_error_names_the_coordinate() {
19660 let atn = predicate_after_token_atn();
19661 let mut parser = mini_parser(vec![
19662 TestToken::new(1).with_text("x"),
19663 TestToken::new(2).with_text("y"),
19664 TestToken::eof("parser-test", 2, 1, 2),
19665 ]);
19666
19667 let error = parser
19668 .parse_atn_rule_with_runtime_options(
19669 &atn,
19670 0,
19671 ParserRuntimeOptions {
19672 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19673 ..ParserRuntimeOptions::default()
19674 },
19675 )
19676 .expect_err("evaluating an unknown predicate under Error policy must fail");
19677
19678 let AntlrError::Unsupported(message) = error else {
19679 panic!("expected AntlrError::Unsupported, got {error:?}");
19680 };
19681 assert!(
19682 message.contains("unsupported semantic predicate"),
19683 "message should name the failure class: {message}"
19684 );
19685 assert!(
19686 message.contains("pred_index=0"),
19687 "message should carry the coordinate: {message}"
19688 );
19689 }
19690
19691 #[test]
19692 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
19693 let atn = predicate_after_token_atn();
19699 let mut parser = mini_parser(vec![
19700 TestToken::new(1).with_text("x"),
19701 TestToken::new(2).with_text("y"),
19702 TestToken::eof("parser-test", 2, 1, 2),
19703 ]);
19704
19705 parser
19706 .parse_atn_rule_with_runtime_options(
19707 &atn,
19708 0,
19709 ParserRuntimeOptions {
19710 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19711 ..ParserRuntimeOptions::default()
19712 },
19713 )
19714 .expect_err("first parse fails loud under the Error policy");
19715
19716 parser.reset_unknown_semantic_hits();
19721 assert!(
19722 parser.take_unknown_semantic_error().is_none(),
19723 "reset must drop stale unknown-predicate coordinates before a reused parse"
19724 );
19725 }
19726
19727 #[derive(Debug, Default)]
19728 struct RecordingHooks {
19729 predicates: Vec<(usize, usize, usize, Option<String>)>,
19730 actions: Vec<(usize, String, Option<String>)>,
19731 action_trees: Vec<Option<String>>,
19732 }
19733
19734 impl SemanticHooks for RecordingHooks {
19735 fn sempred<S>(
19736 &mut self,
19737 ctx: &mut ParserSemCtx<'_, S>,
19738 rule_index: usize,
19739 pred_index: usize,
19740 ) -> Option<bool>
19741 where
19742 S: TokenSource,
19743 {
19744 self.predicates.push((
19745 ctx.input_index(),
19746 rule_index,
19747 pred_index,
19748 ctx.token_text(1)
19749 .and_then(|token| token.text().map(str::to_owned)),
19750 ));
19751 Some(true)
19752 }
19753
19754 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19755 where
19756 S: TokenSource,
19757 {
19758 self.actions.push((
19759 action.source_state(),
19760 ctx.action_text(),
19761 ctx.rule_name().map(str::to_owned),
19762 ));
19763 self.action_trees.push(ctx.tree().map(Node::text));
19764 true
19765 }
19766 }
19767
19768 #[derive(Debug, Default)]
19769 struct StatefulActionHooks {
19770 entered: bool,
19771 events: Vec<String>,
19772 }
19773
19774 impl SemanticHooks for StatefulActionHooks {
19775 fn sempred<S>(
19776 &mut self,
19777 _ctx: &mut ParserSemCtx<'_, S>,
19778 _rule_index: usize,
19779 _pred_index: usize,
19780 ) -> Option<bool>
19781 where
19782 S: TokenSource,
19783 {
19784 self.events.push(format!("predicate:{}", self.entered));
19785 Some(self.entered)
19786 }
19787
19788 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19789 where
19790 S: TokenSource,
19791 {
19792 self.events.push(format!(
19793 "action:{}",
19794 action
19795 .action_index()
19796 .map_or_else(|| "legacy".to_owned(), |index| index.to_string())
19797 ));
19798 self.entered = true;
19799 true
19800 }
19801 }
19802
19803 #[derive(Debug, Default)]
19804 struct InitOrderingHooks {
19805 initialized: bool,
19806 events: Vec<String>,
19807 }
19808
19809 impl SemanticHooks for InitOrderingHooks {
19810 fn sempred<S>(
19811 &mut self,
19812 _ctx: &mut ParserSemCtx<'_, S>,
19813 _rule_index: usize,
19814 _pred_index: usize,
19815 ) -> Option<bool>
19816 where
19817 S: TokenSource,
19818 {
19819 self.events.push(format!("predicate:{}", self.initialized));
19820 Some(self.initialized)
19821 }
19822
19823 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19824 where
19825 S: TokenSource,
19826 {
19827 if action.is_rule_init() {
19828 self.initialized = true;
19829 self.events.push("init".to_owned());
19830 } else {
19831 self.events.push(format!(
19832 "action:{}:initialized={}",
19833 action
19834 .action_index()
19835 .map_or_else(|| "legacy".to_owned(), |index| index.to_string()),
19836 self.initialized
19837 ));
19838 }
19839 true
19840 }
19841 }
19842
19843 #[derive(Debug, Default)]
19844 struct ActionContextHooks {
19845 actions: Vec<(usize, Option<i64>, Option<usize>)>,
19846 }
19847
19848 impl SemanticHooks for ActionContextHooks {
19849 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19850 where
19851 S: TokenSource,
19852 {
19853 self.actions.push((
19854 action.action_index().unwrap_or(usize::MAX),
19855 ctx.local_int_arg(),
19856 action.stop_index(),
19857 ));
19858 true
19859 }
19860 }
19861
19862 #[derive(Debug, Default)]
19863 struct DecliningActionHooks {
19864 actions: Vec<usize>,
19865 }
19866
19867 impl SemanticHooks for DecliningActionHooks {
19868 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19869 where
19870 S: TokenSource,
19871 {
19872 self.actions.push(action.source_state());
19873 false
19874 }
19875 }
19876
19877 #[derive(Debug, Default)]
19878 struct ForcedSecondAlternativeHooks {
19879 decisions: Vec<(usize, usize, usize)>,
19880 }
19881
19882 impl SemanticHooks for ForcedSecondAlternativeHooks {
19883 fn observes_parser_decisions(&self) -> bool {
19884 true
19885 }
19886
19887 fn parser_decision_override(
19888 &mut self,
19889 decision: usize,
19890 input_index: usize,
19891 alternative_count: usize,
19892 ) -> Option<usize> {
19893 self.decisions
19894 .push((decision, input_index, alternative_count));
19895 Some(2)
19896 }
19897 }
19898
19899 struct RecordingParseListener {
19900 events: Arc<Mutex<Vec<String>>>,
19901 }
19902
19903 impl ParseListener for RecordingParseListener {
19904 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
19905 self.events
19906 .lock()
19907 .expect("parse-listener event lock")
19908 .push(format!("enter:{}", event.rule_index));
19909 Ok(())
19910 }
19911
19912 fn exit_every_rule(&mut self, rule_index: usize) {
19913 self.events
19914 .lock()
19915 .expect("parse-listener event lock")
19916 .push(format!("exit:{rule_index}"));
19917 }
19918 }
19919
19920 #[derive(Debug, Default)]
19921 struct RejectingPredicateHooks {
19922 predicates: Vec<(usize, usize, usize, Option<String>)>,
19923 }
19924
19925 impl SemanticHooks for RejectingPredicateHooks {
19926 fn sempred<S>(
19927 &mut self,
19928 ctx: &mut ParserSemCtx<'_, S>,
19929 rule_index: usize,
19930 pred_index: usize,
19931 ) -> Option<bool>
19932 where
19933 S: TokenSource,
19934 {
19935 self.predicates.push((
19936 ctx.input_index(),
19937 rule_index,
19938 pred_index,
19939 ctx.token_text(1)
19940 .and_then(|token| token.text().map(str::to_owned)),
19941 ));
19942 Some(false)
19943 }
19944 }
19945
19946 #[test]
19947 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
19948 let atn = predicate_gated_same_lookahead_atn([0, 0]);
19949 let mut parser = mini_parser_with_hooks(
19950 vec![
19951 TestToken::new(1).with_text("x"),
19952 TestToken::eof("parser-test", 1, 1, 1),
19953 ],
19954 RecordingHooks::default(),
19955 );
19956
19957 let (tree, _) = parser
19958 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19959 .expect("both alternatives share one replay-safe predicate result");
19960
19961 assert_eq!(parser.node(tree).text(), "x<EOF>");
19962 assert_eq!(
19963 parser.semantic_hooks.predicates,
19964 vec![(0, 0, 0, Some("x".to_owned()))]
19965 );
19966 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
19967 }
19968
19969 #[test]
19970 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
19971 let atn = predicate_after_token_atn();
19972 let mut parser = mini_parser_with_hooks(
19973 vec![
19974 TestToken::new(1).with_text("x"),
19975 TestToken::new(2).with_text("y"),
19976 TestToken::eof("parser-test", 2, 1, 2),
19977 ],
19978 RecordingHooks::default(),
19979 );
19980
19981 let (tree, _) = parser
19982 .parse_atn_rule_with_runtime_options(
19983 &atn,
19984 0,
19985 ParserRuntimeOptions {
19986 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19987 ..ParserRuntimeOptions::default()
19988 },
19989 )
19990 .expect("hook supplies the missing predicate result");
19991
19992 assert_eq!(parser.node(tree).text(), "xy");
19993 assert_eq!(
19994 parser.semantic_hooks.predicates,
19995 vec![(1, 0, 0, Some("y".to_owned()))]
19996 );
19997 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
19998 }
19999
20000 #[test]
20001 fn runtime_options_default_preserves_semantic_hook_predicates() {
20002 let atn = predicate_after_token_atn();
20003 let mut parser = mini_parser_with_hooks(
20004 vec![
20005 TestToken::new(1).with_text("x"),
20006 TestToken::new(2).with_text("y"),
20007 TestToken::eof("parser-test", 2, 1, 2),
20008 ],
20009 RejectingPredicateHooks::default(),
20010 );
20011
20012 let result =
20013 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
20014
20015 assert!(
20016 result.is_err(),
20017 "default runtime options must not bypass semantic hooks for predicate ATNs"
20018 );
20019 assert_eq!(
20020 parser.semantic_hooks.predicates,
20021 vec![(1, 0, 0, Some("y".to_owned()))]
20022 );
20023 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
20024 }
20025
20026 #[test]
20027 fn committed_action_runs_before_later_predicate() {
20028 let atn = committed_action_then_predicate_atn();
20029 let mut parser = mini_parser_with_hooks(
20030 vec![
20031 TestToken::new(1).with_text("x"),
20032 TestToken::eof("parser-test", 1, 1, 1),
20033 ],
20034 StatefulActionHooks::default(),
20035 );
20036
20037 let (tree, deferred_actions) = parser
20038 .parse_atn_rule_with_runtime_options(
20039 &atn,
20040 0,
20041 ParserRuntimeOptions {
20042 action_indices: &[(0, 7)],
20043 ..ParserRuntimeOptions::default()
20044 },
20045 )
20046 .expect("the predicate should observe the preceding committed action");
20047
20048 assert_eq!(parser.node(tree).text(), "x<EOF>");
20049 assert!(deferred_actions.is_empty());
20050 assert_eq!(parser.semantic_hooks.events, ["action:7", "predicate:true"]);
20051 }
20052
20053 #[test]
20054 fn committed_action_hook_observes_parameterized_rule_argument() {
20055 let atn = parameterized_child_action_eof_atn();
20056 let rule_args = [ParserRuleArg {
20057 source_state: 0,
20058 rule_index: 1,
20059 value: 42,
20060 inherit_local: false,
20061 }];
20062 let mut parser = mini_parser_with_hooks(
20063 vec![TestToken::eof("parser-test", 0, 1, 0)],
20064 ActionContextHooks::default(),
20065 );
20066
20067 parser
20068 .parse_atn_rule_with_runtime_options(
20069 &atn,
20070 0,
20071 ParserRuntimeOptions {
20072 action_indices: &[(1, 20), (4, 10)],
20073 rule_args: &rule_args,
20074 ..ParserRuntimeOptions::default()
20075 },
20076 )
20077 .expect("the parameterized child should parse");
20078
20079 assert_eq!(
20080 parser.semantic_hooks.actions[0],
20081 (10, Some(42), None),
20082 "the child action should observe its invocation argument"
20083 );
20084 }
20085
20086 #[test]
20087 fn committed_parent_propagates_child_eof_consumption() {
20088 let atn = parameterized_child_action_eof_atn();
20089 let mut parser = mini_parser_with_hooks(
20090 vec![TestToken::eof("parser-test", 0, 1, 0)],
20091 ActionContextHooks::default(),
20092 );
20093
20094 let (tree, _) = parser
20095 .parse_atn_rule_with_runtime_options(
20096 &atn,
20097 0,
20098 ParserRuntimeOptions {
20099 action_indices: &[(1, 20), (4, 10)],
20100 ..ParserRuntimeOptions::default()
20101 },
20102 )
20103 .expect("the parent should retain its child's EOF boundary");
20104
20105 assert_eq!(
20106 parser.semantic_hooks.actions[1],
20107 (20, None, Some(0)),
20108 "the parent action should stop at EOF"
20109 );
20110 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20111 assert_eq!(root.stop().map(|token| token.token_type()), Some(TOKEN_EOF));
20112 let child = root
20113 .child_rules(1)
20114 .next()
20115 .expect("the parent should contain the child rule");
20116 assert_eq!(
20117 child.stop().map(|token| token.token_type()),
20118 Some(TOKEN_EOF)
20119 );
20120 }
20121
20122 #[test]
20123 fn committed_walker_does_not_run_action_in_losing_alternative() {
20124 let atn = losing_alternative_action_atn();
20125 let mut parser = mini_parser_with_hooks(
20126 vec![
20127 TestToken::new(2).with_text("y"),
20128 TestToken::eof("parser-test", 1, 1, 1),
20129 ],
20130 StatefulActionHooks::default(),
20131 );
20132
20133 let (tree, deferred_actions) = parser
20134 .parse_atn_rule_with_runtime_options(
20135 &atn,
20136 0,
20137 ParserRuntimeOptions {
20138 action_indices: &[(2, 0)],
20139 ..ParserRuntimeOptions::default()
20140 },
20141 )
20142 .expect("the token-led second alternative should be selected");
20143
20144 assert_eq!(parser.node(tree).text(), "y");
20145 assert!(deferred_actions.is_empty());
20146 assert!(parser.semantic_hooks.events.is_empty());
20147 }
20148
20149 #[test]
20150 fn committed_walker_honors_decision_overrides() {
20151 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20152 let predicates = [(0, 0, ParserPredicate::True), (0, 1, ParserPredicate::True)];
20153 let mut parser = mini_parser_with_hooks(
20154 vec![
20155 TestToken::new(1).with_text("x"),
20156 TestToken::eof("parser-test", 1, 1, 1),
20157 ],
20158 ForcedSecondAlternativeHooks::default(),
20159 );
20160
20161 let (tree, deferred_actions) = parser
20162 .parse_atn_rule_with_runtime_options(
20163 &atn,
20164 0,
20165 ParserRuntimeOptions {
20166 action_indices: &[(usize::MAX, 0)],
20167 track_alt_numbers: true,
20168 predicates: &predicates,
20169 ..ParserRuntimeOptions::default()
20170 },
20171 )
20172 .expect("the forced second alternative should parse");
20173
20174 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20175 assert_eq!(root.alt_number(), 2);
20176 assert_eq!(root.text(), "x<EOF>");
20177 assert!(deferred_actions.is_empty());
20178 assert_eq!(parser.semantic_hooks.decisions, [(0, 0, 2)]);
20179 assert_eq!(parser.number_of_syntax_errors(), 0);
20180 }
20181
20182 #[test]
20183 fn committed_walker_sll_mode_does_not_report_full_context_diagnostics() {
20184 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20185 let predicates = [(0, 0, ParserPredicate::True), (0, 1, ParserPredicate::True)];
20186 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20187 let mut parser = mini_parser(vec![
20188 TestToken::new(1).with_text("x"),
20189 TestToken::eof("parser-test", 1, 1, 1),
20190 ]);
20191 parser.set_prediction_mode(PredictionMode::Sll);
20192 parser.set_report_diagnostic_errors(true);
20193 parser.remove_error_listeners();
20194 parser.add_error_listener(RecordingErrorListener {
20195 diagnostics: Arc::clone(&diagnostics),
20196 });
20197
20198 let (tree, deferred_actions) = parser
20199 .parse_atn_rule_with_runtime_options(
20200 &atn,
20201 0,
20202 ParserRuntimeOptions {
20203 action_indices: &[(usize::MAX, 0)],
20204 predicates: &predicates,
20205 ..ParserRuntimeOptions::default()
20206 },
20207 )
20208 .expect("SLL prediction should select the first viable alternative");
20209
20210 assert_eq!(parser.node(tree).text(), "x<EOF>");
20211 assert!(deferred_actions.is_empty());
20212 assert_eq!(parser.number_of_syntax_errors(), 0);
20213 assert!(
20214 diagnostics
20215 .lock()
20216 .expect("recorded diagnostics lock")
20217 .is_empty(),
20218 "SLL mode must not retry with full context or report LL diagnostics"
20219 );
20220 }
20221
20222 #[test]
20223 fn committed_walker_filters_diagnostics_after_semantic_selection() {
20224 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20225 let predicates = [
20226 (0, 0, ParserPredicate::False),
20227 (0, 1, ParserPredicate::True),
20228 ];
20229 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20230 let mut parser = mini_parser(vec![
20231 TestToken::new(1).with_text("x"),
20232 TestToken::eof("parser-test", 1, 1, 1),
20233 ]);
20234 parser.set_prediction_mode(PredictionMode::LlExactAmbigDetection);
20235 parser.set_report_diagnostic_errors(true);
20236 parser.remove_error_listeners();
20237 parser.add_error_listener(RecordingErrorListener {
20238 diagnostics: Arc::clone(&diagnostics),
20239 });
20240
20241 let (tree, _) = parser
20242 .parse_atn_rule_with_runtime_options(
20243 &atn,
20244 0,
20245 ParserRuntimeOptions {
20246 action_indices: &[(usize::MAX, 0)],
20247 track_alt_numbers: true,
20248 predicates: &predicates,
20249 ..ParserRuntimeOptions::default()
20250 },
20251 )
20252 .expect("the true predicate should make the second alternative unique");
20253
20254 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20255 assert_eq!(root.alt_number(), 2);
20256 assert!(
20257 diagnostics
20258 .lock()
20259 .expect("recorded diagnostics lock")
20260 .is_empty(),
20261 "predicate filtering made the decision unambiguous"
20262 );
20263 }
20264
20265 #[test]
20266 fn committed_walker_skips_diagnostic_only_predicates_when_reporting_is_disabled() {
20267 let atn = predicate_gated_same_lookahead_atn([0, 1]);
20268 let mut parser = mini_parser_with_hooks(
20269 vec![
20270 TestToken::new(1).with_text("x"),
20271 TestToken::eof("parser-test", 1, 1, 1),
20272 ],
20273 RecordingHooks::default(),
20274 );
20275 parser.set_prediction_mode(PredictionMode::LlExactAmbigDetection);
20276
20277 let (tree, _) = parser
20278 .parse_atn_rule_with_runtime_options(
20279 &atn,
20280 0,
20281 ParserRuntimeOptions {
20282 action_indices: &[(usize::MAX, 0)],
20283 track_alt_numbers: true,
20284 ..ParserRuntimeOptions::default()
20285 },
20286 )
20287 .expect("the first predicate-bearing alternative should parse");
20288
20289 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20290 assert_eq!(root.alt_number(), 1);
20291 assert_eq!(
20292 parser.semantic_hooks.predicates,
20293 [
20294 (0, 0, 0, Some("x".to_owned())),
20295 (0, 0, 0, Some("x".to_owned())),
20296 ],
20297 "diagnostic-only alternatives must not invoke semantic hooks"
20298 );
20299 }
20300
20301 #[test]
20302 fn committed_walker_falls_back_only_to_simulator_viable_alternatives() {
20303 let atn = semantic_fallback_viability_atn();
20304 let predicates = [
20305 (0, 0, ParserPredicate::False),
20306 (0, 1, ParserPredicate::True),
20307 ];
20308 let mut parser = mini_parser(vec![
20309 TestToken::new(1).with_text("a"),
20310 TestToken::new(3).with_text("c"),
20311 TestToken::eof("parser-test", 2, 1, 2),
20312 ]);
20313
20314 let (tree, deferred_actions) = parser
20315 .parse_atn_rule_with_runtime_options(
20316 &atn,
20317 0,
20318 ParserRuntimeOptions {
20319 action_indices: &[(usize::MAX, 0)],
20320 track_alt_numbers: true,
20321 predicates: &predicates,
20322 ..ParserRuntimeOptions::default()
20323 },
20324 )
20325 .expect("the true A C alternative should survive semantic fallback");
20326
20327 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20328 assert_eq!(root.alt_number(), 3);
20329 assert_eq!(root.text(), "ac<EOF>");
20330 assert!(deferred_actions.is_empty());
20331 assert_eq!(parser.number_of_syntax_errors(), 0);
20332 }
20333
20334 #[test]
20335 fn committed_walker_evaluates_predicates_reached_through_rule_calls() {
20336 let atn = rule_call_predicate_decision_atn();
20337 let predicates = [(1, 0, ParserPredicate::False)];
20338 let mut parser = mini_parser(vec![
20339 TestToken::new(1).with_text("a"),
20340 TestToken::eof("parser-test", 1, 1, 1),
20341 ]);
20342
20343 let (tree, deferred_actions) = parser
20344 .parse_atn_rule_with_runtime_options(
20345 &atn,
20346 0,
20347 ParserRuntimeOptions {
20348 action_indices: &[(usize::MAX, 0)],
20349 track_alt_numbers: true,
20350 predicates: &predicates,
20351 ..ParserRuntimeOptions::default()
20352 },
20353 )
20354 .expect("the direct caller alternative should survive the false callee predicate");
20355
20356 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20357 assert_eq!(root.alt_number(), 2);
20358 assert_eq!(root.text(), "a<EOF>");
20359 assert_eq!(root.child_rules(1).count(), 0);
20360 assert!(deferred_actions.is_empty());
20361 assert_eq!(parser.number_of_syntax_errors(), 0);
20362 }
20363
20364 #[test]
20365 fn committed_walker_uses_callee_argument_for_prediction_predicates() {
20366 let atn = rule_call_predicate_decision_atn();
20367 let predicates = [(1, 0, ParserPredicate::LocalIntEquals { value: 1 })];
20368 let rule_args = [ParserRuleArg {
20369 source_state: 2,
20370 rule_index: 1,
20371 value: 2,
20372 inherit_local: false,
20373 }];
20374 let mut parser = mini_parser(vec![
20375 TestToken::new(1).with_text("a"),
20376 TestToken::eof("parser-test", 1, 1, 1),
20377 ]);
20378
20379 let (tree, _) = parser
20380 .parse_atn_rule_with_runtime_options(
20381 &atn,
20382 0,
20383 ParserRuntimeOptions {
20384 action_indices: &[(usize::MAX, 0)],
20385 track_alt_numbers: true,
20386 predicates: &predicates,
20387 rule_args: &rule_args,
20388 ..ParserRuntimeOptions::default()
20389 },
20390 )
20391 .expect("the direct alternative should survive the false callee predicate");
20392
20393 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20394 assert_eq!(root.alt_number(), 2);
20395 assert_eq!(root.child_rules(1).count(), 0);
20396 assert_eq!(parser.number_of_syntax_errors(), 0);
20397 }
20398
20399 #[test]
20400 fn committed_predicate_star_loop_uses_single_token_deletion() {
20401 let atn = predicate_gated_star_loop_atn();
20402 let predicates = [(0, 0, ParserPredicate::True)];
20403 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20404 let mut parser = mini_parser(vec![
20405 TestToken::new(2).with_text("x"),
20406 TestToken::new(1).with_text("a"),
20407 TestToken::eof("parser-test", 2, 1, 2),
20408 ]);
20409 parser.remove_error_listeners();
20410 parser.add_error_listener(RecordingErrorListener {
20411 diagnostics: Arc::clone(&diagnostics),
20412 });
20413
20414 let (tree, deferred_actions) = parser
20415 .parse_atn_rule_with_runtime_options(
20416 &atn,
20417 0,
20418 ParserRuntimeOptions {
20419 action_indices: &[(usize::MAX, 0)],
20420 predicates: &predicates,
20421 ..ParserRuntimeOptions::default()
20422 },
20423 )
20424 .expect("the loop decision should delete the extraneous token and continue");
20425
20426 assert_eq!(parser.node(tree).text(), "xa<EOF>");
20427 assert!(deferred_actions.is_empty());
20428 assert_eq!(parser.number_of_syntax_errors(), 1);
20429 insta::assert_debug_snapshot!(
20430 "committed_predicate_star_loop_uses_single_token_deletion",
20431 *diagnostics.lock().expect("recorded diagnostics lock")
20432 );
20433 }
20434
20435 #[test]
20436 fn committed_walker_applies_legacy_and_semir_actions_before_indexed_hooks() {
20437 let atn = committed_action_then_predicate_atn();
20438 let member_actions = [ParserMemberAction {
20439 source_state: 0,
20440 member: 0,
20441 delta: 2,
20442 }];
20443 let return_actions = [ParserReturnAction {
20444 source_state: 0,
20445 rule_index: 0,
20446 name: "legacy",
20447 value: 3,
20448 }];
20449 let predicates = [(
20450 0,
20451 0,
20452 ParserPredicate::MemberEquals {
20453 member: 0,
20454 value: 7,
20455 equals: true,
20456 },
20457 )];
20458 let mut ir = SemIr::new();
20459 let semantic_member = ParserMemberAction {
20460 source_state: 0,
20461 member: 0,
20462 delta: 5,
20463 }
20464 .lower_into_semir(&mut ir);
20465 let semantic_return = ParserReturnAction {
20466 source_state: 0,
20467 rule_index: 0,
20468 name: "semantic",
20469 value: 11,
20470 }
20471 .lower_into_semir(&mut ir);
20472 let semantics = ParserSemantics {
20473 ir,
20474 predicates: Vec::new(),
20475 actions: vec![semantic_member, semantic_return],
20476 };
20477 let mut parser = mini_parser_with_hooks(
20478 vec![
20479 TestToken::new(1).with_text("x"),
20480 TestToken::eof("parser-test", 1, 1, 1),
20481 ],
20482 StatefulActionHooks::default(),
20483 );
20484
20485 let (tree, deferred_actions) = parser
20486 .parse_atn_rule_with_runtime_options(
20487 &atn,
20488 0,
20489 ParserRuntimeOptions {
20490 action_indices: &[(0, 7)],
20491 predicates: &predicates,
20492 semantics: Some(&semantics),
20493 member_actions: &member_actions,
20494 return_actions: &return_actions,
20495 ..ParserRuntimeOptions::default()
20496 },
20497 )
20498 .expect("the predicate should observe both committed member actions");
20499
20500 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20501 assert_eq!(root.text(), "x<EOF>");
20502 assert_eq!(root.int_return("legacy"), Some(3));
20503 assert_eq!(root.int_return("semantic"), Some(11));
20504 assert_eq!(parser.int_member(0), Some(7));
20505 assert!(deferred_actions.is_empty());
20506 assert_eq!(parser.semantic_hooks.events, ["action:7"]);
20507 assert_eq!(parser.number_of_syntax_errors(), 0);
20508 }
20509
20510 #[test]
20511 fn committed_walker_runs_action_once_per_star_loop_iteration() {
20512 let atn = committed_action_star_loop_atn();
20513 let mut parser = mini_parser_with_hooks(
20514 vec![
20515 TestToken::new(1).with_text("a"),
20516 TestToken::new(1).with_text("b"),
20517 TestToken::eof("parser-test", 2, 1, 2),
20518 ],
20519 StatefulActionHooks::default(),
20520 );
20521
20522 let (tree, deferred_actions) = parser
20523 .parse_atn_rule_with_runtime_options(
20524 &atn,
20525 0,
20526 ParserRuntimeOptions {
20527 action_indices: &[(2, 3)],
20528 ..ParserRuntimeOptions::default()
20529 },
20530 )
20531 .expect("the committed star loop should parse");
20532
20533 assert_eq!(parser.node(tree).text(), "ab<EOF>");
20534 assert!(deferred_actions.is_empty());
20535 assert_eq!(parser.semantic_hooks.events, ["action:3", "action:3"]);
20536 }
20537
20538 #[test]
20539 fn committed_walker_has_no_total_step_cap() {
20540 const TOKEN_COUNT: usize = RECOGNITION_DEPTH_LIMIT + 1;
20541 let atn = committed_action_star_loop_atn();
20542 let mut parser = mini_parser(repeated_x_tokens(TOKEN_COUNT));
20543 parser.set_build_parse_trees(false);
20544
20545 parser
20546 .parse_atn_rule_with_runtime_options(
20547 &atn,
20548 0,
20549 ParserRuntimeOptions {
20550 action_indices: &[(usize::MAX, 0)],
20551 ..ParserRuntimeOptions::default()
20552 },
20553 )
20554 .expect("valid committed loops must not have a total-work cap");
20555
20556 assert_eq!(parser.input.index(), TOKEN_COUNT);
20557 assert_eq!(parser.number_of_syntax_errors(), 0);
20558 }
20559
20560 #[test]
20561 fn committed_walker_rejects_non_consuming_cycles() {
20562 let atn = committed_non_consuming_cycle_atn();
20563 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
20564 parser.set_bail_on_error(true);
20565
20566 let error = parser
20567 .parse_atn_rule_with_runtime_options(
20568 &atn,
20569 0,
20570 ParserRuntimeOptions {
20571 action_indices: &[(usize::MAX, 0)],
20572 ..ParserRuntimeOptions::default()
20573 },
20574 )
20575 .expect_err("a non-consuming cycle must not spin forever");
20576
20577 assert!(
20578 error.to_string().contains("non-consuming ATN cycle"),
20579 "unexpected error: {error}"
20580 );
20581 }
20582
20583 #[test]
20584 fn deeply_nested_committed_rule_calls_grow_the_stack() {
20585 const DEPTH: usize = 4_096;
20586 const STACK_SIZE: usize = 256 * 1024;
20587 let atn = nested_rule_chain_atn(DEPTH);
20588 std::thread::Builder::new()
20589 .name("nested-committed-rules".to_owned())
20590 .stack_size(STACK_SIZE)
20591 .spawn(move || {
20592 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
20593 parser.set_build_parse_trees(false);
20594 parser
20595 .parse_atn_rule_with_runtime_options(
20596 &atn,
20597 0,
20598 ParserRuntimeOptions {
20599 action_indices: &[(usize::MAX, 0)],
20600 ..ParserRuntimeOptions::default()
20601 },
20602 )
20603 .expect("nested committed rules should grow the native stack");
20604 assert_eq!(parser.input.index(), 1);
20605 })
20606 .expect("small-stack thread should start")
20607 .join()
20608 .expect("nested committed rules should not overflow their stack");
20609 }
20610
20611 #[test]
20612 fn committed_walker_runs_action_once_per_left_recursive_operator() {
20613 let atn = committed_action_left_recursive_atn();
20614 let mut parser = mini_parser_with_hooks(
20615 vec![
20616 TestToken::new(1).with_text("a"),
20617 TestToken::new(3).with_text("+"),
20618 TestToken::new(1).with_text("b"),
20619 TestToken::new(3).with_text("+"),
20620 TestToken::new(1).with_text("c"),
20621 TestToken::eof("parser-test", 5, 1, 5),
20622 ],
20623 StatefulActionHooks::default(),
20624 );
20625
20626 let (tree, deferred_actions) = parser
20627 .parse_atn_rule_with_runtime_options(
20628 &atn,
20629 0,
20630 ParserRuntimeOptions {
20631 action_indices: &[(6, 11)],
20632 ..ParserRuntimeOptions::default()
20633 },
20634 )
20635 .expect("the committed left-recursive rule should parse");
20636
20637 assert_eq!(parser.node(tree).text(), "a+b+c");
20638 assert!(deferred_actions.is_empty());
20639 assert_eq!(parser.semantic_hooks.events, ["action:11", "action:11"]);
20640 }
20641
20642 #[test]
20643 fn committed_left_recursive_depth_cap_keeps_listener_events_balanced() {
20644 let atn = committed_action_left_recursive_atn();
20645 let events = Arc::new(Mutex::new(Vec::new()));
20646 let mut parser = mini_parser(vec![
20647 TestToken::new(1).with_text("a"),
20648 TestToken::new(3).with_text("+"),
20649 TestToken::new(1).with_text("b"),
20650 TestToken::eof("parser-test", 3, 1, 3),
20651 ]);
20652 parser.set_max_rule_depth(Some(1));
20653 parser.add_parse_listener(RecordingParseListener {
20654 events: Arc::clone(&events),
20655 });
20656
20657 let error = parser
20658 .parse_atn_rule_with_runtime_options(
20659 &atn,
20660 0,
20661 ParserRuntimeOptions {
20662 action_indices: &[(6, 11)],
20663 ..ParserRuntimeOptions::default()
20664 },
20665 )
20666 .expect_err("the left-recursive expansion should exceed the depth cap");
20667
20668 insta::assert_debug_snapshot!(
20669 "committed_left_recursive_depth_cap_keeps_listener_events_balanced",
20670 (
20671 error.to_string(),
20672 events.lock().expect("parse-listener event lock").as_slice(),
20673 )
20674 );
20675 }
20676
20677 #[test]
20678 fn committed_walker_preserves_nested_rule_listener_events() {
20679 let atn = ordinary_star_loop_atn();
20680 let events = Arc::new(Mutex::new(Vec::new()));
20681 let mut parser = mini_parser(vec![
20682 TestToken::new(1).with_text("a"),
20683 TestToken::new(1).with_text("b"),
20684 TestToken::eof("parser-test", 2, 1, 2),
20685 ]);
20686 parser.add_parse_listener(RecordingParseListener {
20687 events: Arc::clone(&events),
20688 });
20689
20690 let (tree, _) = parser
20691 .parse_atn_rule_with_runtime_options(
20692 &atn,
20693 0,
20694 ParserRuntimeOptions {
20695 action_indices: &[(usize::MAX, 0)],
20696 ..ParserRuntimeOptions::default()
20697 },
20698 )
20699 .expect("the committed nested-rule path should parse");
20700
20701 assert_eq!(parser.node(tree).text(), "ab<EOF>");
20702 assert_eq!(
20703 *events.lock().expect("parse-listener event lock"),
20704 [
20705 "enter:0", "enter:1", "exit:1", "enter:1", "exit:1", "exit:0",
20706 ]
20707 );
20708 }
20709
20710 #[test]
20711 fn committed_walker_enforces_rule_depth_cap() {
20712 let atn = ordinary_star_loop_atn();
20713 let mut parser = mini_parser(vec![
20714 TestToken::new(1).with_text("a"),
20715 TestToken::eof("parser-test", 1, 1, 1),
20716 ]);
20717 parser.set_max_rule_depth(Some(1));
20718
20719 let error = parser
20720 .parse_atn_rule_with_runtime_options(
20721 &atn,
20722 0,
20723 ParserRuntimeOptions {
20724 action_indices: &[(usize::MAX, 0)],
20725 ..ParserRuntimeOptions::default()
20726 },
20727 )
20728 .expect_err("the nested rule should exceed the committed-path cap");
20729
20730 assert!(
20731 error
20732 .to_string()
20733 .contains("rule nesting depth limit of 1 exceeded"),
20734 "unexpected error: {error}"
20735 );
20736 }
20737
20738 #[test]
20739 fn committed_abort_precedes_and_clears_unhandled_action_error() {
20740 let atn = action_then_nested_rule_atn();
20741 let mut parser = mini_parser_with_hooks(
20742 vec![TestToken::eof("parser-test", 0, 1, 0)],
20743 DecliningActionHooks::default(),
20744 );
20745 parser.set_max_rule_depth(Some(1));
20746
20747 let error = parser
20748 .parse_atn_rule_with_runtime_options(
20749 &atn,
20750 0,
20751 ParserRuntimeOptions {
20752 action_indices: &[(0, 7)],
20753 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20754 ..ParserRuntimeOptions::default()
20755 },
20756 )
20757 .expect_err("the recovered child abort must outrank the earlier action miss");
20758
20759 assert_eq!(parser.semantic_hooks.actions, [0]);
20760 assert!(
20761 error
20762 .to_string()
20763 .contains("rule nesting depth limit of 1 exceeded"),
20764 "unexpected error: {error}"
20765 );
20766 assert!(
20767 parser.take_parse_abort().is_none(),
20768 "the returned abort must not remain sticky"
20769 );
20770 assert!(
20771 parser.take_unknown_semantic_error().is_none(),
20772 "the masked action miss must not poison parser reuse"
20773 );
20774 }
20775
20776 #[test]
20777 fn top_level_committed_semantic_error_does_not_poison_reuse() {
20778 let atn = committed_action_then_predicate_atn();
20779 let predicates = [(0, 0, ParserPredicate::True)];
20780 let mut parser = mini_parser_with_hooks(
20781 vec![
20782 TestToken::new(1).with_text("x"),
20783 TestToken::eof("parser-test", 1, 1, 1),
20784 ],
20785 DecliningActionHooks::default(),
20786 );
20787
20788 let error = parser
20789 .parse_atn_rule_with_runtime_options(
20790 &atn,
20791 0,
20792 ParserRuntimeOptions {
20793 action_indices: &[(0, 7)],
20794 predicates: &predicates,
20795 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20796 ..ParserRuntimeOptions::default()
20797 },
20798 )
20799 .expect_err("the declined committed action must fail loud");
20800 assert!(
20801 error.to_string().contains("unhandled semantic action"),
20802 "unexpected error: {error}"
20803 );
20804
20805 parser.input.seek(0);
20806 let (tree, _) = parser
20807 .parse_atn_rule_with_runtime_options(
20808 &atn,
20809 0,
20810 ParserRuntimeOptions {
20811 predicates: &predicates,
20812 ..ParserRuntimeOptions::default()
20813 },
20814 )
20815 .expect("a clean interpreted reuse must not observe the prior action miss");
20816
20817 assert_eq!(parser.node(tree).text(), "x<EOF>");
20818 assert!(
20819 parser.take_unknown_semantic_error().is_none(),
20820 "the returned top-level semantic error must drain its recorded hit"
20821 );
20822 }
20823
20824 #[test]
20825 fn committed_walker_runs_handled_rule_init_before_indexed_action() {
20826 let atn = committed_action_then_predicate_atn();
20827 let mut parser = mini_parser_with_hooks(
20828 vec![
20829 TestToken::new(1).with_text("x"),
20830 TestToken::eof("parser-test", 1, 1, 1),
20831 ],
20832 InitOrderingHooks::default(),
20833 );
20834
20835 let (_, deferred_actions) = parser
20836 .parse_atn_rule_with_runtime_options(
20837 &atn,
20838 0,
20839 ParserRuntimeOptions {
20840 init_action_rules: &[0],
20841 action_indices: &[(0, 7)],
20842 ..ParserRuntimeOptions::default()
20843 },
20844 )
20845 .expect("the named action should observe rule-init state");
20846
20847 assert!(deferred_actions.is_empty());
20848 assert_eq!(
20849 parser.semantic_hooks.events,
20850 ["init", "action:7:initialized=true", "predicate:true",]
20851 );
20852 }
20853
20854 #[test]
20855 fn committed_walker_defers_unhandled_rule_init_for_legacy_replay() {
20856 let atn = token_then_eof_atn();
20857 let mut parser = mini_parser(vec![
20858 TestToken::new(1).with_text("x"),
20859 TestToken::eof("parser-test", 1, 1, 1),
20860 ]);
20861
20862 let (_, deferred_actions) = parser
20863 .parse_atn_rule_with_runtime_options(
20864 &atn,
20865 0,
20866 ParserRuntimeOptions {
20867 init_action_rules: &[0],
20868 action_indices: &[(usize::MAX, 0)],
20869 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20870 ..ParserRuntimeOptions::default()
20871 },
20872 )
20873 .expect("a declined init should remain available for legacy replay");
20874
20875 assert_eq!(
20876 deferred_actions,
20877 [ParserAction::new_rule_init(0, 0, Some(0))]
20878 );
20879 }
20880
20881 #[test]
20882 fn committed_walker_dispatches_recovery_diagnostics() {
20883 let atn = noop_action_then_token_then_eof_atn();
20884 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20885 let mut parser = mini_parser_with_hooks(
20886 vec![
20887 TestToken::new(1).with_text("x"),
20888 TestToken::new(2).with_text("y"),
20889 TestToken::eof("parser-test", 2, 1, 2),
20890 ],
20891 StatefulActionHooks::default(),
20892 );
20893 parser.remove_error_listeners();
20894 parser.add_error_listener(RecordingErrorListener {
20895 diagnostics: Arc::clone(&diagnostics),
20896 });
20897
20898 let (tree, _) = parser
20899 .parse_atn_rule_with_runtime_options(
20900 &atn,
20901 0,
20902 ParserRuntimeOptions {
20903 action_indices: &[(0, 5)],
20904 ..ParserRuntimeOptions::default()
20905 },
20906 )
20907 .expect("the committed rule should recover");
20908
20909 assert_eq!(parser.node(tree).text(), "xy<EOF>");
20910 assert_eq!(parser.number_of_syntax_errors(), 1);
20911 insta::assert_debug_snapshot!(
20912 "committed_walker_dispatches_recovery_diagnostics",
20913 *diagnostics.lock().expect("recorded diagnostics lock")
20914 );
20915 }
20916
20917 #[test]
20918 fn committed_bail_error_notifies_error_listener() {
20919 let atn = noop_action_then_token_then_eof_atn();
20920 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20921 let mut parser = mini_parser(vec![
20922 TestToken::new(2)
20923 .with_text("y")
20924 .with_span(0, 0)
20925 .with_byte_span(0, 1)
20926 .with_position(3, 5),
20927 TestToken::eof("parser-test", 1, 1, 1),
20928 ]);
20929 parser.set_bail_on_error(true);
20930 parser.remove_error_listeners();
20931 parser.add_error_listener(RecordingErrorListener {
20932 diagnostics: Arc::clone(&diagnostics),
20933 });
20934
20935 let error = parser
20936 .parse_atn_rule_with_runtime_options(
20937 &atn,
20938 0,
20939 ParserRuntimeOptions {
20940 action_indices: &[(0, 5)],
20941 ..ParserRuntimeOptions::default()
20942 },
20943 )
20944 .expect_err("bail mode must return the committed token mismatch");
20945 let diagnostics = diagnostics
20946 .lock()
20947 .expect("recorded diagnostics lock")
20948 .clone();
20949
20950 insta::assert_debug_snapshot!(
20951 "committed_bail_error_notifies_error_listener",
20952 (error, diagnostics)
20953 );
20954 }
20955
20956 #[test]
20957 fn semantic_hook_handles_committed_parser_action() {
20958 let atn = token_then_eof_atn();
20959 let mut parser = mini_parser_with_hooks(
20960 vec![
20961 TestToken::new(1).with_text("x"),
20962 TestToken::eof("parser-test", 1, 1, 1),
20963 ],
20964 RecordingHooks::default(),
20965 );
20966 let (tree, _) = parser
20967 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
20968 .expect("rule parses before action hook is tested");
20969
20970 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20971 assert_eq!(
20972 parser.semantic_hooks.actions,
20973 vec![(42, "x".to_owned(), Some("s".to_owned()))]
20974 );
20975 assert_eq!(
20976 parser.semantic_hooks.action_trees,
20977 [Some("x<EOF>".to_owned())]
20978 );
20979 }
20980
20981 #[test]
20982 fn unhandled_committed_action_fails_loud_under_error_policy() {
20983 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
20987 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
20988 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
20989
20990 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20992
20993 let error = parser
20994 .take_unknown_semantic_error()
20995 .expect("an unhandled committed action under Error policy must fail loud");
20996 let AntlrError::Unsupported(message) = error else {
20997 panic!("expected AntlrError::Unsupported, got {error:?}");
20998 };
20999 assert!(
21000 message.contains("unhandled semantic action") && message.contains("state=42"),
21001 "message should name the dropped action coordinate: {message}"
21002 );
21003
21004 let mut lenient =
21006 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21007 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
21008 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
21009 assert!(lenient.take_unknown_semantic_error().is_none());
21010 }
21011
21012 #[test]
21013 fn translated_predicate_is_unaffected_by_error_policy() {
21014 let atn = predicate_after_token_atn();
21015 let mut parser = mini_parser(vec![
21016 TestToken::new(1).with_text("x"),
21017 TestToken::new(2).with_text("y"),
21018 TestToken::eof("parser-test", 2, 1, 2),
21019 ]);
21020
21021 let (tree, _) = parser
21022 .parse_atn_rule_with_runtime_options(
21023 &atn,
21024 0,
21025 ParserRuntimeOptions {
21026 predicates: &[(0, 0, ParserPredicate::True)],
21027 unknown_predicate_policy: UnknownSemanticPolicy::Error,
21028 ..ParserRuntimeOptions::default()
21029 },
21030 )
21031 .expect("a predicate covered by the table is not an unknown coordinate");
21032
21033 assert_eq!(parser.node(tree).text(), "xy");
21034 }
21035
21036 #[test]
21041 fn parser_speculative_replay_threads_stack_member_state() {
21042 let mut ir = SemIr::new();
21043 let one = ir.expr(PExpr::Int(1));
21044 let push = ir.stmt(AStmt::PushMember(0, one));
21045 let pop = ir.stmt(AStmt::PopMember(0));
21046 let semantics = ParserSemantics {
21047 ir,
21048 predicates: Vec::new(),
21049 actions: vec![
21050 ParserSemanticAction {
21051 source_state: 1,
21052 rule_index: usize::MAX,
21053 stmt: push,
21054 speculative: true,
21055 },
21056 ParserSemanticAction {
21057 source_state: 2,
21058 rule_index: usize::MAX,
21059 stmt: pop,
21060 speculative: true,
21061 },
21062 ],
21063 };
21064
21065 let pushed = member_values_after_action(1, &[], Some(&semantics), &MemberEnv::new());
21067 assert_eq!(pushed.stack_top(0), Some(1));
21068 assert_eq!(pushed.stack_len(0), 1);
21069
21070 assert_eq!(MemberEnv::new().stack_len(0), 0);
21073
21074 let popped = member_values_after_action(2, &[], Some(&semantics), &pushed);
21077 assert_eq!(popped.stack_top(0), None);
21078 assert_eq!(popped, MemberEnv::new(), "emptied stack must canonicalize");
21079
21080 let underflowed = member_values_after_action(2, &[], Some(&semantics), &MemberEnv::new());
21082 assert_eq!(underflowed, MemberEnv::new());
21083 }
21084
21085 fn hook_predicate_semantics() -> ParserSemantics {
21090 let mut ir = SemIr::new();
21091 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
21092 ParserSemantics {
21093 ir,
21094 predicates: vec![ParserSemanticPredicate {
21095 rule_index: 0,
21096 pred_index: 0,
21097 expr,
21098 failure_message: None,
21099 }],
21100 actions: Vec::new(),
21101 }
21102 }
21103
21104 #[derive(Debug, Default)]
21105 struct DecliningHooks;
21106
21107 impl SemanticHooks for DecliningHooks {}
21108
21109 #[test]
21110 fn semir_hook_none_falls_through_to_assume_true() {
21111 let atn = predicate_after_token_atn();
21112 let semantics = hook_predicate_semantics();
21113 let mut parser = mini_parser_with_hooks(
21114 vec![
21115 TestToken::new(1).with_text("x"),
21116 TestToken::new(2).with_text("y"),
21117 TestToken::eof("parser-test", 2, 1, 2),
21118 ],
21119 DecliningHooks,
21120 );
21121
21122 let (tree, _) = parser
21123 .parse_atn_rule_with_runtime_options(
21124 &atn,
21125 0,
21126 ParserRuntimeOptions {
21127 semantics: Some(&semantics),
21128 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
21129 ..ParserRuntimeOptions::default()
21130 },
21131 )
21132 .expect("a declined SemIR hook must pass under assume-true");
21133
21134 assert_eq!(parser.node(tree).text(), "xy");
21135 }
21136
21137 #[test]
21138 fn semir_hook_none_falls_through_to_assume_false() {
21139 let atn = predicate_after_token_atn();
21140 let semantics = hook_predicate_semantics();
21141 let mut parser = mini_parser_with_hooks(
21142 vec![
21143 TestToken::new(1).with_text("x"),
21144 TestToken::new(2).with_text("y"),
21145 TestToken::eof("parser-test", 2, 1, 2),
21146 ],
21147 DecliningHooks,
21148 );
21149
21150 let result = parser.parse_atn_rule_with_runtime_options(
21151 &atn,
21152 0,
21153 ParserRuntimeOptions {
21154 semantics: Some(&semantics),
21155 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
21156 ..ParserRuntimeOptions::default()
21157 },
21158 );
21159
21160 assert!(
21161 result.is_err(),
21162 "a declined SemIR hook must fail the only guarded path under assume-false"
21163 );
21164 }
21165
21166 #[test]
21167 fn semir_hook_none_records_coordinate_under_error_policy() {
21168 let atn = predicate_after_token_atn();
21169 let semantics = hook_predicate_semantics();
21170 let mut parser = mini_parser_with_hooks(
21171 vec![
21172 TestToken::new(1).with_text("x"),
21173 TestToken::new(2).with_text("y"),
21174 TestToken::eof("parser-test", 2, 1, 2),
21175 ],
21176 DecliningHooks,
21177 );
21178
21179 let error = parser
21180 .parse_atn_rule_with_runtime_options(
21181 &atn,
21182 0,
21183 ParserRuntimeOptions {
21184 semantics: Some(&semantics),
21185 unknown_predicate_policy: UnknownSemanticPolicy::Error,
21186 ..ParserRuntimeOptions::default()
21187 },
21188 )
21189 .expect_err("a declined SemIR hook under Error policy must fail the parse");
21190
21191 let AntlrError::Unsupported(message) = error else {
21192 panic!("expected AntlrError::Unsupported, got {error:?}");
21193 };
21194 assert!(
21195 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
21196 "message should name the unresolved coordinate: {message}"
21197 );
21198 }
21199
21200 #[test]
21201 fn generated_direct_predicate_honors_installed_policy() {
21202 let semantics = hook_predicate_semantics();
21208 let context = ParserRuleContext::new(0, -1);
21209
21210 let mut assume_true =
21211 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21212 assert!(
21213 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
21214 &semantics, 0, 0, &context, 0
21215 ),
21216 "default AssumeTrue accepts a declined hook"
21217 );
21218 assert!(assume_true.take_unknown_semantic_error().is_none());
21219
21220 let mut error_policy =
21221 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
21222 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
21223 assert!(
21224 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
21225 &semantics, 0, 0, &context, 0
21226 ),
21227 "Error policy rejects a declined hook on the generated-direct path"
21228 );
21229 let error = error_policy
21230 .take_unknown_semantic_error()
21231 .expect("Error policy records the unresolved coordinate for the generated path");
21232 let AntlrError::Unsupported(message) = error else {
21233 panic!("expected AntlrError::Unsupported, got {error:?}");
21234 };
21235 assert!(message.contains("pred_index=0"), "message: {message}");
21236 }
21237
21238 #[test]
21239 fn parser_rule_start_skips_leading_hidden_tokens() {
21240 let atn = token_then_eof_atn();
21241 let mut parser = mini_parser(vec![
21242 TestToken::new(99)
21243 .with_text(" ")
21244 .with_channel(HIDDEN_CHANNEL),
21245 TestToken::new(1).with_text("x"),
21246 TestToken::eof("parser-test", 2, 1, 2),
21247 ]);
21248
21249 let tree = parser
21250 .parse_atn_rule(&atn, 0)
21251 .expect("artificial parser rule should parse");
21252 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
21253 panic!("rule node should be present");
21254 };
21255 assert_eq!(
21256 rule.start()
21257 .expect("rule should have a start token")
21258 .token_type(),
21259 1
21260 );
21261 }
21262
21263 #[test]
21264 fn parser_action_after_eof_stops_at_eof_token() {
21265 let atn = eof_then_action_atn();
21266 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
21267
21268 let (_, actions) = parser
21269 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
21270 .expect("EOF action rule should parse");
21271
21272 assert_eq!(actions.len(), 1);
21273 assert_eq!(actions[0].stop_index(), Some(0));
21274 assert_eq!(
21275 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
21276 ""
21277 );
21278 }
21279
21280 #[test]
21281 fn after_action_stop_uses_rule_context_stop_not_cursor() {
21282 let mut id = TestToken::new(1).with_text("x");
21287 id.set_token_index(0);
21288 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
21289 eof.set_token_index(1);
21290 let mut parser = mini_parser(vec![id.clone(), eof]);
21291 parser.consume();
21293 assert_eq!(parser.la(1), TOKEN_EOF);
21294
21295 let mut ctx = ParserRuleContext::new(0, 0);
21298 parser.set_context_stop(
21299 &mut ctx,
21300 parser.token_id_at(0).expect("ID token should be buffered"),
21301 );
21302 let tree = parser.rule_node(ctx);
21303
21304 let current_index = parser.input.index();
21305 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
21307 assert_eq!(
21309 parser.after_action_stop_index_for_tree(tree, current_index),
21310 Some(0)
21311 );
21312 }
21313
21314 #[test]
21315 fn after_action_start_uses_rule_context_start_not_cursor() {
21316 let mut parser = mini_parser(vec![
21321 TestToken::new(9)
21322 .with_text(" ")
21323 .with_channel(HIDDEN_CHANNEL),
21324 TestToken::new(9)
21325 .with_text(" ")
21326 .with_channel(HIDDEN_CHANNEL),
21327 TestToken::new(1).with_text("x"),
21328 TestToken::eof("parser-test", 3, 1, 3),
21329 ]);
21330
21331 let mut ctx = ParserRuleContext::new(0, 0);
21332 parser.set_context_start(
21333 &mut ctx,
21334 parser.token_id_at(2).expect("ID token should be buffered"),
21335 );
21336 let tree = parser.rule_node(ctx);
21337
21338 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
21341
21342 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
21344 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
21345 }
21346
21347 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
21348 FastRecognizeOutcome {
21349 index,
21350 consumed_eof,
21351 diagnostics: DiagnosticSeqId::EMPTY,
21352 deferred_nodes: FastDeferredNodeId::EMPTY,
21353 nodes: NodeSeqId(marker),
21354 }
21355 }
21356
21357 #[test]
21358 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
21359 let mut outcomes = vec![
21360 clean_fast_outcome(4, false, 0),
21361 clean_fast_outcome(2, false, 1),
21362 clean_fast_outcome(4, false, 2),
21363 clean_fast_outcome(4, true, 3),
21364 clean_fast_outcome(2, false, 4),
21365 ];
21366 let mut scratch = FastOutcomeDedupScratch::default();
21367
21368 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21369
21370 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
21371 assert_eq!(
21372 outcomes
21373 .iter()
21374 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
21375 .collect::<Vec<_>>(),
21376 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
21377 );
21378 assert!(scratch.dense_words.is_empty());
21379 assert!(scratch.sparse_keys.is_empty());
21380 }
21381
21382 #[test]
21383 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
21384 let mut scratch = FastOutcomeDedupScratch::default();
21385 let mut outcomes = (100..109)
21386 .flat_map(|index| {
21387 [
21388 clean_fast_outcome(
21389 index,
21390 false,
21391 u32::try_from(index).expect("test index fits in u32"),
21392 ),
21393 clean_fast_outcome(index, false, u32::MAX),
21394 ]
21395 })
21396 .collect();
21397
21398 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21399
21400 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
21401 assert_eq!(outcomes.len(), 9);
21402 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
21403 let dense_capacity = scratch.dense_words.capacity();
21404
21405 let mut reused = (1_000..1_009)
21406 .map(|index| {
21407 clean_fast_outcome(
21408 index,
21409 false,
21410 u32::try_from(index).expect("test index fits in u32"),
21411 )
21412 })
21413 .collect();
21414 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
21415
21416 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
21417 assert_eq!(reused.len(), 9);
21418 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
21419 }
21420
21421 #[test]
21422 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
21423 let mut scratch = FastOutcomeDedupScratch::default();
21424 let sparse_indexes = [
21425 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
21426 ];
21427 let mut outcomes = sparse_indexes
21428 .into_iter()
21429 .chain([400_000])
21430 .enumerate()
21431 .map(|(marker, index)| {
21432 clean_fast_outcome(
21433 index,
21434 false,
21435 u32::try_from(marker).expect("test marker fits in u32"),
21436 )
21437 })
21438 .collect();
21439
21440 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21441
21442 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21443 assert_eq!(outcomes.len(), sparse_indexes.len());
21444 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
21445 let sparse_capacity = scratch.sparse_keys.capacity();
21446
21447 let mut reused = sparse_indexes
21448 .into_iter()
21449 .map(|index| {
21450 clean_fast_outcome(
21451 index,
21452 false,
21453 u32::try_from(index).expect("test index fits in u32"),
21454 )
21455 })
21456 .collect();
21457 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
21458
21459 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21460 assert_eq!(reused.len(), sparse_indexes.len());
21461 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
21462 }
21463
21464 #[test]
21465 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
21466 let mut scratch = FastOutcomeDedupScratch::default();
21467 scratch
21468 .sparse_keys
21469 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
21470 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
21471 let mut outcomes = (0..9)
21472 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
21473 .collect();
21474
21475 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21476
21477 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21478 assert!(scratch.sparse_keys.is_empty());
21479 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
21480 }
21481
21482 #[test]
21483 fn fast_outcome_selection_respects_sll_tie_order() {
21484 let mut arena = RecognitionArena::default();
21485 let first = FastRecognizeOutcome {
21486 index: 1,
21487 consumed_eof: false,
21488 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21489 line: 1,
21490 column: 0,
21491 message: "mismatched input 'x'".to_owned(),
21492 offending: None,
21493 }]),
21494 deferred_nodes: FastDeferredNodeId::EMPTY,
21495 nodes: NodeSeqId::EMPTY,
21496 };
21497 let second = FastRecognizeOutcome {
21498 index: first.index,
21499 consumed_eof: first.consumed_eof,
21500 diagnostics: DiagnosticSeqId::EMPTY,
21501 deferred_nodes: FastDeferredNodeId::EMPTY,
21502 nodes: NodeSeqId::EMPTY,
21503 };
21504
21505 let selected = select_best_fast_outcome(
21506 [first, second].into_iter(),
21507 PredictionMode::Sll,
21508 None,
21509 |_| panic!("caller-follow token probe should not run"),
21510 &arena,
21511 )
21512 .expect("one outcome should be selected");
21513 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
21514 let eof_second = FastRecognizeOutcome {
21515 index: second.index,
21516 consumed_eof: true,
21517 diagnostics: DiagnosticSeqId::EMPTY,
21518 deferred_nodes: FastDeferredNodeId::EMPTY,
21519 nodes: NodeSeqId::EMPTY,
21520 };
21521 let selected = select_best_fast_outcome(
21522 [first, eof_second].into_iter(),
21523 PredictionMode::Sll,
21524 None,
21525 |_| panic!("caller-follow token probe should not run"),
21526 &arena,
21527 )
21528 .expect("one outcome should be selected");
21529 assert!(!selected.consumed_eof);
21530 let selected = select_best_fast_outcome(
21531 [first, second].into_iter(),
21532 PredictionMode::Ll,
21533 None,
21534 |_| panic!("caller-follow token probe should not run"),
21535 &arena,
21536 )
21537 .expect("one outcome should be selected");
21538 assert!(selected.diagnostics.is_empty());
21539 }
21540
21541 #[test]
21542 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
21543 let mut arena = RecognitionArena::default();
21544 let first = FastRecognizeOutcome {
21545 index: 3,
21546 consumed_eof: false,
21547 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21548 line: 1,
21549 column: 0,
21550 message: "mismatched input 'x' expecting 'a'".to_owned(),
21551 offending: None,
21552 }]),
21553 deferred_nodes: FastDeferredNodeId::EMPTY,
21554 nodes: NodeSeqId::EMPTY,
21555 };
21556 let same_rank = FastRecognizeOutcome {
21557 index: first.index,
21558 consumed_eof: first.consumed_eof,
21559 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21560 line: 1,
21561 column: 0,
21562 message: "mismatched input 'x' expecting 'b'".to_owned(),
21563 offending: None,
21564 }]),
21565 deferred_nodes: FastDeferredNodeId::EMPTY,
21566 nodes: NodeSeqId::EMPTY,
21567 };
21568 let better_rank = FastRecognizeOutcome {
21569 index: first.index,
21570 consumed_eof: first.consumed_eof,
21571 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21572 line: 1,
21573 column: 0,
21574 message: "missing 'a' at 'x'".to_owned(),
21575 offending: None,
21576 }]),
21577 deferred_nodes: FastDeferredNodeId::EMPTY,
21578 nodes: NodeSeqId::EMPTY,
21579 };
21580 let mut outcomes = vec![first, same_rank, better_rank];
21581
21582 dedupe_fast_outcomes(&mut outcomes, &arena);
21583
21584 assert_eq!(outcomes.len(), 2);
21585 assert_eq!(
21586 arena
21587 .diagnostics(outcomes[0].diagnostics)
21588 .next()
21589 .expect("first diagnostic")
21590 .message,
21591 "mismatched input 'x' expecting 'a'"
21592 );
21593 assert_eq!(
21594 arena
21595 .diagnostics(outcomes[1].diagnostics)
21596 .next()
21597 .expect("second diagnostic")
21598 .message,
21599 "missing 'a' at 'x'"
21600 );
21601 }
21602
21603 #[test]
21604 fn fast_outcome_selection_prefers_generated_caller_follow() {
21605 let arena = RecognitionArena::default();
21606 let earlier = FastRecognizeOutcome {
21607 index: 7,
21608 consumed_eof: false,
21609 diagnostics: DiagnosticSeqId::EMPTY,
21610 deferred_nodes: FastDeferredNodeId::EMPTY,
21611 nodes: NodeSeqId::EMPTY,
21612 };
21613 let later = FastRecognizeOutcome {
21614 index: 8,
21615 consumed_eof: false,
21616 diagnostics: DiagnosticSeqId::EMPTY,
21617 deferred_nodes: FastDeferredNodeId::EMPTY,
21618 nodes: NodeSeqId::EMPTY,
21619 };
21620 let mut follow = TokenBitSet::default();
21621 follow.insert(5);
21622
21623 let selected = select_best_fast_outcome(
21624 [later, earlier].into_iter(),
21625 PredictionMode::Ll,
21626 Some(&follow),
21627 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
21628 &arena,
21629 )
21630 .expect("one outcome should be selected");
21631 assert_eq!(selected.index, 7);
21632
21633 let selected = select_best_fast_outcome(
21634 [later, earlier].into_iter(),
21635 PredictionMode::Ll,
21636 Some(&follow),
21637 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
21638 &arena,
21639 )
21640 .expect("one outcome should be selected");
21641 assert_eq!(selected.index, 8);
21642
21643 let indented_next_statement = FastRecognizeOutcome {
21644 index: 9,
21645 consumed_eof: false,
21646 diagnostics: DiagnosticSeqId::EMPTY,
21647 deferred_nodes: FastDeferredNodeId::EMPTY,
21648 nodes: NodeSeqId::EMPTY,
21649 };
21650 let selected = select_best_fast_outcome(
21651 [indented_next_statement, earlier].into_iter(),
21652 PredictionMode::Ll,
21653 Some(&follow),
21654 |index| {
21655 let is_boundary = index == 7;
21656 let is_boundary_gap = matches!(index, 7 | 8);
21657 (
21658 if index == 7 { 5 } else { TOKEN_EOF },
21659 is_boundary,
21660 is_boundary_gap,
21661 )
21662 },
21663 &arena,
21664 )
21665 .expect("one outcome should be selected");
21666 assert_eq!(selected.index, 7);
21667
21668 let continuation = FastRecognizeOutcome {
21669 index: 10,
21670 consumed_eof: false,
21671 diagnostics: DiagnosticSeqId::EMPTY,
21672 deferred_nodes: FastDeferredNodeId::EMPTY,
21673 nodes: NodeSeqId::EMPTY,
21674 };
21675 let selected = select_best_fast_outcome(
21676 [continuation, earlier].into_iter(),
21677 PredictionMode::Ll,
21678 Some(&follow),
21679 |index| {
21680 let is_boundary = matches!(index, 7 | 9);
21681 (
21682 if index == 7 { 5 } else { TOKEN_EOF },
21683 is_boundary,
21684 is_boundary,
21685 )
21686 },
21687 &arena,
21688 )
21689 .expect("one outcome should be selected");
21690 assert_eq!(selected.index, 10);
21691
21692 let selected = select_best_fast_outcome(
21693 [earlier, later].into_iter(),
21694 PredictionMode::Sll,
21695 Some(&follow),
21696 |_| panic!("caller-follow token probe should not run in SLL mode"),
21697 &arena,
21698 )
21699 .expect("one outcome should be selected");
21700 assert_eq!(selected.index, 8);
21701 }
21702
21703 #[test]
21704 fn caller_follow_boundary_text_requires_separator_shape() {
21705 assert!(is_caller_follow_boundary_text(";"));
21706 assert!(is_caller_follow_boundary_text("\n"));
21707 assert!(is_caller_follow_boundary_text("\r\n "));
21708 assert!(is_caller_follow_boundary_text(";\n"));
21709 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
21710 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
21711 assert!(!is_caller_follow_boundary_text("identifier"));
21712 assert!(is_caller_follow_boundary_gap_text(" \t "));
21713 assert!(is_caller_follow_boundary_gap_text("\n "));
21714 assert!(is_caller_follow_boundary_gap_text(";\t"));
21715 assert!(!is_caller_follow_boundary_gap_text(
21716 "\"\"\"line1\nline2\"\"\""
21717 ));
21718 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
21719 }
21720
21721 #[test]
21722 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
21723 let mut parser = mini_parser(vec![
21724 TestToken::new(5).with_text("\n"),
21725 TestToken::new(6)
21726 .with_text("// comment\n")
21727 .with_channel(HIDDEN_CHANNEL),
21728 TestToken::new(1).with_text("x"),
21729 TestToken::eof("parser-test", 1, 2, 0),
21730 ]);
21731
21732 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
21733 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
21734 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
21735 }
21736
21737 #[test]
21738 fn caller_follow_token_info_uses_stream_visible_channel() {
21739 let source = Source {
21740 tokens: vec![
21741 TestToken::new(5).with_text("\n").with_channel(2),
21742 TestToken::new(1).with_text("x").with_channel(2),
21743 TestToken::new(6)
21744 .with_text("// comment\n")
21745 .with_channel(HIDDEN_CHANNEL),
21746 TestToken::eof("parser-test", 1, 2, 0),
21747 ],
21748 index: 0,
21749 };
21750 let data = RecognizerData::new(
21751 "Mini.g4",
21752 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21753 );
21754 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
21755
21756 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
21757 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
21758 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
21759 }
21760
21761 #[test]
21762 fn reset_per_parse_caches_clears_state_expected_token_cache() {
21763 let atn = token_then_eof_atn();
21764 let mut parser = mini_parser(Vec::new());
21765
21766 let _ = parser.cached_state_expected_token_set(&atn, 0);
21767 assert!(!parser.state_expected_token_cache.is_empty());
21768
21769 parser.reset_per_parse_caches();
21770 assert!(parser.state_expected_token_cache.is_empty());
21771 }
21772
21773 #[test]
21774 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
21775 let cyclic = epsilon_cycle_atn();
21776 let acyclic = token_then_eof_atn();
21777 let mut parser = mini_parser(Vec::new());
21778
21779 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
21780 assert_eq!(
21781 parser.empty_cycle_cache_atn,
21782 Some(SharedAtnCacheKey::for_atn(&cyclic))
21783 );
21784 assert_eq!(parser.empty_cycle_cache[1], Some(true));
21785
21786 parser.reset_per_parse_caches();
21787 assert_eq!(parser.empty_cycle_cache[1], Some(true));
21788 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
21789
21790 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
21791 assert_eq!(
21792 parser.empty_cycle_cache_atn,
21793 Some(SharedAtnCacheKey::for_atn(&acyclic))
21794 );
21795 assert_eq!(parser.empty_cycle_cache[1], Some(false));
21796 }
21797
21798 #[test]
21799 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
21800 let source = Source {
21801 tokens: vec![
21802 TestToken::new(1).with_text("x"),
21803 TestToken::eof("parser-test", 1, 1, 1),
21804 ],
21805 index: 0,
21806 };
21807 let data = RecognizerData::new(
21808 "Mini.g4",
21809 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21810 );
21811 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
21812 let expected = ExpectedTokens {
21813 index: Some(0),
21814 symbols: BTreeSet::new(),
21815 no_viable: None,
21816 };
21817
21818 let (_, message) = parser.expected_error_message(0, 0, &expected);
21819
21820 assert_eq!(message, "mismatched input 'x'");
21821 }
21822
21823 #[test]
21824 fn eof_rule_stop_index_points_at_eof_token() {
21825 let source = Source {
21826 tokens: vec![
21827 TestToken::new(1).with_text("x"),
21828 TestToken::eof("parser-test", 1, 1, 1),
21829 ],
21830 index: 0,
21831 };
21832 let data = RecognizerData::new(
21833 "Mini.g4",
21834 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21835 );
21836 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
21837
21838 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
21839 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
21840 }
21841
21842 #[test]
21843 fn generated_parser_action_uses_current_rule_stop_boundary() {
21844 let mut parser = mini_parser(vec![
21845 TestToken::new(1).with_text("x"),
21846 TestToken::eof("parser-test", 1, 1, 1),
21847 ]);
21848
21849 parser.match_token(1).expect("token should match");
21850 let action = parser.parser_action_at_current(7, 0, 0, false);
21851 assert_eq!(action.source_state(), 7);
21852 assert_eq!(action.rule_index(), 0);
21853 assert_eq!(action.start_index(), 0);
21854 assert_eq!(action.stop_index(), Some(0));
21855
21856 parser.match_eof().expect("EOF should match");
21857 let action = parser.parser_action_at_current(8, 0, 0, true);
21858 assert_eq!(action.stop_index(), Some(1));
21859 }
21860
21861 #[test]
21862 fn folds_left_recursive_boundary_into_rule_node() {
21863 let mut arena = RecognitionArena::default();
21864 let first = arena.push_node(ArenaRecognizedNode::Token {
21865 token: TokenId::try_from(0).expect("test token ID"),
21866 });
21867 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
21868 rule_index: 1,
21869 alt_number: 3,
21870 });
21871 let second = arena.push_node(ArenaRecognizedNode::Token {
21872 token: TokenId::try_from(1).expect("test token ID"),
21873 });
21874 let mut nodes = NodeSeqId::EMPTY;
21875 for node in [first, boundary, second].into_iter().rev() {
21876 nodes = arena.prepend(nodes, node);
21877 }
21878
21879 let folded = arena.fold_left_recursive_boundaries(nodes);
21880 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
21881
21882 assert_eq!(folded_nodes.len(), 2);
21883 let ArenaRecognizedNode::Rule {
21884 rule_index,
21885 invoking_state,
21886 alt_number,
21887 start_index,
21888 stop_index,
21889 children,
21890 ..
21891 } = arena.node(folded_nodes[0])
21892 else {
21893 panic!("first folded node should be a rule");
21894 };
21895 insta::assert_debug_snapshot!(
21899 "folds_left_recursive_boundary_into_rule_node",
21900 (
21901 rule_index,
21902 invoking_state,
21903 alt_number,
21904 start_index,
21905 stop_index
21906 )
21907 );
21908 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
21909 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
21910
21911 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
21912 assert_eq!(
21913 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
21914 (4, 3, 1)
21915 );
21916 assert_eq!(
21917 (stats.total_links, stats.live_links, stats.dead_links),
21918 (9, 3, 6)
21919 );
21920 }
21921
21922 #[test]
21923 fn recognition_arena_reports_live_dead_and_retained_capacity() {
21924 let mut arena = RecognitionArena::default();
21925 let token = arena.push_node(ArenaRecognizedNode::Token {
21926 token: TokenId::try_from(0).expect("test token ID"),
21927 });
21928 let extra = arena.push_extra(RecognitionExtra::MissingToken {
21929 token_type: 2,
21930 at_index: 1,
21931 text: "<missing X>".to_owned(),
21932 });
21933 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
21934 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
21935 token: TokenId::try_from(1).expect("test token ID"),
21936 });
21937 let mut live = NodeSeqId::EMPTY;
21938 live = arena.prepend(live, missing);
21939 live = arena.prepend(live, token);
21940 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
21941 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
21942 line: 1,
21943 column: 0,
21944 message: "missing X".to_owned(),
21945 offending: None,
21946 }]);
21947 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
21948 line: 1,
21949 column: 1,
21950 message: "discarded".to_owned(),
21951 offending: None,
21952 }]);
21953 let deferred_children = arena.deferred_fragment(live);
21954 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
21955 rule_index: 0,
21956 invoking_state: -1,
21957 start_index: 0,
21958 stop_index: Some(1),
21959 deferred_children,
21960 children: NodeSeqId::EMPTY,
21961 });
21962
21963 let stats = arena.stats(live, live_diagnostics);
21964
21965 assert_eq!(
21966 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
21967 (3, 2, 1)
21968 );
21969 assert_eq!(
21970 (stats.total_links, stats.live_links, stats.dead_links),
21971 (5, 3, 2)
21972 );
21973 assert_eq!(
21974 (stats.total_extras, stats.live_extras, stats.dead_extras),
21975 (3, 2, 1)
21976 );
21977 assert!(size_of::<SeqLink>() <= 8);
21978 assert!(size_of::<DiagnosticLink>() <= 8);
21979 assert!(size_of::<FastDeferredNode>() <= 12);
21980 assert!(size_of::<FastDeferredRule>() <= 28);
21981 assert!(size_of::<FastRecognizeOutcome>() <= 24);
21982 let capacities = (
21983 stats.node_capacity,
21984 stats.link_capacity,
21985 stats.extra_capacity,
21986 );
21987 let deferred_capacities = (
21988 arena.deferred_nodes.capacity(),
21989 arena.deferred_rules.capacity(),
21990 );
21991
21992 arena.reset();
21993 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
21994 assert_eq!(
21995 (reset.total_nodes, reset.total_links, reset.total_extras),
21996 (0, 0, 0)
21997 );
21998 assert_eq!(
21999 (
22000 reset.node_capacity,
22001 reset.link_capacity,
22002 reset.extra_capacity,
22003 ),
22004 capacities
22005 );
22006 assert!(arena.deferred_nodes.is_empty());
22007 assert!(arena.deferred_rules.is_empty());
22008 assert_eq!(
22009 (
22010 arena.deferred_nodes.capacity(),
22011 arena.deferred_rules.capacity(),
22012 ),
22013 deferred_capacities
22014 );
22015 }
22016
22017 #[test]
22018 fn parser_computes_recognition_arena_stats_on_demand() {
22019 let mut parser = mini_parser(Vec::new());
22020 let live = parser
22021 .recognition_arena
22022 .push_node(ArenaRecognizedNode::Token {
22023 token: TokenId::try_from(0).expect("test token ID"),
22024 });
22025 let discarded = parser
22026 .recognition_arena
22027 .push_node(ArenaRecognizedNode::ErrorToken {
22028 token: TokenId::try_from(1).expect("test token ID"),
22029 });
22030 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
22031 let _discarded_root = parser
22032 .recognition_arena
22033 .prepend(NodeSeqId::EMPTY, discarded);
22034 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
22035
22036 let stats = parser.recognition_arena_stats();
22037
22038 assert_eq!(
22039 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
22040 (2, 1, 1)
22041 );
22042 assert_eq!(
22043 (stats.total_links, stats.live_links, stats.dead_links),
22044 (2, 1, 1)
22045 );
22046 }
22047
22048 #[test]
22049 fn recognition_arena_drops_capacity_above_retention_limit() {
22050 let mut storage = Vec::<u8>::with_capacity(4);
22051 storage.extend([1, 2, 3]);
22052
22053 reset_arena_vec(&mut storage, 3);
22054
22055 assert!(storage.is_empty());
22056 assert_eq!(storage.capacity(), 0);
22057 }
22058
22059 #[test]
22060 fn recognition_arena_concatenates_diagnostics_in_source_order() {
22061 let mut arena = RecognitionArena::default();
22062 let prefix = arena.diagnostic_sequence([
22063 ParserDiagnostic {
22064 line: 1,
22065 column: 0,
22066 message: "first".to_owned(),
22067 offending: None,
22068 },
22069 ParserDiagnostic {
22070 line: 1,
22071 column: 1,
22072 message: "second".to_owned(),
22073 offending: None,
22074 },
22075 ]);
22076 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
22077 line: 1,
22078 column: 2,
22079 message: "third".to_owned(),
22080 offending: None,
22081 }]);
22082 let extras_before = arena.extras.len();
22083
22084 let combined = arena.concat_diagnostics(prefix, suffix);
22085 let messages = arena
22086 .diagnostics(combined)
22087 .map(|diagnostic| diagnostic.message.as_str())
22088 .collect::<Vec<_>>();
22089
22090 assert_eq!(messages, ["first", "second", "third"]);
22091 assert_eq!(arena.extras.len(), extras_before);
22092 }
22093
22094 #[test]
22095 fn outcome_ties_keep_later_non_recursive_alternative() {
22096 let arena = RecognitionArena::default();
22097 let first = RecognizeOutcome {
22098 index: 1,
22099 consumed_eof: false,
22100 alt_number: 0,
22101 member_values: MemberEnv::new(),
22102 return_values: BTreeMap::new(),
22103 diagnostics: DiagnosticSeqId::EMPTY,
22104 decisions: Vec::new(),
22105 actions: vec![ParserAction::new(1, 0, 0, None)],
22106 nodes: NodeSeqId::EMPTY,
22107 };
22108 let second = RecognizeOutcome {
22109 actions: vec![ParserAction::new(2, 0, 0, None)],
22110 ..first.clone()
22111 };
22112
22113 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22114 .expect("one outcome should be selected");
22115 assert_eq!(selected.actions[0].source_state(), 2);
22116 }
22117
22118 #[test]
22119 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
22120 let arena = RecognitionArena::default();
22121 let first = RecognizeOutcome {
22122 index: 1,
22123 consumed_eof: false,
22124 alt_number: 0,
22125 member_values: MemberEnv::new(),
22126 return_values: BTreeMap::new(),
22127 diagnostics: DiagnosticSeqId::EMPTY,
22128 decisions: Vec::new(),
22129 actions: vec![ParserAction::new(1, 0, 0, None)],
22130 nodes: NodeSeqId::EMPTY,
22131 };
22132 let second = RecognizeOutcome {
22133 actions: vec![
22134 ParserAction::new(2, 0, 0, None),
22135 ParserAction::new(3, 0, 0, None),
22136 ],
22137 ..first.clone()
22138 };
22139
22140 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
22141 .expect("one outcome should be selected");
22142 assert_eq!(selected.actions.len(), 2);
22143 }
22144
22145 #[test]
22146 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
22147 let arena = RecognitionArena::default();
22148 let first = RecognizeOutcome {
22149 index: 7,
22150 consumed_eof: false,
22151 alt_number: 0,
22152 member_values: MemberEnv::new(),
22153 return_values: BTreeMap::new(),
22154 diagnostics: DiagnosticSeqId::EMPTY,
22155 decisions: vec![1, 0],
22156 actions: vec![
22157 ParserAction::new(23, 2, 2, Some(4)),
22158 ParserAction::new(23, 2, 0, Some(6)),
22159 ],
22160 nodes: NodeSeqId::EMPTY,
22161 };
22162 let second = RecognizeOutcome {
22163 decisions: vec![0, 1],
22164 actions: vec![
22165 ParserAction::new(23, 2, 2, Some(6)),
22166 ParserAction::new(23, 2, 0, Some(6)),
22167 ],
22168 ..first.clone()
22169 };
22170
22171 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22172 .expect("one outcome should be selected");
22173 assert_eq!(selected.actions[0].stop_index(), Some(6));
22174 }
22175
22176 #[test]
22177 fn outcome_ties_keep_first_recursive_tree_shape() {
22178 let mut arena = RecognitionArena::default();
22179 let token = arena.push_node(ArenaRecognizedNode::Token {
22180 token: TokenId::try_from(0).expect("test token ID"),
22181 });
22182 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
22183 let inner = arena.push_node(ArenaRecognizedNode::Rule {
22184 rule_index: 1,
22185 invoking_state: -1,
22186 alt_number: 0,
22187 start_index: 0,
22188 stop_index: Some(0),
22189 return_values: None,
22190 children: token_children,
22191 });
22192 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
22193 let outer = arena.push_node(ArenaRecognizedNode::Rule {
22194 rule_index: 1,
22195 invoking_state: -1,
22196 alt_number: 0,
22197 start_index: 0,
22198 stop_index: Some(0),
22199 return_values: None,
22200 children: inner_children,
22201 });
22202 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
22203 let first = RecognizeOutcome {
22204 index: 1,
22205 consumed_eof: false,
22206 alt_number: 0,
22207 member_values: MemberEnv::new(),
22208 return_values: BTreeMap::new(),
22209 diagnostics: DiagnosticSeqId::EMPTY,
22210 decisions: Vec::new(),
22211 actions: vec![ParserAction::new(1, 0, 0, None)],
22212 nodes: recursive_nodes,
22213 };
22214 let second = RecognizeOutcome {
22215 index: 1,
22216 consumed_eof: false,
22217 alt_number: 0,
22218 member_values: MemberEnv::new(),
22219 return_values: BTreeMap::new(),
22220 diagnostics: DiagnosticSeqId::EMPTY,
22221 decisions: Vec::new(),
22222 actions: vec![ParserAction::new(2, 0, 0, None)],
22223 nodes: recursive_nodes,
22224 };
22225
22226 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
22227 .expect("one outcome should be selected");
22228 assert_eq!(selected.actions[0].source_state(), 1);
22229 }
22230
22231 #[test]
22232 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
22233 let mut arena = RecognitionArena::default();
22234 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
22235 line: 1,
22236 column: 3,
22237 message: "missing 'Y' at '<EOF>'".to_owned(),
22238 offending: None,
22239 }]);
22240 let first_alt = RecognizeOutcome {
22241 index: 2,
22242 consumed_eof: true,
22243 alt_number: 0,
22244 member_values: MemberEnv::new(),
22245 return_values: BTreeMap::new(),
22246 diagnostics: recovered_diagnostics,
22247 decisions: vec![0],
22248 actions: vec![ParserAction::new(1, 0, 0, None)],
22249 nodes: NodeSeqId::EMPTY,
22250 };
22251 let second_alt = RecognizeOutcome {
22252 diagnostics: DiagnosticSeqId::EMPTY,
22253 decisions: vec![1],
22254 actions: vec![ParserAction::new(2, 0, 0, None)],
22255 ..first_alt.clone()
22256 };
22257
22258 let selected = select_best_outcome(
22259 [second_alt, first_alt].into_iter(),
22260 PredictionMode::Sll,
22261 &arena,
22262 )
22263 .expect("one outcome should be selected");
22264 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
22265 assert_eq!(selected.decisions, [0]);
22266 }
22267}