1use std::cell::RefCell;
7#[allow(clippy::disallowed_types)]
8use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
9use std::hash::{BuildHasherDefault, Hash, Hasher};
10use std::rc::Rc;
11
12#[derive(Clone, Copy, Default)]
19struct FxHasher {
20 hash: u64,
21}
22
23const FX_ROT: u32 = 5;
24const FX_SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
25
26impl Hasher for FxHasher {
27 #[inline]
35 fn write(&mut self, mut bytes: &[u8]) {
36 while bytes.len() >= 8 {
37 let (head, rest) = bytes.split_at(8);
38 let word = u64::from_le_bytes(head.try_into().expect("8-byte chunk"));
39 self.hash = (self.hash.rotate_left(FX_ROT) ^ word).wrapping_mul(FX_SEED);
40 bytes = rest;
41 }
42 for byte in bytes {
43 self.hash = (self.hash.rotate_left(FX_ROT) ^ u64::from(*byte)).wrapping_mul(FX_SEED);
44 }
45 }
46 #[inline]
47 fn write_u64(&mut self, value: u64) {
48 self.hash = (self.hash.rotate_left(FX_ROT) ^ value).wrapping_mul(FX_SEED);
49 }
50 #[inline]
51 fn write_usize(&mut self, value: usize) {
52 self.write_u64(value as u64);
53 }
54 #[inline]
55 fn write_u32(&mut self, value: u32) {
56 self.write_u64(u64::from(value));
57 }
58 #[inline]
59 fn write_i32(&mut self, value: i32) {
60 self.write_u64(u64::from(i32::cast_unsigned(value)));
61 }
62 #[inline]
63 fn finish(&self) -> u64 {
64 self.hash
65 }
66}
67
68type FxBuildHasher = BuildHasherDefault<FxHasher>;
69#[allow(clippy::disallowed_types)]
70type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;
71#[allow(clippy::disallowed_types)]
72type FxHashSet<K> = HashSet<K, FxBuildHasher>;
73
74use crate::atn::parser::{
75 ParserAtnPrediction, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
76};
77use crate::atn::{Atn, AtnState, AtnStateKind, Transition};
78use crate::char_stream::CharStream;
79use crate::errors::AntlrError;
80use crate::int_stream::IntStream;
81use crate::lexer::{LexerCustomAction, LexerSemCtx};
82use crate::prediction::{EMPTY_RETURN_STATE, PredictionContext};
83use crate::recognizer::{Recognizer, RecognizerData};
84use crate::semir::{self, AStmt, ArithOp, CmpOp, ExprId, HookId, PExpr, SemIr, StmtId};
85use crate::token::{
86 CommonToken, TOKEN_EOF, Token, TokenFactory, TokenRef, TokenSource, TokenSourceError,
87};
88use crate::token_stream::CommonTokenStream;
89use crate::tree::{ErrorNode, ParseTree, ParserRuleContext, RuleNode, TerminalNode};
90use crate::vocabulary::Vocabulary;
91
92const RECOGNITION_DEPTH_LIMIT: usize = 32_768;
96const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
100const CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT: usize = 4096;
104const CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT: usize = 8;
105
106#[derive(Clone, Copy, Debug, Eq, PartialEq)]
107enum SingleOutcomeMemoMode {
108 Probe,
109 Promote,
110 Sparse,
111}
112
113fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
114 intervals
115 .iter()
116 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
117}
118
119fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
120 let mut symbols = BTreeSet::new();
121 for (start, stop) in intervals {
122 symbols.extend(*start..=*stop);
123 }
124 symbols
125}
126
127fn interval_complement_symbols(
128 intervals: &[(i32, i32)],
129 min_vocabulary: i32,
130 max_vocabulary: i32,
131) -> BTreeSet<i32> {
132 (min_vocabulary..=max_vocabulary)
133 .filter(|symbol| !interval_set_contains(intervals, *symbol))
134 .collect()
135}
136
137#[cfg(feature = "perf-counters")]
138mod perf_counters {
139 use std::cell::Cell;
140 thread_local! {
141 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
142 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
143 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
144 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
145 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
146 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
147 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
148 }
149 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
150 c.with(|v| v.set(v.get() + n));
151 }
152 thread_local! {
153 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
154 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
155 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
156 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
157 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
158 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
159 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
160 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
161 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
162 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
163 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
164 }
165 pub(super) fn snapshot() -> [(&'static str, u64); 18] {
166 [
167 ("rfs_calls", RFS_CALLS.with(Cell::get)),
168 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
169 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
170 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
171 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
172 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
173 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
174 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
175 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
176 (
177 "atom_range_transitions",
178 ATOM_RANGE_TRANSITIONS.with(Cell::get),
179 ),
180 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
181 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
182 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
183 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
184 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
185 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
186 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
187 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
188 ]
189 }
190 pub fn reset() {
191 RFS_CALLS.with(|c| c.set(0));
192 RFS_MEMO_HITS.with(|c| c.set(0));
193 RFS_MEMO_MISSES.with(|c| c.set(0));
194 RFS_VISITING_CYCLE.with(|c| c.set(0));
195 MEMO_INSERTED.with(|c| c.set(0));
196 OUTCOMES_PUSHED.with(|c| c.set(0));
197 OUTCOMES_CLONED.with(|c| c.set(0));
198 EPSILON_TRANSITIONS.with(|c| c.set(0));
199 RULE_TRANSITIONS.with(|c| c.set(0));
200 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
201 SINGLE_TRANS_BODY.with(|c| c.set(0));
202 MULTI_TRANS_BODY.with(|c| c.set(0));
203 SINGLE_TRANS_RULE.with(|c| c.set(0));
204 SINGLE_TRANS_ATOM.with(|c| c.set(0));
205 SINGLE_TRANS_OTHER.with(|c| c.set(0));
206 OUTCOMES_RETURN_0.with(|c| c.set(0));
207 OUTCOMES_RETURN_1.with(|c| c.set(0));
208 OUTCOMES_RETURN_N.with(|c| c.set(0));
209 }
210 pub fn dump() {
211 for (name, value) in snapshot() {
212 #[allow(clippy::print_stderr)]
213 {
214 eprintln!("perf {name}={value}");
215 }
216 }
217 }
218}
219
220#[cfg(feature = "perf-counters")]
221pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
222const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
227#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
236pub struct ParserAction {
237 source_state: usize,
238 rule_index: usize,
239 start_index: usize,
240 stop_index: Option<usize>,
241 rule_init: bool,
242 expected_state: Option<usize>,
243}
244
245impl ParserAction {
246 pub const fn new(
248 source_state: usize,
249 rule_index: usize,
250 start_index: usize,
251 stop_index: Option<usize>,
252 ) -> Self {
253 Self {
254 source_state,
255 rule_index,
256 start_index,
257 stop_index,
258 rule_init: false,
259 expected_state: None,
260 }
261 }
262
263 pub const fn new_rule_init(
265 rule_index: usize,
266 start_index: usize,
267 expected_state: Option<usize>,
268 ) -> Self {
269 Self {
270 source_state: usize::MAX,
271 rule_index,
272 start_index,
273 stop_index: None,
274 rule_init: true,
275 expected_state,
276 }
277 }
278
279 pub const fn source_state(&self) -> usize {
281 self.source_state
282 }
283
284 pub const fn rule_index(&self) -> usize {
286 self.rule_index
287 }
288
289 pub const fn start_index(&self) -> usize {
291 self.start_index
292 }
293
294 pub const fn stop_index(&self) -> Option<usize> {
296 self.stop_index
297 }
298
299 pub const fn is_rule_init(&self) -> bool {
301 self.rule_init
302 }
303
304 pub const fn expected_state(&self) -> Option<usize> {
306 self.expected_state
307 }
308}
309
310pub struct ParserSemCtx<'a, S>
318where
319 S: TokenSource,
320{
321 input: &'a mut CommonTokenStream<S>,
322 rule_index: usize,
323 coordinate_index: usize,
324 rule_name: Option<String>,
325 context: Option<&'a ParserRuleContext>,
326 tree: Option<&'a ParseTree>,
327 local_int_arg: Option<(usize, i64)>,
328 member_values: &'a BTreeMap<usize, i64>,
329 action: Option<ParserAction>,
330}
331
332impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
333where
334 S: TokenSource,
335{
336 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
337 f.debug_struct("ParserSemCtx")
338 .field("rule_index", &self.rule_index)
339 .field("coordinate_index", &self.coordinate_index)
340 .field("rule_name", &self.rule_name)
341 .field("context", &self.context)
342 .field("tree", &self.tree)
343 .field("local_int_arg", &self.local_int_arg)
344 .field("member_values", &self.member_values)
345 .field("action", &self.action)
346 .finish_non_exhaustive()
347 }
348}
349
350impl<'a, S> ParserSemCtx<'a, S>
351where
352 S: TokenSource,
353{
354 #[must_use]
356 pub const fn rule_index(&self) -> usize {
357 self.rule_index
358 }
359
360 #[must_use]
362 pub fn rule_name(&self) -> Option<&str> {
363 self.rule_name.as_deref()
364 }
365
366 #[must_use]
370 pub const fn coordinate_index(&self) -> usize {
371 self.coordinate_index
372 }
373
374 #[must_use]
376 pub fn input_index(&self) -> usize {
377 self.input.index()
378 }
379
380 pub fn la(&mut self, offset: isize) -> i32 {
382 self.input.la(offset)
383 }
384
385 pub fn lt(&mut self, offset: isize) -> Option<&CommonToken> {
387 self.input.lt(offset)
388 }
389
390 pub fn token_text(&mut self, offset: isize) -> Option<&str> {
392 self.lt(offset).and_then(Token::text)
393 }
394
395 pub fn token_at(&mut self, index: usize) -> Option<&CommonToken> {
402 self.input.get(index)
403 }
404
405 #[must_use]
408 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
409 self.context
410 }
411
412 #[must_use]
415 pub const fn tree(&self) -> Option<&'a ParseTree> {
416 self.tree
417 }
418
419 #[must_use]
421 pub fn local_int_arg(&self) -> Option<i64> {
422 self.local_int_arg.map(|(_, value)| value)
423 }
424
425 #[must_use]
427 pub fn member_int(&self, member: usize) -> Option<i64> {
428 self.member_values.get(&member).copied()
429 }
430
431 #[must_use]
434 pub const fn action(&self) -> Option<ParserAction> {
435 self.action
436 }
437
438 pub fn action_text(&mut self) -> String {
446 let Some(action) = self.action else {
447 return String::new();
448 };
449 let Some(stop) = action.stop_index() else {
450 return String::new();
451 };
452 let stop = if self
453 .input
454 .get(stop)
455 .is_some_and(|token| token.token_type() == TOKEN_EOF)
456 {
457 let Some(previous) = self.input.previous_visible_token_index(stop) else {
458 return String::new();
459 };
460 previous
461 } else {
462 stop
463 };
464 self.input.text(action.start_index(), stop)
465 }
466}
467
468pub trait SemanticHooks {
475 fn observes_parser_predicates(&self) -> bool {
480 true
481 }
482
483 fn sempred<S>(
484 &mut self,
485 ctx: &mut ParserSemCtx<'_, S>,
486 rule_index: usize,
487 pred_index: usize,
488 ) -> Option<bool>
489 where
490 S: TokenSource,
491 {
492 let _ = (ctx, rule_index, pred_index);
493 None
494 }
495
496 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
497 where
498 S: TokenSource,
499 {
500 let _ = (ctx, action);
501 false
502 }
503
504 fn lexer_sempred<I, F>(
505 &mut self,
506 ctx: &mut LexerSemCtx<'_, I, F>,
507 rule_index: usize,
508 pred_index: usize,
509 ) -> Option<bool>
510 where
511 I: CharStream,
512 F: TokenFactory,
513 {
514 let _ = (ctx, rule_index, pred_index);
515 None
516 }
517
518 fn lexer_action<I, F>(
528 &mut self,
529 ctx: &mut LexerSemCtx<'_, I, F>,
530 action: LexerCustomAction,
531 ) -> bool
532 where
533 I: CharStream,
534 F: TokenFactory,
535 {
536 let _ = (ctx, action);
537 false
538 }
539
540 fn lexer_token_emitted(&mut self, token: &CommonToken) {
547 let _ = token;
548 }
549}
550
551#[derive(Clone, Copy, Debug, Default)]
554pub struct NoSemanticHooks;
555
556impl SemanticHooks for NoSemanticHooks {
557 fn observes_parser_predicates(&self) -> bool {
558 false
559 }
560}
561
562#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
569pub enum ParserPredicate {
570 True,
571 False,
572 FalseWithMessage {
574 message: &'static str,
575 },
576 Invoke {
579 value: bool,
580 },
581 LookaheadTextEquals {
582 offset: isize,
583 text: &'static str,
584 },
585 LookaheadNotEquals {
586 offset: isize,
587 token_type: i32,
588 },
589 TokenPairAdjacent,
592 ContextChildRuleTextNotEquals {
597 rule_index: usize,
598 text: &'static str,
599 },
600 LocalIntEquals {
603 value: i64,
604 },
605 LocalIntLessOrEqual {
608 value: i64,
609 },
610 MemberModuloEquals {
612 member: usize,
613 modulus: i64,
614 value: i64,
615 equals: bool,
616 },
617 MemberEquals {
619 member: usize,
620 value: i64,
621 equals: bool,
622 },
623}
624
625impl ParserPredicate {
626 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
632 match self {
633 Self::True => ir.expr(PExpr::Bool(true)),
634 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
635 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
636 Self::LookaheadTextEquals { offset, text } => {
637 let token = ir.expr(PExpr::TokenText(offset));
638 let text = ir.intern(text);
639 let text = ir.expr(PExpr::Str(text));
640 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
641 }
642 Self::LookaheadNotEquals { offset, token_type } => {
643 let actual = ir.expr(PExpr::La(offset));
644 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
645 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
646 }
647 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
648 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
649 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
650 let expected = ir.intern(text);
651 let expected = ir.expr(PExpr::Str(expected));
652 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
653 }
654 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
655 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
656 Self::MemberModuloEquals {
657 member,
658 modulus,
659 value,
660 equals,
661 } => {
662 if modulus == 0 {
663 return ir.expr(PExpr::Bool(false));
664 }
665 let member = ir.expr(PExpr::Member(member));
666 let modulus = ir.expr(PExpr::Int(modulus));
667 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
668 let expected = ir.expr(PExpr::Int(value));
669 ir.expr(PExpr::Cmp(
670 if equals { CmpOp::Eq } else { CmpOp::Ne },
671 actual,
672 expected,
673 ))
674 }
675 Self::MemberEquals {
676 member,
677 value,
678 equals,
679 } => {
680 let actual = ir.expr(PExpr::Member(member));
681 let expected = ir.expr(PExpr::Int(value));
682 ir.expr(PExpr::Cmp(
683 if equals { CmpOp::Eq } else { CmpOp::Ne },
684 actual,
685 expected,
686 ))
687 }
688 }
689 }
690
691 #[must_use]
692 pub const fn failure_message(self) -> Option<&'static str> {
693 match self {
694 Self::FalseWithMessage { message } => Some(message),
695 Self::True
696 | Self::False
697 | Self::Invoke { .. }
698 | Self::LookaheadTextEquals { .. }
699 | Self::LookaheadNotEquals { .. }
700 | Self::TokenPairAdjacent
701 | Self::ContextChildRuleTextNotEquals { .. }
702 | Self::LocalIntEquals { .. }
703 | Self::LocalIntLessOrEqual { .. }
704 | Self::MemberModuloEquals { .. }
705 | Self::MemberEquals { .. } => None,
706 }
707 }
708}
709
710fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
711 let local = ir.expr(PExpr::LocalArg);
712 let absent = ir.expr(PExpr::IsNull(local));
713 let expected = ir.expr(PExpr::Int(value));
714 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
715 ir.expr(PExpr::Or([absent, comparison].into()))
716}
717
718#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
731pub enum UnknownSemanticPolicy {
732 #[default]
734 AssumeTrue,
735 AssumeFalse,
737 Error,
740}
741
742fn apply_unknown_predicate_policy(
751 policy: UnknownSemanticPolicy,
752 rule_index: usize,
753 pred_index: usize,
754 hits: &mut Vec<(usize, usize)>,
755) -> bool {
756 match policy {
757 UnknownSemanticPolicy::AssumeTrue => true,
758 UnknownSemanticPolicy::AssumeFalse => false,
759 UnknownSemanticPolicy::Error => {
760 let coordinate = (rule_index, pred_index);
761 if !hits.contains(&coordinate) {
762 hits.push(coordinate);
763 }
764 false
765 }
766 }
767}
768
769#[derive(Clone, Debug, Eq, PartialEq)]
773pub struct ExpectedTokenSet {
774 symbols: BTreeSet<i32>,
775}
776
777impl ExpectedTokenSet {
778 #[must_use]
780 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
781 expected_symbols_display(&self.symbols, vocabulary)
782 }
783}
784
785#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
790pub struct BailErrorStrategy;
791
792impl BailErrorStrategy {
793 #[must_use]
794 pub const fn new() -> Self {
795 Self
796 }
797}
798
799#[derive(Clone, Copy, Debug, Eq, PartialEq)]
801pub enum PredictionMode {
802 Ll,
805 Sll,
808 LlExactAmbigDetection,
810}
811
812#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
818pub struct ParserRuleArg {
819 pub source_state: usize,
821 pub rule_index: usize,
823 pub value: i64,
825 pub inherit_local: bool,
827}
828
829#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
831pub struct ParserMemberAction {
832 pub source_state: usize,
834 pub member: usize,
836 pub delta: i64,
838}
839
840#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
847pub struct ParserReturnAction {
848 pub source_state: usize,
850 pub rule_index: usize,
852 pub name: &'static str,
854 pub value: i64,
856}
857
858impl ParserMemberAction {
859 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
861 let delta = ir.expr(PExpr::Int(self.delta));
862 ParserSemanticAction {
863 source_state: self.source_state,
864 rule_index: usize::MAX,
865 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
866 speculative: true,
867 }
868 }
869}
870
871impl ParserReturnAction {
872 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
874 let name = ir.intern(self.name);
875 let value = ir.expr(PExpr::Int(self.value));
876 ParserSemanticAction {
877 source_state: self.source_state,
878 rule_index: self.rule_index,
879 stmt: ir.stmt(AStmt::SetReturn(name, value)),
880 speculative: false,
881 }
882 }
883}
884
885#[derive(Clone, Copy, Debug, Eq, PartialEq)]
887pub struct ParserSemanticPredicate {
888 pub rule_index: usize,
890 pub pred_index: usize,
892 pub expr: ExprId,
894 pub failure_message: Option<&'static str>,
896}
897
898#[derive(Clone, Copy, Debug, Eq, PartialEq)]
900pub struct ParserSemanticAction {
901 pub source_state: usize,
903 pub rule_index: usize,
905 pub stmt: StmtId,
907 pub speculative: bool,
909}
910
911#[derive(Clone, Debug, Default, Eq, PartialEq)]
918pub struct ParserSemantics {
919 pub ir: SemIr,
920 pub predicates: Vec<ParserSemanticPredicate>,
921 pub actions: Vec<ParserSemanticAction>,
922}
923
924#[derive(Clone, Copy, Debug, Default)]
926pub struct ParserRuntimeOptions<'a> {
927 pub init_action_rules: &'a [usize],
929 pub track_alt_numbers: bool,
931 pub predicates: &'a [(usize, usize, ParserPredicate)],
933 pub semantics: Option<&'a ParserSemantics>,
935 pub rule_args: &'a [ParserRuleArg],
937 pub member_actions: &'a [ParserMemberAction],
939 pub return_actions: &'a [ParserReturnAction],
941 pub unknown_predicate_policy: UnknownSemanticPolicy,
944}
945
946pub trait Parser: Recognizer {
947 fn build_parse_trees(&self) -> bool;
950
951 fn set_build_parse_trees(&mut self, build: bool);
953
954 fn number_of_syntax_errors(&self) -> usize {
957 0
958 }
959
960 fn report_diagnostic_errors(&self) -> bool {
963 false
964 }
965
966 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
969
970 fn prediction_mode(&self) -> PredictionMode {
972 PredictionMode::Ll
973 }
974
975 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
977}
978
979#[derive(Debug)]
980struct CachedPredictionContext {
981 version: usize,
982 atn_key: usize,
983 context: Rc<PredictionContext>,
984}
985
986#[derive(Debug)]
987struct LeftRecursiveCallerOverlap {
988 atn_key: SharedAtnCacheKey,
989 state_number: usize,
990 symbol: i32,
991 context: Rc<PredictionContext>,
992 overlaps: bool,
993}
994
995const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
996
997#[derive(Debug)]
998pub struct BaseParser<S, H = NoSemanticHooks> {
999 input: CommonTokenStream<S>,
1000 data: RecognizerData,
1001 semantic_hooks: H,
1002 build_parse_trees: bool,
1003 syntax_errors: usize,
1004 report_diagnostic_errors: bool,
1005 prediction_mode: PredictionMode,
1006 prediction_diagnostics: Vec<ParserDiagnostic>,
1007 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1008 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1009 generated_sync_expected: Option<TokenBitSet>,
1010 int_members: BTreeMap<usize, i64>,
1011 rule_context_stack: Vec<RuleContextFrame>,
1012 rule_context_version: usize,
1013 prediction_context_cache: Option<CachedPredictionContext>,
1014 left_recursive_caller_overlap_cache:
1015 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1016 pending_invoking_states: Vec<isize>,
1017 precedence_stack: Vec<i32>,
1018 invoked_predicates: Vec<(usize, usize)>,
1022 bail_on_error: bool,
1026 unknown_predicate_policy: UnknownSemanticPolicy,
1029 unknown_predicate_hits: Vec<(usize, usize)>,
1032 unhandled_action_hits: Vec<(usize, usize)>,
1037 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1042 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1048 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1053 rule_stop_reach_cache: Vec<Option<bool>>,
1058 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1063 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1069 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1075 empty_cycle_cache: Vec<Option<bool>>,
1079 single_outcome_memo_mode: SingleOutcomeMemoMode,
1082 single_outcome_probe_seen: FxHashSet<FastRecognizeKey>,
1083 single_outcome_probe_samples: usize,
1084 single_outcome_probe_repeats: usize,
1085 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1088 fast_first_set_prefilter: bool,
1096 fast_recovery_enabled: bool,
1100 fast_token_nodes_enabled: bool,
1105}
1106
1107#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1109pub struct GeneratedDiagnosticsCheckpoint {
1110 diagnostics_len: usize,
1111 syntax_errors: usize,
1112}
1113
1114#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1115struct RuleContextFrame {
1116 rule_index: usize,
1117 invoking_state: isize,
1118}
1119
1120#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1121struct RecognizeOutcome {
1122 index: usize,
1123 consumed_eof: bool,
1124 alt_number: usize,
1125 member_values: BTreeMap<usize, i64>,
1126 return_values: BTreeMap<String, i64>,
1127 diagnostics: Vec<ParserDiagnostic>,
1128 decisions: Vec<usize>,
1129 actions: Vec<ParserAction>,
1130 nodes: Vec<RecognizedNode>,
1131}
1132
1133#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1134enum RecognizedNode {
1135 Token {
1136 index: usize,
1137 },
1138 ErrorToken {
1139 index: usize,
1140 },
1141 MissingToken {
1142 token_type: i32,
1143 at_index: usize,
1144 text: String,
1145 },
1146 Rule {
1147 rule_index: usize,
1148 invoking_state: isize,
1149 alt_number: usize,
1150 start_index: usize,
1151 stop_index: Option<usize>,
1152 return_values: BTreeMap<String, i64>,
1153 children: Vec<Self>,
1154 },
1155 LeftRecursiveBoundary {
1156 rule_index: usize,
1157 },
1158}
1159
1160#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1161struct FastRecognizeOutcome {
1162 index: usize,
1163 consumed_eof: bool,
1164 diagnostics: FastDiagnostics,
1165 nodes: NodeList,
1174}
1175
1176#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
1177#[allow(clippy::box_collection)]
1178struct FastDiagnostics(Option<Box<Vec<ParserDiagnostic>>>);
1179
1180impl FastDiagnostics {
1181 const fn new() -> Self {
1182 Self(None)
1183 }
1184
1185 #[cfg(test)]
1186 fn from_vec(diagnostics: Vec<ParserDiagnostic>) -> Self {
1187 if diagnostics.is_empty() {
1188 Self::new()
1189 } else {
1190 Self(Some(Box::new(diagnostics)))
1191 }
1192 }
1193
1194 fn is_empty(&self) -> bool {
1195 self.0
1196 .as_ref()
1197 .is_none_or(|diagnostics| diagnostics.is_empty())
1198 }
1199
1200 fn as_slice(&self) -> &[ParserDiagnostic] {
1201 self.0.as_deref().map_or(&[], Vec::as_slice)
1202 }
1203
1204 fn insert(&mut self, index: usize, diagnostic: ParserDiagnostic) {
1205 self.0
1206 .get_or_insert_with(Box::default)
1207 .insert(index, diagnostic);
1208 }
1209
1210 fn append(&mut self, other: &mut Self) {
1211 if other.is_empty() {
1212 return;
1213 }
1214 self.0
1215 .get_or_insert_with(Box::default)
1216 .append(other.0.get_or_insert_with(Box::default));
1217 if other.is_empty() {
1218 other.0 = None;
1219 }
1220 }
1221}
1222
1223impl std::ops::Deref for FastDiagnostics {
1224 type Target = [ParserDiagnostic];
1225
1226 fn deref(&self) -> &Self::Target {
1227 self.as_slice()
1228 }
1229}
1230
1231#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
1240enum NodeList {
1241 #[default]
1242 Empty,
1243 One(Rc<FastRecognizedNode>),
1244 Cons {
1245 head: Rc<FastRecognizedNode>,
1246 tail: Rc<Self>,
1247 },
1248}
1249
1250impl NodeList {
1251 const fn new() -> Self {
1253 Self::Empty
1254 }
1255
1256 fn cons(self, node: Rc<FastRecognizedNode>) -> Self {
1259 match self {
1260 Self::Empty => Self::One(node),
1261 existing @ (Self::One(_) | Self::Cons { .. }) => Self::Cons {
1262 head: node,
1263 tail: Rc::new(existing),
1264 },
1265 }
1266 }
1267
1268 fn prepend(&mut self, node: Rc<FastRecognizedNode>) {
1271 let owned = std::mem::take(self);
1272 *self = owned.cons(node);
1273 }
1274
1275 fn to_vec(&self) -> Vec<Rc<FastRecognizedNode>> {
1280 let mut out = Vec::new();
1281 let mut cursor = self;
1282 loop {
1283 match cursor {
1284 Self::Empty => break,
1285 Self::One(node) => {
1286 out.push(Rc::clone(node));
1287 break;
1288 }
1289 Self::Cons { head, tail } => {
1290 out.push(Rc::clone(head));
1291 cursor = tail.as_ref();
1292 }
1293 }
1294 }
1295 out
1296 }
1297
1298 const fn iter(&self) -> NodeListIter<'_> {
1299 NodeListIter { cursor: self }
1300 }
1301
1302 fn len(&self) -> usize {
1303 self.iter().count()
1304 }
1305
1306 fn has_left_recursive_boundary(&self) -> bool {
1307 self.iter()
1308 .any(|node| fast_node_has_left_recursive_boundary(node.as_ref()))
1309 }
1310
1311 fn has_explicit_token_node(&self) -> bool {
1312 self.iter().any(|node| {
1313 matches!(
1314 node.as_ref(),
1315 FastRecognizedNode::Token { .. }
1316 | FastRecognizedNode::ErrorToken { .. }
1317 | FastRecognizedNode::MissingToken { .. }
1318 )
1319 })
1320 }
1321
1322 fn from_vec(nodes: Vec<Rc<FastRecognizedNode>>) -> Self {
1324 let mut list = Self::new();
1325 for node in nodes.into_iter().rev() {
1326 list.prepend(node);
1327 }
1328 list
1329 }
1330}
1331
1332struct NodeListIter<'a> {
1333 cursor: &'a NodeList,
1334}
1335
1336impl<'a> Iterator for NodeListIter<'a> {
1337 type Item = &'a Rc<FastRecognizedNode>;
1338
1339 fn next(&mut self) -> Option<Self::Item> {
1340 match self.cursor {
1341 NodeList::Empty => None,
1342 NodeList::One(node) => {
1343 self.cursor = &NodeList::Empty;
1344 Some(node)
1345 }
1346 NodeList::Cons { head, tail } => {
1347 self.cursor = tail.as_ref();
1348 Some(head)
1349 }
1350 }
1351 }
1352}
1353
1354#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1358enum FastRecognizedNode {
1359 Token {
1360 index: usize,
1361 },
1362 ErrorToken {
1363 index: usize,
1364 },
1365 MissingToken {
1366 token_type: i32,
1367 at_index: usize,
1368 text: String,
1369 },
1370 Rule {
1371 rule_index: usize,
1372 invoking_state: isize,
1373 start_index: usize,
1374 stop_index: Option<usize>,
1375 children: NodeList,
1376 },
1377 LeftRecursiveBoundary {
1381 rule_index: usize,
1382 },
1383}
1384
1385#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1386struct ParserDiagnostic {
1387 line: usize,
1388 column: usize,
1389 message: String,
1390}
1391
1392#[derive(Clone, Debug, Default, Eq, PartialEq)]
1393struct ExpectedTokens {
1394 index: Option<usize>,
1395 symbols: BTreeSet<i32>,
1396 no_viable: Option<NoViableAlternative>,
1397}
1398
1399#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1400struct NoViableAlternative {
1401 start_index: usize,
1402 error_index: usize,
1403}
1404
1405impl ExpectedTokens {
1406 fn record_transition(&mut self, index: usize, transition: &Transition, max_token_type: i32) {
1409 let symbols = transition_expected_symbols(transition, max_token_type);
1410 match self.index {
1411 Some(current) if index < current => {}
1412 Some(current) if index == current => self.symbols.extend(symbols),
1413 _ => {
1414 self.index = Some(index);
1415 self.symbols = symbols;
1416 }
1417 }
1418 }
1419
1420 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
1423 match self.no_viable {
1424 Some(current) if error_index < current.error_index => {}
1425 _ => {
1426 self.no_viable = Some(NoViableAlternative {
1427 start_index,
1428 error_index,
1429 });
1430 }
1431 }
1432 }
1433}
1434
1435#[derive(Clone, Debug, Default, Eq, PartialEq)]
1442struct TokenBitSet {
1443 words: Vec<u64>,
1444}
1445
1446impl TokenBitSet {
1447 fn insert(&mut self, symbol: i32) {
1448 let Some(slot) = token_bit_slot(symbol) else {
1449 return;
1450 };
1451 let word = slot / u64::BITS as usize;
1452 if word >= self.words.len() {
1453 self.words.resize(word + 1, 0);
1454 }
1455 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
1456 }
1457
1458 fn extend_range(&mut self, start: i32, stop: i32) {
1459 let (start, stop) = if start <= stop {
1460 (start, stop)
1461 } else {
1462 (stop, start)
1463 };
1464 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
1465 self.insert(TOKEN_EOF);
1466 }
1467 let positive_start = start.max(1);
1468 if positive_start > stop {
1469 return;
1470 }
1471 let Some(start_slot) = token_bit_slot(positive_start) else {
1472 return;
1473 };
1474 let Some(stop_slot) = token_bit_slot(stop) else {
1475 return;
1476 };
1477 self.extend_slot_range(start_slot, stop_slot);
1478 }
1479
1480 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
1481 if start_slot > stop_slot {
1482 return;
1483 }
1484 let start_word = start_slot / u64::BITS as usize;
1485 let stop_word = stop_slot / u64::BITS as usize;
1486 if stop_word >= self.words.len() {
1487 self.words.resize(stop_word + 1, 0);
1488 }
1489 let start_offset = start_slot % u64::BITS as usize;
1490 let stop_offset = stop_slot % u64::BITS as usize;
1491 if start_word == stop_word {
1492 self.words[start_word] |=
1493 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
1494 return;
1495 }
1496 self.words[start_word] |= !0_u64 << start_offset;
1497 for word in &mut self.words[(start_word + 1)..stop_word] {
1498 *word = !0_u64;
1499 }
1500 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
1501 }
1502
1503 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
1504 for symbol in symbols {
1505 self.insert(symbol);
1506 }
1507 }
1508
1509 fn extend_from(&mut self, other: &Self) {
1510 if other.words.len() > self.words.len() {
1511 self.words.resize(other.words.len(), 0);
1512 }
1513 for (left, right) in self.words.iter_mut().zip(&other.words) {
1514 *left |= *right;
1515 }
1516 }
1517
1518 fn contains(&self, symbol: i32) -> bool {
1519 let Some(slot) = token_bit_slot(symbol) else {
1520 return false;
1521 };
1522 let word = slot / u64::BITS as usize;
1523 self.words
1524 .get(word)
1525 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
1526 }
1527
1528 fn is_empty(&self) -> bool {
1529 self.words.iter().all(|word| *word == 0)
1530 }
1531
1532 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
1533 for (word_index, word) in self.words.iter().copied().enumerate() {
1534 let mut bits = word;
1535 while bits != 0 {
1536 let bit = bits.trailing_zeros() as usize;
1537 if let Some(symbol) = token_bit_symbol(word_index * u64::BITS as usize + bit) {
1538 target.insert(symbol);
1539 }
1540 bits &= bits - 1;
1541 }
1542 }
1543 }
1544
1545 fn to_btree_set(&self) -> BTreeSet<i32> {
1546 let mut out = BTreeSet::new();
1547 self.extend_btree_set(&mut out);
1548 out
1549 }
1550}
1551
1552fn token_bit_slot(symbol: i32) -> Option<usize> {
1553 if symbol == TOKEN_EOF {
1554 Some(0)
1555 } else if symbol > 0 {
1556 usize::try_from(symbol).ok()
1557 } else {
1558 None
1559 }
1560}
1561
1562fn token_bit_symbol(slot: usize) -> Option<i32> {
1563 if slot == 0 {
1564 Some(TOKEN_EOF)
1565 } else {
1566 i32::try_from(slot).ok()
1567 }
1568}
1569
1570fn transition_expected_symbols(transition: &Transition, max_token_type: i32) -> BTreeSet<i32> {
1573 let mut symbols = BTreeSet::new();
1574 match transition {
1575 Transition::Atom { label, .. } => {
1576 symbols.insert(*label);
1577 }
1578 Transition::Range { start, stop, .. } => {
1579 symbols.extend(*start..=*stop);
1580 }
1581 Transition::Set { set, .. } => {
1582 for (start, stop) in set.ranges() {
1583 symbols.extend(*start..=*stop);
1584 }
1585 }
1586 Transition::NotSet { set, .. } => {
1587 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
1588 }
1589 Transition::Wildcard { .. } => {
1590 symbols.extend(1..=max_token_type);
1591 }
1592 Transition::Epsilon { .. }
1593 | Transition::Rule { .. }
1594 | Transition::Predicate { .. }
1595 | Transition::Action { .. }
1596 | Transition::Precedence { .. } => {}
1597 }
1598 symbols
1599}
1600
1601fn transition_expected_token_set(transition: &Transition, max_token_type: i32) -> TokenBitSet {
1602 let mut symbols = TokenBitSet::default();
1603 match transition {
1604 Transition::Atom { label, .. } => {
1605 symbols.insert(*label);
1606 }
1607 Transition::Range { start, stop, .. } => {
1608 symbols.extend_range(*start, *stop);
1609 }
1610 Transition::Set { set, .. } => {
1611 for (start, stop) in set.ranges() {
1612 symbols.extend_range(*start, *stop);
1613 }
1614 }
1615 Transition::NotSet { set, .. } => {
1616 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
1617 }
1618 Transition::Wildcard { .. } => {
1619 symbols.extend_range(1, max_token_type);
1620 }
1621 Transition::Epsilon { .. }
1622 | Transition::Rule { .. }
1623 | Transition::Predicate { .. }
1624 | Transition::Action { .. }
1625 | Transition::Precedence { .. } => {}
1626 }
1627 symbols
1628}
1629
1630fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
1634 let mut symbols = BTreeSet::new();
1635 let mut stack = vec![state_number];
1636 let mut visited = BTreeSet::new();
1637 while let Some(current) = stack.pop() {
1638 if !visited.insert(current) {
1639 continue;
1640 }
1641 let Some(state) = atn.state(current) else {
1642 continue;
1643 };
1644 for transition in &state.transitions {
1645 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1646 if transition_symbols.is_empty() {
1647 if transition.is_epsilon() {
1648 stack.push(transition.target());
1649 }
1650 } else {
1651 symbols.extend(transition_symbols);
1652 }
1653 }
1654 }
1655 symbols
1656}
1657
1658fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
1659 let mut symbols = TokenBitSet::default();
1660 let mut stack = vec![state_number];
1661 let mut visited = BTreeSet::new();
1662 while let Some(current) = stack.pop() {
1663 if !visited.insert(current) {
1664 continue;
1665 }
1666 let Some(state) = atn.state(current) else {
1667 continue;
1668 };
1669 for transition in &state.transitions {
1670 let transition_symbols =
1671 transition_expected_token_set(transition, atn.max_token_type());
1672 if transition_symbols.is_empty() {
1673 if transition.is_epsilon() {
1674 stack.push(transition.target());
1675 }
1676 } else {
1677 symbols.extend_from(&transition_symbols);
1678 }
1679 }
1680 }
1681 symbols
1682}
1683
1684fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
1685 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
1686 return false;
1687 };
1688 let Some(&stop_state) = atn.rule_to_stop_state().get(rule_index) else {
1689 return false;
1690 };
1691 epsilon_reaches_state(atn, state_number, stop_state)
1692}
1693
1694fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
1695 let mut stack = vec![start];
1696 let mut visited = BTreeSet::new();
1697 while let Some(current) = stack.pop() {
1698 if current == target {
1699 return true;
1700 }
1701 if !visited.insert(current) {
1702 continue;
1703 }
1704 let Some(state) = atn.state(current) else {
1705 continue;
1706 };
1707 stack.extend(
1708 state
1709 .transitions
1710 .iter()
1711 .filter(|transition| transition.is_epsilon())
1712 .map(Transition::target),
1713 );
1714 }
1715 false
1716}
1717
1718#[derive(Clone, Debug, Default, Eq, PartialEq)]
1725struct FirstSet {
1726 symbols: TokenBitSet,
1727 nullable: bool,
1728}
1729
1730type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
1737
1738type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
1745
1746#[derive(Debug, Default)]
1747struct LeftRecursiveOperatorLookahead {
1748 unconditional_symbols: TokenBitSet,
1749 predicate_dependent_symbols: TokenBitSet,
1750}
1751
1752#[derive(Default)]
1753struct SharedAtnCache {
1754 first_set: FirstSetCache,
1755 decision_lookahead: DecisionLookaheadCache,
1756 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
1757 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
1758 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
1759 rule_stop_reach: FxHashMap<usize, bool>,
1760 observable_action_transitions: Option<bool>,
1761 predicate_transitions: Option<bool>,
1762}
1763
1764thread_local! {
1765 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
1766 RefCell::new(FxHashMap::default());
1767}
1768
1769#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1780struct SharedAtnCacheKey {
1781 atn: usize,
1782 states: usize,
1783 state_count: usize,
1784 max_token_type: i32,
1785}
1786
1787impl SharedAtnCacheKey {
1788 fn for_atn(atn: &Atn) -> Self {
1789 Self {
1790 atn: std::ptr::from_ref::<Atn>(atn) as usize,
1791 states: atn.states().as_ptr() as usize,
1792 state_count: atn.states().len(),
1793 max_token_type: atn.max_token_type(),
1794 }
1795 }
1796}
1797
1798fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
1799 SHARED_ATN_CACHES.with(|cell| {
1800 let key = SharedAtnCacheKey::for_atn(atn);
1801 let mut map = cell.borrow_mut();
1802 let cache = map.entry(key).or_default();
1803 f(&mut cache.first_set)
1804 })
1805}
1806
1807fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
1808 SHARED_ATN_CACHES.with(|cell| {
1809 let key = SharedAtnCacheKey::for_atn(atn);
1810 let mut map = cell.borrow_mut();
1811 let cache = map.entry(key).or_default();
1812 f(cache)
1813 })
1814}
1815
1816#[derive(Debug, Default)]
1825struct DecisionLookahead {
1826 transitions: Vec<TransitionLookSet>,
1827}
1828
1829#[derive(Clone, Debug, Default)]
1836struct TransitionLookSet {
1837 symbols: TokenBitSet,
1838 nullable: bool,
1839}
1840
1841struct FirstSetCtx<'a> {
1845 cache: &'a mut FirstSetCache,
1846 in_progress: BTreeSet<(usize, usize)>,
1847 hit_cycle: bool,
1848}
1849
1850fn rule_first_set(
1859 atn: &Atn,
1860 target: usize,
1861 rule_stop_state: usize,
1862 cache: &mut FirstSetCache,
1863) -> Rc<FirstSet> {
1864 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
1865 return Rc::clone(cached);
1866 }
1867 let mut ctx = FirstSetCtx {
1868 cache,
1869 in_progress: BTreeSet::new(),
1870 hit_cycle: false,
1871 };
1872 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
1873}
1874
1875fn rule_first_set_cached(
1876 atn: &Atn,
1877 target: usize,
1878 rule_stop_state: usize,
1879 ctx: &mut FirstSetCtx<'_>,
1880) -> Rc<FirstSet> {
1881 let key = (target, rule_stop_state);
1882 if let Some(cached) = ctx.cache.get(&key) {
1883 return Rc::clone(cached);
1884 }
1885 if !ctx.in_progress.insert(key) {
1886 return Rc::new(FirstSet::default());
1890 }
1891 let saved_hit_cycle = ctx.hit_cycle;
1892 ctx.hit_cycle = false;
1893 let mut first = FirstSet::default();
1894 let mut visited = BTreeSet::new();
1895 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
1896 ctx.in_progress.remove(&key);
1897 let entry = Rc::new(first);
1898 if !ctx.hit_cycle {
1899 ctx.cache.insert(key, Rc::clone(&entry));
1900 }
1901 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
1902 entry
1903}
1904
1905fn transition_first_set(
1909 atn: &Atn,
1910 transition: &Transition,
1911 rule_stop_state: usize,
1912 cache: &mut FirstSetCache,
1913) -> TransitionLookSet {
1914 match transition {
1915 Transition::Atom { label, .. } => {
1916 let mut symbols = TokenBitSet::default();
1917 symbols.insert(*label);
1918 TransitionLookSet {
1919 symbols,
1920 nullable: false,
1921 }
1922 }
1923 Transition::Range { start, stop, .. } => {
1924 let mut symbols = TokenBitSet::default();
1925 symbols.extend_range(*start, *stop);
1926 TransitionLookSet {
1927 symbols,
1928 nullable: false,
1929 }
1930 }
1931 Transition::Set { set, .. } => {
1932 let mut symbols = TokenBitSet::default();
1933 for (start, stop) in set.ranges() {
1934 symbols.extend_range(*start, *stop);
1935 }
1936 TransitionLookSet {
1937 symbols,
1938 nullable: false,
1939 }
1940 }
1941 Transition::NotSet { set, .. } => {
1942 let max = atn.max_token_type();
1943 let mut symbols = TokenBitSet::default();
1944 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
1945 TransitionLookSet {
1946 symbols,
1947 nullable: false,
1948 }
1949 }
1950 Transition::Wildcard { .. } => {
1951 let mut symbols = TokenBitSet::default();
1952 symbols.extend_range(1, atn.max_token_type());
1953 TransitionLookSet {
1954 symbols,
1955 nullable: false,
1956 }
1957 }
1958 Transition::Epsilon { target }
1959 | Transition::Action { target, .. }
1960 | Transition::Predicate { target, .. }
1961 | Transition::Precedence { target, .. } => {
1962 let first = rule_first_set(atn, *target, rule_stop_state, cache);
1965 TransitionLookSet {
1966 symbols: first.symbols.clone(),
1967 nullable: first.nullable,
1968 }
1969 }
1970 Transition::Rule {
1971 target,
1972 rule_index,
1973 follow_state,
1974 ..
1975 } => {
1976 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
1977 return TransitionLookSet::default();
1978 };
1979 let child = rule_first_set(atn, *target, child_stop, cache);
1980 let mut symbols = child.symbols.clone();
1981 let nullable = if child.nullable {
1982 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
1983 symbols.extend_from(&follow.symbols);
1984 follow.nullable
1985 } else {
1986 false
1987 };
1988 TransitionLookSet { symbols, nullable }
1989 }
1990 }
1991}
1992
1993fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2014 let mut chosen: Option<usize> = None;
2015 for (index, transition) in entry.transitions.iter().enumerate() {
2016 if transition.nullable {
2017 return None;
2018 }
2019 if transition.symbols.contains(symbol) {
2020 if chosen.is_some() {
2021 return None;
2022 }
2023 chosen = Some(index);
2024 }
2025 }
2026 chosen
2027}
2028
2029fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2038 let mut matching_non_nullable_alt = None;
2039 let mut nullable_alt = None;
2040 for (index, transition) in entry.transitions.iter().enumerate() {
2041 if transition.nullable {
2042 if nullable_alt.is_some() {
2043 return None;
2044 }
2045 nullable_alt = Some(index);
2046 }
2047 if transition.symbols.contains(symbol) {
2048 if transition.nullable {
2049 continue;
2050 }
2051 if matching_non_nullable_alt.is_some() {
2052 return None;
2053 }
2054 matching_non_nullable_alt = Some(index);
2055 }
2056 }
2057 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2058 return None;
2059 }
2060 if non_greedy {
2061 nullable_alt.or(matching_non_nullable_alt)
2062 } else {
2063 matching_non_nullable_alt.or(nullable_alt)
2064 }
2065}
2066
2067fn should_skip_via_lookahead(
2068 transition: &Transition,
2069 transition_index: usize,
2070 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2071 index: usize,
2072 record_expected: bool,
2073 expected: &mut ExpectedTokens,
2074) -> bool {
2075 let prune_non_consuming = matches!(
2076 transition,
2077 Transition::Epsilon { .. }
2078 | Transition::Action { .. }
2079 | Transition::Predicate { .. }
2080 | Transition::Rule { .. }
2081 | Transition::Precedence { .. }
2082 );
2083 if !prune_non_consuming {
2084 return false;
2085 }
2086 let Some((symbol, entry)) = lookahead_filter else {
2087 return false;
2088 };
2089 let Some(set) = entry.transitions.get(transition_index) else {
2090 return false;
2091 };
2092 if set.symbols.contains(*symbol) || set.nullable {
2093 return false;
2094 }
2095 if record_expected && !set.symbols.is_empty() {
2096 record_pruned_transition_expected(set, index, expected);
2097 }
2098 true
2099}
2100
2101fn should_skip_rule_via_first_set(
2102 first: &FirstSet,
2103 symbol: i32,
2104 record_expected: bool,
2105 index: usize,
2106 expected: &mut ExpectedTokens,
2107) -> bool {
2108 if first.nullable || first.symbols.contains(symbol) {
2109 return false;
2110 }
2111 if record_expected && !first.symbols.is_empty() {
2112 record_token_bit_expected(&first.symbols, index, expected);
2113 }
2114 true
2115}
2116
2117fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2118 match expected.index {
2119 Some(current) if index < current => {}
2120 Some(current) if index == current => {
2121 symbols.extend_btree_set(&mut expected.symbols);
2122 }
2123 _ => {
2124 expected.index = Some(index);
2125 expected.symbols = symbols.to_btree_set();
2126 }
2127 }
2128}
2129
2130fn record_pruned_transition_expected(
2132 set: &TransitionLookSet,
2133 index: usize,
2134 expected: &mut ExpectedTokens,
2135) {
2136 match expected.index {
2137 Some(current) if index < current => {}
2138 Some(current) if index == current => {
2139 set.symbols.extend_btree_set(&mut expected.symbols);
2140 }
2141 _ => {
2142 expected.index = Some(index);
2143 expected.symbols = set.symbols.to_btree_set();
2144 }
2145 }
2146}
2147
2148fn rule_first_set_inner(
2149 atn: &Atn,
2150 state_number: usize,
2151 rule_stop_state: usize,
2152 ctx: &mut FirstSetCtx<'_>,
2153 visited: &mut BTreeSet<usize>,
2154 first: &mut FirstSet,
2155) {
2156 if !visited.insert(state_number) {
2157 return;
2158 }
2159 if state_number == rule_stop_state {
2160 first.nullable = true;
2161 return;
2162 }
2163 let Some(state) = atn.state(state_number) else {
2164 return;
2165 };
2166 for transition in &state.transitions {
2167 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2168 if !transition_symbols.is_empty() {
2169 first.symbols.extend_iter(transition_symbols);
2170 continue;
2171 }
2172 match transition {
2173 Transition::Epsilon { target }
2174 | Transition::Action { target, .. }
2175 | Transition::Predicate { target, .. }
2176 | Transition::Precedence { target, .. } => {
2177 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2178 }
2179 Transition::Rule {
2180 target,
2181 rule_index,
2182 follow_state,
2183 ..
2184 } => {
2185 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
2186 continue;
2187 };
2188 let child_key = (*target, child_stop);
2189 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2190 ctx.hit_cycle = true;
2191 }
2192 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2193 first.symbols.extend_from(&child.symbols);
2194 if child.nullable {
2195 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2196 }
2197 }
2198 Transition::Atom { .. }
2199 | Transition::Range { .. }
2200 | Transition::Set { .. }
2201 | Transition::NotSet { .. }
2202 | Transition::Wildcard { .. } => {}
2203 }
2204 }
2205}
2206
2207fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2210 let mut symbols = BTreeSet::new();
2211 state_sync_symbols_inner(
2212 atn,
2213 state_number,
2214 stop_state,
2215 &mut BTreeSet::new(),
2216 &mut symbols,
2217 );
2218 symbols
2219}
2220
2221fn state_sync_symbols_inner(
2224 atn: &Atn,
2225 state_number: usize,
2226 stop_state: usize,
2227 visited: &mut BTreeSet<usize>,
2228 symbols: &mut BTreeSet<i32>,
2229) {
2230 if !visited.insert(state_number) {
2231 return;
2232 }
2233 if state_number == stop_state {
2234 symbols.insert(TOKEN_EOF);
2235 return;
2236 }
2237 let Some(state) = atn.state(state_number) else {
2238 return;
2239 };
2240 for transition in &state.transitions {
2241 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2242 if transition_symbols.is_empty() {
2243 match transition {
2244 Transition::Rule { target, .. }
2245 | Transition::Epsilon { target }
2246 | Transition::Action { target, .. }
2247 | Transition::Predicate { target, .. }
2248 | Transition::Precedence { target, .. } => {
2249 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
2250 }
2251 Transition::Atom { .. }
2252 | Transition::Range { .. }
2253 | Transition::Set { .. }
2254 | Transition::NotSet { .. }
2255 | Transition::Wildcard { .. } => {}
2256 }
2257 } else {
2258 symbols.extend(transition_symbols);
2259 }
2260 }
2261}
2262
2263#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
2264enum OperatorSymbolReachability {
2265 #[default]
2266 None,
2267 PredicateDependent,
2268 Unconditional,
2269}
2270
2271#[derive(Clone, Copy)]
2272struct OperatorReachabilityRequest {
2273 symbol: i32,
2274 precedence: i32,
2275 predicate_dependent: bool,
2276}
2277
2278struct NullablePrecedenceCtx {
2279 cache: FxHashMap<(usize, usize, i32, bool), bool>,
2280 in_progress: BTreeSet<(usize, usize, i32, bool)>,
2281 hit_cycle: bool,
2282}
2283
2284fn state_is_nullable_with_precedence(
2285 atn: &Atn,
2286 state_number: usize,
2287 stop_state_number: usize,
2288 precedence: i32,
2289 allow_predicates: bool,
2290 ctx: &mut NullablePrecedenceCtx,
2291) -> bool {
2292 let saved_hit_cycle = ctx.hit_cycle;
2293 ctx.hit_cycle = false;
2294 let nullable = state_is_nullable_with_precedence_cached(
2295 atn,
2296 state_number,
2297 stop_state_number,
2298 precedence,
2299 allow_predicates,
2300 ctx,
2301 );
2302 ctx.hit_cycle = saved_hit_cycle;
2303 nullable
2304}
2305
2306fn state_is_nullable_with_precedence_cached(
2307 atn: &Atn,
2308 state_number: usize,
2309 stop_state_number: usize,
2310 precedence: i32,
2311 allow_predicates: bool,
2312 ctx: &mut NullablePrecedenceCtx,
2313) -> bool {
2314 if state_number == stop_state_number {
2315 return true;
2316 }
2317 let key = (
2318 state_number,
2319 stop_state_number,
2320 precedence,
2321 allow_predicates,
2322 );
2323 if let Some(cached) = ctx.cache.get(&key) {
2324 return *cached;
2325 }
2326 if !ctx.in_progress.insert(key) {
2327 ctx.hit_cycle = true;
2328 return false;
2329 }
2330 let saved_hit_cycle = ctx.hit_cycle;
2331 ctx.hit_cycle = false;
2332 let nullable = atn.state(state_number).is_some_and(|state| {
2333 state.transitions.iter().any(|transition| match transition {
2334 Transition::Rule {
2335 target,
2336 rule_index,
2337 follow_state,
2338 precedence: rule_precedence,
2339 } => {
2340 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
2341 return false;
2342 };
2343 state_is_nullable_with_precedence_cached(
2344 atn,
2345 *target,
2346 child_stop,
2347 *rule_precedence,
2348 allow_predicates,
2349 ctx,
2350 ) && state_is_nullable_with_precedence_cached(
2351 atn,
2352 *follow_state,
2353 stop_state_number,
2354 precedence,
2355 allow_predicates,
2356 ctx,
2357 )
2358 }
2359 Transition::Epsilon { target } | Transition::Action { target, .. } => {
2360 state_is_nullable_with_precedence_cached(
2361 atn,
2362 *target,
2363 stop_state_number,
2364 precedence,
2365 allow_predicates,
2366 ctx,
2367 )
2368 }
2369 Transition::Predicate { target, .. } if allow_predicates => {
2370 state_is_nullable_with_precedence_cached(
2371 atn,
2372 *target,
2373 stop_state_number,
2374 precedence,
2375 allow_predicates,
2376 ctx,
2377 )
2378 }
2379 Transition::Precedence {
2380 target,
2381 precedence: transition_precedence,
2382 } if *transition_precedence >= precedence => state_is_nullable_with_precedence_cached(
2383 atn,
2384 *target,
2385 stop_state_number,
2386 precedence,
2387 allow_predicates,
2388 ctx,
2389 ),
2390 Transition::Atom { .. }
2391 | Transition::Range { .. }
2392 | Transition::Set { .. }
2393 | Transition::NotSet { .. }
2394 | Transition::Wildcard { .. }
2395 | Transition::Predicate { .. }
2396 | Transition::Precedence { .. } => false,
2397 })
2398 });
2399 ctx.in_progress.remove(&key);
2400 if !ctx.hit_cycle {
2401 ctx.cache.insert(key, nullable);
2402 }
2403 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2404 nullable
2405}
2406
2407fn state_can_reach_symbol_with_precedence(
2408 atn: &Atn,
2409 state_number: usize,
2410 request: OperatorReachabilityRequest,
2411 nullable_ctx: &mut NullablePrecedenceCtx,
2412 visited: &mut BTreeSet<(usize, i32, bool)>,
2413) -> OperatorSymbolReachability {
2414 if !visited.insert((
2415 state_number,
2416 request.precedence,
2417 request.predicate_dependent,
2418 )) {
2419 return OperatorSymbolReachability::None;
2420 }
2421 let Some(state) = atn.state(state_number) else {
2422 return OperatorSymbolReachability::None;
2423 };
2424 let mut reachability = OperatorSymbolReachability::None;
2425 for transition in &state.transitions {
2426 if transition.matches(request.symbol, 1, atn.max_token_type()) {
2427 if request.predicate_dependent {
2428 reachability = OperatorSymbolReachability::PredicateDependent;
2429 continue;
2430 }
2431 return OperatorSymbolReachability::Unconditional;
2432 }
2433 let transition_reachability = match transition {
2434 Transition::Rule {
2435 target,
2436 rule_index,
2437 follow_state,
2438 precedence: rule_precedence,
2439 } => {
2440 let mut result = state_can_reach_symbol_with_precedence(
2441 atn,
2442 *target,
2443 OperatorReachabilityRequest {
2444 precedence: *rule_precedence,
2445 ..request
2446 },
2447 nullable_ctx,
2448 visited,
2449 );
2450 if result == OperatorSymbolReachability::Unconditional {
2451 return result;
2452 }
2453 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
2454 continue;
2455 };
2456 if state_is_nullable_with_precedence(
2457 atn,
2458 *target,
2459 child_stop,
2460 *rule_precedence,
2461 true,
2462 nullable_ctx,
2463 ) {
2464 let child_predicate_dependent = request.predicate_dependent
2465 || !state_is_nullable_with_precedence(
2466 atn,
2467 *target,
2468 child_stop,
2469 *rule_precedence,
2470 false,
2471 nullable_ctx,
2472 );
2473 result = result.max(state_can_reach_symbol_with_precedence(
2474 atn,
2475 *follow_state,
2476 OperatorReachabilityRequest {
2477 predicate_dependent: child_predicate_dependent,
2478 ..request
2479 },
2480 nullable_ctx,
2481 visited,
2482 ));
2483 }
2484 result
2485 }
2486 Transition::Epsilon { target }
2487 | Transition::Action { target, .. }
2488 | Transition::Precedence { target, .. } => {
2489 if matches!(
2490 transition,
2491 Transition::Precedence {
2492 precedence: transition_precedence,
2493 ..
2494 } if *transition_precedence < request.precedence
2495 ) {
2496 continue;
2497 }
2498 state_can_reach_symbol_with_precedence(atn, *target, request, nullable_ctx, visited)
2499 }
2500 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
2501 atn,
2502 *target,
2503 OperatorReachabilityRequest {
2504 predicate_dependent: true,
2505 ..request
2506 },
2507 nullable_ctx,
2508 visited,
2509 ),
2510 Transition::Atom { .. }
2511 | Transition::Range { .. }
2512 | Transition::Set { .. }
2513 | Transition::NotSet { .. }
2514 | Transition::Wildcard { .. } => OperatorSymbolReachability::None,
2515 };
2516 if transition_reachability == OperatorSymbolReachability::Unconditional {
2517 return transition_reachability;
2518 }
2519 reachability = reachability.max(transition_reachability);
2520 }
2521 reachability
2522}
2523
2524fn left_recursive_operator_lookahead(
2525 atn: &Atn,
2526 state_number: usize,
2527 precedence: i32,
2528) -> LeftRecursiveOperatorLookahead {
2529 let Some(state) = atn.state(state_number) else {
2530 return LeftRecursiveOperatorLookahead::default();
2531 };
2532 let mut lookahead = LeftRecursiveOperatorLookahead::default();
2533 let mut nullable_ctx = NullablePrecedenceCtx {
2534 cache: FxHashMap::default(),
2535 in_progress: BTreeSet::new(),
2536 hit_cycle: false,
2537 };
2538 for transition in &state.transitions {
2539 let target = transition.target();
2540 if atn
2541 .state(target)
2542 .is_some_and(|state| state.kind == AtnStateKind::LoopEnd)
2543 {
2544 continue;
2545 }
2546 for symbol in 1..=atn.max_token_type() {
2547 match state_can_reach_symbol_with_precedence(
2548 atn,
2549 target,
2550 OperatorReachabilityRequest {
2551 symbol,
2552 precedence,
2553 predicate_dependent: false,
2554 },
2555 &mut nullable_ctx,
2556 &mut BTreeSet::new(),
2557 ) {
2558 OperatorSymbolReachability::Unconditional => {
2559 lookahead.unconditional_symbols.insert(symbol);
2560 }
2561 OperatorSymbolReachability::PredicateDependent => {
2562 lookahead.predicate_dependent_symbols.insert(symbol);
2563 }
2564 OperatorSymbolReachability::None => {}
2565 }
2566 }
2567 }
2568 lookahead
2569}
2570
2571#[derive(Debug, Default)]
2572struct StateBeforeStopLookahead {
2573 symbols: TokenBitSet,
2574 reaches_context_boundary: bool,
2575}
2576
2577fn state_before_stop_lookahead(
2578 atn: &Atn,
2579 state_number: usize,
2580 stop_state_number: usize,
2581) -> Rc<StateBeforeStopLookahead> {
2582 with_shared_atn_caches(atn, |cache| {
2583 let key = (state_number, stop_state_number);
2584 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
2585 return Rc::clone(cached);
2586 }
2587 let mut lookahead = StateBeforeStopLookahead::default();
2588 state_before_stop_lookahead_inner(
2589 atn,
2590 state_number,
2591 stop_state_number,
2592 &mut BTreeSet::new(),
2593 &mut cache.first_set,
2594 &mut lookahead,
2595 );
2596 let lookahead = Rc::new(lookahead);
2597 cache
2598 .state_before_stop_lookahead
2599 .insert(key, Rc::clone(&lookahead));
2600 lookahead
2601 })
2602}
2603
2604fn state_before_stop_lookahead_inner(
2605 atn: &Atn,
2606 state_number: usize,
2607 stop_state_number: usize,
2608 visited: &mut BTreeSet<usize>,
2609 first_set_cache: &mut FirstSetCache,
2610 lookahead: &mut StateBeforeStopLookahead,
2611) {
2612 if state_number == stop_state_number {
2613 lookahead.reaches_context_boundary = true;
2614 return;
2615 }
2616 if !visited.insert(state_number) {
2617 return;
2618 }
2619 let Some(state) = atn.state(state_number) else {
2620 return;
2621 };
2622 if state.kind == AtnStateKind::RuleStop {
2623 lookahead.reaches_context_boundary = true;
2624 return;
2625 }
2626 for transition in &state.transitions {
2627 match transition {
2628 Transition::Epsilon { target }
2629 | Transition::Action { target, .. }
2630 | Transition::Predicate { target, .. }
2631 | Transition::Precedence { target, .. } => {
2632 state_before_stop_lookahead_inner(
2633 atn,
2634 *target,
2635 stop_state_number,
2636 visited,
2637 first_set_cache,
2638 lookahead,
2639 );
2640 }
2641 Transition::Rule {
2642 target,
2643 rule_index,
2644 follow_state,
2645 ..
2646 } => {
2647 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
2648 continue;
2649 };
2650 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
2651 lookahead.symbols.extend_from(&child.symbols);
2652 if child.nullable {
2653 state_before_stop_lookahead_inner(
2654 atn,
2655 *follow_state,
2656 stop_state_number,
2657 visited,
2658 first_set_cache,
2659 lookahead,
2660 );
2661 }
2662 }
2663 Transition::Atom { .. }
2664 | Transition::Range { .. }
2665 | Transition::Set { .. }
2666 | Transition::NotSet { .. }
2667 | Transition::Wildcard { .. } => {
2668 lookahead.symbols.extend_iter(transition_expected_symbols(
2669 transition,
2670 atn.max_token_type(),
2671 ));
2672 }
2673 }
2674 }
2675}
2676
2677fn context_can_match_symbol_before_state(
2678 atn: &Atn,
2679 context: &PredictionContext,
2680 stop_state_number: usize,
2681 symbol: i32,
2682) -> bool {
2683 (0..context.len()).any(|index| {
2684 context.return_state(index).is_some_and(|return_state| {
2685 if return_state == EMPTY_RETURN_STATE {
2686 return false;
2687 }
2688 let parent = context
2689 .parent(index)
2690 .unwrap_or_else(PredictionContext::empty);
2691 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
2692 lookahead.symbols.contains(symbol)
2693 || (lookahead.reaches_context_boundary
2694 && context_can_match_symbol_before_state(
2695 atn,
2696 &parent,
2697 stop_state_number,
2698 symbol,
2699 ))
2700 })
2701 })
2702}
2703
2704fn next_recovery_context(
2708 atn: &Atn,
2709 state: &AtnState,
2710 inherited: &BTreeSet<i32>,
2711 inherited_state: Option<usize>,
2712) -> (BTreeSet<i32>, Option<usize>) {
2713 let state_symbols = state_expected_symbols(atn, state.state_number);
2714 if state.transitions.len() > 1 && !state_symbols.is_empty() {
2715 let mut symbols = state_symbols;
2716 symbols.extend(inherited.iter().copied());
2717 return (symbols, Some(state.state_number));
2718 }
2719 (inherited.clone(), inherited_state)
2720}
2721
2722fn recovery_expected_symbols(
2723 atn: &Atn,
2724 state_number: usize,
2725 inherited: &BTreeSet<i32>,
2726) -> BTreeSet<i32> {
2727 let mut symbols = state_expected_symbols(atn, state_number);
2728 symbols.extend(inherited.iter().copied());
2729 symbols
2730}
2731
2732fn fast_next_recovery_context<S, H>(
2736 parser: &mut BaseParser<S, H>,
2737 atn: &Atn,
2738 state: &AtnState,
2739 inherited: &Rc<BTreeSet<i32>>,
2740 inherited_state: Option<usize>,
2741) -> (Rc<BTreeSet<i32>>, Option<usize>)
2742where
2743 S: TokenSource,
2744 H: SemanticHooks,
2745{
2746 if state.transitions.len() <= 1 {
2747 return (Rc::clone(inherited), inherited_state);
2748 }
2749 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number);
2750 if state_symbols.is_empty() {
2751 return (Rc::clone(inherited), inherited_state);
2752 }
2753 if inherited.is_empty() {
2754 return (state_symbols, Some(state.state_number));
2755 }
2756 if Rc::ptr_eq(&state_symbols, inherited) {
2757 return (state_symbols, Some(state.state_number));
2758 }
2759 let mut combined = (*state_symbols).clone();
2760 combined.extend(inherited.iter().copied());
2761 (
2762 parser.intern_recovery_symbols(combined),
2763 Some(state.state_number),
2764 )
2765}
2766
2767fn fast_recovery_expected_symbols<S, H>(
2771 parser: &mut BaseParser<S, H>,
2772 atn: &Atn,
2773 state_number: usize,
2774 inherited: &Rc<BTreeSet<i32>>,
2775) -> Rc<BTreeSet<i32>>
2776where
2777 S: TokenSource,
2778 H: SemanticHooks,
2779{
2780 let cached = parser.cached_state_expected_symbols(atn, state_number);
2781 if inherited.is_empty() {
2782 return cached;
2783 }
2784 if cached.is_empty() {
2785 return Rc::clone(inherited);
2786 }
2787 if Rc::ptr_eq(&cached, inherited) {
2788 return cached;
2789 }
2790 let mut combined = (*cached).clone();
2791 combined.extend(inherited.iter().copied());
2792 parser.intern_recovery_symbols(combined)
2793}
2794
2795struct ParserTableSemCtx<'a> {
2796 member_values: &'a mut BTreeMap<usize, i64>,
2797 return_values: &'a mut BTreeMap<String, i64>,
2798}
2799
2800impl semir::PredContext for ParserTableSemCtx<'_> {
2801 fn la(&mut self, _offset: isize) -> i64 {
2802 i64::from(TOKEN_EOF)
2803 }
2804
2805 fn token_text(&mut self, _offset: isize) -> Option<&str> {
2806 None
2807 }
2808
2809 fn token_index_adjacent(&mut self) -> bool {
2810 false
2811 }
2812
2813 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
2814 None
2815 }
2816
2817 fn member(&self, member: usize) -> Option<i64> {
2818 Some(self.member_values.get(&member).copied().unwrap_or_default())
2819 }
2820
2821 fn local_arg(&self) -> Option<i64> {
2822 None
2823 }
2824
2825 fn column(&self) -> Option<i64> {
2826 None
2827 }
2828
2829 fn token_start_column(&self) -> Option<i64> {
2830 None
2831 }
2832
2833 fn token_text_so_far(&self) -> Option<String> {
2834 None
2835 }
2836
2837 fn hook(&mut self, _hook: HookId) -> bool {
2838 false
2839 }
2840}
2841
2842impl semir::ActContext for ParserTableSemCtx<'_> {
2843 fn set_member(&mut self, member: usize, value: i64) {
2844 self.member_values.insert(member, value);
2845 }
2846
2847 fn set_return(&mut self, name: &str, value: i64) {
2848 self.return_values.insert(name.to_owned(), value);
2849 }
2850
2851 fn action_hook(&mut self, _hook: HookId) {}
2852}
2853
2854fn apply_member_actions(
2856 source_state: usize,
2857 actions: &[ParserMemberAction],
2858 semantics: Option<&ParserSemantics>,
2859 values: &mut BTreeMap<usize, i64>,
2860) {
2861 for action in actions
2862 .iter()
2863 .filter(|action| action.source_state == source_state)
2864 {
2865 *values.entry(action.member).or_default() += action.delta;
2866 }
2867 let Some(semantics) = semantics else {
2868 return;
2869 };
2870 let mut return_values = BTreeMap::new();
2871 let mut ctx = ParserTableSemCtx {
2872 member_values: values,
2873 return_values: &mut return_values,
2874 };
2875 for action in semantics
2876 .actions
2877 .iter()
2878 .filter(|action| action.source_state == source_state && action.speculative)
2879 {
2880 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
2881 }
2882}
2883
2884fn member_values_after_action(
2886 source_state: usize,
2887 actions: &[ParserMemberAction],
2888 semantics: Option<&ParserSemantics>,
2889 values: &BTreeMap<usize, i64>,
2890) -> BTreeMap<usize, i64> {
2891 let mut values = values.clone();
2892 apply_member_actions(source_state, actions, semantics, &mut values);
2893 values
2894}
2895
2896fn return_values_after_action(
2898 source_state: usize,
2899 rule_index: usize,
2900 actions: &[ParserReturnAction],
2901 semantics: Option<&ParserSemantics>,
2902 values: &BTreeMap<String, i64>,
2903) -> BTreeMap<String, i64> {
2904 let mut values = values.clone();
2905 for action in actions
2906 .iter()
2907 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
2908 {
2909 values.insert(action.name.to_owned(), action.value);
2910 }
2911 if let Some(semantics) = semantics {
2912 let mut member_values = BTreeMap::new();
2913 let mut ctx = ParserTableSemCtx {
2914 member_values: &mut member_values,
2915 return_values: &mut values,
2916 };
2917 for action in semantics.actions.iter().filter(|action| {
2918 action.source_state == source_state
2919 && action.rule_index == rule_index
2920 && !action.speculative
2921 }) {
2922 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
2923 }
2924 }
2925 values
2926}
2927
2928fn rule_local_int_arg(
2930 rule_args: &[ParserRuleArg],
2931 source_state: usize,
2932 rule_index: usize,
2933 local_int_arg: Option<(usize, i64)>,
2934) -> Option<(usize, i64)> {
2935 rule_args
2936 .iter()
2937 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
2938 .map(|arg| {
2939 let value = if arg.inherit_local {
2940 local_int_arg.map_or(arg.value, |(_, value)| value)
2941 } else {
2942 arg.value
2943 };
2944 (rule_index, value)
2945 })
2946}
2947
2948fn stop_outcome(
2951 index: usize,
2952 consumed_eof: bool,
2953 rule_alt_number: usize,
2954 member_values: BTreeMap<usize, i64>,
2955 return_values: BTreeMap<String, i64>,
2956) -> Vec<RecognizeOutcome> {
2957 vec![RecognizeOutcome {
2958 index,
2959 consumed_eof,
2960 alt_number: rule_alt_number,
2961 member_values,
2962 return_values,
2963 diagnostics: Vec::new(),
2964 decisions: Vec::new(),
2965 actions: Vec::new(),
2966 nodes: Vec::new(),
2967 }]
2968}
2969
2970fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
2971 with_shared_atn_caches(atn, |cache| {
2972 *cache.observable_action_transitions.get_or_insert_with(|| {
2973 atn.states().iter().any(|state| {
2974 state.transitions.iter().any(|transition| {
2975 matches!(
2976 transition,
2977 Transition::Action {
2978 action_index: Some(_),
2979 ..
2980 }
2981 )
2982 })
2983 })
2984 })
2985 })
2986}
2987
2988fn atn_has_predicate_transitions(atn: &Atn) -> bool {
2989 with_shared_atn_caches(atn, |cache| {
2990 *cache.predicate_transitions.get_or_insert_with(|| {
2991 atn.states().iter().any(|state| {
2992 state
2993 .transitions
2994 .iter()
2995 .any(|transition| matches!(transition, Transition::Predicate { .. }))
2996 })
2997 })
2998 })
2999}
3000
3001#[derive(Clone, Debug, Eq, PartialEq)]
3002struct RecognizeRequest<'a> {
3003 state_number: usize,
3004 stop_state: usize,
3005 index: usize,
3006 rule_start_index: usize,
3007 decision_start_index: Option<usize>,
3008 init_action_rules: &'a BTreeSet<usize>,
3009 predicates: &'a [(usize, usize, ParserPredicate)],
3010 semantics: Option<&'a ParserSemantics>,
3011 rule_args: &'a [ParserRuleArg],
3012 member_actions: &'a [ParserMemberAction],
3013 return_actions: &'a [ParserReturnAction],
3014 local_int_arg: Option<(usize, i64)>,
3015 member_values: BTreeMap<usize, i64>,
3016 return_values: BTreeMap<String, i64>,
3017 rule_alt_number: usize,
3018 track_alt_numbers: bool,
3019 consumed_eof: bool,
3020 precedence: i32,
3023 depth: usize,
3024 recovery_symbols: BTreeSet<i32>,
3025 recovery_state: Option<usize>,
3026}
3027
3028#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
3029struct RecognizeKey {
3030 state_number: usize,
3031 stop_state: usize,
3032 index: usize,
3033 rule_start_index: usize,
3034 decision_start_index: Option<usize>,
3035 local_int_arg: Option<(usize, i64)>,
3036 member_values: BTreeMap<usize, i64>,
3037 return_values: BTreeMap<String, i64>,
3038 rule_alt_number: usize,
3039 track_alt_numbers: bool,
3040 consumed_eof: bool,
3041 precedence: i32,
3042 recovery_symbols: BTreeSet<i32>,
3043 recovery_state: Option<usize>,
3044}
3045
3046#[derive(Clone, Debug, Eq, PartialEq)]
3047struct EpsilonActionStep {
3048 source_state: usize,
3049 target: usize,
3050 action_rule_index: Option<usize>,
3051 left_recursive_boundary: Option<usize>,
3052 decision: Option<usize>,
3053 decision_start_index: Option<usize>,
3054 alt_number: usize,
3055 recovery_symbols: BTreeSet<i32>,
3056 recovery_state: Option<usize>,
3057}
3058
3059struct RecognizeScratch<'a> {
3060 visiting: &'a mut BTreeSet<RecognizeKey>,
3061 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
3062 expected: &'a mut ExpectedTokens,
3063}
3064
3065#[derive(Clone, Debug, Eq, PartialEq)]
3066struct FastRecognizeRequest {
3067 state_number: usize,
3068 stop_state: usize,
3069 index: usize,
3070 rule_start_index: usize,
3071 decision_start_index: Option<usize>,
3072 precedence: i32,
3073 depth: usize,
3074 recovery_symbols: Rc<BTreeSet<i32>>,
3075 recovery_state: Option<usize>,
3076}
3077
3078#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3079struct FastRecognizeTopRequest {
3080 start_state: usize,
3081 stop_state: usize,
3082 start_index: usize,
3083 precedence: i32,
3084 caller_follow_state: Option<usize>,
3085}
3086
3087#[derive(Clone, Debug)]
3094struct FastRecognizeKey {
3095 state_number: usize,
3096 stop_state: usize,
3097 index: usize,
3098 rule_start_index: usize,
3099 decision_start_index: Option<usize>,
3100 precedence: i32,
3101 recovery_symbols_id: usize,
3102 recovery_state: Option<usize>,
3103}
3104
3105impl PartialEq for FastRecognizeKey {
3106 fn eq(&self, other: &Self) -> bool {
3107 if self.state_number != other.state_number
3108 || self.stop_state != other.stop_state
3109 || self.index != other.index
3110 || self.rule_start_index != other.rule_start_index
3111 || self.decision_start_index != other.decision_start_index
3112 || self.precedence != other.precedence
3113 || self.recovery_state != other.recovery_state
3114 || self.recovery_symbols_id != other.recovery_symbols_id
3115 {
3116 return false;
3117 }
3118 true
3119 }
3120}
3121
3122impl Eq for FastRecognizeKey {}
3123
3124impl Hash for FastRecognizeKey {
3125 fn hash<H: Hasher>(&self, hasher: &mut H) {
3126 self.state_number.hash(hasher);
3127 self.stop_state.hash(hasher);
3128 self.index.hash(hasher);
3129 self.rule_start_index.hash(hasher);
3130 self.decision_start_index.hash(hasher);
3131 self.precedence.hash(hasher);
3132 self.recovery_state.hash(hasher);
3133 self.recovery_symbols_id.hash(hasher);
3134 }
3135}
3136
3137struct FastRecoveryRequest<'a, 'b> {
3138 atn: &'a Atn,
3139 transition: &'a Transition,
3140 expected_symbols: Rc<BTreeSet<i32>>,
3141 target: usize,
3142 request: FastRecognizeRequest,
3143 visiting: &'b mut FxHashSet<FastRecognizeKey>,
3144 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
3145 expected: &'b mut ExpectedTokens,
3146}
3147
3148struct FastCurrentTokenDeletionRequest<'a, 'b> {
3149 atn: &'a Atn,
3150 expected_symbols: Rc<BTreeSet<i32>>,
3151 request: FastRecognizeRequest,
3152 visiting: &'b mut FxHashSet<FastRecognizeKey>,
3153 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
3154 expected: &'b mut ExpectedTokens,
3155}
3156
3157#[derive(Clone, Copy)]
3158struct FastChildRuleFailureRecoveryRequest<'a> {
3159 atn: &'a Atn,
3160 rule_index: usize,
3161 start_index: usize,
3162 follow_state: usize,
3163 stop_state: usize,
3164 expected: &'a ExpectedTokens,
3165}
3166
3167struct RecoveryRequest<'a, 'b> {
3168 atn: &'a Atn,
3169 transition: &'a Transition,
3170 expected_symbols: BTreeSet<i32>,
3171 target: usize,
3172 request: RecognizeRequest<'a>,
3173 visiting: &'b mut BTreeSet<RecognizeKey>,
3174 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
3175 expected: &'b mut ExpectedTokens,
3176}
3177
3178struct CurrentTokenDeletionRequest<'a, 'b> {
3179 atn: &'a Atn,
3180 expected_symbols: BTreeSet<i32>,
3181 request: RecognizeRequest<'a>,
3182 visiting: &'b mut BTreeSet<RecognizeKey>,
3183 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
3184 expected: &'b mut ExpectedTokens,
3185}
3186
3187struct ConsumingFailureFallback<'a> {
3190 atn: &'a Atn,
3191 target: usize,
3192 request: RecognizeRequest<'a>,
3193 symbol: i32,
3194 expected_symbols: BTreeSet<i32>,
3195 decision_start_index: Option<usize>,
3196 decision: Option<usize>,
3197}
3198
3199struct ChildRuleFailureRecovery<'a> {
3202 atn: &'a Atn,
3203 rule_index: usize,
3204 start_index: usize,
3205 follow_state: usize,
3206 stop_state: usize,
3207 member_values: BTreeMap<usize, i64>,
3208 expected: &'a ExpectedTokens,
3209}
3210
3211#[derive(Clone, Copy, Debug)]
3213struct PredicateEval<'a> {
3214 index: usize,
3215 rule_index: usize,
3216 pred_index: usize,
3217 predicates: &'a [(usize, usize, ParserPredicate)],
3218 semantics: Option<&'a ParserSemantics>,
3219 context: Option<&'a ParserRuleContext>,
3220 local_int_arg: Option<(usize, i64)>,
3221 member_values: &'a BTreeMap<usize, i64>,
3222}
3223
3224#[derive(Clone, Copy, Debug)]
3225struct ParserSemanticHookRequest<'a> {
3226 index: usize,
3227 rule_index: usize,
3228 pred_index: usize,
3229 context: Option<&'a ParserRuleContext>,
3230 local_int_arg: Option<(usize, i64)>,
3231 member_values: &'a BTreeMap<usize, i64>,
3232}
3233
3234struct ParserSemIrCtx<'a, S, H>
3243where
3244 S: TokenSource,
3245 H: SemanticHooks,
3246{
3247 input: &'a mut CommonTokenStream<S>,
3248 semantic_hooks: &'a mut H,
3249 rule_index: usize,
3250 coordinate_index: usize,
3251 rule_name: Option<&'a str>,
3252 context: Option<&'a ParserRuleContext>,
3253 local_int_arg: Option<(usize, i64)>,
3254 member_values: &'a BTreeMap<usize, i64>,
3255 invoked_predicates: &'a mut Vec<(usize, usize)>,
3256 unknown_predicate_policy: UnknownSemanticPolicy,
3260 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
3261}
3262
3263impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
3264where
3265 S: TokenSource,
3266 H: SemanticHooks,
3267{
3268 fn la(&mut self, offset: isize) -> i64 {
3269 i64::from(self.input.la(offset))
3270 }
3271
3272 fn token_text(&mut self, offset: isize) -> Option<&str> {
3273 self.input.lt(offset).and_then(Token::text)
3274 }
3275
3276 fn token_index_adjacent(&mut self) -> bool {
3277 let Some(first) = self.input.lt(-2).map(Token::token_index) else {
3278 return false;
3279 };
3280 let Some(second) = self.input.lt(-1).map(Token::token_index) else {
3281 return false;
3282 };
3283 first + 1 == second
3284 }
3285
3286 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
3287 self.context.and_then(|context| {
3288 context.children().iter().find_map(|child| match child {
3289 ParseTree::Rule(rule) if rule.context().rule_index() == rule_index => {
3290 Some(child.text())
3291 }
3292 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
3293 })
3294 })
3295 }
3296
3297 fn member(&self, member: usize) -> Option<i64> {
3298 Some(self.member_values.get(&member).copied().unwrap_or_default())
3299 }
3300
3301 fn local_arg(&self) -> Option<i64> {
3302 self.local_int_arg.map(|(_, value)| value)
3303 }
3304
3305 fn column(&self) -> Option<i64> {
3306 None
3307 }
3308
3309 fn token_start_column(&self) -> Option<i64> {
3310 None
3311 }
3312
3313 fn token_text_so_far(&self) -> Option<String> {
3314 None
3315 }
3316
3317 fn hook(&mut self, _hook: HookId) -> bool {
3318 let mut ctx = ParserSemCtx {
3319 input: &mut *self.input,
3320 rule_index: self.rule_index,
3321 coordinate_index: self.coordinate_index,
3322 rule_name: self.rule_name.map(str::to_owned),
3323 context: self.context,
3324 tree: None,
3325 local_int_arg: self.local_int_arg,
3326 member_values: self.member_values,
3327 action: None,
3328 };
3329 match self
3330 .semantic_hooks
3331 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
3332 {
3333 Some(result) => result,
3334 None => apply_unknown_predicate_policy(
3338 self.unknown_predicate_policy,
3339 self.rule_index,
3340 self.coordinate_index,
3341 self.unknown_predicate_hits,
3342 ),
3343 }
3344 }
3345
3346 fn trace_bool(&mut self, value: bool) -> bool {
3347 let key = (self.rule_index, self.coordinate_index);
3348 if !self.invoked_predicates.contains(&key) {
3349 self.invoked_predicates.push(key);
3350 use std::io::Write as _;
3351 let mut stdout = std::io::stdout().lock();
3352 let _ = writeln!(stdout, "eval={value}");
3353 }
3354 value
3355 }
3356}
3357
3358struct PredicateFailureRecovery<'a> {
3360 rule_index: usize,
3361 index: usize,
3362 message: &'a str,
3363 member_values: BTreeMap<usize, i64>,
3364 return_values: BTreeMap<String, i64>,
3365 rule_alt_number: usize,
3366}
3367
3368#[derive(Debug)]
3369enum DirectAdaptiveParseControl {
3370 Fallback(DirectAdaptiveFallback),
3371}
3372
3373#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3374enum DirectAdaptiveFallback {
3375 Action,
3376 InvalidAlt,
3377 LeftRecursiveBoundary,
3378 MissingAtn,
3379 NoTransition,
3380 Predicate,
3381 Prediction,
3382 Precedence,
3383 RuleStop,
3384 SemanticContext,
3385 StepLimit,
3386 TokenMismatch,
3387 UnknownDecision,
3388}
3389
3390type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
3391
3392struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
3393where
3394 S: TokenSource,
3395 H: SemanticHooks,
3396{
3397 parser: &'sim mut BaseParser<S, H>,
3398 atn: &'atn Atn,
3399 simulator: &'sim mut ParserAtnSimulator<'atn>,
3400 decision_by_state: Vec<Option<usize>>,
3401 steps: usize,
3402}
3403
3404#[derive(Clone, Debug, Eq, PartialEq)]
3414pub struct GeneratedMatch {
3415 children: GeneratedMatchChildren,
3416 consumed_eof: bool,
3417}
3418
3419#[derive(Clone, Debug, Eq, PartialEq)]
3420enum GeneratedMatchChildren {
3421 One(ParseTree),
3422 Many(Vec<ParseTree>),
3423}
3424
3425struct GeneratedMatchChildrenIntoIter {
3426 one: Option<ParseTree>,
3427 many: Option<std::vec::IntoIter<ParseTree>>,
3428}
3429
3430impl Iterator for GeneratedMatchChildrenIntoIter {
3431 type Item = ParseTree;
3432
3433 fn next(&mut self) -> Option<Self::Item> {
3434 self.one
3435 .take()
3436 .or_else(|| self.many.as_mut().and_then(Iterator::next))
3437 }
3438}
3439
3440impl GeneratedMatch {
3441 #[must_use]
3445 pub fn children(&self) -> &[ParseTree] {
3446 match &self.children {
3447 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
3448 GeneratedMatchChildren::Many(children) => children,
3449 }
3450 }
3451
3452 #[must_use]
3455 pub fn into_children(self) -> Vec<ParseTree> {
3456 match self.children {
3457 GeneratedMatchChildren::One(child) => vec![child],
3458 GeneratedMatchChildren::Many(children) => children,
3459 }
3460 }
3461
3462 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
3464 match self.children {
3465 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
3466 one: Some(child),
3467 many: None,
3468 },
3469 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
3470 one: None,
3471 many: Some(children.into_iter()),
3472 },
3473 }
3474 }
3475
3476 #[must_use]
3478 pub const fn consumed_eof(&self) -> bool {
3479 self.consumed_eof
3480 }
3481}
3482
3483impl<S> BaseParser<S, NoSemanticHooks>
3484where
3485 S: TokenSource,
3486{
3487 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
3490 Self::with_semantic_hooks(input, data, NoSemanticHooks)
3491 }
3492}
3493
3494impl<S, H> BaseParser<S, H>
3495where
3496 S: TokenSource,
3497 H: SemanticHooks,
3498{
3499 pub fn with_semantic_hooks(
3501 input: CommonTokenStream<S>,
3502 data: RecognizerData,
3503 semantic_hooks: H,
3504 ) -> Self {
3505 Self {
3506 input,
3507 data,
3508 semantic_hooks,
3509 build_parse_trees: true,
3510 syntax_errors: 0,
3511 report_diagnostic_errors: false,
3512 prediction_mode: PredictionMode::Ll,
3513 prediction_diagnostics: Vec::new(),
3514 reported_prediction_diagnostics: BTreeSet::new(),
3515 generated_parser_diagnostics: Vec::new(),
3516 generated_sync_expected: None,
3517 int_members: BTreeMap::new(),
3518 rule_context_stack: Vec::new(),
3519 rule_context_version: 0,
3520 prediction_context_cache: None,
3521 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
3522 pending_invoking_states: Vec::new(),
3523 precedence_stack: vec![0],
3524 invoked_predicates: Vec::new(),
3525 bail_on_error: false,
3526 unknown_predicate_policy: UnknownSemanticPolicy::default(),
3527 unknown_predicate_hits: Vec::new(),
3528 unhandled_action_hits: Vec::new(),
3529 rule_first_set_cache: Vec::new(),
3530 state_expected_cache: FxHashMap::default(),
3531 state_expected_token_cache: FxHashMap::default(),
3532 rule_stop_reach_cache: Vec::new(),
3533 recovery_symbols_intern: FxHashMap::default(),
3534 decision_lookahead_cache: FxHashMap::default(),
3535 ll1_decision_cache: FxHashMap::default(),
3536 empty_cycle_cache: Vec::new(),
3537 single_outcome_memo_mode: SingleOutcomeMemoMode::Probe,
3538 single_outcome_probe_seen: FxHashSet::default(),
3539 single_outcome_probe_samples: 0,
3540 single_outcome_probe_repeats: 0,
3541 empty_recovery_symbols: Rc::new(BTreeSet::new()),
3542 fast_first_set_prefilter: true,
3543 fast_recovery_enabled: true,
3544 fast_token_nodes_enabled: true,
3545 }
3546 }
3547
3548 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
3549 &mut self.input
3550 }
3551
3552 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
3563 self.unknown_predicate_policy = policy;
3564 }
3565
3566 #[must_use]
3572 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
3573 let error = self.unknown_semantic_error();
3574 self.unknown_predicate_hits.clear();
3575 self.unhandled_action_hits.clear();
3576 error
3577 }
3578
3579 pub fn reset_unknown_semantic_hits(&mut self) {
3586 self.unknown_predicate_hits.clear();
3587 self.unhandled_action_hits.clear();
3588 }
3589
3590 #[must_use]
3592 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
3593 &self.input
3594 }
3595
3596 #[must_use]
3598 pub fn into_token_stream(self) -> CommonTokenStream<S> {
3599 self.input
3600 }
3601
3602 pub const fn number_of_syntax_errors(&self) -> usize {
3605 self.syntax_errors
3606 }
3607
3608 pub const fn record_generated_syntax_error(&mut self) {
3611 self.record_syntax_errors(1);
3612 }
3613
3614 const fn record_syntax_errors(&mut self, count: usize) {
3615 self.syntax_errors = self.syntax_errors.saturating_add(count);
3616 }
3617
3618 pub fn report_token_source_errors(&mut self) {
3621 report_token_source_errors(&self.input.drain_source_errors());
3622 }
3623
3624 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
3627 GeneratedDiagnosticsCheckpoint {
3628 diagnostics_len: self.generated_parser_diagnostics.len(),
3629 syntax_errors: self.syntax_errors,
3630 }
3631 }
3632
3633 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
3635 self.generated_parser_diagnostics
3636 .truncate(marker.diagnostics_len);
3637 self.syntax_errors = marker.syntax_errors;
3638 self.generated_sync_expected = None;
3639 }
3640
3641 pub fn report_generated_parser_diagnostics(&mut self) {
3643 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
3644 let token_errors = self.input.drain_source_errors();
3645 report_generated_diagnostics(&parser_diagnostics, &token_errors);
3646 }
3647
3648 pub fn record_generated_ambiguity_diagnostic(
3651 &mut self,
3652 atn: &Atn,
3653 state_number: usize,
3654 start_index: usize,
3655 stop_index: usize,
3656 alts: &[usize],
3657 ) {
3658 if !self.report_diagnostic_errors || alts.len() < 2 {
3659 return;
3660 }
3661 let Some(decision) = atn
3662 .decision_to_state()
3663 .iter()
3664 .position(|candidate| *candidate == state_number)
3665 else {
3666 return;
3667 };
3668 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
3669 return;
3670 };
3671 let rule_name = self
3672 .rule_names()
3673 .get(rule_index)
3674 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
3675 let input = display_input_text(&self.input.text(start_index, stop_index));
3676 let alts = alts
3677 .iter()
3678 .map(usize::to_string)
3679 .collect::<Vec<_>>()
3680 .join(", ");
3681 let key = (decision, start_index, format!("{alts}:{input}"));
3682 if !self.reported_prediction_diagnostics.insert(key) {
3683 return;
3684 }
3685 let start_token = self.token_at(start_index);
3686 let stop_token = self.token_at(stop_index);
3687 self.generated_parser_diagnostics.push(diagnostic_for_token(
3688 start_token.as_ref(),
3689 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
3690 ));
3691 self.generated_parser_diagnostics.push(diagnostic_for_token(
3692 stop_token.as_ref(),
3693 format!(
3694 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
3695 ),
3696 ));
3697 }
3698
3699 pub fn record_generated_prediction_diagnostic(
3702 &mut self,
3703 atn: &Atn,
3704 state_number: usize,
3705 prediction: &ParserAtnPrediction,
3706 ) {
3707 let Some(diagnostic) = &prediction.diagnostic else {
3708 return;
3709 };
3710 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
3711 return;
3712 }
3713 let Some(decision) = atn
3714 .decision_to_state()
3715 .iter()
3716 .position(|candidate| *candidate == state_number)
3717 else {
3718 return;
3719 };
3720 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
3721 return;
3722 };
3723 let rule_name = self
3724 .rule_names()
3725 .get(rule_index)
3726 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
3727 let attempt_input = display_input_text(
3728 &self
3729 .input
3730 .text(diagnostic.start_index, diagnostic.sll_stop_index),
3731 );
3732 let result_input = display_input_text(
3733 &self
3734 .input
3735 .text(diagnostic.start_index, diagnostic.ll_stop_index),
3736 );
3737 let alts = diagnostic
3738 .conflicting_alts
3739 .iter()
3740 .map(usize::to_string)
3741 .collect::<Vec<_>>()
3742 .join(", ");
3743 let key = (
3744 decision,
3745 diagnostic.start_index,
3746 format!(
3747 "{:?}:{alts}:{attempt_input}:{result_input}",
3748 diagnostic.kind
3749 ),
3750 );
3751 if !self.reported_prediction_diagnostics.insert(key) {
3752 return;
3753 }
3754 let attempt_token = self.token_at(diagnostic.sll_stop_index);
3755 self.generated_parser_diagnostics.push(diagnostic_for_token(
3756 attempt_token.as_ref(),
3757 format!(
3758 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
3759 ),
3760 ));
3761 let result_token = self.token_at(diagnostic.ll_stop_index);
3762 let message = match diagnostic.kind {
3763 ParserAtnPredictionDiagnosticKind::Ambiguity => {
3764 if !diagnostic.exact {
3769 return;
3770 }
3771 format!(
3772 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
3773 )
3774 }
3775 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
3776 format!(
3777 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
3778 )
3779 }
3780 };
3781 self.generated_parser_diagnostics
3782 .push(diagnostic_for_token(result_token.as_ref(), message));
3783 }
3784
3785 pub fn la(&mut self, offset: isize) -> i32 {
3786 self.input.la_token(offset)
3787 }
3788
3789 pub fn consume(&mut self) {
3790 IntStream::consume(&mut self.input);
3791 }
3792
3793 pub fn set_int_member(&mut self, member: usize, value: i64) {
3795 self.int_members.insert(member, value);
3796 }
3797
3798 pub fn int_member(&self, member: usize) -> Option<i64> {
3800 self.int_members.get(&member).copied()
3801 }
3802
3803 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
3806 self.int_members.clone()
3807 }
3808
3809 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
3811 self.int_members = members;
3812 }
3813
3814 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
3816 let value = self.int_members.entry(member).or_default();
3817 *value += delta;
3818 *value
3819 }
3820
3821 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
3828 let current = self
3829 .input
3830 .lt_ref(1)
3831 .ok_or_else(|| AntlrError::ParserError {
3832 line: 0,
3833 column: 0,
3834 message: "missing current token".to_owned(),
3835 })?;
3836 if current.token_type() == token_type {
3837 self.consume();
3838 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
3839 } else {
3840 Err(AntlrError::MismatchedInput {
3841 expected: self.vocabulary().display_name(token_type),
3842 found: self.vocabulary().display_name(current.token_type()),
3843 })
3844 }
3845 }
3846
3847 pub fn match_token_recovering(
3851 &mut self,
3852 token_type: i32,
3853 follow_state: usize,
3854 atn: &Atn,
3855 ) -> Result<GeneratedMatch, AntlrError> {
3856 let current = self
3857 .input
3858 .lt_ref(1)
3859 .ok_or_else(|| AntlrError::ParserError {
3860 line: 0,
3861 column: 0,
3862 message: "missing current token".to_owned(),
3863 })?;
3864 if current.token_type() == token_type {
3865 self.generated_sync_expected = None;
3866 let consumed_eof = current.token_type() == TOKEN_EOF;
3867 self.consume();
3868 return Ok(GeneratedMatch {
3869 children: GeneratedMatchChildren::One(ParseTree::Terminal(TerminalNode::from_ref(
3870 current,
3871 ))),
3872 consumed_eof,
3873 });
3874 }
3875 let mut expected_symbols = BTreeSet::new();
3876 expected_symbols.insert(token_type);
3877 self.recover_generated_match(
3878 current.as_ref().clone(),
3879 &expected_symbols,
3880 follow_state,
3881 atn,
3882 |symbol| symbol == token_type,
3883 )
3884 }
3885
3886 pub fn match_set_recovering(
3887 &mut self,
3888 intervals: &[(i32, i32)],
3889 follow_state: usize,
3890 atn: &Atn,
3891 ) -> Result<GeneratedMatch, AntlrError> {
3892 let current = self
3893 .input
3894 .lt_ref(1)
3895 .ok_or_else(|| AntlrError::ParserError {
3896 line: 0,
3897 column: 0,
3898 message: "missing current token".to_owned(),
3899 })?;
3900 if interval_set_contains(intervals, current.token_type()) {
3901 self.generated_sync_expected = None;
3902 let consumed_eof = current.token_type() == TOKEN_EOF;
3903 self.consume();
3904 return Ok(GeneratedMatch {
3905 children: GeneratedMatchChildren::One(ParseTree::Terminal(TerminalNode::from_ref(
3906 current,
3907 ))),
3908 consumed_eof,
3909 });
3910 }
3911 let expected_symbols = interval_symbols(intervals);
3912 self.recover_generated_match(
3913 current.as_ref().clone(),
3914 &expected_symbols,
3915 follow_state,
3916 atn,
3917 |symbol| interval_set_contains(intervals, symbol),
3918 )
3919 }
3920
3921 pub fn match_not_set_recovering(
3922 &mut self,
3923 intervals: &[(i32, i32)],
3924 min_vocabulary: i32,
3925 max_vocabulary: i32,
3926 follow_state: usize,
3927 atn: &Atn,
3928 ) -> Result<GeneratedMatch, AntlrError> {
3929 let current = self
3930 .input
3931 .lt_ref(1)
3932 .ok_or_else(|| AntlrError::ParserError {
3933 line: 0,
3934 column: 0,
3935 message: "missing current token".to_owned(),
3936 })?;
3937 if (min_vocabulary..=max_vocabulary).contains(¤t.token_type())
3938 && !interval_set_contains(intervals, current.token_type())
3939 {
3940 self.generated_sync_expected = None;
3941 let consumed_eof = current.token_type() == TOKEN_EOF;
3942 self.consume();
3943 return Ok(GeneratedMatch {
3944 children: GeneratedMatchChildren::One(ParseTree::Terminal(TerminalNode::from_ref(
3945 current,
3946 ))),
3947 consumed_eof,
3948 });
3949 }
3950 let expected_symbols =
3951 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
3952 self.recover_generated_match(
3953 current.as_ref().clone(),
3954 &expected_symbols,
3955 follow_state,
3956 atn,
3957 |symbol| {
3958 (min_vocabulary..=max_vocabulary).contains(&symbol)
3959 && !interval_set_contains(intervals, symbol)
3960 },
3961 )
3962 }
3963
3964 fn recover_generated_match(
3965 &mut self,
3966 current: CommonToken,
3967 expected_symbols: &BTreeSet<i32>,
3968 follow_state: usize,
3969 atn: &Atn,
3970 matches: impl Fn(i32) -> bool,
3971 ) -> Result<GeneratedMatch, AntlrError> {
3972 let expected_display = self.expected_symbols_display(expected_symbols);
3973 if self.bail_on_error {
3974 return Err(AntlrError::ParserError {
3975 line: current.line(),
3976 column: current.column(),
3977 message: format!(
3978 "mismatched input {} expecting {expected_display}",
3979 token_input_display(¤t)
3980 ),
3981 });
3982 }
3983 if current.token_type() != TOKEN_EOF
3984 && let Some(next) = self.input.lt(2).cloned()
3985 && matches(next.token_type())
3986 {
3987 let message = format!(
3988 "extraneous input {} expecting {expected_display}",
3989 token_input_display(¤t)
3990 );
3991 self.push_generated_parser_diagnostic(diagnostic_for_token(Some(¤t), message));
3992 self.record_syntax_errors(1);
3993 self.generated_sync_expected = None;
3994 let consumed_eof = next.token_type() == TOKEN_EOF;
3997 self.consume();
3998 self.consume();
3999 return Ok(GeneratedMatch {
4000 children: GeneratedMatchChildren::Many(vec![
4001 ParseTree::Error(ErrorNode::new(current)),
4002 ParseTree::Terminal(TerminalNode::new(next)),
4003 ]),
4004 consumed_eof,
4005 });
4006 }
4007 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
4008 let follow_explicitly_expects_eof = current.token_type() == TOKEN_EOF
4017 && self
4018 .cached_state_expected_symbols(atn, follow_state)
4019 .contains(&TOKEN_EOF);
4020 if follow_symbols.contains(¤t.token_type())
4021 && (current.token_type() != TOKEN_EOF
4022 || self.rule_context_stack.len() > 1
4023 || expected_symbols.is_empty()
4024 || follow_explicitly_expects_eof)
4025 {
4026 let message = format!(
4027 "missing {expected_display} at {}",
4028 token_input_display(¤t)
4029 );
4030 self.push_generated_parser_diagnostic(diagnostic_for_token(Some(¤t), message));
4031 self.record_syntax_errors(1);
4032 self.generated_sync_expected = None;
4033 let token_type = expected_symbols.iter().next().copied().unwrap_or(TOKEN_EOF);
4034 let mut missing_symbol = BTreeSet::new();
4035 missing_symbol.insert(token_type);
4036 let missing_display = self.expected_symbols_display(&missing_symbol);
4037 let token = CommonToken::new(token_type)
4038 .with_text(format!("<missing {missing_display}>"))
4039 .with_span(usize::MAX, usize::MAX)
4040 .with_position(current.line(), current.column());
4041 return Ok(GeneratedMatch {
4046 children: GeneratedMatchChildren::One(ParseTree::Error(ErrorNode::new(token))),
4047 consumed_eof: false,
4048 });
4049 }
4050 let mismatch_expected = self.generated_sync_expected.take().map_or_else(
4051 || expected_symbols.clone(),
4052 |symbols| symbols.to_btree_set(),
4053 );
4054 let mismatch_expected_display = self.expected_symbols_display(&mismatch_expected);
4055 Err(AntlrError::ParserError {
4056 line: current.line(),
4057 column: current.column(),
4058 message: format!(
4059 "mismatched input {} expecting {mismatch_expected_display}",
4060 token_input_display(¤t)
4061 ),
4062 })
4063 }
4064
4065 fn generated_recovery_follow_symbols(
4066 &mut self,
4067 atn: &Atn,
4068 follow_state: usize,
4069 ) -> BTreeSet<i32> {
4070 let mut follow = self
4071 .cached_state_expected_symbols(atn, follow_state)
4072 .as_ref()
4073 .clone();
4074 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
4075 follow.extend(self.context_expected_symbols(atn));
4076 }
4077 follow
4078 }
4079
4080 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
4081 self.match_token(TOKEN_EOF)
4082 }
4083
4084 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
4085 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
4086 }
4087
4088 pub fn match_not_set(
4089 &mut self,
4090 intervals: &[(i32, i32)],
4091 min_vocabulary: i32,
4092 max_vocabulary: i32,
4093 ) -> Result<ParseTree, AntlrError> {
4094 self.match_interval_condition(intervals, |symbol| {
4095 (min_vocabulary..=max_vocabulary).contains(&symbol)
4096 && !interval_set_contains(intervals, symbol)
4097 })
4098 }
4099
4100 fn match_interval_condition(
4101 &mut self,
4102 intervals: &[(i32, i32)],
4103 matches: impl FnOnce(i32) -> bool,
4104 ) -> Result<ParseTree, AntlrError> {
4105 let current = self
4106 .input
4107 .lt_ref(1)
4108 .ok_or_else(|| AntlrError::ParserError {
4109 line: 0,
4110 column: 0,
4111 message: "missing current token".to_owned(),
4112 })?;
4113 if matches(current.token_type()) {
4114 self.consume();
4115 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
4116 } else {
4117 Err(AntlrError::MismatchedInput {
4118 expected: self.interval_display(intervals),
4119 found: self.vocabulary().display_name(current.token_type()),
4120 })
4121 }
4122 }
4123
4124 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
4125 let values = intervals
4126 .iter()
4127 .map(|(start, stop)| {
4128 if start == stop {
4129 self.vocabulary().display_name(*start)
4130 } else {
4131 format!(
4132 "{}..{}",
4133 self.vocabulary().display_name(*start),
4134 self.vocabulary().display_name(*stop)
4135 )
4136 }
4137 })
4138 .collect::<Vec<_>>()
4139 .join(", ");
4140 format!("{{{values}}}")
4141 }
4142
4143 pub const fn rule_node(&self, context: ParserRuleContext) -> ParseTree {
4144 ParseTree::Rule(RuleNode::new(context))
4145 }
4146
4147 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
4150 self.set_state(state);
4151 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
4152 self.rule_context_stack.push(RuleContextFrame {
4153 rule_index,
4154 invoking_state,
4155 });
4156 self.invalidate_prediction_context_cache();
4157 let start_index = self.current_visible_index();
4158 let mut context = ParserRuleContext::new(rule_index, invoking_state);
4159 if let Some(token) = self.token_ref_at(start_index) {
4160 context.set_start_ref(token);
4161 }
4162 context
4163 }
4164
4165 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
4172 let marker = self.pending_invoking_states.len();
4173 self.pending_invoking_states.push(invoking_state);
4174 marker
4175 }
4176
4177 pub fn discard_invoking_state(&mut self, marker: usize) {
4179 self.pending_invoking_states.truncate(marker);
4180 }
4181
4182 pub fn exit_rule(&mut self) {
4184 self.rule_context_stack.pop();
4185 self.invalidate_prediction_context_cache();
4186 }
4187
4188 pub fn prediction_context(&mut self, atn: &Atn) -> Rc<PredictionContext> {
4191 let atn_ptr: *const Atn = atn;
4192 let atn_key = atn_ptr as usize;
4193 if let Some(cached) = &self.prediction_context_cache
4194 && cached.version == self.rule_context_version
4195 && cached.atn_key == atn_key
4196 {
4197 return Rc::clone(&cached.context);
4198 }
4199 let mut context = PredictionContext::empty();
4200 for frame in self.rule_context_stack.iter().skip(1) {
4201 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
4202 continue;
4203 };
4204 let Some(Transition::Rule { follow_state, .. }) = atn
4205 .state(state_number)
4206 .and_then(|state| state.transitions.first())
4207 else {
4208 continue;
4209 };
4210 context = PredictionContext::singleton(context, *follow_state);
4211 }
4212 self.prediction_context_cache = Some(CachedPredictionContext {
4213 version: self.rule_context_version,
4214 atn_key,
4215 context: Rc::clone(&context),
4216 });
4217 context
4218 }
4219
4220 fn invalidate_prediction_context_cache(&mut self) {
4221 self.rule_context_version = self.rule_context_version.wrapping_add(1);
4222 self.prediction_context_cache = None;
4223 }
4224
4225 pub fn add_parse_child(&self, context: &mut ParserRuleContext, child: ParseTree) {
4230 if self.build_parse_trees {
4231 context.add_child(child);
4232 } else {
4233 context.note_matched_child();
4234 }
4235 }
4236
4237 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
4239 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
4240 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
4241 context.set_stop_ref(token);
4242 }
4243 self.exit_rule();
4244 self.rule_node(context)
4245 }
4246
4247 pub fn recover_generated_rule(
4254 &mut self,
4255 context: &mut ParserRuleContext,
4256 atn: &Atn,
4257 error: AntlrError,
4258 ) {
4259 let diagnostic = self.generated_rule_error_diagnostic(error);
4260 self.push_generated_parser_diagnostic(diagnostic);
4261 self.generated_sync_expected = None;
4262 let recovery_symbols = self.context_expected_symbols(atn);
4263 loop {
4264 let symbol = self.la(1);
4265 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
4266 break;
4267 }
4268 let Some(token) = self.input.lt(1).cloned() else {
4269 break;
4270 };
4271 self.consume();
4272 self.add_parse_child(context, ParseTree::Error(ErrorNode::new(token)));
4273 }
4274 self.record_syntax_errors(1);
4275 }
4276
4277 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
4278 if self
4279 .generated_parser_diagnostics
4280 .iter()
4281 .any(|existing| existing == &diagnostic)
4282 {
4283 return;
4284 }
4285 self.generated_parser_diagnostics.push(diagnostic);
4286 }
4287
4288 fn generated_rule_error_diagnostic(&mut self, error: AntlrError) -> ParserDiagnostic {
4289 match error {
4290 AntlrError::ParserError {
4291 line,
4292 column,
4293 message,
4294 } => ParserDiagnostic {
4295 line,
4296 column,
4297 message,
4298 },
4299 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
4300 self.input.lt(1),
4301 format!("mismatched input {found} expecting {expected}"),
4302 ),
4303 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
4304 self.input.lt(1),
4305 format!("no viable alternative at input {input}"),
4306 ),
4307 AntlrError::LexerError {
4308 line,
4309 column,
4310 message,
4311 } => ParserDiagnostic {
4312 line,
4313 column,
4314 message,
4315 },
4316 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
4317 }
4318 }
4319
4320 pub fn finish_recursion_rule(
4322 &mut self,
4323 mut context: ParserRuleContext,
4324 consumed_eof: bool,
4325 ) -> ParseTree {
4326 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
4327 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
4328 context.set_stop_ref(token);
4329 }
4330 self.unroll_recursion_context();
4331 self.rule_node(context)
4332 }
4333
4334 pub fn enter_recursion_rule(
4336 &mut self,
4337 state: isize,
4338 rule_index: usize,
4339 precedence: i32,
4340 ) -> ParserRuleContext {
4341 self.precedence_stack.push(precedence);
4342 self.enter_rule(state, rule_index)
4343 }
4344
4345 pub fn push_new_recursion_context(
4347 &mut self,
4348 state: isize,
4349 rule_index: usize,
4350 ) -> ParserRuleContext {
4351 self.set_state(state);
4352 ParserRuleContext::new(rule_index, state)
4353 }
4354
4355 pub fn push_new_recursion_context_with_previous(
4358 &mut self,
4359 state: isize,
4360 rule_index: usize,
4361 current: &mut ParserRuleContext,
4362 ) {
4363 self.set_state(state);
4364 if let Some(stop) = self
4365 .rule_stop_token_index(self.input.index(), false)
4366 .and_then(|index| self.token_ref_at(index))
4367 {
4368 current.set_stop_ref(stop);
4369 }
4370 let invoking_state = current.invoking_state();
4371 let start = current.start_ref();
4372 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
4373 if let Some(start) = start {
4374 replacement.set_start_ref(start);
4375 }
4376 let previous = std::mem::replace(current, replacement);
4377 if self.build_parse_trees {
4378 current.add_child(self.rule_node(previous));
4379 }
4380 }
4381
4382 pub fn unroll_recursion_context(&mut self) {
4384 if self.precedence_stack.len() > 1 {
4385 self.precedence_stack.pop();
4386 }
4387 self.exit_rule();
4388 }
4389
4390 pub fn left_recursive_loop_enter_prediction(
4396 &mut self,
4397 atn: &Atn,
4398 state_number: usize,
4399 precedence: i32,
4400 ) -> Option<bool> {
4401 let symbol = self.la(1);
4402 if symbol == TOKEN_EOF {
4403 return Some(false);
4404 }
4405 let operator_lookahead = with_shared_atn_caches(atn, |cache| {
4406 let key = (state_number, precedence);
4407 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
4408 return Rc::clone(cached);
4409 }
4410 let lookahead = Rc::new(left_recursive_operator_lookahead(
4411 atn,
4412 state_number,
4413 precedence,
4414 ));
4415 cache
4416 .left_recursive_operator_lookahead
4417 .insert(key, Rc::clone(&lookahead));
4418 lookahead
4419 });
4420 if !operator_lookahead.unconditional_symbols.contains(symbol) {
4421 if operator_lookahead
4422 .predicate_dependent_symbols
4423 .contains(symbol)
4424 {
4425 return None;
4426 }
4427 return Some(false);
4428 }
4429 let context = self.prediction_context(atn);
4430 let atn_key = SharedAtnCacheKey::for_atn(atn);
4431 let cached_overlap = self
4432 .left_recursive_caller_overlap_cache
4433 .iter()
4434 .flatten()
4435 .find(|entry| {
4436 entry.atn_key == atn_key
4437 && entry.state_number == state_number
4438 && entry.symbol == symbol
4439 && entry.context == context
4440 })
4441 .map(|entry| entry.overlaps);
4442 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
4443 let overlaps =
4444 context_can_match_symbol_before_state(atn, &context, state_number, symbol);
4445 if let Some(slot) = self
4446 .left_recursive_caller_overlap_cache
4447 .iter_mut()
4448 .find(|slot| slot.is_none())
4449 {
4450 *slot = Some(LeftRecursiveCallerOverlap {
4451 atn_key,
4452 state_number,
4453 symbol,
4454 context: Rc::clone(&context),
4455 overlaps,
4456 });
4457 }
4458 overlaps
4459 });
4460 if caller_overlaps {
4461 return None;
4462 }
4463 Some(true)
4464 }
4465
4466 pub fn left_recursive_loop_enter_matches(
4469 &mut self,
4470 atn: &Atn,
4471 state_number: usize,
4472 precedence: i32,
4473 ) -> bool {
4474 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
4475 }
4476
4477 pub fn precpred(&self, precedence: i32) -> bool {
4479 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
4480 }
4481
4482 pub fn parser_semantic_predicate_matches(
4485 &mut self,
4486 predicates: &[(usize, usize, ParserPredicate)],
4487 rule_index: usize,
4488 pred_index: usize,
4489 ) -> bool {
4490 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
4491 }
4492
4493 pub fn parser_semantic_predicate_matches_with_local(
4496 &mut self,
4497 predicates: &[(usize, usize, ParserPredicate)],
4498 rule_index: usize,
4499 pred_index: usize,
4500 local_int_arg: i32,
4501 ) -> bool {
4502 self.parser_semantic_predicate_matches_inner(
4503 predicates,
4504 rule_index,
4505 pred_index,
4506 Some((rule_index, i64::from(local_int_arg))),
4507 )
4508 }
4509
4510 fn parser_semantic_predicate_matches_inner(
4511 &mut self,
4512 predicates: &[(usize, usize, ParserPredicate)],
4513 rule_index: usize,
4514 pred_index: usize,
4515 local_int_arg: Option<(usize, i64)>,
4516 ) -> bool {
4517 let index = self.input.index();
4518 let member_values = self.int_members.clone();
4519 self.parser_predicate_matches(PredicateEval {
4520 index,
4521 rule_index,
4522 pred_index,
4523 predicates,
4524 semantics: None,
4525 context: None,
4526 local_int_arg,
4527 member_values: &member_values,
4528 })
4529 }
4530
4531 pub fn parser_semantic_predicate_matches_with_context_and_local(
4534 &mut self,
4535 predicates: &[(usize, usize, ParserPredicate)],
4536 rule_index: usize,
4537 pred_index: usize,
4538 context: &ParserRuleContext,
4539 local_int_arg: i32,
4540 ) -> bool {
4541 let index = self.input.index();
4542 let member_values = self.int_members.clone();
4543 self.parser_predicate_matches(PredicateEval {
4544 index,
4545 rule_index,
4546 pred_index,
4547 predicates,
4548 semantics: None,
4549 context: Some(context),
4550 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
4551 member_values: &member_values,
4552 })
4553 }
4554
4555 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
4558 &mut self,
4559 semantics: &ParserSemantics,
4560 rule_index: usize,
4561 pred_index: usize,
4562 context: &ParserRuleContext,
4563 local_int_arg: i32,
4564 ) -> bool {
4565 let index = self.input.index();
4566 let member_values = self.int_members.clone();
4567 self.parser_predicate_matches(PredicateEval {
4568 index,
4569 rule_index,
4570 pred_index,
4571 predicates: &[],
4572 semantics: Some(semantics),
4573 context: Some(context),
4574 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
4575 member_values: &member_values,
4576 })
4577 }
4578
4579 pub fn parser_semantic_predicate_failure_message(
4582 &self,
4583 rule_index: usize,
4584 pred_index: usize,
4585 predicates: &[(usize, usize, ParserPredicate)],
4586 ) -> Option<&'static str> {
4587 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
4588 }
4589
4590 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
4592 let current = self
4593 .input
4594 .lt_ref(1)
4595 .ok_or_else(|| AntlrError::ParserError {
4596 line: 0,
4597 column: 0,
4598 message: "missing current token".to_owned(),
4599 })?;
4600 if current.token_type() == TOKEN_EOF {
4601 return Err(AntlrError::MismatchedInput {
4602 expected: "wildcard".to_owned(),
4603 found: self.vocabulary().display_name(TOKEN_EOF),
4604 });
4605 }
4606 self.consume();
4607 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
4608 }
4609
4610 #[allow(clippy::unnecessary_wraps)]
4614 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
4615 self.set_state(state);
4616 Ok(())
4617 }
4618
4619 pub fn sync_decision(
4627 &mut self,
4628 atn: &Atn,
4629 state_number: usize,
4630 current_context_empty: bool,
4631 loop_back: bool,
4632 ) -> Result<Vec<ParseTree>, AntlrError> {
4633 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
4634 self.generated_sync_expected = None;
4635 let Some(state) = atn.state(state_number) else {
4636 return Ok(Vec::new());
4637 };
4638 let Some(rule_index) = state.rule_index else {
4639 return Ok(Vec::new());
4640 };
4641 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index).copied() else {
4642 return Ok(Vec::new());
4643 };
4644 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
4645 let symbol = self.la(1);
4646 let mut has_expected_symbols = false;
4647 let mut nullable = false;
4648 let mut explicit_eof_expected = false;
4656 for transition in &entry.transitions {
4657 if transition.symbols.contains(symbol) {
4658 return Ok(Vec::new());
4659 }
4660 has_expected_symbols |= !transition.symbols.is_empty();
4661 nullable |= transition.nullable;
4662 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
4663 }
4664 if nullable && self.context_expected_contains(atn, symbol) {
4669 return Ok(Vec::new());
4670 }
4671 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
4672 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
4673 return Ok(Vec::new());
4674 }
4675 let mut expected = TokenBitSet::default();
4676 for transition in &entry.transitions {
4677 expected.extend_from(&transition.symbols);
4678 }
4679 if let Some(context_expected) = context_expected {
4680 expected.extend_from(&context_expected);
4681 }
4682 let can_delete_in_place =
4683 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
4684 let loop_sync = loop_back;
4701 if symbol != TOKEN_EOF && can_delete_in_place {
4702 let mut cursor = self.input.index();
4703 let mut skipped = Vec::new();
4704 loop {
4705 let current = self.token_type_at(cursor);
4706 if current == TOKEN_EOF {
4707 break;
4708 }
4709 skipped.push(cursor);
4710 let next = self.consume_index(cursor, current);
4711 if next == cursor {
4712 break;
4713 }
4714 let next_symbol = self.token_type_at(next);
4715 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
4723 explicit_eof_expected
4724 } else {
4725 expected.contains(next_symbol)
4726 };
4727 if next_is_expected_stop {
4728 let current_token = self.input.lt(1).cloned();
4729 let expected_symbols = expected.to_btree_set();
4730 let message = format!(
4731 "extraneous input {} expecting {}",
4732 current_token
4733 .as_ref()
4734 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4735 self.expected_symbols_display(&expected_symbols)
4736 );
4737 self.push_generated_parser_diagnostic(diagnostic_for_token(
4738 current_token.as_ref(),
4739 message,
4740 ));
4741 self.record_syntax_errors(1);
4742 let mut children = Vec::with_capacity(skipped.len());
4743 for index in skipped {
4744 if let Some(token) = self.token_at(index) {
4745 self.consume();
4746 children.push(ParseTree::Error(ErrorNode::new(token)));
4747 }
4748 }
4749 return Ok(children);
4750 }
4751 if !loop_sync {
4755 break;
4756 }
4757 cursor = next;
4758 }
4759 }
4760 if nullable {
4761 self.generated_sync_expected = Some(expected);
4762 return Ok(Vec::new());
4763 }
4764 let current = self.input.lt(1).cloned();
4765 let expected_symbols = expected.to_btree_set();
4766 Err(AntlrError::ParserError {
4767 line: current.as_ref().map(Token::line).unwrap_or_default(),
4768 column: current.as_ref().map(Token::column).unwrap_or_default(),
4769 message: format!(
4770 "mismatched input {} expecting {}",
4771 current
4772 .as_ref()
4773 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4774 self.expected_symbols_display(&expected_symbols)
4775 ),
4776 })
4777 }
4778
4779 pub fn ll1_decision_prediction(
4786 &mut self,
4787 atn: &Atn,
4788 state_number: usize,
4789 ) -> Option<ParserAtnPrediction> {
4790 let state = atn.state(state_number)?;
4791 if state.precedence_rule_decision {
4792 return None;
4793 }
4794 let rule_stop = state
4795 .rule_index
4796 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())?;
4797 let symbol = self.la(1);
4798 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
4799 ll1_greedy_alt(&entry, symbol, state.non_greedy).map(|alt| ParserAtnPrediction {
4800 alt: alt + 1,
4801 requires_full_context: false,
4802 has_semantic_context: false,
4803 diagnostic: None,
4804 })
4805 }
4806
4807 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
4808 let context = self.prediction_context(atn);
4809 let mut expected = BTreeSet::new();
4810 self.collect_context_expected_symbols(atn, &context, &mut expected);
4811 expected
4812 }
4813
4814 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
4815 let context = self.prediction_context(atn);
4816 let mut expected = TokenBitSet::default();
4817 self.collect_context_expected_token_set(atn, &context, &mut expected);
4818 expected
4819 }
4820
4821 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
4832 for index in (1..self.rule_context_stack.len()).rev() {
4833 let invoking_state = self.rule_context_stack[index].invoking_state;
4834 let Ok(state_number) = usize::try_from(invoking_state) else {
4835 continue;
4836 };
4837 let Some(Transition::Rule { follow_state, .. }) = atn
4838 .state(state_number)
4839 .and_then(|state| state.transitions.first())
4840 else {
4841 continue;
4842 };
4843 let follow_state = *follow_state;
4844 if self
4845 .cached_state_expected_token_set(atn, follow_state)
4846 .contains(symbol)
4847 {
4848 return true;
4849 }
4850 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
4851 return false;
4852 }
4853 }
4854 symbol == TOKEN_EOF
4855 }
4856
4857 fn collect_context_expected_symbols(
4858 &mut self,
4859 atn: &Atn,
4860 context: &Rc<PredictionContext>,
4861 expected: &mut BTreeSet<i32>,
4862 ) {
4863 if context.is_empty() {
4864 expected.insert(TOKEN_EOF);
4865 return;
4866 }
4867 for index in 0..context.len() {
4868 let Some(return_state) = context.return_state(index) else {
4869 continue;
4870 };
4871 if return_state == EMPTY_RETURN_STATE {
4872 expected.insert(TOKEN_EOF);
4873 continue;
4874 }
4875 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
4876 if self.cached_state_can_reach_rule_stop(atn, return_state)
4877 && let Some(parent) = context.parent(index)
4878 {
4879 self.collect_context_expected_symbols(atn, &parent, expected);
4880 }
4881 }
4882 }
4883
4884 fn collect_context_expected_token_set(
4885 &mut self,
4886 atn: &Atn,
4887 context: &Rc<PredictionContext>,
4888 expected: &mut TokenBitSet,
4889 ) {
4890 if context.is_empty() {
4891 expected.insert(TOKEN_EOF);
4892 return;
4893 }
4894 for index in 0..context.len() {
4895 let Some(return_state) = context.return_state(index) else {
4896 continue;
4897 };
4898 if return_state == EMPTY_RETURN_STATE {
4899 expected.insert(TOKEN_EOF);
4900 continue;
4901 }
4902 let state_expected = self.cached_state_expected_token_set(atn, return_state);
4903 expected.extend_from(&state_expected);
4904 if self.cached_state_can_reach_rule_stop(atn, return_state)
4905 && let Some(parent) = context.parent(index)
4906 {
4907 self.collect_context_expected_token_set(atn, &parent, expected);
4908 }
4909 }
4910 }
4911
4912 pub fn no_viable_alternative_error(&mut self, start_index: usize) -> AntlrError {
4914 let error_index = self.input.index();
4915 self.no_viable_alternative_error_at(start_index, error_index)
4916 }
4917
4918 pub fn no_viable_alternative_error_at(
4923 &mut self,
4924 start_index: usize,
4925 error_index: usize,
4926 ) -> AntlrError {
4927 let diagnostic = self.no_viable_alternative(start_index, error_index);
4928 AntlrError::ParserError {
4929 line: diagnostic.line,
4930 column: diagnostic.column,
4931 message: diagnostic.message,
4932 }
4933 }
4934
4935 pub fn failed_predicate_error(&mut self, message: impl Into<String>) -> AntlrError {
4937 let current = self.input.lt(1).cloned();
4938 AntlrError::ParserError {
4939 line: current.as_ref().map(Token::line).unwrap_or_default(),
4940 column: current.as_ref().map(Token::column).unwrap_or_default(),
4941 message: format!("rule failed predicate: {}", message.into()),
4942 }
4943 }
4944
4945 pub fn failed_predicate_option_error(
4948 &mut self,
4949 rule_index: usize,
4950 message: impl Into<String>,
4951 ) -> AntlrError {
4952 let current = self.input.lt(1).cloned();
4953 let rule_name = self
4954 .rule_names()
4955 .get(rule_index)
4956 .map_or_else(|| rule_index.to_string(), Clone::clone);
4957 AntlrError::ParserError {
4958 line: current.as_ref().map(Token::line).unwrap_or_default(),
4959 column: current.as_ref().map(Token::column).unwrap_or_default(),
4960 message: format!("rule {rule_name} {}", message.into()),
4961 }
4962 }
4963
4964 pub fn parser_action_at_current(
4966 &mut self,
4967 source_state: usize,
4968 rule_index: usize,
4969 start_index: usize,
4970 consumed_eof: bool,
4971 ) -> ParserAction {
4972 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
4973 ParserAction::new(source_state, rule_index, start_index, stop_index)
4974 }
4975
4976 pub fn parser_action_hook(&mut self, action: ParserAction, tree: &ParseTree) -> bool {
4981 let rule_index = action.rule_index();
4982 let rule_name = self.rule_names().get(rule_index).cloned();
4983 let context = match tree {
4984 ParseTree::Rule(rule) if rule.context().rule_index() == rule_index => {
4985 Some(rule.context())
4986 }
4987 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
4988 };
4989 let input = &mut self.input;
4990 let semantic_hooks = &mut self.semantic_hooks;
4991 let member_values = &self.int_members;
4992 let mut ctx = ParserSemCtx {
4993 input,
4994 rule_index,
4995 coordinate_index: usize::MAX,
4996 rule_name,
4997 context,
4998 tree: Some(tree),
4999 local_int_arg: None,
5000 member_values,
5001 action: Some(action),
5002 };
5003 let handled = semantic_hooks.action(&mut ctx, action);
5004 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
5010 let coordinate = (rule_index, action.source_state());
5011 if !self.unhandled_action_hits.contains(&coordinate) {
5012 self.unhandled_action_hits.push(coordinate);
5013 }
5014 }
5015 handled
5016 }
5017
5018 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
5023 &mut self,
5024 atn: &'atn Atn,
5025 simulator: &mut ParserAtnSimulator<'atn>,
5026 rule_index: usize,
5027 ) -> Result<ParseTree, AntlrError> {
5028 let start_index = self.current_visible_index();
5029 self.clear_prediction_diagnostics();
5030 self.reset_per_parse_caches();
5031 let mut decision_by_state = vec![None; atn.states().len()];
5032 for (decision, &state_number) in atn.decision_to_state().iter().enumerate() {
5033 if let Some(slot) = decision_by_state.get_mut(state_number) {
5034 *slot = Some(decision);
5035 }
5036 }
5037
5038 let result = DirectAdaptiveParser {
5039 parser: self,
5040 atn,
5041 simulator,
5042 decision_by_state,
5043 steps: 0,
5044 }
5045 .parse_rule(rule_index, -1, 0);
5046
5047 match result {
5048 Ok(tree) => {
5049 report_token_source_errors(&self.input.drain_source_errors());
5050 Ok(tree)
5051 }
5052 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
5053 let _ = reason;
5054 self.input.seek(start_index);
5055 self.parse_atn_rule(atn, rule_index)
5056 }
5057 }
5058 }
5059
5060 pub fn parse_atn_rule(
5070 &mut self,
5071 atn: &Atn,
5072 rule_index: usize,
5073 ) -> Result<ParseTree, AntlrError> {
5074 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
5075 }
5076
5077 pub fn parse_atn_rule_with_precedence(
5080 &mut self,
5081 atn: &Atn,
5082 rule_index: usize,
5083 precedence: i32,
5084 ) -> Result<ParseTree, AntlrError> {
5085 let start_state = atn
5086 .rule_to_start_state()
5087 .get(rule_index)
5088 .copied()
5089 .ok_or_else(|| {
5090 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
5091 })?;
5092 let stop_state = atn
5093 .rule_to_stop_state()
5094 .get(rule_index)
5095 .copied()
5096 .filter(|state| *state != usize::MAX)
5097 .ok_or_else(|| {
5098 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
5099 })?;
5100
5101 let start_index = self.current_visible_index();
5102 self.clear_prediction_diagnostics();
5103 self.reset_per_parse_caches();
5104 let caller_follow_state = self.pending_invoking_follow_state(atn);
5105 self.fast_recovery_enabled = false;
5106 self.fast_token_nodes_enabled = false;
5107 let top_request = FastRecognizeTopRequest {
5108 start_state,
5109 stop_state,
5110 start_index,
5111 precedence,
5112 caller_follow_state,
5113 };
5114 let first_pass = self.fast_recognize_top(atn, top_request);
5115 self.fast_token_nodes_enabled = true;
5116 let needs_tree_retry = matches!(
5117 &first_pass,
5118 Ok((outcome, _)) if self.build_parse_trees && outcome.nodes.has_left_recursive_boundary()
5119 );
5120 let needs_retry = match &first_pass {
5121 Err(_) => true,
5134 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
5135 };
5136 let (outcome, _expected) = if needs_retry {
5137 self.fast_first_set_prefilter = false;
5138 self.fast_recovery_enabled = false;
5139 let clean_retry = self.fast_recognize_top(atn, top_request);
5140 let clean_selected = if needs_tree_retry {
5141 match clean_retry {
5142 ok @ Ok(_) => ok,
5143 Err(_) => first_pass,
5144 }
5145 } else {
5146 select_better_top_outcome(first_pass, clean_retry)
5147 };
5148 let selected = if clean_selected.is_err()
5149 || matches!(&clean_selected, Ok((outcome, _)) if !outcome.diagnostics.is_empty())
5150 {
5151 self.fast_recovery_enabled = true;
5152 let recovery_retry = self.fast_recognize_top(atn, top_request);
5153 select_better_top_outcome(clean_selected, recovery_retry)
5154 } else {
5155 clean_selected
5156 };
5157 self.fast_first_set_prefilter = true;
5158 self.fast_recovery_enabled = true;
5159 selected.map_err(|expected| {
5160 let error = self.recognition_error(rule_index, start_index, &expected);
5161 self.record_syntax_errors(1);
5162 report_token_source_errors(&self.input.drain_source_errors());
5163 error
5164 })?
5165 } else {
5166 first_pass.expect("first_pass is Ok in the no-retry branch")
5167 };
5168 self.record_syntax_errors(outcome.diagnostics.len());
5169 report_parser_diagnostics(&self.prediction_diagnostics);
5170 report_parser_diagnostics(&outcome.diagnostics);
5171 report_token_source_errors(&self.input.drain_source_errors());
5172 let mut context = ParserRuleContext::with_child_capacity(
5173 rule_index,
5174 self.state(),
5175 if self.build_parse_trees {
5176 outcome.nodes.len()
5177 } else {
5178 0
5179 },
5180 );
5181 if let Some(token) = self.token_ref_at(start_index) {
5182 context.set_start_ref(token);
5183 }
5184 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
5185 if let Some(token) = stop_index.and_then(|token_index| self.token_ref_at(token_index)) {
5186 context.set_stop_ref(token);
5187 }
5188 if self.build_parse_trees {
5189 if outcome.nodes.has_left_recursive_boundary() {
5190 let folded = fold_fast_left_recursive_boundaries(outcome.nodes.to_vec());
5191 if folded.iter().any(|node| {
5192 matches!(
5193 node.as_ref(),
5194 FastRecognizedNode::Token { .. }
5195 | FastRecognizedNode::ErrorToken { .. }
5196 | FastRecognizedNode::MissingToken { .. }
5197 )
5198 }) {
5199 for node in &folded {
5200 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
5201 }
5202 } else {
5203 self.add_fast_implicit_token_children(
5204 &mut context,
5205 start_index,
5206 stop_index,
5207 &folded,
5208 )?;
5209 }
5210 } else if outcome.nodes.has_explicit_token_node() {
5211 for node in outcome.nodes.iter() {
5212 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
5213 }
5214 } else {
5215 self.add_fast_implicit_token_children_iter(
5216 &mut context,
5217 start_index,
5218 stop_index,
5219 outcome.nodes.iter(),
5220 )?;
5221 }
5222 }
5223 self.input.seek(outcome.index);
5224
5225 Ok(self.rule_node(context))
5226 }
5227
5228 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
5229 let invoking_state = self.pending_invoking_states.last().copied()?;
5230 let state_number = usize::try_from(invoking_state).ok()?;
5231 match atn.state(state_number)?.transitions.first()? {
5232 Transition::Rule { follow_state, .. } => Some(*follow_state),
5233 _ => None,
5234 }
5235 }
5236
5237 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
5238 let token_type = self.token_type_at(index);
5241 let visible_channel = self.input.channel();
5242 let token = self.token_at(index);
5243 let is_boundary = token
5244 .as_ref()
5245 .and_then(Token::text)
5246 .is_some_and(is_caller_follow_boundary_text);
5247 let is_boundary_gap = token.as_ref().is_some_and(|token| {
5248 token.channel() != visible_channel || is_caller_follow_boundary_gap_text(token.text())
5249 });
5250 (token_type, is_boundary, is_boundary_gap)
5251 }
5252
5253 fn fast_recognize_top(
5258 &mut self,
5259 atn: &Atn,
5260 request: FastRecognizeTopRequest,
5261 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
5262 let FastRecognizeTopRequest {
5263 start_state,
5264 stop_state,
5265 start_index,
5266 precedence,
5267 caller_follow_state,
5268 } = request;
5269 let memo_capacity = self.input.size().saturating_mul(8).clamp(65_536, 524_288);
5278 let mut visiting = FxHashSet::with_capacity_and_hasher(256, FxBuildHasher::default());
5279 let mut memo = FxHashMap::with_capacity_and_hasher(memo_capacity, FxBuildHasher::default());
5280 let mut expected = ExpectedTokens::default();
5281 let empty_recovery = self.empty_recovery_symbols();
5282 let outcomes = self.recognize_state_fast(
5283 atn,
5284 FastRecognizeRequest {
5285 state_number: start_state,
5286 stop_state,
5287 index: start_index,
5288 rule_start_index: start_index,
5289 decision_start_index: None,
5290 precedence,
5291 depth: 0,
5292 recovery_symbols: empty_recovery,
5293 recovery_state: None,
5294 },
5295 &mut visiting,
5296 &mut memo,
5297 &mut expected,
5298 );
5299 #[cfg(feature = "perf-counters")]
5300 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
5301 perf_counters::dump();
5302 perf_counters::reset();
5303 }
5304 let caller_follow =
5305 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
5306 match select_best_fast_outcome(
5307 outcomes.into_iter(),
5308 self.prediction_mode,
5309 caller_follow.as_deref(),
5310 |index| self.caller_follow_token_info(index),
5311 ) {
5312 Some(outcome) => Ok((outcome, expected)),
5313 None => Err(expected),
5314 }
5315 }
5316
5317 fn fast_recognized_node_tree(
5320 &mut self,
5321 node: &FastRecognizedNode,
5322 ) -> Result<ParseTree, AntlrError> {
5323 match node {
5324 FastRecognizedNode::Token { index } => {
5325 let token = self
5326 .input
5327 .get_ref(*index)
5328 .ok_or_else(|| AntlrError::ParserError {
5329 line: 0,
5330 column: 0,
5331 message: format!("missing token at index {index}"),
5332 })?;
5333 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
5334 }
5335 FastRecognizedNode::ErrorToken { index } => {
5336 let token = self
5337 .input
5338 .get_ref(*index)
5339 .ok_or_else(|| AntlrError::ParserError {
5340 line: 0,
5341 column: 0,
5342 message: format!("missing error token at index {index}"),
5343 })?;
5344 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
5345 }
5346 FastRecognizedNode::MissingToken {
5347 token_type,
5348 at_index,
5349 text,
5350 } => {
5351 let current = self.token_at(*at_index);
5352 let token = CommonToken::new(*token_type)
5353 .with_text(text.as_str())
5354 .with_span(usize::MAX, usize::MAX)
5355 .with_position(
5356 current.as_ref().map(Token::line).unwrap_or_default(),
5357 current.as_ref().map(Token::column).unwrap_or_default(),
5358 );
5359 Ok(ParseTree::Error(ErrorNode::new(token)))
5360 }
5361 FastRecognizedNode::Rule {
5362 rule_index,
5363 invoking_state,
5364 start_index,
5365 stop_index,
5366 children,
5367 } => {
5368 let mut context = ParserRuleContext::with_child_capacity(
5369 *rule_index,
5370 *invoking_state,
5371 children.len(),
5372 );
5373 if let Some(token) = self.token_ref_at(*start_index) {
5374 context.set_start_ref(token);
5375 }
5376 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
5377 context.set_stop_ref(token);
5378 }
5379 if children.has_left_recursive_boundary() {
5380 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
5381 for child in &folded {
5382 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
5383 }
5384 } else {
5385 for child in children.iter() {
5386 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
5387 }
5388 }
5389 Ok(self.rule_node(context))
5390 }
5391 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
5392 Err(AntlrError::Unsupported(format!(
5393 "unfolded left-recursive boundary for rule {rule_index}"
5394 )))
5395 }
5396 }
5397 }
5398
5399 fn fast_recognized_node_tree_with_implicit_tokens(
5400 &mut self,
5401 node: &FastRecognizedNode,
5402 ) -> Result<ParseTree, AntlrError> {
5403 match node {
5404 FastRecognizedNode::Rule {
5405 rule_index,
5406 invoking_state,
5407 start_index,
5408 stop_index,
5409 children,
5410 } => {
5411 let mut context = ParserRuleContext::with_child_capacity(
5412 *rule_index,
5413 *invoking_state,
5414 children.len(),
5415 );
5416 if let Some(token) = self.token_ref_at(*start_index) {
5417 context.set_start_ref(token);
5418 }
5419 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
5420 context.set_stop_ref(token);
5421 }
5422 if children.has_left_recursive_boundary() {
5423 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
5424 self.add_fast_implicit_token_children(
5425 &mut context,
5426 *start_index,
5427 *stop_index,
5428 &folded,
5429 )?;
5430 } else {
5431 self.add_fast_implicit_token_children_iter(
5432 &mut context,
5433 *start_index,
5434 *stop_index,
5435 children.iter(),
5436 )?;
5437 }
5438 Ok(self.rule_node(context))
5439 }
5440 _ => self.fast_recognized_node_tree(node),
5441 }
5442 }
5443
5444 fn add_fast_implicit_token_children(
5445 &mut self,
5446 context: &mut ParserRuleContext,
5447 start_index: usize,
5448 stop_index: Option<usize>,
5449 children: &[Rc<FastRecognizedNode>],
5450 ) -> Result<(), AntlrError> {
5451 self.add_fast_implicit_token_children_iter(
5452 context,
5453 start_index,
5454 stop_index,
5455 children.iter(),
5456 )
5457 }
5458
5459 fn add_fast_implicit_token_children_iter<'a>(
5460 &mut self,
5461 context: &mut ParserRuleContext,
5462 start_index: usize,
5463 stop_index: Option<usize>,
5464 children: impl IntoIterator<Item = &'a Rc<FastRecognizedNode>>,
5465 ) -> Result<(), AntlrError> {
5466 let mut cursor = Some(start_index);
5467 for child in children {
5468 if let Some((child_start, child_stop)) = fast_recognized_node_span(child.as_ref()) {
5469 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
5470 context.add_child(
5471 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
5472 );
5473 if let Some(child_stop) = child_stop {
5474 cursor = self.next_visible_after_token(child_stop);
5475 }
5476 } else {
5477 context.add_child(
5478 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
5479 );
5480 }
5481 }
5482 if let Some(stop) = stop_index {
5483 self.add_visible_terminals_through(context, cursor, stop)?;
5484 }
5485 Ok(())
5486 }
5487
5488 fn add_visible_terminals_before(
5489 &mut self,
5490 context: &mut ParserRuleContext,
5491 cursor: &mut Option<usize>,
5492 before: usize,
5493 ) -> Result<(), AntlrError> {
5494 let Some(stop) = before.checked_sub(1) else {
5495 return Ok(());
5496 };
5497 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
5498 *cursor = next;
5499 Ok(())
5500 }
5501
5502 fn add_visible_terminals_through(
5503 &mut self,
5504 context: &mut ParserRuleContext,
5505 mut cursor: Option<usize>,
5506 stop: usize,
5507 ) -> Result<Option<usize>, AntlrError> {
5508 while let Some(index) = cursor {
5509 if index > stop {
5510 return Ok(Some(index));
5511 }
5512 let token = self
5513 .input
5514 .get_ref(index)
5515 .ok_or_else(|| AntlrError::ParserError {
5516 line: 0,
5517 column: 0,
5518 message: format!("missing token at index {index}"),
5519 })?;
5520 let is_eof = token.token_type() == TOKEN_EOF;
5521 context.add_child(ParseTree::Terminal(TerminalNode::from_ref(token)));
5522 if is_eof {
5523 return Ok(None);
5524 }
5525 cursor = self.next_visible_after_token(index);
5526 }
5527 Ok(None)
5528 }
5529
5530 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
5531 let next = self.input.next_visible_after(index);
5532 (next != index).then_some(next)
5533 }
5534
5535 pub fn parse_atn_rule_with_actions(
5542 &mut self,
5543 atn: &Atn,
5544 rule_index: usize,
5545 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5546 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
5547 }
5548
5549 pub fn parse_atn_rule_with_action_inits(
5557 &mut self,
5558 atn: &Atn,
5559 rule_index: usize,
5560 init_action_rules: &[usize],
5561 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5562 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
5563 }
5564
5565 pub fn parse_atn_rule_with_action_options(
5571 &mut self,
5572 atn: &Atn,
5573 rule_index: usize,
5574 init_action_rules: &[usize],
5575 track_alt_numbers: bool,
5576 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5577 self.parse_atn_rule_with_runtime_options(
5578 atn,
5579 rule_index,
5580 ParserRuntimeOptions {
5581 init_action_rules,
5582 track_alt_numbers,
5583 ..ParserRuntimeOptions::default()
5584 },
5585 )
5586 }
5587
5588 pub fn parse_atn_rule_with_runtime_options(
5595 &mut self,
5596 atn: &Atn,
5597 rule_index: usize,
5598 options: ParserRuntimeOptions<'_>,
5599 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5600 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
5601 }
5602
5603 pub fn parse_atn_rule_with_runtime_options_and_precedence(
5606 &mut self,
5607 atn: &Atn,
5608 rule_index: usize,
5609 precedence: i32,
5610 options: ParserRuntimeOptions<'_>,
5611 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5612 let ParserRuntimeOptions {
5613 init_action_rules,
5614 track_alt_numbers,
5615 predicates,
5616 semantics,
5617 rule_args,
5618 member_actions,
5619 return_actions,
5620 unknown_predicate_policy,
5621 } = options;
5622 if init_action_rules.is_empty()
5623 && !track_alt_numbers
5624 && predicates.is_empty()
5625 && semantics.is_none()
5626 && rule_args.is_empty()
5627 && member_actions.is_empty()
5628 && return_actions.is_empty()
5629 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
5630 && !atn_has_observable_action_transitions(atn)
5631 && (!self.semantic_hooks.observes_parser_predicates()
5632 || !atn_has_predicate_transitions(atn))
5633 {
5634 return self
5635 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
5636 .map(|tree| (tree, Vec::new()));
5637 }
5638 self.unknown_predicate_policy = unknown_predicate_policy;
5639 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
5646 let start_state = atn
5647 .rule_to_start_state()
5648 .get(rule_index)
5649 .copied()
5650 .ok_or_else(|| {
5651 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
5652 })?;
5653 let stop_state = atn
5654 .rule_to_stop_state()
5655 .get(rule_index)
5656 .copied()
5657 .filter(|state| *state != usize::MAX)
5658 .ok_or_else(|| {
5659 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
5660 })?;
5661
5662 let start_index = self.current_visible_index();
5663 self.clear_prediction_diagnostics();
5664 self.reset_per_parse_caches();
5665 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
5666 let invoking_state = self.pending_invoking_states.pop();
5667 let local_int_arg = invoking_state
5668 .and_then(|state| usize::try_from(state).ok())
5669 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
5670 let mut visiting = BTreeSet::new();
5671 let mut memo = BTreeMap::new();
5672 let mut expected = ExpectedTokens::default();
5673 let member_values = self.int_members.clone();
5674 let return_values = BTreeMap::new();
5675 let outcomes = self.recognize_state(
5676 atn,
5677 RecognizeRequest {
5678 state_number: start_state,
5679 stop_state,
5680 index: start_index,
5681 rule_start_index: start_index,
5682 decision_start_index: None,
5683 init_action_rules: &init_action_rules,
5684 predicates,
5685 semantics,
5686 rule_args,
5687 member_actions,
5688 return_actions,
5689 local_int_arg,
5690 member_values,
5691 return_values,
5692 rule_alt_number: 0,
5693 track_alt_numbers,
5694 consumed_eof: false,
5695 precedence,
5696 depth: 0,
5697 recovery_symbols: BTreeSet::new(),
5698 recovery_state: None,
5699 },
5700 &mut visiting,
5701 &mut memo,
5702 &mut expected,
5703 );
5704 if let Some(error) = self.unknown_semantic_error() {
5705 report_token_source_errors(&self.input.drain_source_errors());
5706 return Err(error);
5713 }
5714 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
5717 let Some(outcome) = select_best_outcome(outcomes.into_iter(), self.prediction_mode) else {
5718 let error = self.recognition_error(rule_index, start_index, &expected);
5719 self.record_syntax_errors(1);
5720 report_token_source_errors(&self.input.drain_source_errors());
5721 return Err(error);
5722 };
5723
5724 self.record_syntax_errors(outcome.diagnostics.len());
5725 report_parser_diagnostics(&self.prediction_diagnostics);
5726 report_parser_diagnostics(&outcome.diagnostics);
5727 report_token_source_errors(&self.input.drain_source_errors());
5728 let mut actions = outcome.actions;
5729 if init_action_rules.contains(&rule_index) {
5730 actions.insert(
5731 0,
5732 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
5733 );
5734 }
5735 let mut context =
5736 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
5737 if track_alt_numbers {
5738 context.set_alt_number(outcome.alt_number);
5739 }
5740 for (name, value) in outcome.return_values {
5741 context.set_int_return(name, value);
5742 }
5743 if let Some(token) = self.token_ref_at(start_index) {
5744 context.set_start_ref(token);
5745 }
5746 if let Some(token) = self.rule_stop_token_ref(outcome.index, outcome.consumed_eof) {
5747 context.set_stop_ref(token);
5748 }
5749 if self.build_parse_trees {
5750 let nodes = fold_left_recursive_boundaries(outcome.nodes);
5751 for node in &nodes {
5752 context.add_child(self.recognized_node_tree(node, track_alt_numbers)?);
5753 }
5754 }
5755 self.input.seek(outcome.index);
5756
5757 Ok((self.rule_node(context), actions))
5758 }
5759
5760 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
5767 let mut context = ParserRuleContext::new(rule_index, self.state());
5768 while self.la(1) != TOKEN_EOF {
5769 let token_type = self.la(1);
5770 let child = self.match_token(token_type)?;
5771 if self.build_parse_trees {
5772 context.add_child(child);
5773 }
5774 }
5775 if self.build_parse_trees {
5776 context.add_child(self.match_eof()?);
5777 }
5778 Ok(self.rule_node(context))
5779 }
5780
5781 fn recognition_error(
5784 &mut self,
5785 rule_index: usize,
5786 start_index: usize,
5787 expected: &ExpectedTokens,
5788 ) -> AntlrError {
5789 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
5790 self.input.seek(index);
5791 let current = self.input.lt(1).cloned();
5792 let line = current.as_ref().map(Token::line).unwrap_or_default();
5793 let column = current.as_ref().map(Token::column).unwrap_or_default();
5794 AntlrError::ParserError {
5795 line,
5796 column,
5797 message,
5798 }
5799 }
5800
5801 fn expected_error_message(
5803 &mut self,
5804 rule_index: usize,
5805 start_index: usize,
5806 expected: &ExpectedTokens,
5807 ) -> (usize, String) {
5808 let index = expected
5809 .index
5810 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
5811 .unwrap_or_else(|| self.input.index());
5812 self.input.seek(index);
5813 let current = self.input.lt(1).cloned();
5814 let message = if expected
5815 .no_viable
5816 .as_ref()
5817 .is_some_and(|no_viable| no_viable.error_index == index)
5818 {
5819 let start = expected
5820 .no_viable
5821 .as_ref()
5822 .map_or(start_index, |no_viable| no_viable.start_index);
5823 let text = display_input_text(&self.input.text(start, index));
5824 format!("no viable alternative at input '{text}'")
5825 } else if expected.symbols.is_empty() {
5826 if expected.index.is_some() {
5827 let found = current
5828 .as_ref()
5829 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
5830 if current
5831 .as_ref()
5832 .is_some_and(|token| token.token_type() == TOKEN_EOF)
5833 {
5834 format!(
5835 "missing {} at {found}",
5836 self.expected_symbols_display(&expected.symbols)
5837 )
5838 } else {
5839 format!("mismatched input {found}")
5840 }
5841 } else {
5842 format!("no viable alternative while parsing rule {rule_index}")
5843 }
5844 } else {
5845 format!(
5846 "mismatched input {} expecting {}",
5847 current
5848 .as_ref()
5849 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5850 self.expected_symbols_display(&expected.symbols)
5851 )
5852 };
5853 (index, message)
5854 }
5855
5856 fn child_rule_failure_recovery(
5859 &mut self,
5860 rule_index: usize,
5861 start_index: usize,
5862 sync_symbols: &BTreeSet<i32>,
5863 member_values: BTreeMap<usize, i64>,
5864 expected: &ExpectedTokens,
5865 ) -> Option<RecognizeOutcome> {
5866 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
5867 let token = self.token_at(error_index);
5868 let mut next_index = error_index;
5869 loop {
5870 let symbol = self.token_type_at(next_index);
5871 if sync_symbols.contains(&symbol) {
5872 if next_index == error_index {
5873 return None;
5874 }
5875 break;
5876 }
5877 if symbol == TOKEN_EOF {
5878 break;
5879 }
5880 let after = self.consume_index(next_index, symbol);
5881 if after == next_index {
5882 break;
5883 }
5884 next_index = after;
5885 }
5886 Some(RecognizeOutcome {
5887 index: next_index,
5888 consumed_eof: false,
5889 alt_number: 0,
5890 member_values,
5891 return_values: BTreeMap::new(),
5892 diagnostics: vec![diagnostic_for_token(token.as_ref(), message)],
5893 decisions: Vec::new(),
5894 actions: Vec::new(),
5895 nodes: vec![RecognizedNode::ErrorToken { index: error_index }],
5896 })
5897 }
5898
5899 fn child_rule_failure_recovery_outcomes(
5902 &mut self,
5903 request: ChildRuleFailureRecovery<'_>,
5904 ) -> Vec<RecognizeOutcome> {
5905 let sync_symbols =
5906 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
5907 self.child_rule_failure_recovery(
5908 request.rule_index,
5909 request.start_index,
5910 &sync_symbols,
5911 request.member_values,
5912 request.expected,
5913 )
5914 .into_iter()
5915 .collect()
5916 }
5917
5918 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
5920 expected_symbols_display(symbols, self.vocabulary())
5921 }
5922
5923 fn single_token_deletion(
5926 &mut self,
5927 transition: &Transition,
5928 index: usize,
5929 max_token_type: i32,
5930 expected_symbols: &BTreeSet<i32>,
5931 ) -> Option<(ParserDiagnostic, usize, i32)> {
5932 let current_symbol = self.token_type_at(index);
5933 if current_symbol == TOKEN_EOF {
5934 return None;
5935 }
5936 let next_index = self.consume_index(index, current_symbol);
5937 if next_index == index {
5938 return None;
5939 }
5940 let next_symbol = self.token_type_at(next_index);
5941 if !transition.matches(next_symbol, 1, max_token_type) {
5942 return None;
5943 }
5944 let transition_expected = transition_expected_symbols(transition, max_token_type);
5945 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
5946 &transition_expected
5947 } else {
5948 expected_symbols
5949 });
5950 let current = self.token_at(index);
5951 let message = format!(
5952 "extraneous input {} expecting {expected_display}",
5953 current
5954 .as_ref()
5955 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
5956 );
5957 Some((
5958 diagnostic_for_token(current.as_ref(), message),
5959 next_index,
5960 next_symbol,
5961 ))
5962 }
5963
5964 fn current_token_deletion(
5967 &mut self,
5968 index: usize,
5969 expected_symbols: &BTreeSet<i32>,
5970 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
5971 if expected_symbols.is_empty() {
5972 return None;
5973 }
5974 let current_symbol = self.token_type_at(index);
5975 if current_symbol == TOKEN_EOF {
5976 return None;
5977 }
5978 let current = self.token_at(index);
5979 let message = format!(
5980 "extraneous input {} expecting {}",
5981 current
5982 .as_ref()
5983 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5984 self.expected_symbols_display(expected_symbols)
5985 );
5986 let diagnostic = diagnostic_for_token(current.as_ref(), message);
5987 let mut skipped = Vec::new();
5988 let mut cursor = index;
5989 loop {
5990 let symbol = self.token_type_at(cursor);
5991 if symbol == TOKEN_EOF {
5992 return None;
5993 }
5994 skipped.push(cursor);
5995 let next_index = self.consume_index(cursor, symbol);
5996 if next_index == cursor {
5997 return None;
5998 }
5999 let next_symbol = self.token_type_at(next_index);
6000 if expected_symbols.contains(&next_symbol) {
6001 return Some((diagnostic, next_index, skipped));
6002 }
6003 cursor = next_index;
6004 }
6005 }
6006
6007 fn single_token_insertion(
6011 &mut self,
6012 transition: &Transition,
6013 index: usize,
6014 max_token_type: i32,
6015 expected_symbols: &BTreeSet<i32>,
6016 follow_symbols: &BTreeSet<i32>,
6017 ) -> Option<(ParserDiagnostic, i32, String)> {
6018 let current_symbol = self.token_type_at(index);
6019 if !follow_symbols.contains(¤t_symbol) {
6020 return None;
6021 }
6022 let transition_expected = transition_expected_symbols(transition, max_token_type);
6023 let token_type = transition_expected.iter().next().copied()?;
6024 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
6025 &transition_expected
6026 } else {
6027 expected_symbols
6028 });
6029 let mut token_symbols = BTreeSet::new();
6030 token_symbols.insert(token_type);
6031 let missing_token_display = self.expected_symbols_display(&token_symbols);
6032 let current = self.token_at(index);
6033 let message = format!(
6034 "missing {expected_display} at {}",
6035 current
6036 .as_ref()
6037 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
6038 );
6039 let text = format!("<missing {missing_token_display}>");
6040 Some((
6041 diagnostic_for_token(current.as_ref(), message),
6042 token_type,
6043 text,
6044 ))
6045 }
6046
6047 fn fast_single_token_deletion_recovery(
6051 &mut self,
6052 recovery: FastRecoveryRequest<'_, '_>,
6053 ) -> Vec<FastRecognizeOutcome> {
6054 let FastRecoveryRequest {
6055 atn,
6056 transition,
6057 expected_symbols,
6058 target,
6059 request,
6060 visiting,
6061 memo,
6062 expected,
6063 } = recovery;
6064 let FastRecognizeRequest {
6065 stop_state,
6066 index,
6067 rule_start_index,
6068 decision_start_index,
6069 precedence,
6070 depth,
6071 ..
6072 } = request;
6073 let Some((diagnostic, next_index, next_symbol)) =
6074 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
6075 else {
6076 return Vec::new();
6077 };
6078 let after_next = self.consume_index(next_index, next_symbol);
6079 let empty_recovery = self.empty_recovery_symbols();
6080 self.recognize_state_fast(
6081 atn,
6082 FastRecognizeRequest {
6083 state_number: target,
6084 stop_state,
6085 index: after_next,
6086 rule_start_index,
6087 decision_start_index,
6088 precedence,
6089 depth: depth + 1,
6090 recovery_symbols: empty_recovery,
6091 recovery_state: None,
6092 },
6093 visiting,
6094 memo,
6095 expected,
6096 )
6097 .into_iter()
6098 .map(|mut outcome| {
6099 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
6100 outcome.diagnostics.insert(0, diagnostic.clone());
6101 if self.fast_token_nodes_enabled {
6102 outcome
6103 .nodes
6104 .prepend(Rc::new(FastRecognizedNode::Token { index: next_index }));
6105 outcome
6106 .nodes
6107 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index }));
6108 }
6109 outcome
6110 })
6111 .collect()
6112 }
6113
6114 fn fast_single_token_insertion_recovery(
6118 &mut self,
6119 recovery: FastRecoveryRequest<'_, '_>,
6120 ) -> Vec<FastRecognizeOutcome> {
6121 let FastRecoveryRequest {
6122 atn,
6123 transition,
6124 expected_symbols,
6125 target,
6126 request,
6127 visiting,
6128 memo,
6129 expected,
6130 } = recovery;
6131 let FastRecognizeRequest {
6132 stop_state,
6133 index,
6134 rule_start_index,
6135 decision_start_index,
6136 precedence,
6137 depth,
6138 ..
6139 } = request;
6140 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
6141 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
6142 transition,
6143 index,
6144 atn.max_token_type(),
6145 &expected_symbols,
6146 &follow_symbols,
6147 ) else {
6148 return Vec::new();
6149 };
6150 let empty_recovery = self.empty_recovery_symbols();
6151 self.recognize_state_fast(
6152 atn,
6153 FastRecognizeRequest {
6154 state_number: target,
6155 stop_state,
6156 index,
6157 rule_start_index,
6158 decision_start_index,
6159 precedence,
6160 depth: depth + 1,
6161 recovery_symbols: empty_recovery,
6162 recovery_state: None,
6163 },
6164 visiting,
6165 memo,
6166 expected,
6167 )
6168 .into_iter()
6169 .map(|mut outcome| {
6170 outcome.diagnostics.insert(0, diagnostic.clone());
6171 outcome
6172 .nodes
6173 .prepend(Rc::new(FastRecognizedNode::MissingToken {
6174 token_type,
6175 at_index: index,
6176 text: text.clone(),
6177 }));
6178 outcome
6179 })
6180 .collect()
6181 }
6182
6183 fn fast_current_token_deletion_recovery(
6186 &mut self,
6187 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
6188 ) -> Vec<FastRecognizeOutcome> {
6189 let FastCurrentTokenDeletionRequest {
6190 atn,
6191 expected_symbols,
6192 mut request,
6193 visiting,
6194 memo,
6195 expected,
6196 } = recovery;
6197 if request.index == request.rule_start_index {
6198 return Vec::new();
6199 }
6200 let Some((diagnostic, next_index, skipped)) =
6201 self.current_token_deletion(request.index, &expected_symbols)
6202 else {
6203 return Vec::new();
6204 };
6205 request.state_number = request.recovery_state.unwrap_or(request.state_number);
6206 request.index = next_index;
6207 request.depth += 1;
6208 request.recovery_state = None;
6209 self.recognize_state_fast(atn, request, visiting, memo, expected)
6210 .into_iter()
6211 .map(|mut outcome| {
6212 outcome.diagnostics.insert(0, diagnostic.clone());
6213 for index in skipped.iter().rev() {
6214 outcome
6215 .nodes
6216 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index: *index }));
6217 }
6218 outcome
6219 })
6220 .collect()
6221 }
6222
6223 fn fast_child_rule_failure_recovery(
6226 &mut self,
6227 rule_index: usize,
6228 start_index: usize,
6229 sync_symbols: &BTreeSet<i32>,
6230 expected: &ExpectedTokens,
6231 ) -> Option<FastRecognizeOutcome> {
6232 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
6233 let token = self.token_at(error_index);
6234 let mut next_index = error_index;
6235 loop {
6236 let symbol = self.token_type_at(next_index);
6237 if sync_symbols.contains(&symbol) {
6238 if next_index == error_index {
6239 return None;
6240 }
6241 break;
6242 }
6243 if symbol == TOKEN_EOF {
6244 break;
6245 }
6246 let after = self.consume_index(next_index, symbol);
6247 if after == next_index {
6248 break;
6249 }
6250 next_index = after;
6251 }
6252 let mut diagnostics = FastDiagnostics::new();
6253 diagnostics.insert(0, diagnostic_for_token(token.as_ref(), message));
6254 let mut nodes = NodeList::new();
6255 if self.fast_token_nodes_enabled {
6256 nodes.prepend(Rc::new(FastRecognizedNode::ErrorToken {
6257 index: error_index,
6258 }));
6259 }
6260 Some(FastRecognizeOutcome {
6261 index: next_index,
6262 consumed_eof: false,
6263 diagnostics,
6264 nodes,
6265 })
6266 }
6267
6268 fn fast_child_rule_failure_recovery_outcomes(
6271 &mut self,
6272 request: FastChildRuleFailureRecoveryRequest<'_>,
6273 ) -> Vec<FastRecognizeOutcome> {
6274 let FastChildRuleFailureRecoveryRequest {
6275 atn,
6276 rule_index,
6277 start_index,
6278 follow_state,
6279 stop_state,
6280 expected,
6281 } = request;
6282 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
6283 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
6284 .into_iter()
6285 .collect()
6286 }
6287
6288 #[allow(clippy::too_many_lines)]
6291 fn recognize_state_fast(
6292 &mut self,
6293 atn: &Atn,
6294 request: FastRecognizeRequest,
6295 visiting: &mut FxHashSet<FastRecognizeKey>,
6296 memo: &mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
6297 expected: &mut ExpectedTokens,
6298 ) -> Vec<FastRecognizeOutcome> {
6299 #[cfg(feature = "perf-counters")]
6300 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
6301 let FastRecognizeRequest {
6302 mut state_number,
6303 stop_state,
6304 mut index,
6305 rule_start_index,
6306 decision_start_index,
6307 precedence,
6308 mut depth,
6309 recovery_symbols,
6310 recovery_state,
6311 } = request;
6312 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
6331 let mut inline_consumed_eof = false;
6332 loop {
6333 if depth > RECOGNITION_DEPTH_LIMIT {
6334 return Vec::new();
6335 }
6336 if state_number == stop_state {
6337 let mut nodes = NodeList::new();
6338 if self.fast_token_nodes_enabled {
6339 for token_index in inline_consumed_tokens.iter().rev() {
6340 nodes.prepend(Rc::new(FastRecognizedNode::Token {
6341 index: *token_index,
6342 }));
6343 }
6344 }
6345 return vec![FastRecognizeOutcome {
6346 index,
6347 consumed_eof: inline_consumed_eof,
6348 diagnostics: FastDiagnostics::new(),
6349 nodes,
6350 }];
6351 }
6352 let Some(state) = atn.state(state_number) else {
6353 return Vec::new();
6354 };
6355 if state.transitions.len() == 1
6356 && !starts_prediction_decision(state)
6357 && !state.precedence_rule_decision
6358 {
6359 match &state.transitions[0] {
6360 Transition::Epsilon { target }
6361 | Transition::Predicate { target, .. }
6362 | Transition::Action { target, .. }
6363 if left_recursive_boundary(atn, state, *target).is_none() =>
6364 {
6365 #[cfg(feature = "perf-counters")]
6366 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
6367 state_number = *target;
6368 depth += 1;
6369 continue;
6370 }
6371 Transition::Precedence {
6372 target,
6373 precedence: transition_precedence,
6374 } if *transition_precedence >= precedence
6375 && left_recursive_boundary(atn, state, *target).is_none() =>
6376 {
6377 #[cfg(feature = "perf-counters")]
6378 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
6379 state_number = *target;
6380 depth += 1;
6381 continue;
6382 }
6383 Transition::Atom { target, .. }
6393 | Transition::Range { target, .. }
6394 | Transition::Set { target, .. }
6395 | Transition::NotSet { target, .. }
6396 | Transition::Wildcard { target, .. }
6397 if !self.fast_recovery_enabled =>
6398 {
6399 let symbol = self.token_type_at(index);
6400 let transition = &state.transitions[0];
6401 if transition.matches(symbol, 1, atn.max_token_type()) {
6402 #[cfg(feature = "perf-counters")]
6403 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
6404 if self.fast_token_nodes_enabled {
6405 inline_consumed_tokens.push(index);
6406 }
6407 inline_consumed_eof |= symbol == TOKEN_EOF;
6408 index = self.consume_index(index, symbol);
6409 state_number = *target;
6410 depth += 1;
6411 continue;
6412 }
6413 }
6416 _ => {}
6417 }
6418 }
6419 break;
6420 }
6421 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
6425 let Some(state) = atn.state(state_number) else {
6426 return Vec::new();
6427 };
6428 let transition_count = state.transitions.len();
6429 let memo_lookup_enabled = self.fast_recovery_enabled || transition_count > 1;
6430 let key = if self.fast_recovery_enabled {
6440 FastRecognizeKey {
6441 state_number,
6442 stop_state,
6443 index,
6444 rule_start_index,
6445 decision_start_index,
6446 precedence,
6447 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
6448 recovery_state,
6449 }
6450 } else {
6451 FastRecognizeKey {
6452 state_number,
6453 stop_state,
6454 index,
6455 rule_start_index: 0,
6456 decision_start_index: None,
6457 precedence,
6458 recovery_symbols_id: 0,
6459 recovery_state: None,
6460 }
6461 };
6462 if memo_lookup_enabled {
6463 if let Some(outcomes) = memo.get(&key) {
6464 #[cfg(feature = "perf-counters")]
6465 {
6466 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
6467 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
6468 }
6469 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
6473 let inline_eof = inline_consumed_eof;
6474 let inline_tokens = &inline_consumed_tokens;
6475 return outcomes
6476 .iter()
6477 .cloned()
6478 .map(|mut outcome| {
6479 if inline_eof {
6480 outcome.consumed_eof = true;
6481 }
6482 if self.fast_token_nodes_enabled {
6483 for token_index in inline_tokens.iter().rev() {
6484 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
6485 index: *token_index,
6486 }));
6487 }
6488 }
6489 outcome
6490 })
6491 .collect();
6492 }
6493 return outcomes.to_vec();
6494 }
6495 #[cfg(feature = "perf-counters")]
6496 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
6497 }
6498
6499 let needs_cycle_guard = if self.fast_recovery_enabled {
6504 state.transitions.iter().any(Transition::is_epsilon)
6505 } else {
6506 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
6507 };
6508 #[cfg(feature = "perf-counters")]
6509 if needs_cycle_guard {
6510 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
6511 } else {
6512 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
6513 match &state.transitions[0] {
6514 Transition::Rule { .. } => {
6515 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
6516 }
6517 Transition::Atom { .. }
6518 | Transition::Range { .. }
6519 | Transition::Set { .. }
6520 | Transition::NotSet { .. }
6521 | Transition::Wildcard { .. } => {
6522 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
6523 }
6524 _ => {
6525 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
6526 }
6527 }
6528 }
6529 let has_inserted_cycle_guard = if needs_cycle_guard {
6530 if !visiting.insert(key.clone()) {
6531 #[cfg(feature = "perf-counters")]
6532 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
6533 return Vec::new();
6534 }
6535 true
6536 } else {
6537 false
6538 };
6539 let next_decision_start_index = if starts_prediction_decision(state) {
6540 Some(index)
6541 } else {
6542 decision_start_index
6543 };
6544 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
6545 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
6546 } else {
6547 (Rc::clone(&recovery_symbols), recovery_state)
6548 };
6549
6550 let transition_count = state.transitions.len();
6569 let lookahead_filter = if transition_count > 1
6570 && self.fast_first_set_prefilter
6571 && !state.precedence_rule_decision
6572 && (!self.fast_recovery_enabled || state.kind != AtnStateKind::RuleStart)
6573 {
6574 state
6575 .rule_index
6576 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())
6577 .map(|rule_stop| {
6578 let symbol = self.token_type_at(index);
6579 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6580 (symbol, entry)
6581 })
6582 } else {
6583 None
6584 };
6585 let ll1_only_alt: Option<usize> = if transition_count > 1
6594 && let Some((symbol, entry)) = lookahead_filter.as_ref()
6595 {
6596 let key = (state.state_number, *symbol);
6597 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
6598 cached
6599 } else {
6600 let result = ll1_unique_alt(entry, *symbol);
6601 self.ll1_decision_cache.insert(key, result);
6602 result
6603 }
6604 } else {
6605 None
6606 };
6607 let lookahead_filter = lookahead_filter.as_ref();
6608 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
6614 for (transition_index, transition) in state.transitions.iter().enumerate() {
6615 if let Some(alt) = ll1_only_alt {
6616 if alt != transition_index {
6618 continue;
6619 }
6620 } else if should_skip_via_lookahead(
6621 transition,
6622 transition_index,
6623 lookahead_filter,
6624 index,
6625 self.fast_recovery_enabled,
6626 expected,
6627 ) {
6628 continue;
6629 }
6630 match transition {
6631 Transition::Epsilon { target }
6632 | Transition::Predicate { target, .. }
6633 | Transition::Action { target, .. } => {
6634 #[cfg(feature = "perf-counters")]
6635 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
6636 let boundary = left_recursive_boundary(atn, state, *target);
6637 outcomes.extend(
6638 self.recognize_state_fast(
6639 atn,
6640 FastRecognizeRequest {
6641 state_number: *target,
6642 stop_state,
6643 index,
6644 rule_start_index,
6645 decision_start_index: next_decision_start_index,
6646 precedence,
6647 depth: depth + 1,
6648 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6649 recovery_state: epsilon_recovery_state,
6650 },
6651 visiting,
6652 memo,
6653 expected,
6654 )
6655 .into_iter()
6656 .map(|mut outcome| {
6657 if let Some(rule_index) = boundary {
6658 outcome.nodes.prepend(Rc::new(
6659 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
6660 ));
6661 }
6662 outcome
6663 }),
6664 );
6665 }
6666 Transition::Precedence {
6667 target,
6668 precedence: transition_precedence,
6669 } => {
6670 if *transition_precedence >= precedence {
6671 let boundary = left_recursive_boundary(atn, state, *target);
6672 outcomes.extend(
6673 self.recognize_state_fast(
6674 atn,
6675 FastRecognizeRequest {
6676 state_number: *target,
6677 stop_state,
6678 index,
6679 rule_start_index,
6680 decision_start_index: next_decision_start_index,
6681 precedence,
6682 depth: depth + 1,
6683 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6684 recovery_state: epsilon_recovery_state,
6685 },
6686 visiting,
6687 memo,
6688 expected,
6689 )
6690 .into_iter()
6691 .map(|mut outcome| {
6692 if let Some(rule_index) = boundary {
6693 outcome.nodes.prepend(Rc::new(
6694 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
6695 ));
6696 }
6697 outcome
6698 }),
6699 );
6700 }
6701 }
6702 Transition::Rule {
6703 target,
6704 rule_index,
6705 follow_state,
6706 precedence: rule_precedence,
6707 ..
6708 } => {
6709 #[cfg(feature = "perf-counters")]
6710 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
6711 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
6712 else {
6713 continue;
6714 };
6715 let symbol = self.token_type_at(index);
6727 if self.fast_first_set_prefilter {
6728 let first = self.cached_rule_first_set(atn, *target, child_stop);
6741 if should_skip_rule_via_first_set(
6742 &first,
6743 symbol,
6744 self.fast_recovery_enabled,
6745 index,
6746 expected,
6747 ) {
6748 continue;
6749 }
6750 }
6751 let expected_before_child =
6752 self.fast_recovery_enabled.then(|| expected.clone());
6753 let mut children = self.recognize_state_fast(
6754 atn,
6755 FastRecognizeRequest {
6756 state_number: *target,
6757 stop_state: child_stop,
6758 index,
6759 rule_start_index: index,
6760 decision_start_index: None,
6761 precedence: *rule_precedence,
6762 depth: depth + 1,
6763 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6764 recovery_state: epsilon_recovery_state,
6765 },
6766 visiting,
6767 memo,
6768 expected,
6769 );
6770 if children.is_empty() && self.fast_recovery_enabled {
6771 children = self.fast_child_rule_failure_recovery_outcomes(
6772 FastChildRuleFailureRecoveryRequest {
6773 atn,
6774 rule_index: *rule_index,
6775 start_index: index,
6776 follow_state: *follow_state,
6777 stop_state,
6778 expected,
6779 },
6780 );
6781 }
6782 if let Some(expected_before_child) = expected_before_child {
6783 if children
6784 .iter()
6785 .any(|child| child.diagnostics.is_empty() && child.index > index)
6786 {
6787 *expected = expected_before_child;
6788 }
6789 }
6790 for child in children {
6791 let child_index = child.index;
6792 let child_consumed_eof = child.consumed_eof;
6793 let child_diagnostics = child.diagnostics;
6794 let empty_recovery = self.empty_recovery_symbols();
6795 let follow_outcomes = self.recognize_state_fast(
6796 atn,
6797 FastRecognizeRequest {
6798 state_number: *follow_state,
6799 stop_state,
6800 index: child_index,
6801 rule_start_index,
6802 decision_start_index: next_decision_start_index,
6803 precedence,
6804 depth: depth + 1,
6805 recovery_symbols: empty_recovery,
6806 recovery_state: None,
6807 },
6808 visiting,
6809 memo,
6810 expected,
6811 );
6812 if follow_outcomes.is_empty() {
6813 continue;
6814 }
6815 let child_node = Rc::new(FastRecognizedNode::Rule {
6816 rule_index: *rule_index,
6817 invoking_state: invoking_state_number(state_number),
6818 start_index: index,
6819 stop_index: self.rule_stop_token_index(child_index, child_consumed_eof),
6820 children: child.nodes,
6821 });
6822 let child_diags_empty = child_diagnostics.is_empty();
6823 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
6824 outcome.consumed_eof |= child_consumed_eof;
6825 if !child_diags_empty {
6828 let mut diagnostics = child_diagnostics.clone();
6829 diagnostics.append(&mut outcome.diagnostics);
6830 outcome.diagnostics = diagnostics;
6831 }
6832 outcome.nodes.prepend(Rc::clone(&child_node));
6833 outcome
6834 }));
6835 }
6836 }
6837 Transition::Atom { target, .. }
6838 | Transition::Range { target, .. }
6839 | Transition::Set { target, .. }
6840 | Transition::NotSet { target, .. }
6841 | Transition::Wildcard { target, .. } => {
6842 #[cfg(feature = "perf-counters")]
6843 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
6844 let symbol = self.token_type_at(index);
6845 if transition.matches(symbol, 1, atn.max_token_type()) {
6846 let next_index = self.consume_index(index, symbol);
6847 let empty_recovery = self.empty_recovery_symbols();
6848 outcomes.extend(
6849 self.recognize_state_fast(
6850 atn,
6851 FastRecognizeRequest {
6852 state_number: *target,
6853 stop_state,
6854 index: next_index,
6855 rule_start_index,
6856 decision_start_index: next_decision_start_index,
6857 precedence,
6858 depth: depth + 1,
6859 recovery_symbols: empty_recovery,
6860 recovery_state: None,
6861 },
6862 visiting,
6863 memo,
6864 expected,
6865 )
6866 .into_iter()
6867 .map(|mut outcome| {
6868 outcome.consumed_eof |= symbol == TOKEN_EOF;
6869 if self.fast_token_nodes_enabled {
6870 outcome
6871 .nodes
6872 .prepend(Rc::new(FastRecognizedNode::Token { index }));
6873 }
6874 outcome
6875 }),
6876 );
6877 } else {
6878 if !self.fast_recovery_enabled {
6879 continue;
6887 }
6888 let expected_symbols = fast_recovery_expected_symbols(
6889 self,
6890 atn,
6891 state.state_number,
6892 &recovery_symbols,
6893 );
6894 if expected_symbols.contains(&symbol) {
6895 continue;
6896 }
6897 {
6898 expected.record_transition(index, transition, atn.max_token_type());
6899 record_no_viable_if_ambiguous(
6900 expected,
6901 next_decision_start_index,
6902 index,
6903 );
6904 outcomes.extend(self.fast_single_token_deletion_recovery(
6905 FastRecoveryRequest {
6906 atn,
6907 transition,
6908 expected_symbols: Rc::clone(&expected_symbols),
6909 target: *target,
6910 request: FastRecognizeRequest {
6911 state_number,
6912 stop_state,
6913 index,
6914 rule_start_index,
6915 decision_start_index,
6916 precedence,
6917 depth,
6918 recovery_symbols: Rc::clone(&recovery_symbols),
6919 recovery_state,
6920 },
6921 visiting,
6922 memo,
6923 expected,
6924 },
6925 ));
6926 if !state_is_left_recursive_rule(atn, state) {
6927 outcomes.extend(self.fast_single_token_insertion_recovery(
6928 FastRecoveryRequest {
6929 atn,
6930 transition,
6931 expected_symbols: Rc::clone(&expected_symbols),
6932 target: *target,
6933 request: FastRecognizeRequest {
6934 state_number,
6935 stop_state,
6936 index,
6937 rule_start_index,
6938 decision_start_index,
6939 precedence,
6940 depth,
6941 recovery_symbols: Rc::clone(&recovery_symbols),
6942 recovery_state,
6943 },
6944 visiting,
6945 memo,
6946 expected,
6947 },
6948 ));
6949 }
6950 outcomes.extend(self.fast_current_token_deletion_recovery(
6951 FastCurrentTokenDeletionRequest {
6952 atn,
6953 expected_symbols,
6954 request: FastRecognizeRequest {
6955 state_number,
6956 stop_state,
6957 index,
6958 rule_start_index,
6959 decision_start_index,
6960 precedence,
6961 depth,
6962 recovery_symbols: Rc::clone(&recovery_symbols),
6963 recovery_state,
6964 },
6965 visiting,
6966 memo,
6967 expected,
6968 },
6969 ));
6970 }
6971 }
6972 }
6973 }
6974 }
6975
6976 if has_inserted_cycle_guard {
6977 visiting.remove(&key);
6978 }
6979 if matches!(
6980 self.prediction_mode,
6981 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
6982 ) && self.fast_recovery_enabled
6983 {
6984 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
6988 }
6989 if self.fast_recovery_enabled {
6990 dedupe_fast_outcomes(&mut outcomes);
6991 } else {
6992 dedupe_clean_fast_outcomes(&mut outcomes);
6993 }
6994 let should_memoize = self.fast_recovery_enabled
7004 || (transition_count > 1
7005 && (outcomes.is_empty()
7006 || outcomes.len() > 1
7007 || (outcomes.len() == 1 && self.should_memoize_single_outcome(&key))));
7008 let apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
7012 if inline_consumed_eof {
7013 outcome.consumed_eof = true;
7014 }
7015 if !inline_consumed_tokens.is_empty() {
7016 for token_index in inline_consumed_tokens.iter().rev() {
7017 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
7018 index: *token_index,
7019 }));
7020 }
7021 }
7022 outcome
7023 };
7024 if should_memoize {
7025 #[cfg(feature = "perf-counters")]
7026 {
7027 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
7028 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
7029 match outcomes.len() {
7030 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
7031 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
7032 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
7033 }
7034 }
7035 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
7040 memo.insert(key, Rc::clone(&stored));
7041 if inline_pending {
7042 return stored.iter().cloned().map(apply_inline_pending).collect();
7043 }
7044 return stored.to_vec();
7045 }
7046 #[cfg(feature = "perf-counters")]
7047 match outcomes.len() {
7048 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
7049 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
7050 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
7051 }
7052 if inline_pending {
7053 return outcomes.into_iter().map(apply_inline_pending).collect();
7054 }
7055 outcomes
7056 }
7057
7058 fn single_token_deletion_recovery(
7061 &mut self,
7062 recovery: RecoveryRequest<'_, '_>,
7063 ) -> Vec<RecognizeOutcome> {
7064 let RecoveryRequest {
7065 atn,
7066 transition,
7067 expected_symbols,
7068 target,
7069 request,
7070 visiting,
7071 memo,
7072 expected,
7073 } = recovery;
7074 let RecognizeRequest {
7075 stop_state,
7076 index,
7077 rule_start_index,
7078 decision_start_index,
7079 init_action_rules,
7080 predicates,
7081 semantics,
7082 rule_args,
7083 member_actions,
7084 return_actions,
7085 local_int_arg,
7086 member_values,
7087 return_values,
7088 rule_alt_number,
7089 track_alt_numbers,
7090 consumed_eof,
7091 precedence,
7092 depth,
7093 ..
7094 } = request;
7095 let Some((diagnostic, next_index, next_symbol)) =
7096 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
7097 else {
7098 return Vec::new();
7099 };
7100 let after_next = self.consume_index(next_index, next_symbol);
7101 self.recognize_state(
7102 atn,
7103 RecognizeRequest {
7104 state_number: target,
7105 stop_state,
7106 index: after_next,
7107 rule_start_index,
7108 decision_start_index,
7109 init_action_rules,
7110 predicates,
7111 semantics,
7112 rule_args,
7113 member_actions,
7114 return_actions,
7115 local_int_arg,
7116 member_values,
7117 return_values,
7118 rule_alt_number,
7119 track_alt_numbers,
7120 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
7121 precedence,
7122 depth: depth + 1,
7123 recovery_symbols: BTreeSet::new(),
7124 recovery_state: None,
7125 },
7126 visiting,
7127 memo,
7128 expected,
7129 )
7130 .into_iter()
7131 .map(|mut outcome| {
7132 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
7133 outcome.diagnostics.insert(0, diagnostic.clone());
7134 outcome
7135 .nodes
7136 .insert(0, RecognizedNode::Token { index: next_index });
7137 outcome
7138 .nodes
7139 .insert(0, RecognizedNode::ErrorToken { index });
7140 outcome
7141 })
7142 .collect()
7143 }
7144
7145 fn current_token_deletion_recovery(
7148 &mut self,
7149 recovery: CurrentTokenDeletionRequest<'_, '_>,
7150 ) -> Vec<RecognizeOutcome> {
7151 let CurrentTokenDeletionRequest {
7152 atn,
7153 expected_symbols,
7154 mut request,
7155 visiting,
7156 memo,
7157 expected,
7158 } = recovery;
7159 let error_index = request.index;
7160 if error_index == request.rule_start_index {
7161 return Vec::new();
7162 }
7163 let Some((diagnostic, next_index, skipped)) =
7164 self.current_token_deletion(error_index, &expected_symbols)
7165 else {
7166 return Vec::new();
7167 };
7168 request.state_number = request.recovery_state.unwrap_or(request.state_number);
7169 request.index = next_index;
7170 request.depth += 1;
7171 request.recovery_state = None;
7172 self.recognize_state(atn, request, visiting, memo, expected)
7173 .into_iter()
7174 .map(|mut outcome| {
7175 outcome.diagnostics.insert(0, diagnostic.clone());
7176 for index in skipped.iter().rev() {
7177 outcome
7178 .nodes
7179 .insert(0, RecognizedNode::ErrorToken { index: *index });
7180 }
7181 outcome
7182 })
7183 .collect()
7184 }
7185
7186 fn consuming_failure_fallback(
7189 &mut self,
7190 fallback: ConsumingFailureFallback<'_>,
7191 visiting: &mut BTreeSet<RecognizeKey>,
7192 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
7193 expected: &mut ExpectedTokens,
7194 ) -> Vec<RecognizeOutcome> {
7195 if fallback.expected_symbols.is_empty() {
7196 return Vec::new();
7197 }
7198 if fallback.symbol == TOKEN_EOF {
7199 return self.eof_consuming_failure_fallback(fallback, expected);
7200 }
7201 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
7202 }
7203
7204 fn non_eof_consuming_failure_fallback(
7207 &mut self,
7208 fallback: ConsumingFailureFallback<'_>,
7209 visiting: &mut BTreeSet<RecognizeKey>,
7210 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
7211 expected: &mut ExpectedTokens,
7212 ) -> Vec<RecognizeOutcome> {
7213 let ConsumingFailureFallback {
7214 atn,
7215 target,
7216 request,
7217 symbol,
7218 expected_symbols,
7219 decision_start_index,
7220 decision,
7221 } = fallback;
7222 let error_index = request.index;
7223 let diagnostic =
7224 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
7225 let next_index = self.consume_index(error_index, symbol);
7226 self.recognize_state(
7227 atn,
7228 RecognizeRequest {
7229 state_number: target,
7230 stop_state: request.stop_state,
7231 index: next_index,
7232 rule_start_index: request.rule_start_index,
7233 decision_start_index,
7234 init_action_rules: request.init_action_rules,
7235 predicates: request.predicates,
7236 semantics: request.semantics,
7237 rule_args: request.rule_args,
7238 member_actions: request.member_actions,
7239 return_actions: request.return_actions,
7240 local_int_arg: request.local_int_arg,
7241 member_values: request.member_values,
7242 return_values: request.return_values,
7243 rule_alt_number: request.rule_alt_number,
7244 track_alt_numbers: request.track_alt_numbers,
7245 consumed_eof: request.consumed_eof,
7246 precedence: request.precedence,
7247 depth: request.depth + 1,
7248 recovery_symbols: BTreeSet::new(),
7249 recovery_state: None,
7250 },
7251 visiting,
7252 memo,
7253 expected,
7254 )
7255 .into_iter()
7256 .map(|mut outcome| {
7257 prepend_decision(&mut outcome, decision);
7258 outcome.diagnostics.insert(0, diagnostic.clone());
7259 outcome
7260 .nodes
7261 .insert(0, RecognizedNode::ErrorToken { index: error_index });
7262 outcome
7263 })
7264 .collect()
7265 }
7266
7267 fn eof_consuming_failure_fallback(
7270 &mut self,
7271 fallback: ConsumingFailureFallback<'_>,
7272 expected: &ExpectedTokens,
7273 ) -> Vec<RecognizeOutcome> {
7274 let request = fallback.request;
7275 if request.index == request.rule_start_index {
7276 return Vec::new();
7277 }
7278 let diagnostic =
7279 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
7280 vec![RecognizeOutcome {
7281 index: request.index,
7282 consumed_eof: request.consumed_eof,
7283 alt_number: request.rule_alt_number,
7284 member_values: request.member_values,
7285 return_values: request.return_values,
7286 diagnostics: vec![diagnostic],
7287 decisions: Vec::new(),
7288 actions: Vec::new(),
7289 nodes: Vec::new(),
7290 }]
7291 }
7292
7293 fn single_token_insertion_recovery(
7296 &mut self,
7297 recovery: RecoveryRequest<'_, '_>,
7298 ) -> Vec<RecognizeOutcome> {
7299 let RecoveryRequest {
7300 atn,
7301 transition,
7302 expected_symbols,
7303 target,
7304 request,
7305 visiting,
7306 memo,
7307 expected,
7308 } = recovery;
7309 let RecognizeRequest {
7310 stop_state,
7311 index,
7312 rule_start_index,
7313 decision_start_index,
7314 init_action_rules,
7315 predicates,
7316 semantics,
7317 rule_args,
7318 member_actions,
7319 return_actions,
7320 local_int_arg,
7321 member_values,
7322 return_values,
7323 rule_alt_number,
7324 track_alt_numbers,
7325 consumed_eof,
7326 precedence,
7327 depth,
7328 ..
7329 } = request;
7330 let follow_symbols = state_expected_symbols(atn, transition.target());
7331 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
7332 transition,
7333 index,
7334 atn.max_token_type(),
7335 &expected_symbols,
7336 &follow_symbols,
7337 ) else {
7338 return Vec::new();
7339 };
7340 self.recognize_state(
7341 atn,
7342 RecognizeRequest {
7343 state_number: target,
7344 stop_state,
7345 index,
7346 rule_start_index,
7347 decision_start_index,
7348 init_action_rules,
7349 predicates,
7350 semantics,
7351 rule_args,
7352 member_actions,
7353 return_actions,
7354 local_int_arg,
7355 member_values,
7356 return_values,
7357 rule_alt_number,
7358 track_alt_numbers,
7359 consumed_eof,
7360 precedence,
7361 depth: depth + 1,
7362 recovery_symbols: BTreeSet::new(),
7363 recovery_state: None,
7364 },
7365 visiting,
7366 memo,
7367 expected,
7368 )
7369 .into_iter()
7370 .map(|mut outcome| {
7371 outcome.diagnostics.insert(0, diagnostic.clone());
7372 outcome.nodes.insert(
7373 0,
7374 RecognizedNode::MissingToken {
7375 token_type,
7376 at_index: index,
7377 text: text.clone(),
7378 },
7379 );
7380 outcome
7381 })
7382 .collect()
7383 }
7384
7385 #[allow(clippy::too_many_lines)]
7388 fn recognize_state(
7389 &mut self,
7390 atn: &Atn,
7391 request: RecognizeRequest<'_>,
7392 visiting: &mut BTreeSet<RecognizeKey>,
7393 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
7394 expected: &mut ExpectedTokens,
7395 ) -> Vec<RecognizeOutcome> {
7396 let request_template = request.clone();
7397 let RecognizeRequest {
7398 state_number,
7399 stop_state,
7400 index,
7401 rule_start_index,
7402 decision_start_index,
7403 init_action_rules,
7404 predicates,
7405 semantics,
7406 rule_args,
7407 member_actions,
7408 return_actions,
7409 local_int_arg,
7410 member_values,
7411 return_values,
7412 rule_alt_number,
7413 track_alt_numbers,
7414 consumed_eof,
7415 precedence,
7416 depth,
7417 recovery_symbols,
7418 recovery_state,
7419 } = request;
7420 if depth > RECOGNITION_DEPTH_LIMIT {
7421 return Vec::new();
7422 }
7423 if state_number == stop_state {
7424 return stop_outcome(
7425 index,
7426 consumed_eof,
7427 rule_alt_number,
7428 member_values,
7429 return_values,
7430 );
7431 }
7432 let key = RecognizeKey {
7433 state_number,
7434 stop_state,
7435 index,
7436 rule_start_index,
7437 decision_start_index,
7438 local_int_arg,
7439 member_values: member_values.clone(),
7440 return_values: return_values.clone(),
7441 rule_alt_number,
7442 track_alt_numbers,
7443 consumed_eof,
7444 precedence,
7445 recovery_symbols: recovery_symbols.clone(),
7446 recovery_state,
7447 };
7448 if let Some(outcomes) = memo.get(&key) {
7449 return outcomes.clone();
7450 }
7451
7452 let visit_key = key.clone();
7453 if !visiting.insert(visit_key.clone()) {
7454 return Vec::new();
7455 }
7456
7457 let Some(state) = atn.state(state_number) else {
7458 visiting.remove(&visit_key);
7459 return Vec::new();
7460 };
7461 let next_decision_start_index = if starts_prediction_decision(state) {
7462 Some(index)
7463 } else {
7464 decision_start_index
7465 };
7466 let (epsilon_recovery_symbols, epsilon_recovery_state) =
7467 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
7468 let mut outcomes = Vec::new();
7469 for (transition_index, transition) in state.transitions.iter().enumerate() {
7470 let decision = transition_decision(atn, state, transition_index, predicates);
7471 let next_alt_number =
7472 next_alt_number(state, transition_index, rule_alt_number, track_alt_numbers);
7473 match transition {
7474 Transition::Epsilon { target } | Transition::Action { target, .. } => {
7475 let action_rule_index = match transition {
7476 Transition::Action { rule_index, .. } => Some(*rule_index),
7477 _ => None,
7478 };
7479 outcomes.extend(self.recognize_epsilon_or_action_step(
7480 atn,
7481 &request_template,
7482 EpsilonActionStep {
7483 source_state: state_number,
7484 target: *target,
7485 action_rule_index,
7486 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
7487 decision,
7488 decision_start_index: next_decision_start_index,
7489 alt_number: next_alt_number,
7490 recovery_symbols: epsilon_recovery_symbols.clone(),
7491 recovery_state: epsilon_recovery_state,
7492 },
7493 RecognizeScratch {
7494 visiting,
7495 memo,
7496 expected,
7497 },
7498 ));
7499 }
7500 Transition::Predicate {
7501 target,
7502 rule_index,
7503 pred_index,
7504 ..
7505 } => {
7506 let predicate = PredicateEval {
7507 index,
7508 rule_index: *rule_index,
7509 pred_index: *pred_index,
7510 predicates,
7511 semantics,
7512 context: None,
7513 local_int_arg,
7514 member_values: &member_values,
7515 };
7516 if self.parser_predicate_matches(predicate) {
7517 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
7518 outcomes.extend(
7519 self.recognize_state(
7520 atn,
7521 RecognizeRequest {
7522 state_number: *target,
7523 stop_state,
7524 index,
7525 rule_start_index,
7526 decision_start_index: next_decision_start_index,
7527 init_action_rules,
7528 predicates,
7529 semantics,
7530 rule_args,
7531 member_actions,
7532 return_actions,
7533 local_int_arg,
7534 member_values: member_values.clone(),
7535 return_values: return_values.clone(),
7536 rule_alt_number: next_alt_number,
7537 track_alt_numbers,
7538 consumed_eof,
7539 precedence,
7540 depth: depth + 1,
7541 recovery_symbols: epsilon_recovery_symbols.clone(),
7542 recovery_state: epsilon_recovery_state,
7543 },
7544 visiting,
7545 memo,
7546 expected,
7547 )
7548 .into_iter()
7549 .map(|mut outcome| {
7550 prepend_decision(&mut outcome, decision);
7551 if let Some(rule_index) = left_recursive_boundary {
7552 outcome.nodes.insert(
7553 0,
7554 RecognizedNode::LeftRecursiveBoundary { rule_index },
7555 );
7556 }
7557 outcome
7558 }),
7559 );
7560 } else if let Some(message) = semantics
7561 .and_then(|semantics| {
7562 self.parser_semantic_ir_predicate_failure_message(
7563 *rule_index,
7564 *pred_index,
7565 semantics,
7566 )
7567 })
7568 .or_else(|| {
7569 self.parser_predicate_failure_message(
7570 *rule_index,
7571 *pred_index,
7572 predicates,
7573 )
7574 })
7575 {
7576 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
7577 rule_index: *rule_index,
7578 index,
7579 message,
7580 member_values: member_values.clone(),
7581 return_values: return_values.clone(),
7582 rule_alt_number,
7583 }));
7584 } else {
7585 record_predicate_no_viable(expected, next_decision_start_index, index);
7586 }
7587 }
7588 Transition::Precedence {
7589 target,
7590 precedence: transition_precedence,
7591 } => {
7592 if *transition_precedence >= precedence {
7593 outcomes.extend(
7594 self.recognize_state(
7595 atn,
7596 RecognizeRequest {
7597 state_number: *target,
7598 stop_state,
7599 index,
7600 rule_start_index,
7601 decision_start_index: next_decision_start_index,
7602 init_action_rules,
7603 predicates,
7604 semantics,
7605 rule_args,
7606 member_actions,
7607 return_actions,
7608 local_int_arg,
7609 member_values: member_values.clone(),
7610 return_values: return_values.clone(),
7611 rule_alt_number: next_alt_number,
7612 track_alt_numbers,
7613 consumed_eof,
7614 precedence,
7615 depth: depth + 1,
7616 recovery_symbols: epsilon_recovery_symbols.clone(),
7617 recovery_state: epsilon_recovery_state,
7618 },
7619 visiting,
7620 memo,
7621 expected,
7622 )
7623 .into_iter()
7624 .map(|mut outcome| {
7625 prepend_decision(&mut outcome, decision);
7626 outcome
7627 }),
7628 );
7629 }
7630 }
7631 Transition::Rule {
7632 target,
7633 rule_index,
7634 follow_state,
7635 precedence: rule_precedence,
7636 ..
7637 } => {
7638 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
7639 else {
7640 continue;
7641 };
7642 let child_local_int_arg =
7643 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
7644 let expected_before_child = expected.clone();
7645 let children = self.recognize_state(
7646 atn,
7647 RecognizeRequest {
7648 state_number: *target,
7649 stop_state: child_stop,
7650 index,
7651 rule_start_index: index,
7652 decision_start_index: None,
7653 init_action_rules,
7654 predicates,
7655 semantics,
7656 rule_args,
7657 member_actions,
7658 return_actions,
7659 local_int_arg: child_local_int_arg,
7660 member_values: member_values.clone(),
7661 return_values: BTreeMap::new(),
7662 rule_alt_number: 0,
7663 track_alt_numbers,
7664 consumed_eof: false,
7665 precedence: *rule_precedence,
7666 depth: depth + 1,
7667 recovery_symbols: epsilon_recovery_symbols.clone(),
7668 recovery_state: epsilon_recovery_state,
7669 },
7670 visiting,
7671 memo,
7672 expected,
7673 );
7674 let children = if children.is_empty() {
7675 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
7676 atn,
7677 rule_index: *rule_index,
7678 start_index: index,
7679 follow_state: *follow_state,
7680 stop_state,
7681 member_values: member_values.clone(),
7682 expected,
7683 })
7684 } else {
7685 children
7686 };
7687 let preserve_child_expected =
7688 self.child_expected_reaches_clean_eof(&children, expected);
7689 restore_expected(
7690 &children,
7691 index,
7692 expected,
7693 expected_before_child,
7694 preserve_child_expected,
7695 );
7696 for child in children {
7697 let child_node = RecognizedNode::Rule {
7698 rule_index: *rule_index,
7699 invoking_state: invoking_state_number(state_number),
7700 alt_number: child.alt_number,
7701 start_index: index,
7702 stop_index: self.rule_stop_token_index(child.index, child.consumed_eof),
7703 return_values: child.return_values.clone(),
7704 children: fold_left_recursive_boundaries(child.nodes.clone()),
7705 };
7706 outcomes.extend(
7707 self.recognize_state(
7708 atn,
7709 RecognizeRequest {
7710 state_number: *follow_state,
7711 stop_state,
7712 index: child.index,
7713 rule_start_index,
7714 decision_start_index: next_decision_start_index,
7715 init_action_rules,
7716 predicates,
7717 semantics,
7718 rule_args,
7719 member_actions,
7720 return_actions,
7721 local_int_arg,
7722 member_values: child.member_values.clone(),
7723 return_values: return_values.clone(),
7724 rule_alt_number,
7725 track_alt_numbers,
7726 consumed_eof: consumed_eof || child.consumed_eof,
7727 precedence,
7728 depth: depth + 1,
7729 recovery_symbols: BTreeSet::new(),
7730 recovery_state: None,
7731 },
7732 visiting,
7733 memo,
7734 expected,
7735 )
7736 .into_iter()
7737 .map(|mut outcome| {
7738 outcome.consumed_eof |= child.consumed_eof;
7739 let mut diagnostics = child.diagnostics.clone();
7740 diagnostics.append(&mut outcome.diagnostics);
7741 outcome.diagnostics = diagnostics;
7742 let mut decisions = child.decisions.clone();
7743 decisions.append(&mut outcome.decisions);
7744 outcome.decisions = decisions;
7745 prepend_decision(&mut outcome, decision);
7746 let mut actions = child.actions.clone();
7747 if init_action_rules.contains(rule_index) {
7748 actions.insert(
7749 0,
7750 ParserAction::new_rule_init(
7751 *rule_index,
7752 index,
7753 Some(*follow_state),
7754 ),
7755 );
7756 }
7757 actions.append(&mut outcome.actions);
7758 outcome.actions = actions;
7759 outcome.nodes.insert(0, child_node.clone());
7760 outcome
7761 }),
7762 );
7763 }
7764 }
7765 Transition::Atom { target, .. }
7766 | Transition::Range { target, .. }
7767 | Transition::Set { target, .. }
7768 | Transition::NotSet { target, .. }
7769 | Transition::Wildcard { target, .. } => {
7770 let symbol = self.token_type_at(index);
7771 if transition.matches(symbol, 1, atn.max_token_type()) {
7772 let next_index = self.consume_index(index, symbol);
7773 outcomes.extend(
7774 self.recognize_state(
7775 atn,
7776 RecognizeRequest {
7777 state_number: *target,
7778 stop_state,
7779 index: next_index,
7780 rule_start_index,
7781 decision_start_index: next_decision_start_index,
7782 init_action_rules,
7783 predicates,
7784 semantics,
7785 rule_args,
7786 member_actions,
7787 return_actions,
7788 local_int_arg,
7789 member_values: member_values.clone(),
7790 return_values: return_values.clone(),
7791 rule_alt_number: next_alt_number,
7792 track_alt_numbers,
7793 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
7794 precedence,
7795 depth: depth + 1,
7796 recovery_symbols: BTreeSet::new(),
7797 recovery_state: None,
7798 },
7799 visiting,
7800 memo,
7801 expected,
7802 )
7803 .into_iter()
7804 .map(|mut outcome| {
7805 prepend_decision(&mut outcome, decision);
7806 outcome.consumed_eof |= symbol == TOKEN_EOF;
7807 outcome.nodes.insert(0, RecognizedNode::Token { index });
7808 outcome
7809 }),
7810 );
7811 } else {
7812 let expected_symbols =
7813 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
7814 if expected_symbols.contains(&symbol) {
7815 continue;
7816 }
7817 expected.record_transition(index, transition, atn.max_token_type());
7818 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
7819 let before_recovery = outcomes.len();
7820 let recovery_request = request_template.clone();
7821 outcomes.extend(
7822 self.single_token_deletion_recovery(RecoveryRequest {
7823 atn,
7824 transition,
7825 expected_symbols: expected_symbols.clone(),
7826 target: *target,
7827 request: recovery_request.clone(),
7828 visiting,
7829 memo,
7830 expected,
7831 })
7832 .into_iter()
7833 .map(|mut outcome| {
7834 prepend_decision(&mut outcome, decision);
7835 outcome
7836 }),
7837 );
7838 if !state_is_left_recursive_rule(atn, state) {
7839 outcomes.extend(
7840 self.single_token_insertion_recovery(RecoveryRequest {
7841 atn,
7842 transition,
7843 expected_symbols: expected_symbols.clone(),
7844 target: *target,
7845 request: recovery_request.clone(),
7846 visiting,
7847 memo,
7848 expected,
7849 })
7850 .into_iter()
7851 .map(|mut outcome| {
7852 prepend_decision(&mut outcome, decision);
7853 outcome
7854 }),
7855 );
7856 }
7857 outcomes.extend(self.current_token_deletion_recovery(
7858 CurrentTokenDeletionRequest {
7859 atn,
7860 expected_symbols: expected_symbols.clone(),
7861 request: recovery_request.clone(),
7862 visiting,
7863 memo,
7864 expected,
7865 },
7866 ));
7867 if outcomes.len() == before_recovery {
7868 outcomes.extend(self.consuming_failure_fallback(
7869 ConsumingFailureFallback {
7870 atn,
7871 target: *target,
7872 request: recovery_request,
7873 symbol,
7874 expected_symbols,
7875 decision_start_index: next_decision_start_index,
7876 decision,
7877 },
7878 visiting,
7879 memo,
7880 expected,
7881 ));
7882 }
7883 }
7884 }
7885 }
7886 }
7887
7888 visiting.remove(&visit_key);
7889 self.record_prediction_diagnostics(atn, state, index, &outcomes);
7890 if matches!(
7891 self.prediction_mode,
7892 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
7893 ) {
7894 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes);
7895 }
7896 dedupe_outcomes(&mut outcomes);
7897 memo.insert(key, outcomes.clone());
7898 outcomes
7899 }
7900
7901 fn recognize_epsilon_or_action_step(
7904 &mut self,
7905 atn: &Atn,
7906 request: &RecognizeRequest<'_>,
7907 step: EpsilonActionStep,
7908 scratch: RecognizeScratch<'_>,
7909 ) -> Vec<RecognizeOutcome> {
7910 let RecognizeScratch {
7911 visiting,
7912 memo,
7913 expected,
7914 } = scratch;
7915 let action = step.action_rule_index.map(|rule_index| {
7916 ParserAction::new(
7917 step.source_state,
7918 rule_index,
7919 request.rule_start_index,
7920 self.rule_stop_token_index(request.index, request.consumed_eof),
7921 )
7922 });
7923 let next_member_values = if action.is_some() {
7924 member_values_after_action(
7925 step.source_state,
7926 request.member_actions,
7927 request.semantics,
7928 &request.member_values,
7929 )
7930 } else {
7931 request.member_values.clone()
7932 };
7933 let next_return_values = action.map_or_else(
7934 || request.return_values.clone(),
7935 |action| {
7936 return_values_after_action(
7937 step.source_state,
7938 action.rule_index(),
7939 request.return_actions,
7940 request.semantics,
7941 &request.return_values,
7942 )
7943 },
7944 );
7945
7946 self.recognize_state(
7947 atn,
7948 RecognizeRequest {
7949 state_number: step.target,
7950 stop_state: request.stop_state,
7951 index: request.index,
7952 rule_start_index: request.rule_start_index,
7953 decision_start_index: step.decision_start_index,
7954 init_action_rules: request.init_action_rules,
7955 predicates: request.predicates,
7956 semantics: request.semantics,
7957 rule_args: request.rule_args,
7958 member_actions: request.member_actions,
7959 return_actions: request.return_actions,
7960 local_int_arg: request.local_int_arg,
7961 member_values: next_member_values,
7962 return_values: next_return_values,
7963 rule_alt_number: step.alt_number,
7964 track_alt_numbers: request.track_alt_numbers,
7965 consumed_eof: request.consumed_eof,
7966 precedence: request.precedence,
7967 depth: request.depth + 1,
7968 recovery_symbols: step.recovery_symbols,
7969 recovery_state: step.recovery_state,
7970 },
7971 visiting,
7972 memo,
7973 expected,
7974 )
7975 .into_iter()
7976 .map(|mut outcome| {
7977 prepend_decision(&mut outcome, step.decision);
7978 if let Some(rule_index) = step.left_recursive_boundary {
7979 outcome
7980 .nodes
7981 .insert(0, RecognizedNode::LeftRecursiveBoundary { rule_index });
7982 }
7983 if let Some(action) = action {
7984 outcome.actions.insert(0, action);
7985 }
7986 outcome
7987 })
7988 .collect()
7989 }
7990
7991 fn token_type_at(&mut self, index: usize) -> i32 {
7996 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
7997 self.input.fill();
7998 }
7999 self.input.token_type_at_index(index)
8000 }
8001
8002 fn cached_state_expected_symbols(
8014 &mut self,
8015 atn: &Atn,
8016 state_number: usize,
8017 ) -> Rc<BTreeSet<i32>> {
8018 if let Some(cached) = self.state_expected_cache.get(&state_number) {
8019 return Rc::clone(cached);
8020 }
8021 let symbols = state_expected_symbols(atn, state_number);
8022 let entry = self.intern_recovery_symbols(symbols);
8023 self.state_expected_cache
8024 .insert(state_number, Rc::clone(&entry));
8025 entry
8026 }
8027
8028 fn cached_state_expected_token_set(
8029 &mut self,
8030 atn: &Atn,
8031 state_number: usize,
8032 ) -> Rc<TokenBitSet> {
8033 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
8034 return Rc::clone(cached);
8035 }
8036 let symbols = with_shared_atn_caches(atn, |cache| {
8040 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
8041 return Rc::clone(cached);
8042 }
8043 let symbols = Rc::new(state_expected_token_set(atn, state_number));
8044 cache
8045 .state_expected_tokens
8046 .insert(state_number, Rc::clone(&symbols));
8047 symbols
8048 });
8049 self.state_expected_token_cache
8050 .insert(state_number, Rc::clone(&symbols));
8051 symbols
8052 }
8053
8054 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
8055 if self.rule_stop_reach_cache.len() <= state_number {
8056 self.rule_stop_reach_cache
8057 .resize_with(atn.states().len().max(state_number + 1), || None);
8058 }
8059 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
8060 return reaches;
8061 }
8062 let reaches = with_shared_atn_caches(atn, |cache| {
8063 *cache
8064 .rule_stop_reach
8065 .entry(state_number)
8066 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
8067 });
8068 self.rule_stop_reach_cache[state_number] = Some(reaches);
8069 reaches
8070 }
8071
8072 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
8075 Rc::clone(&self.empty_recovery_symbols)
8076 }
8077
8078 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
8087 if set.is_empty() {
8088 return Rc::clone(&self.empty_recovery_symbols);
8089 }
8090 let candidate = Rc::new(set);
8091 match self.recovery_symbols_intern.get(&candidate) {
8092 Some(existing) => Rc::clone(existing),
8093 None => {
8094 self.recovery_symbols_intern
8095 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
8096 candidate
8097 }
8098 }
8099 }
8100
8101 fn cached_decision_lookahead(
8106 &mut self,
8107 atn: &Atn,
8108 state: &AtnState,
8109 rule_stop_state: usize,
8110 ) -> Rc<DecisionLookahead> {
8111 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number) {
8118 return Rc::clone(cached);
8119 }
8120 let entry = with_shared_atn_caches(atn, |cache| {
8121 if let Some(cached) = cache.decision_lookahead.get(&state.state_number) {
8122 return Rc::clone(cached);
8123 }
8124 let mut entry = DecisionLookahead {
8125 transitions: Vec::with_capacity(state.transitions.len()),
8126 };
8127 for transition in &state.transitions {
8128 entry.transitions.push(transition_first_set(
8129 atn,
8130 transition,
8131 rule_stop_state,
8132 &mut cache.first_set,
8133 ));
8134 }
8135 let entry = Rc::new(entry);
8136 cache
8137 .decision_lookahead
8138 .insert(state.state_number, Rc::clone(&entry));
8139 entry
8140 });
8141 self.decision_lookahead_cache
8142 .insert(state.state_number, Rc::clone(&entry));
8143 entry
8144 }
8145
8146 fn cached_rule_first_set(
8147 &mut self,
8148 atn: &Atn,
8149 target: usize,
8150 child_stop: usize,
8151 ) -> Rc<FirstSet> {
8152 if self.rule_first_set_cache.len() <= target {
8153 self.rule_first_set_cache
8154 .resize_with(atn.states().len().max(target + 1), || None);
8155 }
8156 if let Some(cached) = self
8157 .rule_first_set_cache
8158 .get(target)
8159 .and_then(Option::as_ref)
8160 {
8161 return Rc::clone(cached);
8162 }
8163 let first = with_shared_first_set_cache(atn, |cache| {
8164 rule_first_set(atn, target, child_stop, cache)
8165 });
8166 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
8167 first
8168 }
8169
8170 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
8171 if self.empty_cycle_cache.len() <= state_number {
8172 self.empty_cycle_cache
8173 .resize_with(atn.states().len().max(state_number + 1), || None);
8174 }
8175 if let Some(cached) = self.empty_cycle_cache[state_number] {
8176 return cached;
8177 }
8178 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
8179 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
8180 self.empty_cycle_cache[state_number] = Some(result);
8181 result
8182 }
8183
8184 fn empty_path_reaches_state(
8185 &mut self,
8186 atn: &Atn,
8187 state_number: usize,
8188 target_state: usize,
8189 visited: &mut FxHashSet<usize>,
8190 ) -> bool {
8191 if !visited.insert(state_number) {
8192 return false;
8193 }
8194 let Some(state) = atn.state(state_number) else {
8195 return false;
8196 };
8197 for transition in &state.transitions {
8198 match transition {
8199 Transition::Atom { .. }
8200 | Transition::Range { .. }
8201 | Transition::Set { .. }
8202 | Transition::NotSet { .. }
8203 | Transition::Wildcard { .. } => {}
8204 Transition::Rule {
8205 target,
8206 rule_index,
8207 follow_state,
8208 ..
8209 } => {
8210 if *target == target_state
8211 || self.empty_path_reaches_state(atn, *target, target_state, visited)
8212 {
8213 return true;
8214 }
8215 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
8216 else {
8217 continue;
8218 };
8219 if self
8220 .cached_rule_first_set(atn, *target, child_stop)
8221 .nullable
8222 && (*follow_state == target_state
8223 || self.empty_path_reaches_state(
8224 atn,
8225 *follow_state,
8226 target_state,
8227 visited,
8228 ))
8229 {
8230 return true;
8231 }
8232 }
8233 Transition::Epsilon { target }
8234 | Transition::Predicate { target, .. }
8235 | Transition::Action { target, .. }
8236 | Transition::Precedence { target, .. } => {
8237 if *target == target_state
8238 || self.empty_path_reaches_state(atn, *target, target_state, visited)
8239 {
8240 return true;
8241 }
8242 }
8243 }
8244 }
8245 false
8246 }
8247
8248 fn should_memoize_single_outcome(&mut self, key: &FastRecognizeKey) -> bool {
8251 match self.single_outcome_memo_mode {
8252 SingleOutcomeMemoMode::Promote => true,
8253 SingleOutcomeMemoMode::Sparse => false,
8254 SingleOutcomeMemoMode::Probe => {
8255 self.single_outcome_probe_samples += 1;
8256 if !self.single_outcome_probe_seen.insert(key.clone()) {
8257 self.single_outcome_probe_repeats += 1;
8258 }
8259 if self.single_outcome_probe_repeats >= CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
8260 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Promote;
8261 self.single_outcome_probe_seen.clear();
8262 return true;
8263 }
8264 if self.single_outcome_probe_samples >= CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT {
8265 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Sparse;
8266 self.single_outcome_probe_seen.clear();
8267 return false;
8268 }
8269 true
8270 }
8271 }
8272 }
8273
8274 fn token_at(&mut self, index: usize) -> Option<CommonToken> {
8276 self.input.get(index).cloned()
8277 }
8278
8279 fn token_ref_at(&mut self, index: usize) -> Option<TokenRef> {
8281 self.input.get_ref(index)
8282 }
8283
8284 fn current_visible_index(&mut self) -> usize {
8287 let index = self.input.index();
8288 self.input.seek(index);
8289 self.input.index()
8290 }
8291
8292 fn child_expected_reaches_clean_eof(
8295 &mut self,
8296 children: &[RecognizeOutcome],
8297 expected: &ExpectedTokens,
8298 ) -> bool {
8299 let Some(index) = expected.index else {
8300 return false;
8301 };
8302 self.token_type_at(index) == TOKEN_EOF
8303 && children
8304 .iter()
8305 .any(|child| child.diagnostics.is_empty() && child.index == index)
8306 }
8307
8308 fn previous_token_index(&mut self, index: usize) -> Option<usize> {
8315 self.input.previous_visible_token_index(index)
8316 }
8317
8318 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
8323 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
8324 Some(index)
8325 } else {
8326 self.previous_token_index(index)
8327 }
8328 }
8329
8330 #[must_use]
8347 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
8348 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
8349 self.rule_stop_token_index(current_index, consumed_eof)
8350 }
8351
8352 #[must_use]
8361 pub fn after_action_stop_index_for_tree(
8362 &mut self,
8363 tree: &ParseTree,
8364 current_index: usize,
8365 ) -> Option<usize> {
8366 if let ParseTree::Rule(rule) = tree {
8367 if let Some(stop) = rule.context().stop() {
8368 let token_index = stop.token_index();
8369 if token_index >= 0 {
8370 return Some(token_index.unsigned_abs());
8371 }
8372 }
8373 }
8374 self.after_action_stop_index(current_index)
8375 }
8376
8377 #[must_use]
8387 pub fn after_action_start_index_for_tree(
8388 &self,
8389 tree: &ParseTree,
8390 fallback_index: usize,
8391 ) -> usize {
8392 if let ParseTree::Rule(rule) = tree {
8393 if let Some(start) = rule.context().start() {
8394 let token_index = start.token_index();
8395 if token_index >= 0 {
8396 return token_index.unsigned_abs();
8397 }
8398 }
8399 }
8400 fallback_index
8401 }
8402
8403 fn rule_stop_token_ref(&mut self, index: usize, consumed_eof: bool) -> Option<TokenRef> {
8408 self.rule_stop_token_index(index, consumed_eof)
8409 .and_then(|token_index| self.token_ref_at(token_index))
8410 }
8411
8412 fn predicate_failure_recovery(
8419 &mut self,
8420 request: PredicateFailureRecovery<'_>,
8421 ) -> RecognizeOutcome {
8422 let PredicateFailureRecovery {
8423 rule_index,
8424 index,
8425 message,
8426 member_values,
8427 return_values,
8428 rule_alt_number,
8429 } = request;
8430 let rule_name = self
8431 .rule_names()
8432 .get(rule_index)
8433 .map_or_else(|| rule_index.to_string(), Clone::clone);
8434 let diagnostic = diagnostic_for_token(
8435 self.token_at(index).as_ref(),
8436 format!("rule {rule_name} {message}"),
8437 );
8438 let mut nodes = Vec::new();
8439 let mut next_index = index;
8440 loop {
8441 let symbol = self.token_type_at(next_index);
8442 if symbol == TOKEN_EOF {
8443 break;
8444 }
8445 nodes.push(RecognizedNode::ErrorToken { index: next_index });
8446 let after = self.consume_index(next_index, symbol);
8447 if after == next_index {
8448 break;
8449 }
8450 next_index = after;
8451 }
8452 RecognizeOutcome {
8453 index: next_index,
8454 consumed_eof: false,
8455 alt_number: rule_alt_number,
8456 member_values,
8457 return_values,
8458 diagnostics: vec![diagnostic],
8459 decisions: Vec::new(),
8460 actions: Vec::new(),
8461 nodes,
8462 }
8463 }
8464
8465 fn parser_semantic_hook_result(
8468 &mut self,
8469 request: ParserSemanticHookRequest<'_>,
8470 ) -> Option<bool> {
8471 let ParserSemanticHookRequest {
8472 index,
8473 rule_index,
8474 pred_index,
8475 context,
8476 local_int_arg,
8477 member_values,
8478 } = request;
8479 let rule_name = self.rule_names().get(rule_index).cloned();
8480 self.input.seek(index);
8481 let input = &mut self.input;
8482 let semantic_hooks = &mut self.semantic_hooks;
8483 let mut ctx = ParserSemCtx {
8484 input,
8485 rule_index,
8486 coordinate_index: pred_index,
8487 rule_name,
8488 context,
8489 tree: None,
8490 local_int_arg,
8491 member_values,
8492 action: None,
8493 };
8494 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
8495 }
8496
8497 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
8502 if prior.is_empty() {
8503 return;
8504 }
8505 let mut merged = prior;
8506 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
8507 if !merged.contains(&coordinate) {
8508 merged.push(coordinate);
8509 }
8510 }
8511 self.unknown_predicate_hits = merged;
8512 }
8513
8514 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
8523 apply_unknown_predicate_policy(
8524 self.unknown_predicate_policy,
8525 rule_index,
8526 pred_index,
8527 &mut self.unknown_predicate_hits,
8528 )
8529 }
8530
8531 fn unknown_semantic_error(&self) -> Option<AntlrError> {
8534 use std::fmt::Write as _;
8535 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
8536 return None;
8537 }
8538 let mut message = String::new();
8539 for (rule_index, pred_index) in &self.unknown_predicate_hits {
8540 if !message.is_empty() {
8541 message.push_str("; ");
8542 }
8543 let _ = match self.rule_names().get(*rule_index) {
8544 Some(rule_name) => write!(
8545 message,
8546 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
8547 ),
8548 None => write!(
8549 message,
8550 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
8551 ),
8552 };
8553 }
8554 for (rule_index, source_state) in &self.unhandled_action_hits {
8555 if !message.is_empty() {
8556 message.push_str("; ");
8557 }
8558 let _ = match self.rule_names().get(*rule_index) {
8559 Some(rule_name) => write!(
8560 message,
8561 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
8562 ),
8563 None => write!(
8564 message,
8565 "unhandled semantic action: rule_index={rule_index} state={source_state}"
8566 ),
8567 };
8568 }
8569 Some(AntlrError::Unsupported(message))
8570 }
8571
8572 fn parser_semir_predicate_matches(
8580 &mut self,
8581 semantics: &ParserSemantics,
8582 predicate: &ParserSemanticPredicate,
8583 request: ParserSemanticHookRequest<'_>,
8584 ) -> bool {
8585 self.input.seek(request.index);
8586 let rule_name = self
8587 .data
8588 .rule_names()
8589 .get(request.rule_index)
8590 .map(String::as_str);
8591 let unknown_predicate_policy = self.unknown_predicate_policy;
8592 let mut ctx = ParserSemIrCtx {
8593 input: &mut self.input,
8594 semantic_hooks: &mut self.semantic_hooks,
8595 rule_index: request.rule_index,
8596 coordinate_index: request.pred_index,
8597 rule_name,
8598 context: request.context,
8599 local_int_arg: request.local_int_arg,
8600 member_values: request.member_values,
8601 invoked_predicates: &mut self.invoked_predicates,
8602 unknown_predicate_policy,
8603 unknown_predicate_hits: &mut self.unknown_predicate_hits,
8604 };
8605 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
8606 }
8607
8608 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
8609 let PredicateEval {
8610 index,
8611 rule_index,
8612 pred_index,
8613 predicates,
8614 semantics,
8615 context,
8616 local_int_arg,
8617 member_values,
8618 } = eval;
8619 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
8620 semantics
8621 .predicates
8622 .iter()
8623 .find(|predicate| {
8624 predicate.rule_index == rule_index && predicate.pred_index == pred_index
8625 })
8626 .map(|predicate| (semantics, predicate))
8627 }) {
8628 return self.parser_semir_predicate_matches(
8629 semantics,
8630 predicate,
8631 ParserSemanticHookRequest {
8632 index,
8633 rule_index,
8634 pred_index,
8635 context,
8636 local_int_arg,
8637 member_values,
8638 },
8639 );
8640 }
8641 let Some((_, _, predicate)) = predicates
8642 .iter()
8643 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
8644 else {
8645 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
8646 index,
8647 rule_index,
8648 pred_index,
8649 context,
8650 local_int_arg,
8651 member_values,
8652 }) {
8653 return result;
8654 }
8655 return self.unknown_predicate_result(rule_index, pred_index);
8656 };
8657 self.input.seek(index);
8658 match predicate {
8659 ParserPredicate::True => true,
8660 ParserPredicate::False => false,
8661 ParserPredicate::FalseWithMessage { .. } => false,
8662 ParserPredicate::Invoke { value } => {
8663 let key = (rule_index, pred_index);
8664 if !self.invoked_predicates.contains(&key) {
8665 self.invoked_predicates.push(key);
8666 use std::io::Write as _;
8667 let mut stdout = std::io::stdout().lock();
8668 let _ = writeln!(stdout, "eval={value}");
8669 }
8670 *value
8671 }
8672 ParserPredicate::LookaheadTextEquals { offset, text } => {
8673 self.input.lt(*offset).and_then(Token::text) == Some(*text)
8674 }
8675 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
8676 self.la(*offset) != *token_type
8677 }
8678 ParserPredicate::TokenPairAdjacent => {
8679 let Some(first) = self.input.lt(-2).map(Token::token_index) else {
8680 return false;
8681 };
8682 let Some(second) = self.input.lt(-1).map(Token::token_index) else {
8683 return false;
8684 };
8685 first + 1 == second
8686 }
8687 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
8688 .and_then(|context| {
8689 context.children().iter().find_map(|child| match child {
8690 ParseTree::Rule(rule) if rule.context().rule_index() == *rule_index => {
8691 Some(child.text())
8692 }
8693 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
8694 })
8695 })
8696 .is_none_or(|actual| actual != *text),
8697 ParserPredicate::LocalIntEquals { value } => {
8698 local_int_arg.is_none_or(|(_, actual)| actual == *value)
8699 }
8700 ParserPredicate::LocalIntLessOrEqual { value } => {
8701 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
8702 }
8703 ParserPredicate::MemberModuloEquals {
8704 member,
8705 modulus,
8706 value,
8707 equals,
8708 } => {
8709 if *modulus == 0 {
8710 return false;
8711 }
8712 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
8713 (actual == *value) == *equals
8714 }
8715 ParserPredicate::MemberEquals {
8716 member,
8717 value,
8718 equals,
8719 } => {
8720 let actual = member_values.get(member).copied().unwrap_or_default();
8721 (actual == *value) == *equals
8722 }
8723 }
8724 }
8725
8726 fn parser_predicate_failure_message(
8728 &self,
8729 rule_index: usize,
8730 pred_index: usize,
8731 predicates: &[(usize, usize, ParserPredicate)],
8732 ) -> Option<&'static str> {
8733 predicates
8734 .iter()
8735 .find_map(|(rule, pred, predicate)| match predicate {
8736 ParserPredicate::FalseWithMessage { message }
8737 if *rule == rule_index && *pred == pred_index =>
8738 {
8739 Some(*message)
8740 }
8741 _ => None,
8742 })
8743 }
8744
8745 pub fn parser_semantic_ir_predicate_failure_message(
8748 &self,
8749 rule_index: usize,
8750 pred_index: usize,
8751 semantics: &ParserSemantics,
8752 ) -> Option<&'static str> {
8753 semantics
8754 .predicates
8755 .iter()
8756 .find(|predicate| {
8757 predicate.rule_index == rule_index && predicate.pred_index == pred_index
8758 })
8759 .and_then(|predicate| predicate.failure_message)
8760 }
8761
8762 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
8771 if symbol == TOKEN_EOF {
8772 return index;
8773 }
8774 self.input.next_visible_after(index)
8775 }
8776
8777 fn no_viable_alternative(
8780 &mut self,
8781 start_index: usize,
8782 error_index: usize,
8783 ) -> ParserDiagnostic {
8784 let text = display_input_text(&self.input.text(start_index, error_index));
8785 diagnostic_for_token(
8786 self.token_at(error_index).as_ref(),
8787 format!("no viable alternative at input '{text}'"),
8788 )
8789 }
8790
8791 fn recovery_failure_diagnostic(
8794 &mut self,
8795 index: usize,
8796 decision_start_index: Option<usize>,
8797 expected_symbols: &BTreeSet<i32>,
8798 ) -> ParserDiagnostic {
8799 if expected_symbols.len() > 1 {
8800 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
8801 return self.no_viable_alternative(decision_start, index);
8802 }
8803 }
8804 diagnostic_for_token(
8805 self.token_at(index).as_ref(),
8806 format!(
8807 "mismatched input {} expecting {}",
8808 self.token_at(index)
8809 .as_ref()
8810 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8811 self.expected_symbols_display(expected_symbols)
8812 ),
8813 )
8814 }
8815
8816 fn eof_rule_recovery_diagnostic(
8819 &mut self,
8820 index: usize,
8821 expected_symbols: &BTreeSet<i32>,
8822 expected: &ExpectedTokens,
8823 ) -> ParserDiagnostic {
8824 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
8825 &expected.symbols
8826 } else {
8827 expected_symbols
8828 };
8829 diagnostic_for_token(
8830 self.token_at(index).as_ref(),
8831 format!(
8832 "mismatched input {} expecting {}",
8833 self.token_at(index)
8834 .as_ref()
8835 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8836 self.expected_symbols_display(symbols)
8837 ),
8838 )
8839 }
8840
8841 pub fn text_interval(&mut self, start: usize, stop: Option<usize>) -> String {
8847 let Some(stop) = stop else {
8848 return String::new();
8849 };
8850 let stop = if self
8851 .token_at(stop)
8852 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8853 {
8854 let Some(previous) = self.previous_token_index(stop) else {
8855 return String::new();
8856 };
8857 previous
8858 } else {
8859 stop
8860 };
8861 self.input.text(start, stop)
8862 }
8863
8864 fn clear_prediction_diagnostics(&mut self) {
8867 self.prediction_diagnostics.clear();
8868 self.reported_prediction_diagnostics.clear();
8869 }
8870
8871 fn reset_per_parse_caches(&mut self) {
8893 self.rule_first_set_cache.clear();
8894 self.decision_lookahead_cache.clear();
8895 self.ll1_decision_cache.clear();
8896 self.empty_cycle_cache.clear();
8897 self.rule_stop_reach_cache.clear();
8898 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Probe;
8899 self.single_outcome_probe_seen.clear();
8900 self.single_outcome_probe_samples = 0;
8901 self.single_outcome_probe_repeats = 0;
8902 self.recovery_symbols_intern.clear();
8903 self.state_expected_cache.clear();
8904 self.state_expected_token_cache.clear();
8905 }
8906
8907 fn record_prediction_diagnostics(
8910 &mut self,
8911 atn: &Atn,
8912 state: &AtnState,
8913 start_index: usize,
8914 outcomes: &[RecognizeOutcome],
8915 ) {
8916 if !self.report_diagnostic_errors || state.transitions.len() < 2 {
8917 return;
8918 }
8919 let Some(decision) = atn
8920 .decision_to_state()
8921 .iter()
8922 .position(|state_number| *state_number == state.state_number)
8923 else {
8924 return;
8925 };
8926 let Some(rule_index) = state.rule_index else {
8927 return;
8928 };
8929 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
8930 for outcome in outcomes
8931 .iter()
8932 .filter(|outcome| outcome.diagnostics.is_empty())
8933 {
8934 let Some(alt) = outcome.decisions.first() else {
8935 continue;
8936 };
8937 alts_by_end
8938 .entry(outcome.index)
8939 .or_default()
8940 .insert(alt + 1);
8941 }
8942 let Some((&end_index, ambig_alts)) = alts_by_end
8943 .iter()
8944 .filter(|(_, alts)| alts.len() > 1)
8945 .max_by_key(|(end, _)| *end)
8946 else {
8947 return;
8948 };
8949 let rule_name = self
8950 .rule_names()
8951 .get(rule_index)
8952 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
8953 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
8954 let input = display_input_text(&self.input.text(start_index, stop_index));
8955 let alts = ambig_alts
8956 .iter()
8957 .map(usize::to_string)
8958 .collect::<Vec<_>>()
8959 .join(", ");
8960 let key = (decision, start_index, format!("{alts}:{input}"));
8961 if !self.reported_prediction_diagnostics.insert(key) {
8962 return;
8963 }
8964 let start_token = self.token_at(start_index);
8965 let stop_token = self.token_at(stop_index);
8966 self.prediction_diagnostics.push(diagnostic_for_token(
8967 start_token.as_ref(),
8968 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
8969 ));
8970 self.prediction_diagnostics.push(diagnostic_for_token(
8971 stop_token.as_ref(),
8972 format!(
8973 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
8974 ),
8975 ));
8976 }
8977
8978 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
8980 expected_symbols_display(
8981 &state_expected_symbols(atn, state_number),
8982 self.vocabulary(),
8983 )
8984 }
8985
8986 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
8991 let state = usize::try_from(self.data().state()).unwrap_or(0);
8992 ExpectedTokenSet {
8993 symbols: state_expected_symbols(atn, state),
8994 }
8995 }
8996
8997 pub const fn set_bail_on_error(&mut self, bail: bool) {
9000 self.bail_on_error = bail;
9001 }
9002
9003 #[must_use]
9005 pub const fn bail_on_error(&self) -> bool {
9006 self.bail_on_error
9007 }
9008
9009 pub fn rule_invocation_stack(&self) -> Vec<String> {
9012 self.rule_context_stack
9013 .iter()
9014 .rev()
9015 .map(|frame| {
9016 self.data()
9017 .rule_names()
9018 .get(frame.rule_index)
9019 .cloned()
9020 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
9021 })
9022 .collect()
9023 }
9024
9025 pub fn token_display_at(&mut self, index: usize) -> Option<String> {
9027 self.token_at(index).map(|token| format!("{token}"))
9028 }
9029
9030 fn recognized_node_tree(
9032 &mut self,
9033 node: &RecognizedNode,
9034 track_alt_numbers: bool,
9035 ) -> Result<ParseTree, AntlrError> {
9036 match node {
9037 RecognizedNode::Token { index } => {
9038 let token = self
9039 .input
9040 .get_ref(*index)
9041 .ok_or_else(|| AntlrError::ParserError {
9042 line: 0,
9043 column: 0,
9044 message: format!("missing token at index {index}"),
9045 })?;
9046 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
9047 }
9048 RecognizedNode::ErrorToken { index } => {
9049 let token = self
9050 .input
9051 .get_ref(*index)
9052 .ok_or_else(|| AntlrError::ParserError {
9053 line: 0,
9054 column: 0,
9055 message: format!("missing error token at index {index}"),
9056 })?;
9057 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
9058 }
9059 RecognizedNode::MissingToken {
9060 token_type,
9061 at_index,
9062 text,
9063 } => {
9064 let current = self.token_at(*at_index);
9065 let token = CommonToken::new(*token_type)
9066 .with_text(text.as_str())
9067 .with_span(usize::MAX, usize::MAX)
9068 .with_position(
9069 current.as_ref().map(Token::line).unwrap_or_default(),
9070 current.as_ref().map(Token::column).unwrap_or_default(),
9071 );
9072 Ok(ParseTree::Error(ErrorNode::new(token)))
9073 }
9074 RecognizedNode::Rule {
9075 rule_index,
9076 invoking_state,
9077 alt_number,
9078 start_index,
9079 stop_index,
9080 return_values,
9081 children,
9082 } => {
9083 let mut context = ParserRuleContext::new(*rule_index, *invoking_state);
9084 if track_alt_numbers {
9085 context.set_alt_number(*alt_number);
9086 }
9087 for (name, value) in return_values {
9088 context.set_int_return(name.clone(), *value);
9089 }
9090 if let Some(token) = self.token_ref_at(*start_index) {
9091 context.set_start_ref(token);
9092 }
9093 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
9094 context.set_stop_ref(token);
9095 }
9096 for child in children {
9097 context.add_child(self.recognized_node_tree(child, track_alt_numbers)?);
9098 }
9099 Ok(self.rule_node(context))
9100 }
9101 RecognizedNode::LeftRecursiveBoundary { rule_index } => Err(AntlrError::Unsupported(
9102 format!("unfolded left-recursive boundary for rule {rule_index}"),
9103 )),
9104 }
9105 }
9106}
9107
9108impl<S, H> DirectAdaptiveParser<'_, '_, S, H>
9109where
9110 S: TokenSource,
9111 H: SemanticHooks,
9112{
9113 fn parse_rule(
9114 &mut self,
9115 rule_index: usize,
9116 invoking_state: isize,
9117 precedence: i32,
9118 ) -> DirectAdaptiveParseResult<ParseTree> {
9119 let start_state = *self.atn.rule_to_start_state().get(rule_index).ok_or(
9120 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
9121 )?;
9122 let stop_state = *self
9123 .atn
9124 .rule_to_stop_state()
9125 .get(rule_index)
9126 .filter(|state| **state != usize::MAX)
9127 .ok_or(DirectAdaptiveParseControl::Fallback(
9128 DirectAdaptiveFallback::MissingAtn,
9129 ))?;
9130 let start_index = self.parser.current_visible_index();
9131 let mut children = Vec::new();
9132 let mut state_number = start_state;
9133 let mut consumed_eof = false;
9134 while state_number != stop_state {
9135 self.step()?;
9136 let (transition, boundary) = self.next_transition(state_number, precedence)?;
9137 if boundary.is_some() {
9138 return Err(DirectAdaptiveParseControl::Fallback(
9139 DirectAdaptiveFallback::LeftRecursiveBoundary,
9140 ));
9141 }
9142 match transition {
9143 Transition::Epsilon { target } => {
9144 state_number = target;
9145 }
9146 Transition::Precedence {
9147 target,
9148 precedence: transition_precedence,
9149 } => {
9150 if transition_precedence < precedence {
9151 return Err(DirectAdaptiveParseControl::Fallback(
9152 DirectAdaptiveFallback::Precedence,
9153 ));
9154 }
9155 state_number = target;
9156 }
9157 Transition::Rule {
9158 rule_index,
9159 follow_state,
9160 precedence: rule_precedence,
9161 ..
9162 } => {
9163 let child = self.parse_rule(
9164 rule_index,
9165 invoking_state_number(state_number),
9166 rule_precedence,
9167 )?;
9168 if self.parser.build_parse_trees {
9169 children.push(child);
9170 }
9171 state_number = follow_state;
9172 }
9173 Transition::Atom { .. }
9174 | Transition::Range { .. }
9175 | Transition::Set { .. }
9176 | Transition::NotSet { .. }
9177 | Transition::Wildcard { .. } => {
9178 let (matched_eof, child) = self.consume_transition(&transition)?;
9179 consumed_eof |= matched_eof;
9180 if let Some(child) = child {
9181 children.push(child);
9182 }
9183 state_number = transition.target();
9184 }
9185 Transition::Predicate { .. } => {
9186 return Err(DirectAdaptiveParseControl::Fallback(
9187 DirectAdaptiveFallback::Predicate,
9188 ));
9189 }
9190 Transition::Action { .. } => {
9191 return Err(DirectAdaptiveParseControl::Fallback(
9192 DirectAdaptiveFallback::Action,
9193 ));
9194 }
9195 }
9196 }
9197
9198 let mut context = ParserRuleContext::with_child_capacity(
9199 rule_index,
9200 invoking_state,
9201 if self.parser.build_parse_trees {
9202 children.len()
9203 } else {
9204 0
9205 },
9206 );
9207 if let Some(token) = self.parser.token_ref_at(start_index) {
9208 context.set_start_ref(token);
9209 }
9210 let stop_index = self
9211 .parser
9212 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
9213 if let Some(token) = stop_index.and_then(|index| self.parser.token_ref_at(index)) {
9214 context.set_stop_ref(token);
9215 }
9216 if self.parser.build_parse_trees {
9217 for child in children {
9218 context.add_child(child);
9219 }
9220 }
9221 Ok(self.parser.rule_node(context))
9222 }
9223
9224 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
9225 self.steps += 1;
9226 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
9227 return Err(DirectAdaptiveParseControl::Fallback(
9228 DirectAdaptiveFallback::StepLimit,
9229 ));
9230 }
9231 Ok(())
9232 }
9233
9234 fn next_transition(
9235 &mut self,
9236 state_number: usize,
9237 precedence: i32,
9238 ) -> DirectAdaptiveParseResult<(Transition, Option<usize>)> {
9239 let state = self
9240 .atn
9241 .state(state_number)
9242 .ok_or(DirectAdaptiveParseControl::Fallback(
9243 DirectAdaptiveFallback::MissingAtn,
9244 ))?;
9245 if state.is_rule_stop() {
9246 return Err(DirectAdaptiveParseControl::Fallback(
9247 DirectAdaptiveFallback::RuleStop,
9248 ));
9249 }
9250 let transition_index =
9251 self.transition_index(state_number, state.transitions.len(), precedence)?;
9252 let transition = state.transitions.get(transition_index).cloned().ok_or(
9253 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
9254 )?;
9255 let boundary = match &transition {
9256 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
9257 left_recursive_boundary(self.atn, state, *target)
9258 }
9259 _ => None,
9260 };
9261 Ok((transition, boundary))
9262 }
9263
9264 fn transition_index(
9265 &mut self,
9266 state_number: usize,
9267 transition_count: usize,
9268 precedence: i32,
9269 ) -> DirectAdaptiveParseResult<usize> {
9270 match transition_count {
9271 0 => Err(DirectAdaptiveParseControl::Fallback(
9272 DirectAdaptiveFallback::NoTransition,
9273 )),
9274 1 => Ok(0),
9275 _ => {
9276 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
9277 return Ok(alt);
9278 }
9279 let decision = self
9280 .decision_by_state
9281 .get(state_number)
9282 .and_then(|decision| *decision)
9283 .ok_or(DirectAdaptiveParseControl::Fallback(
9284 DirectAdaptiveFallback::UnknownDecision,
9285 ))?;
9286 let prediction = self
9287 .simulator
9288 .adaptive_predict_stream_info_with_precedence(
9289 decision,
9290 direct_precedence(precedence),
9291 &mut self.parser.input,
9292 )
9293 .map_err(|_| {
9294 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
9295 })?;
9296 if prediction.has_semantic_context {
9297 return Err(DirectAdaptiveParseControl::Fallback(
9298 DirectAdaptiveFallback::SemanticContext,
9299 ));
9300 }
9301 prediction
9302 .alt
9303 .checked_sub(1)
9304 .filter(|index| *index < transition_count)
9305 .ok_or(DirectAdaptiveParseControl::Fallback(
9306 DirectAdaptiveFallback::InvalidAlt,
9307 ))
9308 }
9309 }
9310 }
9311
9312 fn ll1_transition_index(
9313 &mut self,
9314 state_number: usize,
9315 transition_count: usize,
9316 ) -> DirectAdaptiveParseResult<Option<usize>> {
9317 let state = self
9318 .atn
9319 .state(state_number)
9320 .ok_or(DirectAdaptiveParseControl::Fallback(
9321 DirectAdaptiveFallback::MissingAtn,
9322 ))?;
9323 if state.precedence_rule_decision {
9324 return Ok(None);
9325 }
9326 let Some(rule_stop) = state
9327 .rule_index
9328 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index).copied())
9329 else {
9330 return Ok(None);
9331 };
9332 let symbol = self.parser.input.la_token(1);
9333 let entry = self
9334 .parser
9335 .cached_decision_lookahead(self.atn, state, rule_stop);
9336 Ok(ll1_greedy_alt(&entry, symbol, state.non_greedy).filter(|alt| *alt < transition_count))
9337 }
9338
9339 fn consume_transition(
9340 &mut self,
9341 transition: &Transition,
9342 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
9343 let symbol = self.parser.input.la_token(1);
9344 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
9345 return Err(DirectAdaptiveParseControl::Fallback(
9346 DirectAdaptiveFallback::TokenMismatch,
9347 ));
9348 }
9349 let token = self
9350 .parser
9351 .input
9352 .lt_ref(1)
9353 .ok_or(DirectAdaptiveParseControl::Fallback(
9354 DirectAdaptiveFallback::TokenMismatch,
9355 ))?;
9356 let matched_eof = symbol == TOKEN_EOF;
9357 if !matched_eof {
9358 self.parser.consume();
9359 }
9360 let child = self
9361 .parser
9362 .build_parse_trees
9363 .then(|| ParseTree::Terminal(TerminalNode::from_ref(token)));
9364 Ok((matched_eof, child))
9365 }
9366}
9367
9368fn left_recursive_boundary(atn: &Atn, state: &AtnState, target: usize) -> Option<usize> {
9371 if !state.precedence_rule_decision {
9372 return None;
9373 }
9374 let target_state = atn.state(target)?;
9375 if target_state.kind == AtnStateKind::LoopEnd {
9376 return None;
9377 }
9378 state.rule_index
9379}
9380
9381const fn next_alt_number(
9388 state: &AtnState,
9389 transition_index: usize,
9390 current_alt_number: usize,
9391 track_alt_numbers: bool,
9392) -> usize {
9393 if !track_alt_numbers || current_alt_number != 0 || state.transitions.len() <= 1 {
9394 return current_alt_number;
9395 }
9396 if matches!(
9397 state.kind,
9398 AtnStateKind::Basic
9399 | AtnStateKind::BlockStart
9400 | AtnStateKind::PlusBlockStart
9401 | AtnStateKind::StarBlockStart
9402 | AtnStateKind::StarLoopEntry
9403 ) && !state.precedence_rule_decision
9404 {
9405 return transition_index + 1;
9406 }
9407 current_alt_number
9408}
9409
9410fn fold_left_recursive_boundaries(nodes: Vec<RecognizedNode>) -> Vec<RecognizedNode> {
9413 let mut folded = Vec::new();
9414 for node in nodes {
9415 match node {
9416 RecognizedNode::LeftRecursiveBoundary { rule_index } => {
9417 if !folded.is_empty() {
9418 let children = std::mem::take(&mut folded);
9419 let start_index = recognized_nodes_start_index(&children).unwrap_or_default();
9420 let stop_index = recognized_nodes_stop_index(&children);
9421 folded.push(RecognizedNode::Rule {
9422 rule_index,
9423 invoking_state: -1,
9424 alt_number: 0,
9425 start_index,
9426 stop_index,
9427 return_values: BTreeMap::new(),
9428 children,
9429 });
9430 }
9431 }
9432 node => folded.push(node),
9433 }
9434 }
9435 folded
9436}
9437
9438fn fold_fast_left_recursive_boundaries(
9440 nodes: Vec<Rc<FastRecognizedNode>>,
9441) -> Vec<Rc<FastRecognizedNode>> {
9442 if !nodes.iter().any(|node| {
9447 matches!(
9448 node.as_ref(),
9449 FastRecognizedNode::LeftRecursiveBoundary { .. }
9450 )
9451 }) {
9452 return nodes;
9453 }
9454 let mut folded: Vec<Rc<FastRecognizedNode>> = Vec::with_capacity(nodes.len());
9455 for node in nodes {
9456 match node.as_ref() {
9457 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
9458 if !folded.is_empty() {
9459 let children = std::mem::take(&mut folded);
9460 let start_index =
9461 fast_recognized_nodes_start_index(&children).unwrap_or_default();
9462 let stop_index = fast_recognized_nodes_stop_index(&children);
9463 folded.push(Rc::new(FastRecognizedNode::Rule {
9464 rule_index: *rule_index,
9465 invoking_state: -1,
9466 start_index,
9467 stop_index,
9468 children: NodeList::from_vec(children),
9469 }));
9470 }
9471 }
9472 _ => folded.push(node),
9473 }
9474 }
9475 folded
9476}
9477
9478fn fast_node_has_left_recursive_boundary(node: &FastRecognizedNode) -> bool {
9479 match node {
9480 FastRecognizedNode::LeftRecursiveBoundary { .. } => true,
9481 FastRecognizedNode::Rule { children, .. } => children.has_left_recursive_boundary(),
9482 FastRecognizedNode::Token { .. }
9483 | FastRecognizedNode::ErrorToken { .. }
9484 | FastRecognizedNode::MissingToken { .. } => false,
9485 }
9486}
9487
9488fn fast_recognized_nodes_start_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
9489 nodes
9490 .iter()
9491 .find_map(|node| fast_recognized_node_start_index(node.as_ref()))
9492}
9493
9494const fn fast_recognized_node_start_index(node: &FastRecognizedNode) -> Option<usize> {
9495 match node {
9496 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
9497 Some(*index)
9498 }
9499 FastRecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
9500 FastRecognizedNode::Rule { start_index, .. } => Some(*start_index),
9501 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
9502 }
9503}
9504
9505const fn fast_recognized_node_span(node: &FastRecognizedNode) -> Option<(usize, Option<usize>)> {
9506 match node {
9507 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
9508 Some((*index, Some(*index)))
9509 }
9510 FastRecognizedNode::MissingToken { at_index, .. } => Some((*at_index, None)),
9511 FastRecognizedNode::Rule {
9512 start_index,
9513 stop_index,
9514 ..
9515 } => Some((*start_index, *stop_index)),
9516 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
9517 }
9518}
9519
9520fn fast_recognized_nodes_stop_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
9521 nodes
9522 .iter()
9523 .rev()
9524 .find_map(|node| fast_recognized_node_stop_index(node.as_ref()))
9525}
9526
9527const fn fast_recognized_node_stop_index(node: &FastRecognizedNode) -> Option<usize> {
9528 match node {
9529 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
9530 Some(*index)
9531 }
9532 FastRecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
9533 FastRecognizedNode::Rule { stop_index, .. } => *stop_index,
9534 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
9535 }
9536}
9537
9538fn recognized_nodes_start_index(nodes: &[RecognizedNode]) -> Option<usize> {
9539 nodes.iter().find_map(recognized_node_start_index)
9540}
9541
9542const fn recognized_node_start_index(node: &RecognizedNode) -> Option<usize> {
9543 match node {
9544 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
9545 RecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
9546 RecognizedNode::Rule { start_index, .. } => Some(*start_index),
9547 RecognizedNode::LeftRecursiveBoundary { .. } => None,
9548 }
9549}
9550
9551fn recognized_nodes_stop_index(nodes: &[RecognizedNode]) -> Option<usize> {
9552 nodes.iter().rev().find_map(recognized_node_stop_index)
9553}
9554
9555fn invoking_state_number(state_number: usize) -> isize {
9558 isize::try_from(state_number).unwrap_or(isize::MAX)
9559}
9560
9561fn direct_precedence(precedence: i32) -> usize {
9562 usize::try_from(precedence.max(0)).unwrap_or_default()
9563}
9564
9565const fn recognized_node_stop_index(node: &RecognizedNode) -> Option<usize> {
9566 match node {
9567 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
9568 RecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
9569 RecognizedNode::Rule { stop_index, .. } => *stop_index,
9570 RecognizedNode::LeftRecursiveBoundary { .. } => None,
9571 }
9572}
9573
9574fn token_input_display(token: &impl Token) -> String {
9575 format!("'{}'", token.text().unwrap_or("<EOF>"))
9576}
9577
9578fn display_input_text(text: &str) -> String {
9579 let mut out = String::new();
9580 for ch in text.chars() {
9581 match ch {
9582 '\n' => out.push_str("\\n"),
9583 '\r' => out.push_str("\\r"),
9584 '\t' => out.push_str("\\t"),
9585 other => out.push(other),
9586 }
9587 }
9588 out
9589}
9590
9591fn diagnostic_for_token(token: Option<&impl Token>, message: String) -> ParserDiagnostic {
9592 ParserDiagnostic {
9593 line: token.map(Token::line).unwrap_or_default(),
9594 column: token.map(Token::column).unwrap_or_default(),
9595 message,
9596 }
9597}
9598
9599#[allow(clippy::print_stderr)]
9601fn report_parser_diagnostics(diagnostics: &[ParserDiagnostic]) {
9602 for diagnostic in diagnostics {
9603 eprintln!(
9604 "line {}:{} {}",
9605 diagnostic.line, diagnostic.column, diagnostic.message
9606 );
9607 }
9608}
9609
9610#[allow(clippy::print_stderr)]
9613fn report_generated_diagnostics(
9614 parser_diagnostics: &[ParserDiagnostic],
9615 token_errors: &[TokenSourceError],
9616) {
9617 let mut token_iter = token_errors.iter().peekable();
9624 for diagnostic in parser_diagnostics {
9625 while let Some(error) = token_iter.peek() {
9626 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
9627 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9628 token_iter.next();
9629 } else {
9630 break;
9631 }
9632 }
9633 eprintln!(
9634 "line {}:{} {}",
9635 diagnostic.line, diagnostic.column, diagnostic.message
9636 );
9637 }
9638 for error in token_iter {
9639 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9640 }
9641}
9642
9643#[allow(clippy::print_stderr)]
9646fn report_token_source_errors(errors: &[TokenSourceError]) {
9647 for error in errors {
9648 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9649 }
9650}
9651
9652fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
9653 let items = symbols
9654 .iter()
9655 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
9656 .collect::<Vec<_>>();
9657 if let [single] = items.as_slice() {
9658 return single.clone();
9659 }
9660 format!("{{{}}}", items.join(", "))
9661}
9662
9663fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
9664 if symbol == TOKEN_EOF {
9665 return "<EOF>".to_owned();
9666 }
9667 vocabulary.display_name(symbol)
9668}
9669
9670fn is_caller_follow_boundary_text(text: &str) -> bool {
9671 text.chars().any(|ch| ch == ';' || ch == '\n')
9672 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
9673}
9674
9675fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
9676 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
9677}
9678
9679fn state_is_left_recursive_rule(atn: &Atn, state: &AtnState) -> bool {
9683 let Some(rule_index) = state.rule_index else {
9684 return false;
9685 };
9686 atn.rule_to_start_state()
9687 .get(rule_index)
9688 .and_then(|state_number| atn.state(*state_number))
9689 .is_some_and(|rule_start| rule_start.left_recursive_rule)
9690}
9691
9692fn select_better_top_outcome(
9699 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
9700 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
9701) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
9702 match (first, second) {
9703 (Ok(first), Ok(second)) => {
9704 if first.0.diagnostics.is_empty() {
9705 Ok(first)
9706 } else {
9707 Ok(second)
9708 }
9709 }
9710 (Ok(first), Err(_)) => Ok(first),
9711 (Err(_), Ok(second)) => Ok(second),
9712 (Err(_), Err(second_expected)) => Err(second_expected),
9713 }
9714}
9715
9716fn select_best_fast_outcome(
9722 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
9723 prediction_mode: PredictionMode,
9724 caller_follow: Option<&TokenBitSet>,
9725 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
9726) -> Option<FastRecognizeOutcome> {
9727 let mut best = None;
9728 let mut best_caller_follow = None;
9729 for outcome in outcomes {
9730 if matches!(
9731 prediction_mode,
9732 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9733 ) && outcome.diagnostics.is_empty()
9734 && let Some(follow) = caller_follow
9735 {
9736 let (token_type, is_boundary, _) = token_info_at(outcome.index);
9737 if is_boundary && follow.contains(token_type) {
9738 let replace =
9739 best_caller_follow
9740 .as_ref()
9741 .is_none_or(|existing: &FastRecognizeOutcome| {
9742 (outcome.index, outcome.consumed_eof)
9743 < (existing.index, existing.consumed_eof)
9744 });
9745 if replace {
9746 best_caller_follow = Some(outcome.clone());
9747 }
9748 }
9749 }
9750 let Some(existing) = best else {
9751 best = Some(outcome);
9752 continue;
9753 };
9754 let outcome_position = (outcome.index, outcome.consumed_eof);
9755 let best_position = (existing.index, existing.consumed_eof);
9756 let better = match prediction_mode {
9757 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
9758 outcome_position,
9759 &outcome.diagnostics,
9760 best_position,
9761 &existing.diagnostics,
9762 ),
9763 PredictionMode::Sll => outcome.index > existing.index,
9764 };
9765 best = Some(if better { outcome } else { existing });
9766 }
9767 let should_use_caller_follow =
9768 best_caller_follow
9769 .as_ref()
9770 .zip(best.as_ref())
9771 .is_some_and(|(candidate, selected)| {
9772 if !selected.diagnostics.is_empty() {
9773 return true;
9774 }
9775 candidate.index < selected.index
9776 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
9777 });
9778 if should_use_caller_follow {
9779 best_caller_follow
9780 } else {
9781 best
9782 }
9783}
9784
9785fn select_best_outcome(
9786 outcomes: impl Iterator<Item = RecognizeOutcome>,
9787 prediction_mode: PredictionMode,
9788) -> Option<RecognizeOutcome> {
9789 let outcomes = outcomes.collect::<Vec<_>>();
9790 let prefer_first_tie = outcomes
9791 .iter()
9792 .any(|outcome| nodes_need_stable_tie(&outcome.nodes));
9793 outcomes.into_iter().reduce(|best, outcome| {
9794 let outcome_position = (outcome.index, outcome.consumed_eof);
9795 let best_position = (best.index, best.consumed_eof);
9796 let better = match prediction_mode {
9797 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
9798 outcome_is_better(
9799 outcome_position,
9800 &outcome.diagnostics,
9801 best_position,
9802 &best.diagnostics,
9803 ) || (!prefer_first_tie
9804 && outcome_position == best_position
9805 && outcome.diagnostics.len() == best.diagnostics.len()
9806 && diagnostic_recovery_rank(&outcome.diagnostics)
9807 == diagnostic_recovery_rank(&best.diagnostics)
9808 && (outcome.decisions < best.decisions
9809 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
9810 }
9811 PredictionMode::Sll => {
9812 outcome_position > best_position
9813 || (outcome_position == best_position
9814 && !prefer_first_tie
9815 && (outcome.decisions < best.decisions
9816 || (outcome.decisions == best.decisions
9817 && outcome_is_better(
9818 outcome_position,
9819 &outcome.diagnostics,
9820 best_position,
9821 &best.diagnostics,
9822 ))))
9823 }
9824 };
9825 if better {
9826 return outcome;
9827 }
9828 best
9829 })
9830}
9831
9832fn transition_decision(
9839 atn: &Atn,
9840 state: &AtnState,
9841 transition_index: usize,
9842 predicates: &[(usize, usize, ParserPredicate)],
9843) -> Option<usize> {
9844 if state.transitions.len() <= 1
9845 || state.precedence_rule_decision
9846 || decision_reaches_unsupported_predicate(atn, state, predicates)
9847 {
9848 return None;
9849 }
9850 Some(transition_index)
9851}
9852
9853const fn starts_prediction_decision(state: &AtnState) -> bool {
9859 state.transitions.len() > 1
9860 && !matches!(
9861 state.kind,
9862 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
9863 )
9864}
9865
9866fn record_no_viable_if_ambiguous(
9869 expected: &mut ExpectedTokens,
9870 decision_start_index: Option<usize>,
9871 index: usize,
9872) {
9873 if expected.index == Some(index) && expected.symbols.len() > 1 {
9874 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
9875 expected.record_no_viable(decision_start, index);
9876 }
9877 }
9878}
9879
9880const fn record_predicate_no_viable(
9883 expected: &mut ExpectedTokens,
9884 decision_start_index: Option<usize>,
9885 index: usize,
9886) {
9887 if let Some(decision_start) = decision_start_index {
9888 expected.record_no_viable(decision_start, index);
9889 }
9890}
9891
9892const fn no_viable_decision_start(
9894 decision_start_index: Option<usize>,
9895 index: usize,
9896) -> Option<usize> {
9897 match decision_start_index {
9898 Some(start) if index > start => Some(start),
9899 _ => None,
9900 }
9901}
9902
9903fn restore_expected(
9907 children: &[RecognizeOutcome],
9908 child_start_index: usize,
9909 expected: &mut ExpectedTokens,
9910 snapshot: ExpectedTokens,
9911 preserve_child_expected: bool,
9912) {
9913 if preserve_child_expected {
9914 return;
9915 }
9916 if children
9917 .iter()
9918 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
9919 {
9920 *expected = snapshot;
9921 }
9922}
9923
9924fn decision_reaches_unsupported_predicate(
9927 atn: &Atn,
9928 state: &AtnState,
9929 predicates: &[(usize, usize, ParserPredicate)],
9930) -> bool {
9931 state.transitions.iter().any(|transition| {
9932 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
9933 })
9934}
9935
9936fn transition_reaches_unsupported_predicate(
9938 atn: &Atn,
9939 transition: &Transition,
9940 predicates: &[(usize, usize, ParserPredicate)],
9941 visited: &mut BTreeSet<usize>,
9942) -> bool {
9943 match transition {
9944 Transition::Predicate {
9945 rule_index,
9946 pred_index,
9947 ..
9948 } => !predicates
9949 .iter()
9950 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
9951 Transition::Epsilon { target }
9952 | Transition::Action { target, .. }
9953 | Transition::Rule { target, .. } => {
9954 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
9955 }
9956 Transition::Precedence { .. }
9957 | Transition::Atom { .. }
9958 | Transition::Range { .. }
9959 | Transition::Set { .. }
9960 | Transition::NotSet { .. }
9961 | Transition::Wildcard { .. } => false,
9962 }
9963}
9964
9965fn state_reaches_unsupported_predicate(
9967 atn: &Atn,
9968 state_number: usize,
9969 predicates: &[(usize, usize, ParserPredicate)],
9970 visited: &mut BTreeSet<usize>,
9971) -> bool {
9972 if !visited.insert(state_number) {
9973 return false;
9974 }
9975 let Some(state) = atn.state(state_number) else {
9976 return false;
9977 };
9978 state.transitions.iter().any(|transition| {
9979 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
9980 })
9981}
9982
9983fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
9985 if let Some(decision) = decision {
9986 outcome.decisions.insert(0, decision);
9987 }
9988}
9989
9990fn outcome_is_better(
9991 outcome_position: (usize, bool),
9992 outcome_diagnostics: &[ParserDiagnostic],
9993 best_position: (usize, bool),
9994 best_diagnostics: &[ParserDiagnostic],
9995) -> bool {
9996 outcome_position > best_position
9997 || (outcome_position == best_position
9998 && (outcome_diagnostics.len() < best_diagnostics.len()
9999 || (outcome_diagnostics.len() == best_diagnostics.len()
10000 && diagnostic_recovery_rank(outcome_diagnostics)
10001 < diagnostic_recovery_rank(best_diagnostics))))
10002}
10003
10004fn diagnostic_recovery_rank(diagnostics: &[ParserDiagnostic]) -> usize {
10007 diagnostics
10008 .iter()
10009 .filter(|diagnostic| {
10010 diagnostic.message.starts_with("mismatched input ")
10011 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
10012 })
10013 .count()
10014}
10015
10016fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
10017 if outcomes
10018 .iter()
10019 .any(|outcome| outcome.diagnostics.is_empty())
10020 {
10021 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
10022 }
10023}
10024
10025fn discard_recovered_outcomes_if_clean_path_exists(outcomes: &mut Vec<RecognizeOutcome>) {
10026 if outcomes.iter().any(outcome_has_rule_failure_diagnostic) {
10027 return;
10028 }
10029 if outcomes
10030 .iter()
10031 .any(|outcome| outcome.diagnostics.is_empty())
10032 {
10033 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
10034 }
10035}
10036
10037fn outcome_has_rule_failure_diagnostic(outcome: &RecognizeOutcome) -> bool {
10040 outcome
10041 .diagnostics
10042 .iter()
10043 .any(|diagnostic| diagnostic.message.starts_with("rule "))
10044}
10045
10046fn nodes_need_stable_tie(nodes: &[RecognizedNode]) -> bool {
10049 nodes.iter().any(node_needs_stable_tie)
10050}
10051
10052fn node_needs_stable_tie(node: &RecognizedNode) -> bool {
10053 match node {
10054 RecognizedNode::Token { .. }
10055 | RecognizedNode::ErrorToken { .. }
10056 | RecognizedNode::MissingToken { .. } => false,
10057 RecognizedNode::LeftRecursiveBoundary { .. } => true,
10058 RecognizedNode::Rule {
10059 rule_index,
10060 children,
10061 ..
10062 } => children.iter().any(|child| {
10063 matches!(
10064 child,
10065 RecognizedNode::Rule {
10066 rule_index: child_rule,
10067 ..
10068 } if child_rule == rule_index
10069 ) || node_needs_stable_tie(child)
10070 }),
10071 }
10072}
10073
10074fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
10088 if outcomes.len() < 2 {
10089 return;
10090 }
10091 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
10092 outcomes.retain(|outcome| {
10093 seen.insert((
10094 outcome.index,
10095 outcome.consumed_eof,
10096 outcome.diagnostics.len(),
10097 diagnostic_recovery_rank(&outcome.diagnostics),
10098 ))
10099 });
10100}
10101
10102fn dedupe_clean_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
10103 if outcomes.len() < 2 {
10104 return;
10105 }
10106 let mut inline_keys: [(usize, bool); 8] = [(0, false); 8];
10116 let mut inline_len = 0_usize;
10117 let mut overflow: Vec<(usize, bool)> = Vec::new();
10118 outcomes.retain(|outcome| {
10119 let key = (outcome.index, outcome.consumed_eof);
10120 for &existing in &inline_keys[..inline_len] {
10121 if existing == key {
10122 return false;
10123 }
10124 }
10125 if !overflow.is_empty() {
10126 for &existing in &overflow {
10127 if existing == key {
10128 return false;
10129 }
10130 }
10131 }
10132 if inline_len < inline_keys.len() {
10133 inline_keys[inline_len] = key;
10134 inline_len += 1;
10135 } else {
10136 overflow.push(key);
10137 }
10138 true
10139 });
10140}
10141
10142fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>) {
10144 outcomes.sort_unstable();
10145 outcomes.dedup();
10146}
10147
10148impl<S, H> Recognizer for BaseParser<S, H>
10149where
10150 S: TokenSource,
10151 H: SemanticHooks,
10152{
10153 fn data(&self) -> &RecognizerData {
10154 &self.data
10155 }
10156
10157 fn data_mut(&mut self) -> &mut RecognizerData {
10158 &mut self.data
10159 }
10160}
10161
10162impl<S, H> Parser for BaseParser<S, H>
10163where
10164 S: TokenSource,
10165 H: SemanticHooks,
10166{
10167 fn build_parse_trees(&self) -> bool {
10168 self.build_parse_trees
10169 }
10170
10171 fn set_build_parse_trees(&mut self, build: bool) {
10172 self.build_parse_trees = build;
10173 }
10174
10175 fn number_of_syntax_errors(&self) -> usize {
10176 Self::number_of_syntax_errors(self)
10177 }
10178
10179 fn report_diagnostic_errors(&self) -> bool {
10180 self.report_diagnostic_errors
10181 }
10182
10183 fn set_report_diagnostic_errors(&mut self, report: bool) {
10184 self.report_diagnostic_errors = report;
10185 }
10186
10187 fn prediction_mode(&self) -> PredictionMode {
10188 self.prediction_mode
10189 }
10190
10191 fn set_prediction_mode(&mut self, mode: PredictionMode) {
10192 self.prediction_mode = mode;
10193 }
10194}
10195
10196#[cfg(test)]
10197mod tests {
10198 use super::*;
10199 use crate::atn::AtnType;
10200 use crate::atn::IntervalSet;
10201 use crate::atn::parser::{
10202 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
10203 };
10204 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
10205 use crate::token::{CommonToken, HIDDEN_CHANNEL, Token};
10206 use crate::token_stream::CommonTokenStream;
10207 use crate::vocabulary::Vocabulary;
10208
10209 #[test]
10210 fn fx_hasher_write_matches_typed_methods_for_full_words() {
10211 let value: u64 = 0x0102_0304_0506_0708;
10218 let mut typed = FxHasher::default();
10219 typed.write_u64(value);
10220 let mut bytewise = FxHasher::default();
10221 bytewise.write(&value.to_le_bytes());
10222 assert_eq!(typed.finish(), bytewise.finish());
10223 }
10224
10225 #[derive(Debug)]
10226 struct Source {
10227 tokens: Vec<CommonToken>,
10228 index: usize,
10229 }
10230
10231 impl TokenSource for Source {
10232 fn next_token(&mut self) -> CommonToken {
10233 let token = self
10234 .tokens
10235 .get(self.index)
10236 .cloned()
10237 .unwrap_or_else(|| CommonToken::eof("parser-test", self.index, 1, self.index));
10238 self.index += 1;
10239 token
10240 }
10241
10242 fn line(&self) -> usize {
10243 1
10244 }
10245
10246 fn column(&self) -> usize {
10247 self.index
10248 }
10249
10250 fn source_name(&self) -> &'static str {
10251 "parser-test"
10252 }
10253 }
10254
10255 fn mini_parser_data() -> RecognizerData {
10256 RecognizerData::new(
10257 "Mini.g4",
10258 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10259 )
10260 .with_rule_names(["s"])
10261 }
10262
10263 fn mini_parser(tokens: Vec<CommonToken>) -> BaseParser<Source> {
10264 let data = mini_parser_data();
10265 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
10266 }
10267
10268 fn mini_parser_with_hooks<H>(tokens: Vec<CommonToken>, hooks: H) -> BaseParser<Source, H>
10269 where
10270 H: SemanticHooks,
10271 {
10272 BaseParser::with_semantic_hooks(
10273 CommonTokenStream::new(Source { tokens, index: 0 }),
10274 mini_parser_data(),
10275 hooks,
10276 )
10277 }
10278
10279 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
10280 let mut atn = Atn::new(AtnType::Parser, 2);
10281 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10282 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
10283 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10284 let mut callee_start = AtnState::new(3, AtnStateKind::RuleStart).with_rule_index(1);
10285 callee_start.left_recursive_rule = true;
10286 atn.add_state(callee_start);
10287 let mut loop_entry = AtnState::new(4, AtnStateKind::StarLoopEntry).with_rule_index(1);
10288 loop_entry.precedence_rule_decision = true;
10289 atn.add_state(loop_entry);
10290 atn.add_state(AtnState::new(5, AtnStateKind::Basic).with_rule_index(1));
10291 atn.add_state(AtnState::new(6, AtnStateKind::Basic).with_rule_index(1));
10292 atn.add_state(AtnState::new(7, AtnStateKind::LoopEnd).with_rule_index(1));
10293 atn.add_state(AtnState::new(8, AtnStateKind::RuleStop).with_rule_index(1));
10294 atn.add_state(AtnState::new(9, AtnStateKind::RuleStop).with_rule_index(0));
10295 atn.set_rule_to_start_state(vec![0, 3]);
10296 atn.set_rule_to_stop_state(vec![9, 8]);
10297 atn.state_mut(1)
10298 .expect("caller invoking state")
10299 .add_transition(Transition::Rule {
10300 target: 3,
10301 rule_index: 1,
10302 follow_state: 2,
10303 precedence: 0,
10304 });
10305 atn.state_mut(2)
10306 .expect("caller follow")
10307 .add_transition(Transition::Atom {
10308 target: 9,
10309 label: caller_symbol,
10310 });
10311 atn.state_mut(4)
10312 .expect("precedence loop")
10313 .add_transition(Transition::Epsilon { target: 5 });
10314 atn.state_mut(4)
10315 .expect("precedence loop")
10316 .add_transition(Transition::Epsilon { target: 7 });
10317 atn.state_mut(5)
10318 .expect("precedence predicate")
10319 .add_transition(Transition::Precedence {
10320 target: 6,
10321 precedence: 1,
10322 });
10323 atn.state_mut(6)
10324 .expect("operator token")
10325 .add_transition(Transition::Atom {
10326 target: 4,
10327 label: 1,
10328 });
10329 atn.state_mut(7)
10330 .expect("loop exit")
10331 .add_transition(Transition::Epsilon { target: 8 });
10332 atn
10333 }
10334
10335 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
10336 let mut parser = mini_parser(vec![
10337 CommonToken::new(symbol).with_text("lookahead"),
10338 CommonToken::eof("parser-test", 1, 1, 1),
10339 ]);
10340 parser.rule_context_stack = vec![
10341 RuleContextFrame {
10342 rule_index: 0,
10343 invoking_state: -1,
10344 },
10345 RuleContextFrame {
10346 rule_index: 1,
10347 invoking_state: 1,
10348 },
10349 ];
10350 parser
10351 }
10352
10353 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
10354 let mut atn = Atn::new(AtnType::Parser, 2);
10355 for (state, kind, rule) in [
10356 (0, AtnStateKind::RuleStart, 0),
10357 (1, AtnStateKind::StarLoopEntry, 0),
10358 (2, AtnStateKind::Basic, 0),
10359 (3, AtnStateKind::Basic, 0),
10360 (4, AtnStateKind::Basic, 0),
10361 (5, AtnStateKind::LoopEnd, 0),
10362 (6, AtnStateKind::RuleStop, 0),
10363 (7, AtnStateKind::RuleStart, 1),
10364 (8, AtnStateKind::RuleStop, 1),
10365 (9, AtnStateKind::Basic, 1),
10366 ] {
10367 let mut atn_state = AtnState::new(state, kind).with_rule_index(rule);
10368 if state == 0 {
10369 atn_state.left_recursive_rule = true;
10370 } else if state == 1 {
10371 atn_state.precedence_rule_decision = true;
10372 }
10373 atn.add_state(atn_state);
10374 }
10375 atn.set_rule_to_start_state(vec![0, 7]);
10376 atn.set_rule_to_stop_state(vec![6, 8]);
10377 atn.state_mut(1)
10378 .expect("precedence loop")
10379 .add_transition(Transition::Epsilon { target: 2 });
10380 atn.state_mut(1)
10381 .expect("precedence loop")
10382 .add_transition(Transition::Epsilon { target: 5 });
10383 atn.state_mut(2)
10384 .expect("precedence predicate")
10385 .add_transition(Transition::Precedence {
10386 target: 3,
10387 precedence: 3,
10388 });
10389 atn.state_mut(3)
10390 .expect("nullable operator prefix")
10391 .add_transition(Transition::Rule {
10392 target: 7,
10393 rule_index: 1,
10394 follow_state: 4,
10395 precedence: 0,
10396 });
10397 atn.state_mut(4)
10398 .expect("operator token")
10399 .add_transition(Transition::Atom {
10400 target: 1,
10401 label: 1,
10402 });
10403 atn.state_mut(5)
10404 .expect("loop exit")
10405 .add_transition(Transition::Epsilon { target: 6 });
10406 atn.state_mut(7)
10407 .expect("nullable operator prefix")
10408 .add_transition(Transition::Precedence {
10409 target: 9,
10410 precedence: 1,
10411 });
10412 atn.state_mut(9)
10413 .expect("nullable operator prefix")
10414 .add_transition(Transition::Epsilon { target: 8 });
10415 atn
10416 }
10417
10418 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
10419 let mut atn = Atn::new(AtnType::Parser, 2);
10420 for (state, kind) in [
10421 (0, AtnStateKind::RuleStart),
10422 (1, AtnStateKind::StarLoopEntry),
10423 (2, AtnStateKind::Basic),
10424 (3, AtnStateKind::Basic),
10425 (4, AtnStateKind::Basic),
10426 (5, AtnStateKind::LoopEnd),
10427 (6, AtnStateKind::RuleStop),
10428 ] {
10429 let mut atn_state = AtnState::new(state, kind).with_rule_index(0);
10430 if state == 0 {
10431 atn_state.left_recursive_rule = true;
10432 } else if state == 1 {
10433 atn_state.precedence_rule_decision = true;
10434 }
10435 atn.add_state(atn_state);
10436 }
10437 atn.set_rule_to_start_state(vec![0]);
10438 atn.set_rule_to_stop_state(vec![6]);
10439 atn.state_mut(1)
10440 .expect("precedence loop")
10441 .add_transition(Transition::Epsilon { target: 2 });
10442 atn.state_mut(1)
10443 .expect("precedence loop")
10444 .add_transition(Transition::Epsilon { target: 5 });
10445 atn.state_mut(2)
10446 .expect("precedence predicate")
10447 .add_transition(Transition::Precedence {
10448 target: 3,
10449 precedence: 1,
10450 });
10451 atn.state_mut(3)
10452 .expect("semantic predicate")
10453 .add_transition(Transition::Predicate {
10454 target: 4,
10455 rule_index: 0,
10456 pred_index: 0,
10457 context_dependent: false,
10458 });
10459 atn.state_mut(4)
10460 .expect("operator token")
10461 .add_transition(Transition::Atom {
10462 target: 1,
10463 label: 1,
10464 });
10465 atn.state_mut(5)
10466 .expect("loop exit")
10467 .add_transition(Transition::Epsilon { target: 6 });
10468 atn
10469 }
10470
10471 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
10472 let mut atn = Atn::new(AtnType::Parser, 2);
10473 for (state, kind, rule) in [
10474 (0, AtnStateKind::RuleStart, 0),
10475 (1, AtnStateKind::Basic, 0),
10476 (2, AtnStateKind::Basic, 0),
10477 (3, AtnStateKind::Basic, 0),
10478 (4, AtnStateKind::RuleStop, 0),
10479 (5, AtnStateKind::RuleStart, 1),
10480 (6, AtnStateKind::StarLoopEntry, 1),
10481 (7, AtnStateKind::Basic, 1),
10482 (8, AtnStateKind::Basic, 1),
10483 (9, AtnStateKind::LoopEnd, 1),
10484 (10, AtnStateKind::RuleStop, 1),
10485 (11, AtnStateKind::RuleStart, 2),
10486 (12, AtnStateKind::RuleStop, 2),
10487 ] {
10488 let mut atn_state = AtnState::new(state, kind).with_rule_index(rule);
10489 if state == 5 {
10490 atn_state.left_recursive_rule = true;
10491 } else if state == 6 {
10492 atn_state.precedence_rule_decision = true;
10493 }
10494 atn.add_state(atn_state);
10495 }
10496 atn.set_rule_to_start_state(vec![0, 5, 11]);
10497 atn.set_rule_to_stop_state(vec![4, 10, 12]);
10498 atn.state_mut(0)
10499 .expect("caller start")
10500 .add_transition(Transition::Epsilon { target: 1 });
10501 atn.state_mut(1)
10502 .expect("caller invoking state")
10503 .add_transition(Transition::Rule {
10504 target: 5,
10505 rule_index: 1,
10506 follow_state: 2,
10507 precedence: 0,
10508 });
10509 atn.state_mut(2)
10510 .expect("nullable child invocation")
10511 .add_transition(Transition::Rule {
10512 target: 11,
10513 rule_index: 2,
10514 follow_state: 3,
10515 precedence: 0,
10516 });
10517 atn.state_mut(3)
10518 .expect("caller follow")
10519 .add_transition(Transition::Atom {
10520 target: 4,
10521 label: caller_symbol,
10522 });
10523 atn.state_mut(6)
10524 .expect("precedence loop")
10525 .add_transition(Transition::Epsilon { target: 7 });
10526 atn.state_mut(6)
10527 .expect("precedence loop")
10528 .add_transition(Transition::Epsilon { target: 9 });
10529 atn.state_mut(7)
10530 .expect("precedence predicate")
10531 .add_transition(Transition::Precedence {
10532 target: 8,
10533 precedence: 1,
10534 });
10535 atn.state_mut(8)
10536 .expect("operator token")
10537 .add_transition(Transition::Atom {
10538 target: 6,
10539 label: 1,
10540 });
10541 atn.state_mut(9)
10542 .expect("loop exit")
10543 .add_transition(Transition::Epsilon { target: 10 });
10544 atn.state_mut(11)
10545 .expect("nullable child")
10546 .add_transition(Transition::Epsilon { target: 12 });
10547 atn
10548 }
10549
10550 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
10551 let mut atn = Atn::new(AtnType::Parser, 2);
10552 for (state, kind, rule) in [
10553 (0, AtnStateKind::RuleStart, 0),
10554 (1, AtnStateKind::Basic, 0),
10555 (2, AtnStateKind::Basic, 0),
10556 (3, AtnStateKind::RuleStop, 0),
10557 (4, AtnStateKind::RuleStart, 1),
10558 (5, AtnStateKind::Basic, 1),
10559 (6, AtnStateKind::Basic, 1),
10560 (7, AtnStateKind::RuleStop, 1),
10561 (8, AtnStateKind::RuleStart, 2),
10562 (9, AtnStateKind::StarLoopEntry, 2),
10563 (10, AtnStateKind::Basic, 2),
10564 (11, AtnStateKind::Basic, 2),
10565 (12, AtnStateKind::LoopEnd, 2),
10566 (13, AtnStateKind::RuleStop, 2),
10567 ] {
10568 let mut atn_state = AtnState::new(state, kind).with_rule_index(rule);
10569 if state == 8 {
10570 atn_state.left_recursive_rule = true;
10571 } else if state == 9 {
10572 atn_state.precedence_rule_decision = true;
10573 }
10574 atn.add_state(atn_state);
10575 }
10576 atn.set_rule_to_start_state(vec![0, 4, 8]);
10577 atn.set_rule_to_stop_state(vec![3, 7, 13]);
10578 atn.state_mut(0)
10579 .expect("parent start")
10580 .add_transition(Transition::Epsilon { target: 1 });
10581 atn.state_mut(1)
10582 .expect("parent invocation")
10583 .add_transition(Transition::Rule {
10584 target: 4,
10585 rule_index: 1,
10586 follow_state: 2,
10587 precedence: 0,
10588 });
10589 atn.state_mut(2)
10590 .expect("parent follow")
10591 .add_transition(Transition::Atom {
10592 target: 3,
10593 label: caller_symbol,
10594 });
10595 atn.state_mut(4)
10596 .expect("caller start")
10597 .add_transition(Transition::Epsilon { target: 5 });
10598 atn.state_mut(5)
10599 .expect("caller invocation")
10600 .add_transition(Transition::Rule {
10601 target: 8,
10602 rule_index: 2,
10603 follow_state: 6,
10604 precedence: 0,
10605 });
10606 atn.state_mut(6)
10607 .expect("nullable caller return")
10608 .add_transition(Transition::Epsilon { target: 7 });
10609 atn.state_mut(9)
10610 .expect("precedence loop")
10611 .add_transition(Transition::Epsilon { target: 10 });
10612 atn.state_mut(9)
10613 .expect("precedence loop")
10614 .add_transition(Transition::Epsilon { target: 12 });
10615 atn.state_mut(10)
10616 .expect("precedence predicate")
10617 .add_transition(Transition::Precedence {
10618 target: 11,
10619 precedence: 1,
10620 });
10621 atn.state_mut(11)
10622 .expect("operator token")
10623 .add_transition(Transition::Atom {
10624 target: 9,
10625 label: 1,
10626 });
10627 atn.state_mut(12)
10628 .expect("loop exit")
10629 .add_transition(Transition::Epsilon { target: 13 });
10630 atn
10631 }
10632
10633 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
10634 let mut atn = Atn::new(AtnType::Parser, 2);
10635 for (state, kind, rule) in [
10636 (0, AtnStateKind::RuleStart, 0),
10637 (1, AtnStateKind::Basic, 0),
10638 (2, AtnStateKind::Basic, 0),
10639 (3, AtnStateKind::RuleStop, 0),
10640 (4, AtnStateKind::RuleStart, 1),
10641 (5, AtnStateKind::StarLoopEntry, 1),
10642 (6, AtnStateKind::Basic, 1),
10643 (7, AtnStateKind::Basic, 1),
10644 (8, AtnStateKind::Basic, 1),
10645 (9, AtnStateKind::Basic, 1),
10646 (10, AtnStateKind::LoopEnd, 1),
10647 (11, AtnStateKind::RuleStop, 1),
10648 ] {
10649 let mut atn_state = AtnState::new(state, kind).with_rule_index(rule);
10650 if state == 4 {
10651 atn_state.left_recursive_rule = true;
10652 } else if state == 5 {
10653 atn_state.precedence_rule_decision = true;
10654 }
10655 atn.add_state(atn_state);
10656 }
10657 atn.set_rule_to_start_state(vec![0, 4]);
10658 atn.set_rule_to_stop_state(vec![3, 11]);
10659 atn.state_mut(0)
10660 .expect("caller start")
10661 .add_transition(Transition::Epsilon { target: 1 });
10662 atn.state_mut(1)
10663 .expect("caller invocation")
10664 .add_transition(Transition::Rule {
10665 target: 4,
10666 rule_index: 1,
10667 follow_state: 2,
10668 precedence: 0,
10669 });
10670 atn.state_mut(2)
10671 .expect("caller follow")
10672 .add_transition(Transition::Atom {
10673 target: 3,
10674 label: caller_symbol,
10675 });
10676 atn.state_mut(5)
10677 .expect("precedence loop")
10678 .add_transition(Transition::Epsilon { target: 6 });
10679 atn.state_mut(5)
10680 .expect("precedence loop")
10681 .add_transition(Transition::Epsilon { target: 10 });
10682 atn.state_mut(6)
10683 .expect("precedence predicate")
10684 .add_transition(Transition::Precedence {
10685 target: 7,
10686 precedence: 1,
10687 });
10688 atn.state_mut(7)
10689 .expect("operator token")
10690 .add_transition(Transition::Atom {
10691 target: 8,
10692 label: 1,
10693 });
10694 atn.state_mut(8)
10695 .expect("recursive operand")
10696 .add_transition(Transition::Rule {
10697 target: 4,
10698 rule_index: 1,
10699 follow_state: 9,
10700 precedence: 2,
10701 });
10702 atn.state_mut(9)
10703 .expect("recursive operand follow")
10704 .add_transition(Transition::Epsilon { target: 5 });
10705 atn.state_mut(10)
10706 .expect("loop exit")
10707 .add_transition(Transition::Epsilon { target: 11 });
10708 atn
10709 }
10710
10711 #[test]
10712 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
10713 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
10714 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
10715
10716 let mut overlapping = parser_inside_left_recursive_callee(1);
10717 assert_eq!(
10718 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
10719 None
10720 );
10721
10722 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
10723 assert_eq!(
10724 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
10725 Some(true)
10726 );
10727
10728 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
10729 assert_eq!(
10730 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
10731 Some(false)
10732 );
10733
10734 assert_eq!(
10735 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
10736 Some(true),
10737 "overlap results must not leak across ATNs"
10738 );
10739 }
10740
10741 #[test]
10742 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
10743 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
10744 let mut parser = mini_parser(vec![
10745 CommonToken::new(1).with_text("operator"),
10746 CommonToken::eof("parser-test", 1, 1, 1),
10747 ]);
10748 parser.rule_context_stack = vec![RuleContextFrame {
10749 rule_index: 0,
10750 invoking_state: -1,
10751 }];
10752
10753 assert_eq!(
10754 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
10755 Some(true)
10756 );
10757 assert_eq!(
10758 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
10759 Some(true),
10760 "cached operator lookahead must preserve the nullable prefix return path"
10761 );
10762 assert_eq!(
10763 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
10764 Some(true),
10765 "the nullable child must use its rule-call precedence, not the caller precedence"
10766 );
10767 }
10768
10769 #[test]
10770 fn left_recursive_loop_defers_predicate_guarded_operator() {
10771 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
10772 let mut parser = mini_parser_with_hooks(
10773 vec![
10774 CommonToken::new(1).with_text("operator"),
10775 CommonToken::eof("parser-test", 1, 1, 1),
10776 ],
10777 RejectingPredicateHooks::default(),
10778 );
10779 parser.rule_context_stack = vec![RuleContextFrame {
10780 rule_index: 0,
10781 invoking_state: -1,
10782 }];
10783
10784 assert_eq!(
10785 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
10786 None,
10787 "a false predicate must be evaluated before entering the operator alternative"
10788 );
10789 assert_eq!(
10790 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
10791 None,
10792 "cached predicate-dependent lookahead must keep deferring"
10793 );
10794 }
10795
10796 #[test]
10797 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
10798 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
10799 let mut parser = parser_inside_left_recursive_callee(1);
10800
10801 assert_eq!(
10802 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
10803 None
10804 );
10805 assert_eq!(
10806 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
10807 None,
10808 "the cached overlap must preserve the nullable child return path"
10809 );
10810 }
10811
10812 #[test]
10813 fn left_recursive_loop_defers_through_nullable_parent_return() {
10814 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
10815 let mut parser = mini_parser(vec![
10816 CommonToken::new(1).with_text("lookahead"),
10817 CommonToken::eof("parser-test", 1, 1, 1),
10818 ]);
10819 parser.rule_context_stack = vec![
10820 RuleContextFrame {
10821 rule_index: 0,
10822 invoking_state: -1,
10823 },
10824 RuleContextFrame {
10825 rule_index: 1,
10826 invoking_state: 1,
10827 },
10828 RuleContextFrame {
10829 rule_index: 2,
10830 invoking_state: 5,
10831 },
10832 ];
10833
10834 assert_eq!(
10835 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
10836 None,
10837 "a nullable caller must unwind to its parent's consuming follow path"
10838 );
10839 assert_eq!(
10840 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
10841 None,
10842 "the caller-overlap cache must not retain a false negative"
10843 );
10844 }
10845
10846 #[test]
10847 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
10848 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
10849 let mut parser = mini_parser(vec![
10850 CommonToken::new(1).with_text("lookahead"),
10851 CommonToken::eof("parser-test", 1, 1, 1),
10852 ]);
10853 parser.rule_context_stack = vec![
10854 RuleContextFrame {
10855 rule_index: 0,
10856 invoking_state: -1,
10857 },
10858 RuleContextFrame {
10859 rule_index: 1,
10860 invoking_state: 1,
10861 },
10862 RuleContextFrame {
10863 rule_index: 1,
10864 invoking_state: 8,
10865 },
10866 ];
10867
10868 assert_eq!(
10869 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
10870 None,
10871 "a recursive operand return must preserve its parent caller context"
10872 );
10873 assert_eq!(
10874 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
10875 None,
10876 "the caller-overlap cache must preserve the loop-boundary return"
10877 );
10878 }
10879
10880 fn token_then_eof_atn() -> Atn {
10881 AtnDeserializer::new(&SerializedAtn::from_i32(&[
10882 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, ]))
10898 .deserialize()
10899 .expect("artificial parser ATN should deserialize")
10900 }
10901
10902 fn eof_then_action_atn() -> Atn {
10903 AtnDeserializer::new(&SerializedAtn::from_i32(&[
10904 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, ]))
10920 .deserialize()
10921 .expect("artificial parser ATN should deserialize")
10922 }
10923
10924 fn noop_action_then_token_then_eof_atn() -> Atn {
10925 AtnDeserializer::new(&SerializedAtn::from_i32(&[
10926 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, ]))
10944 .deserialize()
10945 .expect("artificial no-op action ATN should deserialize")
10946 }
10947
10948 fn two_alt_decision_atn() -> Atn {
10949 let mut atn = Atn::new(AtnType::Parser, 2);
10950 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10951 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
10952 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10953 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
10954 atn.add_state(AtnState::new(4, AtnStateKind::BlockEnd).with_rule_index(0));
10955 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
10956 atn.set_rule_to_start_state(vec![0]);
10957 atn.set_rule_to_stop_state(vec![5]);
10958 atn.add_decision_state(1);
10959 atn.state_mut(0)
10960 .expect("state 0")
10961 .add_transition(Transition::Epsilon { target: 1 });
10962 atn.state_mut(1)
10963 .expect("state 1")
10964 .add_transition(Transition::Atom {
10965 target: 2,
10966 label: 1,
10967 });
10968 atn.state_mut(1)
10969 .expect("state 1")
10970 .add_transition(Transition::Atom {
10971 target: 3,
10972 label: 2,
10973 });
10974 atn.state_mut(2)
10975 .expect("state 2")
10976 .add_transition(Transition::Epsilon { target: 4 });
10977 atn.state_mut(3)
10978 .expect("state 3")
10979 .add_transition(Transition::Epsilon { target: 4 });
10980 atn.state_mut(4)
10981 .expect("state 4")
10982 .add_transition(Transition::Epsilon { target: 5 });
10983 atn
10984 }
10985
10986 fn optional_then_b_eof_atn() -> Atn {
10989 let mut atn = Atn::new(AtnType::Parser, 3);
10990 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10991 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
10992 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10993 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
10994 atn.add_state(AtnState::new(4, AtnStateKind::Basic).with_rule_index(0));
10995 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
10996 atn.set_rule_to_start_state(vec![0]);
10997 atn.set_rule_to_stop_state(vec![5]);
10998 atn.add_decision_state(1);
10999 atn.state_mut(0)
11000 .expect("state 0")
11001 .add_transition(Transition::Epsilon { target: 1 });
11002 atn.state_mut(1)
11004 .expect("state 1")
11005 .add_transition(Transition::Atom {
11006 target: 3,
11007 label: 1,
11008 });
11009 atn.state_mut(1)
11010 .expect("state 1")
11011 .add_transition(Transition::Epsilon { target: 3 });
11012 atn.state_mut(3)
11014 .expect("state 3")
11015 .add_transition(Transition::Atom {
11016 target: 4,
11017 label: 2,
11018 });
11019 atn.state_mut(4)
11020 .expect("state 4")
11021 .add_transition(Transition::Atom {
11022 target: 5,
11023 label: TOKEN_EOF,
11024 });
11025 atn
11026 }
11027
11028 #[test]
11029 fn sync_decision_deletes_only_a_single_token() {
11030 let atn = optional_then_b_eof_atn();
11038
11039 let mut single = mini_parser(vec![
11040 CommonToken::new(3).with_text("c"),
11041 CommonToken::new(2).with_text("b"),
11042 CommonToken::eof("parser-test", 1, 2, 2),
11043 ]);
11044 single.rule_context_stack = vec![RuleContextFrame {
11045 rule_index: 0,
11046 invoking_state: 0,
11047 }];
11048 let children = single
11049 .sync_decision(&atn, 1, true, false)
11050 .expect("single extraneous token recovers");
11051 assert_eq!(children.len(), 1);
11052 assert!(matches!(children[0], ParseTree::Error(_)));
11053 assert_eq!(single.number_of_syntax_errors(), 1);
11054 assert_eq!(single.la(1), 2);
11056
11057 let mut double = mini_parser(vec![
11058 CommonToken::new(3).with_text("c"),
11059 CommonToken::new(3).with_text("c"),
11060 CommonToken::new(2).with_text("b"),
11061 CommonToken::eof("parser-test", 1, 3, 3),
11062 ]);
11063 double.rule_context_stack = vec![RuleContextFrame {
11064 rule_index: 0,
11065 invoking_state: 0,
11066 }];
11067 let result = double.sync_decision(&atn, 1, true, false);
11068 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
11073 match error {
11074 AntlrError::ParserError { message, .. } => {
11075 assert!(message.starts_with("mismatched input"), "got: {message}");
11076 }
11077 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
11078 }
11079 assert_eq!(double.la(1), 3);
11080 }
11081
11082 fn star_loop_then_eof_atn() -> Atn {
11086 AtnDeserializer::new(&SerializedAtn::from_i32(&[
11087 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,
11088 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,
11089 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,
11090 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
11091 ]))
11092 .deserialize()
11093 .expect("star-loop-then-EOF ATN should deserialize")
11094 }
11095
11096 fn plus_loop_with_recovering_body_atn() -> Atn {
11102 let mut atn = Atn::new(AtnType::Parser, 2);
11103 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
11104 let mut loop_start = AtnState::new(1, AtnStateKind::PlusBlockStart).with_rule_index(0);
11105 loop_start.end_state = Some(3);
11106 atn.add_state(loop_start);
11107 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
11108 atn.add_state(AtnState::new(3, AtnStateKind::BlockEnd).with_rule_index(0));
11109 atn.add_state(AtnState::new(4, AtnStateKind::PlusLoopBack).with_rule_index(0));
11110 let mut loop_end = AtnState::new(5, AtnStateKind::LoopEnd).with_rule_index(0);
11111 loop_end.loop_back_state = Some(4);
11112 atn.add_state(loop_end);
11113 atn.add_state(AtnState::new(6, AtnStateKind::RuleStop).with_rule_index(0));
11114 atn.add_state(AtnState::new(7, AtnStateKind::RuleStart).with_rule_index(1));
11115 atn.add_state(AtnState::new(8, AtnStateKind::Basic).with_rule_index(1));
11116 atn.add_state(AtnState::new(9, AtnStateKind::RuleStop).with_rule_index(1));
11117 atn.set_rule_to_start_state(vec![0, 7]);
11118 atn.set_rule_to_stop_state(vec![6, 9]);
11119 atn.state_mut(0)
11120 .expect("state 0")
11121 .add_transition(Transition::Epsilon { target: 1 });
11122 atn.state_mut(1)
11123 .expect("state 1")
11124 .add_transition(Transition::Epsilon { target: 2 });
11125 atn.state_mut(2)
11126 .expect("state 2")
11127 .add_transition(Transition::Rule {
11128 target: 7,
11129 rule_index: 1,
11130 follow_state: 3,
11131 precedence: 0,
11132 });
11133 atn.state_mut(3)
11134 .expect("state 3")
11135 .add_transition(Transition::Epsilon { target: 4 });
11136 atn.state_mut(4)
11137 .expect("state 4")
11138 .add_transition(Transition::Epsilon { target: 1 });
11139 atn.state_mut(4)
11140 .expect("state 4")
11141 .add_transition(Transition::Epsilon { target: 5 });
11142 atn.state_mut(5)
11143 .expect("state 5")
11144 .add_transition(Transition::Atom {
11145 target: 6,
11146 label: 2,
11147 });
11148 atn.state_mut(7)
11149 .expect("state 7")
11150 .add_transition(Transition::Atom {
11151 target: 8,
11152 label: 1,
11153 });
11154 atn.state_mut(8)
11155 .expect("state 8")
11156 .add_transition(Transition::Epsilon { target: 9 });
11157 atn
11158 }
11159
11160 #[test]
11161 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
11162 let atn = plus_loop_with_recovering_body_atn();
11163 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11164
11165 let error = parser
11166 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11167 .expect_err("EOF recovery should report a bounded mismatch");
11168
11169 let AntlrError::ParserError { message, .. } = error else {
11170 panic!("expected ParserError, got {error:?}");
11171 };
11172 assert_eq!(message, "mismatched input '<EOF>' expecting {'x', 2}");
11173 assert_eq!(parser.number_of_syntax_errors(), 1);
11174 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
11175 }
11176
11177 #[test]
11178 fn sync_decision_deletes_token_before_eof_at_loop_back() {
11179 let atn = star_loop_then_eof_atn();
11185 let mut parser = mini_parser(vec![
11186 CommonToken::new(2).with_text("c"),
11187 CommonToken::eof("parser-test", 1, 1, 1),
11188 ]);
11189 parser.rule_context_stack = vec![RuleContextFrame {
11190 rule_index: 0,
11191 invoking_state: 0,
11192 }];
11193 let children = parser
11194 .sync_decision(&atn, 5, true, false)
11195 .expect("single token before EOF recovers");
11196 assert_eq!(children.len(), 1);
11197 assert!(matches!(children[0], ParseTree::Error(_)));
11198 assert_eq!(parser.number_of_syntax_errors(), 1);
11199 assert_eq!(
11200 parser.la(1),
11201 TOKEN_EOF,
11202 "EOF is left for the rule's EOF match"
11203 );
11204 }
11205
11206 #[test]
11207 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
11208 let atn = star_loop_then_eof_atn();
11213 let mut parser = mini_parser(vec![
11214 CommonToken::new(2).with_text("c"),
11215 CommonToken::new(2).with_text("c"),
11216 CommonToken::eof("parser-test", 1, 2, 2),
11217 ]);
11218 parser.rule_context_stack = vec![RuleContextFrame {
11219 rule_index: 0,
11220 invoking_state: 0,
11221 }];
11222 let error = parser
11223 .sync_decision(&atn, 5, true, false)
11224 .expect_err("two tokens at the loop entry must not be deleted");
11225 match error {
11226 AntlrError::ParserError { message, .. } => {
11227 assert!(message.starts_with("mismatched input"), "got: {message}");
11228 }
11229 other => panic!("expected mismatched-input ParserError, got {other:?}"),
11230 }
11231 assert_eq!(
11232 parser.la(1),
11233 2,
11234 "nothing consumed; cursor still on first `c`"
11235 );
11236 }
11237
11238 #[test]
11239 fn sync_decision_consumes_until_eof_at_loop_back() {
11240 let atn = star_loop_then_eof_atn();
11246 let mut parser = mini_parser(vec![
11247 CommonToken::new(2).with_text("c"),
11248 CommonToken::new(2).with_text("c"),
11249 CommonToken::eof("parser-test", 1, 2, 2),
11250 ]);
11251 parser.rule_context_stack = vec![RuleContextFrame {
11252 rule_index: 0,
11253 invoking_state: 0,
11254 }];
11255 let children = parser
11256 .sync_decision(&atn, 5, false, true)
11257 .expect("loop-back multi-token deletion recovers onto EOF");
11258 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
11259 assert!(children.iter().all(|c| matches!(c, ParseTree::Error(_))));
11260 assert_eq!(parser.number_of_syntax_errors(), 1);
11261 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
11262 }
11263
11264 fn predicate_after_token_atn() -> Atn {
11265 let mut atn = Atn::new(AtnType::Parser, 2);
11266 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
11267 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
11268 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
11269 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
11270 atn.add_state(AtnState::new(4, AtnStateKind::RuleStop).with_rule_index(0));
11271 atn.set_rule_to_start_state(vec![0]);
11272 atn.set_rule_to_stop_state(vec![4]);
11273 atn.state_mut(0)
11274 .expect("state 0")
11275 .add_transition(Transition::Atom {
11276 target: 1,
11277 label: 1,
11278 });
11279 atn.state_mut(1)
11280 .expect("state 1")
11281 .add_transition(Transition::Predicate {
11282 target: 2,
11283 rule_index: 0,
11284 pred_index: 0,
11285 context_dependent: false,
11286 });
11287 atn.state_mut(2)
11288 .expect("state 2")
11289 .add_transition(Transition::Atom {
11290 target: 3,
11291 label: 2,
11292 });
11293 atn.state_mut(3)
11294 .expect("state 3")
11295 .add_transition(Transition::Epsilon { target: 4 });
11296 atn
11297 }
11298
11299 fn nested_nullable_context_atn() -> Atn {
11300 let mut atn = Atn::new(AtnType::Parser, 1);
11301 for state_number in 0..=20 {
11302 let kind = match state_number {
11303 0 | 10 | 16 => AtnStateKind::RuleStart,
11304 9 | 15 | 20 => AtnStateKind::RuleStop,
11305 _ => AtnStateKind::Basic,
11306 };
11307 let rule_index = match state_number {
11308 0..=9 => 0,
11309 10..=15 => 1,
11310 _ => 2,
11311 };
11312 atn.add_state(AtnState::new(state_number, kind).with_rule_index(rule_index));
11313 }
11314 atn.set_rule_to_start_state(vec![0, 10, 16]);
11315 atn.set_rule_to_stop_state(vec![9, 15, 20]);
11316 atn.state_mut(1)
11317 .expect("state 1")
11318 .add_transition(Transition::Rule {
11319 target: 10,
11320 rule_index: 1,
11321 follow_state: 8,
11322 precedence: 0,
11323 });
11324 atn.state_mut(8)
11325 .expect("state 8")
11326 .add_transition(Transition::Atom {
11327 target: 9,
11328 label: 1,
11329 });
11330 atn.state_mut(8)
11331 .expect("state 8")
11332 .add_transition(Transition::Epsilon { target: 9 });
11333 atn.state_mut(2)
11334 .expect("state 2")
11335 .add_transition(Transition::Rule {
11336 target: 16,
11337 rule_index: 2,
11338 follow_state: 14,
11339 precedence: 0,
11340 });
11341 atn.state_mut(14)
11342 .expect("state 14")
11343 .add_transition(Transition::Epsilon { target: 15 });
11344 atn
11345 }
11346
11347 fn generated_match_recovery_atn() -> Atn {
11348 let mut atn = Atn::new(AtnType::Parser, 2);
11349 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
11350 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
11351 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
11352 atn.add_state(AtnState::new(3, AtnStateKind::RuleStop).with_rule_index(0));
11353 atn.add_state(AtnState::new(4, AtnStateKind::RuleStart).with_rule_index(1));
11354 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(1));
11355 atn.set_rule_to_start_state(vec![0, 4]);
11356 atn.set_rule_to_stop_state(vec![3, 5]);
11357 atn.state_mut(1)
11358 .expect("state 1")
11359 .add_transition(Transition::Rule {
11360 target: 4,
11361 rule_index: 1,
11362 follow_state: 2,
11363 precedence: 0,
11364 });
11365 atn.state_mut(2)
11366 .expect("state 2")
11367 .add_transition(Transition::Atom {
11368 target: 3,
11369 label: TOKEN_EOF,
11370 });
11371 atn
11372 }
11373
11374 fn complement_set_atn() -> Atn {
11375 let mut atn = Atn::new(AtnType::Parser, 1);
11376 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
11377 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
11378 atn.set_rule_to_start_state(vec![0]);
11379 atn.set_rule_to_stop_state(vec![1]);
11380 let mut excluded = IntervalSet::new();
11381 excluded.add(1);
11382 atn.state_mut(0)
11383 .expect("state 0")
11384 .add_transition(Transition::NotSet {
11385 target: 1,
11386 set: excluded,
11387 });
11388 atn
11389 }
11390
11391 fn wildcard_then_eof_atn() -> Atn {
11394 let mut atn = Atn::new(AtnType::Parser, 1);
11395 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
11396 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
11397 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
11398 atn.set_rule_to_start_state(vec![0]);
11399 atn.set_rule_to_stop_state(vec![1]);
11400 atn.state_mut(0)
11401 .expect("state 0")
11402 .add_transition(Transition::Wildcard { target: 2 });
11403 atn.state_mut(2)
11404 .expect("state 2")
11405 .add_transition(Transition::Atom {
11406 target: 1,
11407 label: TOKEN_EOF,
11408 });
11409 atn
11410 }
11411
11412 #[test]
11413 fn parser_matches_token_and_reports_mismatch() {
11414 let source = Source {
11415 tokens: vec![
11416 CommonToken::new(1).with_text("x"),
11417 CommonToken::eof("parser-test", 1, 1, 1),
11418 ],
11419 index: 0,
11420 };
11421 let data = RecognizerData::new(
11422 "Mini.g4",
11423 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
11424 );
11425 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
11426 assert_eq!(
11427 parser.match_token(1).expect("token 1 should match").text(),
11428 "x"
11429 );
11430 assert!(parser.match_token(1).is_err());
11431 }
11432
11433 #[test]
11434 fn parser_matches_token_sets() {
11435 let mut parser = mini_parser(vec![
11436 CommonToken::new(1).with_text("x"),
11437 CommonToken::eof("parser-test", 1, 1, 1),
11438 ]);
11439
11440 assert_eq!(
11441 parser
11442 .match_set(&[(1, 1), (3, 4)])
11443 .expect("token set should match")
11444 .text(),
11445 "x"
11446 );
11447 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
11448 }
11449
11450 #[test]
11451 fn generated_rule_api_tracks_state_and_precedence() {
11452 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11453
11454 let context = parser.enter_rule(7, 2);
11455 assert_eq!(context.rule_index(), 2);
11456 assert_eq!(parser.state(), 7);
11457 assert_eq!(
11458 parser.rule_context_stack,
11459 vec![RuleContextFrame {
11460 rule_index: 2,
11461 invoking_state: 7
11462 }]
11463 );
11464
11465 let recursive = parser.enter_recursion_rule(11, 3, 4);
11466 assert_eq!(recursive.rule_index(), 3);
11467 assert!(parser.precpred(4));
11468 assert!(parser.precpred(5));
11469 assert!(!parser.precpred(3));
11470
11471 let next = parser.push_new_recursion_context(13, 3);
11472 assert_eq!(next.invoking_state(), 13);
11473 parser.unroll_recursion_context();
11474 assert_eq!(parser.precedence_stack, vec![0]);
11475 assert_eq!(
11476 parser.rule_context_stack,
11477 vec![RuleContextFrame {
11478 rule_index: 2,
11479 invoking_state: 7
11480 }]
11481 );
11482
11483 parser.exit_rule();
11484 assert!(parser.rule_context_stack.is_empty());
11485 }
11486
11487 #[test]
11488 fn parser_predicates_support_token_adjacency() {
11489 let mut parser = mini_parser(vec![
11490 CommonToken::new(1).with_text("=").with_span(0, 0),
11491 CommonToken::new(1).with_text(">").with_span(1, 1),
11492 CommonToken::eof("parser-test", 2, 1, 2),
11493 ]);
11494 parser.consume();
11495 parser.consume();
11496
11497 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
11498
11499 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
11500
11501 let mut parser = mini_parser(vec![
11502 CommonToken::new(1).with_text("=").with_span(0, 0),
11503 CommonToken::new(1)
11504 .with_text(" ")
11505 .with_channel(HIDDEN_CHANNEL)
11506 .with_span(1, 1),
11507 CommonToken::new(1).with_text(">").with_span(2, 2),
11508 CommonToken::eof("parser-test", 3, 1, 3),
11509 ]);
11510 parser.consume();
11511 parser.consume();
11512
11513 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
11514 }
11515
11516 #[test]
11517 fn parser_predicates_support_context_child_text_checks() {
11518 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11519 let mut context = ParserRuleContext::new(1, 0);
11520 let mut child_context = ParserRuleContext::new(2, 0);
11521 child_context.add_child(ParseTree::Terminal(TerminalNode::new(
11522 CommonToken::new(1).with_text("var"),
11523 )));
11524 context.add_child(ParseTree::Rule(RuleNode::new(child_context)));
11525 let predicates = [(
11526 1,
11527 0,
11528 ParserPredicate::ContextChildRuleTextNotEquals {
11529 rule_index: 2,
11530 text: "var",
11531 },
11532 )];
11533
11534 assert!(
11535 !parser.parser_semantic_predicate_matches_with_context_and_local(
11536 &predicates,
11537 1,
11538 0,
11539 &context,
11540 0,
11541 )
11542 );
11543 }
11544
11545 #[test]
11546 fn context_expected_symbols_walks_nullable_parent_contexts() {
11547 let atn = nested_nullable_context_atn();
11548 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11549 parser.rule_context_stack = vec![
11550 RuleContextFrame {
11551 rule_index: 0,
11552 invoking_state: 0,
11553 },
11554 RuleContextFrame {
11555 rule_index: 1,
11556 invoking_state: 1,
11557 },
11558 RuleContextFrame {
11559 rule_index: 2,
11560 invoking_state: 2,
11561 },
11562 ];
11563
11564 let expected = parser.context_expected_symbols(&atn);
11565
11566 assert!(expected.contains(&1));
11567 assert!(expected.contains(&TOKEN_EOF));
11568 }
11569
11570 #[test]
11571 fn prediction_context_reuses_cached_stack_until_rule_stack_changes() {
11572 let atn = nested_nullable_context_atn();
11573 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11574 parser.rule_context_stack = vec![
11575 RuleContextFrame {
11576 rule_index: 0,
11577 invoking_state: 0,
11578 },
11579 RuleContextFrame {
11580 rule_index: 1,
11581 invoking_state: 1,
11582 },
11583 RuleContextFrame {
11584 rule_index: 2,
11585 invoking_state: 2,
11586 },
11587 ];
11588
11589 let first = parser.prediction_context(&atn);
11590 let second = parser.prediction_context(&atn);
11591 assert!(Rc::ptr_eq(&first, &second));
11592
11593 parser.exit_rule();
11594 let after_pop = parser.prediction_context(&atn);
11595 assert!(!Rc::ptr_eq(&first, &after_pop));
11596 }
11597
11598 #[test]
11599 fn generated_match_token_recovers_missing_token_from_context_follow() {
11600 let atn = generated_match_recovery_atn();
11601 let data = RecognizerData::new(
11602 "Mini.g4",
11603 Vocabulary::new(
11604 [None, Some("'X'"), Some("'Y'")],
11605 [None, Some("X"), Some("Y")],
11606 [None::<&str>, None, None],
11607 ),
11608 );
11609 let mut parser = BaseParser::new(
11610 CommonTokenStream::new(Source {
11611 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
11612 index: 0,
11613 }),
11614 data,
11615 );
11616 parser.rule_context_stack = vec![
11617 RuleContextFrame {
11618 rule_index: 0,
11619 invoking_state: 0,
11620 },
11621 RuleContextFrame {
11622 rule_index: 1,
11623 invoking_state: 1,
11624 },
11625 ];
11626 assert_eq!(parser.number_of_syntax_errors(), 0);
11627
11628 let node = parser
11629 .match_token_recovering(2, 5, &atn)
11630 .expect("generated match should insert missing token");
11631
11632 assert_eq!(node.children().len(), 1);
11633 assert_eq!(node.children()[0].text(), "<missing 'Y'>");
11634 assert_eq!(
11635 node.clone()
11636 .into_child_iter()
11637 .map(|child| child.text())
11638 .collect::<Vec<_>>(),
11639 ["<missing 'Y'>"]
11640 );
11641 assert!(!node.consumed_eof());
11644 assert_eq!(parser.la(1), TOKEN_EOF);
11645 assert_eq!(parser.number_of_syntax_errors(), 1);
11646 assert_eq!(
11647 parser.generated_parser_diagnostics,
11648 [ParserDiagnostic {
11649 line: 1,
11650 column: 3,
11651 message: "missing 'Y' at '<EOF>'".to_owned(),
11652 }]
11653 );
11654 }
11655
11656 #[test]
11657 fn generated_match_token_counts_single_token_deletion_recovery() {
11658 let atn = generated_match_recovery_atn();
11659 let data = RecognizerData::new(
11660 "Mini.g4",
11661 Vocabulary::new(
11662 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
11663 [None, Some("X"), Some("Y"), Some("Z")],
11664 [None::<&str>, None, None, None],
11665 ),
11666 );
11667 let mut parser = BaseParser::new(
11668 CommonTokenStream::new(Source {
11669 tokens: vec![
11670 CommonToken::new(3).with_text("z"),
11671 CommonToken::new(2).with_text("y"),
11672 CommonToken::eof("parser-test", 3, 1, 3),
11673 ],
11674 index: 0,
11675 }),
11676 data,
11677 );
11678
11679 let node = parser
11680 .match_token_recovering(2, 5, &atn)
11681 .expect("generated match should delete the extraneous token");
11682
11683 assert_eq!(node.children().len(), 2);
11684 assert!(matches!(node.children()[0], ParseTree::Error(_)));
11685 assert_eq!(node.children()[0].text(), "z");
11686 assert_eq!(node.children()[1].text(), "y");
11687 assert_eq!(
11688 node.into_child_iter()
11689 .map(|child| child.text())
11690 .collect::<Vec<_>>(),
11691 ["z", "y"]
11692 );
11693 assert_eq!(parser.number_of_syntax_errors(), 1);
11694 }
11695
11696 #[test]
11697 fn generated_match_token_iterates_single_success_without_a_children_vec() {
11698 let atn = generated_match_recovery_atn();
11699 let data = RecognizerData::new(
11700 "Mini.g4",
11701 Vocabulary::new(
11702 [None, Some("'X'"), Some("'Y'")],
11703 [None, Some("X"), Some("Y")],
11704 [None::<&str>, None, None],
11705 ),
11706 );
11707 let mut parser = BaseParser::new(
11708 CommonTokenStream::new(Source {
11709 tokens: vec![
11710 CommonToken::new(2).with_text("y"),
11711 CommonToken::eof("parser-test", 1, 1, 1),
11712 ],
11713 index: 0,
11714 }),
11715 data,
11716 );
11717
11718 let node = parser
11719 .match_token_recovering(2, 5, &atn)
11720 .expect("generated match should consume the expected token");
11721
11722 assert_eq!(
11723 node.into_child_iter()
11724 .map(|child| child.text())
11725 .collect::<Vec<_>>(),
11726 ["y"]
11727 );
11728 assert_eq!(parser.number_of_syntax_errors(), 0);
11729 }
11730
11731 #[test]
11732 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
11733 let atn = generated_match_recovery_atn();
11734 let data = RecognizerData::new(
11735 "Mini.g4",
11736 Vocabulary::new(
11737 [None, Some("'X'"), Some("'Y'")],
11738 [None, Some("X"), Some("Y")],
11739 [None::<&str>, None, None],
11740 ),
11741 );
11742 let mut parser = BaseParser::new(
11743 CommonTokenStream::new(Source {
11744 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
11745 index: 0,
11746 }),
11747 data,
11748 );
11749 parser.rule_context_stack = vec![
11750 RuleContextFrame {
11751 rule_index: 0,
11752 invoking_state: 0,
11753 },
11754 RuleContextFrame {
11755 rule_index: 1,
11756 invoking_state: 1,
11757 },
11758 ];
11759 let marker = parser.generated_diagnostics_checkpoint();
11760
11761 let _ = parser
11762 .match_token_recovering(2, 5, &atn)
11763 .expect("generated match should insert missing token");
11764 assert_eq!(parser.number_of_syntax_errors(), 1);
11765
11766 parser.restore_generated_diagnostics(marker);
11767
11768 assert_eq!(parser.number_of_syntax_errors(), 0);
11769 assert!(parser.generated_parser_diagnostics.is_empty());
11770 }
11771
11772 #[test]
11773 fn generated_prediction_diagnostics_use_adaptive_context() {
11774 let atn = two_alt_decision_atn();
11775 let data = RecognizerData::new(
11776 "Mini.g4",
11777 Vocabulary::new(
11778 [None, Some("'x'"), Some("'y'")],
11779 [None, Some("X"), Some("Y")],
11780 [None::<&str>, None, None],
11781 ),
11782 )
11783 .with_rule_names(["s"]);
11784 let mut parser = BaseParser::new(
11785 CommonTokenStream::new(Source {
11786 tokens: vec![
11787 CommonToken::new(1)
11788 .with_text("x")
11789 .with_position(1, 0)
11790 .with_span(0, 0),
11791 CommonToken::new(2)
11792 .with_text("y")
11793 .with_position(1, 2)
11794 .with_span(1, 1),
11795 CommonToken::eof("parser-test", 2, 1, 3),
11796 ],
11797 index: 0,
11798 }),
11799 data,
11800 );
11801 parser.set_report_diagnostic_errors(true);
11802
11803 parser.record_generated_prediction_diagnostic(
11804 &atn,
11805 1,
11806 &ParserAtnPrediction {
11807 alt: 1,
11808 requires_full_context: true,
11809 has_semantic_context: false,
11810 diagnostic: Some(ParserAtnPredictionDiagnostic {
11811 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
11812 start_index: 0,
11813 sll_stop_index: 1,
11814 ll_stop_index: 0,
11815 conflicting_alts: vec![1, 2],
11816 exact: false,
11817 }),
11818 },
11819 );
11820 parser.record_generated_prediction_diagnostic(
11825 &atn,
11826 1,
11827 &ParserAtnPrediction {
11828 alt: 1,
11829 requires_full_context: true,
11830 has_semantic_context: false,
11831 diagnostic: Some(ParserAtnPredictionDiagnostic {
11832 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
11833 start_index: 0,
11834 sll_stop_index: 1,
11835 ll_stop_index: 1,
11836 conflicting_alts: vec![1, 2],
11837 exact: false,
11838 }),
11839 },
11840 );
11841
11842 assert_eq!(
11843 parser.generated_parser_diagnostics,
11844 [
11845 ParserDiagnostic {
11846 line: 1,
11847 column: 2,
11848 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
11849 },
11850 ParserDiagnostic {
11851 line: 1,
11852 column: 0,
11853 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
11854 },
11855 ParserDiagnostic {
11856 line: 1,
11857 column: 2,
11858 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
11859 },
11860 ]
11861 );
11862 }
11863
11864 #[test]
11865 fn generated_match_not_set_recovers_empty_complement_at_eof() {
11866 let atn = complement_set_atn();
11867 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11868 parser.rule_context_stack = vec![RuleContextFrame {
11869 rule_index: 0,
11870 invoking_state: 0,
11871 }];
11872
11873 let node = parser
11874 .match_not_set_recovering(&[(1, 1)], 1, 1, 1, &atn)
11875 .expect("empty complement should recover at EOF");
11876
11877 assert_eq!(node.children().len(), 1);
11878 assert!(!node.consumed_eof());
11881 assert_eq!(parser.la(1), TOKEN_EOF);
11882 assert_eq!(
11883 parser.generated_parser_diagnostics,
11884 [ParserDiagnostic {
11885 line: 1,
11886 column: 1,
11887 message: "missing {} at '<EOF>'".to_owned(),
11888 }]
11889 );
11890 }
11891
11892 #[test]
11893 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
11894 let atn = wildcard_then_eof_atn();
11900 let data = RecognizerData::new(
11901 "Mini.g4",
11902 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
11903 );
11904 let mut parser = BaseParser::new(
11905 CommonTokenStream::new(Source {
11906 tokens: vec![CommonToken::eof("parser-test", 1, 1, 1)],
11907 index: 0,
11908 }),
11909 data,
11910 );
11911 parser.rule_context_stack = vec![RuleContextFrame {
11912 rule_index: 0,
11913 invoking_state: 0,
11914 }];
11915
11916 let node = parser
11917 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
11918 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
11919
11920 assert_eq!(node.children().len(), 1);
11922 assert!(!node.consumed_eof());
11923 assert!(node.children()[0].text().starts_with("<missing"));
11924 assert_eq!(parser.la(1), TOKEN_EOF);
11925 assert_eq!(
11926 parser.generated_parser_diagnostics,
11927 [ParserDiagnostic {
11928 line: 1,
11929 column: 1,
11930 message: "missing 'x' at '<EOF>'".to_owned(),
11931 }]
11932 );
11933 }
11934
11935 #[test]
11936 fn generated_rule_recovery_consumes_to_parent_follow() {
11937 let atn = generated_match_recovery_atn();
11938 let data = RecognizerData::new(
11939 "Mini.g4",
11940 Vocabulary::new(
11941 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
11942 [None, Some("X"), Some("Y"), Some("Z")],
11943 [None::<&str>, None, None, None],
11944 ),
11945 );
11946 let mut parser = BaseParser::new(
11947 CommonTokenStream::new(Source {
11948 tokens: vec![
11949 CommonToken::new(3).with_text("z"),
11950 CommonToken::eof("parser-test", 1, 1, 1),
11951 ],
11952 index: 0,
11953 }),
11954 data,
11955 );
11956 let _parent = parser.enter_rule(0, 0);
11957 let marker = parser.push_invoking_state(1);
11958 let mut child = parser.enter_rule(4, 1);
11959 parser.discard_invoking_state(marker);
11960
11961 parser.recover_generated_rule(
11962 &mut child,
11963 &atn,
11964 AntlrError::ParserError {
11965 line: 1,
11966 column: 0,
11967 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
11968 },
11969 );
11970 let tree = parser.finish_rule(child, false);
11971
11972 assert_eq!(parser.la(1), TOKEN_EOF);
11973 assert_eq!(tree.to_string_tree_with_names(&["s", "a"]), "(a z)");
11974 assert_eq!(parser.number_of_syntax_errors(), 1);
11975 assert_eq!(
11976 parser.generated_parser_diagnostics,
11977 [ParserDiagnostic {
11978 line: 1,
11979 column: 0,
11980 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
11981 }]
11982 );
11983 parser.exit_rule();
11984 }
11985
11986 #[test]
11987 fn greedy_ll1_alt_handles_nullable_loop_exit() {
11988 let mut body_symbols = TokenBitSet::default();
11989 body_symbols.insert(1);
11990 let entry = DecisionLookahead {
11991 transitions: vec![
11992 TransitionLookSet {
11993 symbols: body_symbols,
11994 nullable: false,
11995 },
11996 TransitionLookSet {
11997 symbols: TokenBitSet::default(),
11998 nullable: true,
11999 },
12000 ],
12001 };
12002
12003 assert_eq!(ll1_unique_alt(&entry, 2), None);
12004 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
12005 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
12006 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
12007 }
12008
12009 #[test]
12010 fn single_outcome_memo_probe_selects_sparse_or_promote_mode() {
12011 let key = |state_number| FastRecognizeKey {
12012 state_number,
12013 stop_state: 10,
12014 index: state_number,
12015 rule_start_index: 0,
12016 decision_start_index: None,
12017 precedence: 0,
12018 recovery_symbols_id: 0,
12019 recovery_state: None,
12020 };
12021
12022 let mut sparse = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
12023 for state_number in 0..(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT - 1) {
12024 assert!(sparse.should_memoize_single_outcome(&key(state_number)));
12025 }
12026 assert!(!sparse.should_memoize_single_outcome(&key(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT)));
12027 assert_eq!(
12028 sparse.single_outcome_memo_mode,
12029 SingleOutcomeMemoMode::Sparse
12030 );
12031
12032 let mut promote = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
12033 let repeated = key(1);
12034 for _ in 0..=CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
12035 assert!(promote.should_memoize_single_outcome(&repeated));
12036 }
12037 assert_eq!(
12038 promote.single_outcome_memo_mode,
12039 SingleOutcomeMemoMode::Promote
12040 );
12041 }
12042
12043 #[test]
12044 fn clean_empty_multi_alt_outcomes_are_memoized() {
12045 let mut atn = Atn::new(AtnType::Parser, 2);
12046 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
12047 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
12048 atn.add_state(AtnState::new(2, AtnStateKind::RuleStop).with_rule_index(0));
12049 atn.set_rule_to_start_state(vec![0]);
12050 atn.set_rule_to_stop_state(vec![2]);
12051 atn.state_mut(0)
12052 .expect("state 0")
12053 .add_transition(Transition::Epsilon { target: 1 });
12054 atn.state_mut(1)
12055 .expect("state 1")
12056 .add_transition(Transition::Atom {
12057 target: 2,
12058 label: 1,
12059 });
12060 atn.state_mut(1)
12061 .expect("state 1")
12062 .add_transition(Transition::Atom {
12063 target: 2,
12064 label: 2,
12065 });
12066
12067 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
12068 parser.fast_recovery_enabled = false;
12069 let mut visiting = FxHashSet::default();
12070 let mut memo = FxHashMap::default();
12071 let mut expected = ExpectedTokens::default();
12072 let outcomes = parser.recognize_state_fast(
12073 &atn,
12074 FastRecognizeRequest {
12075 state_number: 1,
12076 stop_state: 2,
12077 index: 0,
12078 rule_start_index: 0,
12079 decision_start_index: None,
12080 precedence: 0,
12081 depth: 0,
12082 recovery_symbols: parser.empty_recovery_symbols(),
12083 recovery_state: None,
12084 },
12085 &mut visiting,
12086 &mut memo,
12087 &mut expected,
12088 );
12089
12090 assert!(outcomes.is_empty());
12091 assert_eq!(memo.len(), 1);
12092 assert!(memo.values().next().expect("memo entry").is_empty());
12093 }
12094
12095 #[test]
12096 fn wildcard_matches_non_eof_only() {
12097 let mut parser = mini_parser(vec![
12098 CommonToken::new(1).with_text("x"),
12099 CommonToken::eof("parser-test", 1, 1, 1),
12100 ]);
12101 assert_eq!(parser.match_wildcard().expect("wildcard").text(), "x");
12102 assert!(parser.match_wildcard().is_err());
12103 }
12104
12105 #[test]
12106 fn add_parse_child_records_match_even_without_tree_building() {
12107 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
12112 let token = CommonToken::new(1).with_text("x");
12113
12114 parser.set_build_parse_trees(false);
12115 let mut ctx = ParserRuleContext::new(0, 0);
12116 assert!(!ctx.has_matched_child());
12117 parser.add_parse_child(
12118 &mut ctx,
12119 ParseTree::Terminal(TerminalNode::new(token.clone())),
12120 );
12121 assert!(ctx.children().is_empty());
12123 assert!(ctx.has_matched_child());
12125
12126 parser.set_build_parse_trees(true);
12128 let mut ctx = ParserRuleContext::new(0, 0);
12129 parser.add_parse_child(&mut ctx, ParseTree::Terminal(TerminalNode::new(token)));
12130 assert_eq!(ctx.children().len(), 1);
12131 assert!(ctx.has_matched_child());
12132 }
12133
12134 #[test]
12135 fn parser_interprets_simple_atn_rule() {
12136 let atn = token_then_eof_atn();
12137 let mut parser = mini_parser(vec![
12138 CommonToken::new(1).with_text("x"),
12139 CommonToken::eof("parser-test", 1, 1, 1),
12140 ]);
12141
12142 let tree = parser
12143 .parse_atn_rule(&atn, 0)
12144 .expect("artificial parser rule should parse");
12145 assert_eq!(tree.text(), "x<EOF>");
12146 assert_eq!(parser.number_of_syntax_errors(), 0);
12147 assert_eq!(
12148 tree.first_rule_stop(0)
12149 .expect("rule should stop at EOF")
12150 .token_type(),
12151 TOKEN_EOF
12152 );
12153
12154 let mut parser = mini_parser(vec![
12155 CommonToken::new(1).with_text("x"),
12156 CommonToken::eof("parser-test", 1, 1, 1),
12157 ]);
12158 let (tree, actions) = parser
12159 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
12160 .expect("runtime-option parser rule should parse");
12161 assert!(actions.is_empty());
12162 assert_eq!(
12163 tree.first_rule_stop(0)
12164 .expect("rule should stop at EOF")
12165 .token_type(),
12166 TOKEN_EOF
12167 );
12168 }
12169
12170 #[test]
12171 fn runtime_options_default_ignores_noop_action_transitions() {
12172 let atn = noop_action_then_token_then_eof_atn();
12173 let mut parser = mini_parser(vec![
12174 CommonToken::new(1).with_text("x"),
12175 CommonToken::eof("parser-test", 1, 1, 1),
12176 ]);
12177
12178 let (tree, actions) = parser
12179 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
12180 .expect("no-op parser action should not force action replay");
12181
12182 assert_eq!(tree.text(), "x<EOF>");
12183 assert!(
12184 actions.is_empty(),
12185 "action_index=None transitions are ANTLR metadata, not replay actions"
12186 );
12187 assert_eq!(parser.number_of_syntax_errors(), 0);
12188 }
12189
12190 #[test]
12191 fn parser_exposes_buffered_token_stream_after_parse() {
12192 let atn = token_then_eof_atn();
12193 let mut parser = mini_parser(vec![
12194 CommonToken::new(1).with_text("x"),
12195 CommonToken::eof("parser-test", 1, 1, 1),
12196 ]);
12197
12198 let tree = parser
12199 .parse_atn_rule(&atn, 0)
12200 .expect("artificial parser rule should parse");
12201 assert_eq!(tree.text(), "x<EOF>");
12202
12203 let stream = parser.token_stream();
12204 let source_index_after_parse = stream.token_source().index;
12205 let buffered = stream.tokens();
12206 assert_eq!(buffered.len(), 2);
12207 assert_eq!(buffered[0].text(), "x");
12208 assert_eq!(buffered[0].token_index(), 0);
12209 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
12210 assert_eq!(stream.token_source().index, source_index_after_parse);
12211
12212 let stream = parser.into_token_stream();
12213 assert_eq!(stream.token_source().index, source_index_after_parse);
12214 assert_eq!(stream.tokens()[0].text(), "x");
12215 assert_eq!(stream.tokens()[1].token_type(), TOKEN_EOF);
12216 }
12217
12218 #[test]
12219 fn parser_syntax_error_count_tracks_interpreted_recovery() {
12220 let atn = token_then_eof_atn();
12221 let mut parser = mini_parser(vec![
12222 CommonToken::new(1).with_text("x"),
12223 CommonToken::new(2).with_text("y"),
12224 CommonToken::eof("parser-test", 2, 1, 2),
12225 ]);
12226
12227 let tree = parser
12228 .parse_atn_rule(&atn, 0)
12229 .expect("invalid token should recover into an error node");
12230
12231 assert_eq!(parser.number_of_syntax_errors(), 1);
12232 assert_eq!(
12233 tree.first_error_token()
12234 .expect("recovery should embed an error token")
12235 .text(),
12236 "y"
12237 );
12238 }
12239
12240 #[test]
12241 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
12242 let atn = token_then_eof_atn();
12243 let mut parser = mini_parser(vec![
12244 CommonToken::new(2).with_text("y"),
12245 CommonToken::eof("parser-test", 1, 1, 1),
12246 ]);
12247
12248 let error = parser
12249 .parse_atn_rule(&atn, 0)
12250 .expect_err("start-rule mismatch should remain a parser error");
12251
12252 assert_eq!(parser.number_of_syntax_errors(), 1);
12253 assert!(matches!(error, AntlrError::ParserError { .. }));
12254 }
12255
12256 #[test]
12257 fn adaptive_direct_rule_uses_simulator_decision() {
12258 let atn = two_alt_decision_atn();
12259 let mut simulator = ParserAtnSimulator::new(&atn);
12260 let mut parser = mini_parser(vec![
12261 CommonToken::new(2).with_text("y"),
12262 CommonToken::eof("parser-test", 1, 1, 1),
12263 ]);
12264
12265 let tree = parser
12266 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
12267 .expect("direct adaptive rule should parse");
12268
12269 assert_eq!(tree.text(), "y");
12270 assert_eq!(parser.input.index(), 1);
12271 }
12272
12273 #[test]
12274 fn adaptive_direct_rule_restores_input_on_fallback() {
12275 let atn = predicate_after_token_atn();
12276 let mut simulator = ParserAtnSimulator::new(&atn);
12277 let mut parser = mini_parser(vec![
12278 CommonToken::new(1).with_text("x"),
12279 CommonToken::new(2).with_text("y"),
12280 CommonToken::eof("parser-test", 2, 1, 2),
12281 ]);
12282
12283 let tree = parser
12284 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
12285 .expect("fallback recognizer should parse");
12286
12287 assert_eq!(tree.text(), "xy");
12288 assert_eq!(parser.input.index(), 2);
12289 }
12290
12291 #[test]
12292 fn unknown_predicate_policy_defaults_to_assume_true() {
12293 let atn = predicate_after_token_atn();
12294 let mut parser = mini_parser(vec![
12295 CommonToken::new(1).with_text("x"),
12296 CommonToken::new(2).with_text("y"),
12297 CommonToken::eof("parser-test", 2, 1, 2),
12298 ]);
12299
12300 let (tree, _) = parser
12301 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
12302 .expect("unknown predicate should pass under the default policy");
12303
12304 assert_eq!(tree.text(), "xy");
12305 assert_eq!(parser.number_of_syntax_errors(), 0);
12306 }
12307
12308 #[test]
12309 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
12310 let atn = token_then_eof_atn();
12314 let mut parser = mini_parser(vec![
12315 CommonToken::new(1).with_text("x"),
12316 CommonToken::eof("parser-test", 1, 1, 1),
12317 ]);
12318
12319 parser.unknown_predicate_hits.push((7, 3));
12321
12322 parser
12324 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
12325 .expect("child rule parses");
12326
12327 let error = parser
12329 .take_unknown_semantic_error()
12330 .expect("parent's recorded coordinate must survive the nested interpreted parse");
12331 let AntlrError::Unsupported(message) = error else {
12332 panic!("expected AntlrError::Unsupported, got {error:?}");
12333 };
12334 assert!(message.contains("pred_index=3"), "message: {message}");
12335 }
12336
12337 #[test]
12338 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
12339 let atn = predicate_after_token_atn();
12340 let mut parser = mini_parser(vec![
12341 CommonToken::new(1).with_text("x"),
12342 CommonToken::new(2).with_text("y"),
12343 CommonToken::eof("parser-test", 2, 1, 2),
12344 ]);
12345
12346 let result = parser.parse_atn_rule_with_runtime_options(
12347 &atn,
12348 0,
12349 ParserRuntimeOptions {
12350 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
12351 ..ParserRuntimeOptions::default()
12352 },
12353 );
12354
12355 assert!(
12356 result.is_err(),
12357 "the only path is predicate-guarded, so assume-false must fail the parse"
12358 );
12359 }
12360
12361 #[test]
12362 fn unknown_predicate_policy_error_names_the_coordinate() {
12363 let atn = predicate_after_token_atn();
12364 let mut parser = mini_parser(vec![
12365 CommonToken::new(1).with_text("x"),
12366 CommonToken::new(2).with_text("y"),
12367 CommonToken::eof("parser-test", 2, 1, 2),
12368 ]);
12369
12370 let error = parser
12371 .parse_atn_rule_with_runtime_options(
12372 &atn,
12373 0,
12374 ParserRuntimeOptions {
12375 unknown_predicate_policy: UnknownSemanticPolicy::Error,
12376 ..ParserRuntimeOptions::default()
12377 },
12378 )
12379 .expect_err("evaluating an unknown predicate under Error policy must fail");
12380
12381 let AntlrError::Unsupported(message) = error else {
12382 panic!("expected AntlrError::Unsupported, got {error:?}");
12383 };
12384 assert!(
12385 message.contains("unsupported semantic predicate"),
12386 "message should name the failure class: {message}"
12387 );
12388 assert!(
12389 message.contains("pred_index=0"),
12390 "message should carry the coordinate: {message}"
12391 );
12392 }
12393
12394 #[test]
12395 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
12396 let atn = predicate_after_token_atn();
12402 let mut parser = mini_parser(vec![
12403 CommonToken::new(1).with_text("x"),
12404 CommonToken::new(2).with_text("y"),
12405 CommonToken::eof("parser-test", 2, 1, 2),
12406 ]);
12407
12408 parser
12409 .parse_atn_rule_with_runtime_options(
12410 &atn,
12411 0,
12412 ParserRuntimeOptions {
12413 unknown_predicate_policy: UnknownSemanticPolicy::Error,
12414 ..ParserRuntimeOptions::default()
12415 },
12416 )
12417 .expect_err("first parse fails loud under the Error policy");
12418
12419 parser.reset_unknown_semantic_hits();
12424 assert!(
12425 parser.take_unknown_semantic_error().is_none(),
12426 "reset must drop stale unknown-predicate coordinates before a reused parse"
12427 );
12428 }
12429
12430 #[derive(Debug, Default)]
12431 struct RecordingHooks {
12432 predicates: Vec<(usize, usize, usize, Option<String>)>,
12433 actions: Vec<(usize, String, Option<String>)>,
12434 }
12435
12436 impl SemanticHooks for RecordingHooks {
12437 fn sempred<S>(
12438 &mut self,
12439 ctx: &mut ParserSemCtx<'_, S>,
12440 rule_index: usize,
12441 pred_index: usize,
12442 ) -> Option<bool>
12443 where
12444 S: TokenSource,
12445 {
12446 self.predicates.push((
12447 ctx.input_index(),
12448 rule_index,
12449 pred_index,
12450 ctx.token_text(1).map(str::to_owned),
12451 ));
12452 Some(true)
12453 }
12454
12455 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
12456 where
12457 S: TokenSource,
12458 {
12459 self.actions.push((
12460 action.source_state(),
12461 ctx.action_text(),
12462 ctx.rule_name().map(str::to_owned),
12463 ));
12464 true
12465 }
12466 }
12467
12468 #[derive(Debug, Default)]
12469 struct RejectingPredicateHooks {
12470 predicates: Vec<(usize, usize, usize, Option<String>)>,
12471 }
12472
12473 impl SemanticHooks for RejectingPredicateHooks {
12474 fn sempred<S>(
12475 &mut self,
12476 ctx: &mut ParserSemCtx<'_, S>,
12477 rule_index: usize,
12478 pred_index: usize,
12479 ) -> Option<bool>
12480 where
12481 S: TokenSource,
12482 {
12483 self.predicates.push((
12484 ctx.input_index(),
12485 rule_index,
12486 pred_index,
12487 ctx.token_text(1).map(str::to_owned),
12488 ));
12489 Some(false)
12490 }
12491 }
12492
12493 #[test]
12494 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
12495 let atn = predicate_after_token_atn();
12496 let mut parser = mini_parser_with_hooks(
12497 vec![
12498 CommonToken::new(1).with_text("x"),
12499 CommonToken::new(2).with_text("y"),
12500 CommonToken::eof("parser-test", 2, 1, 2),
12501 ],
12502 RecordingHooks::default(),
12503 );
12504
12505 let (tree, _) = parser
12506 .parse_atn_rule_with_runtime_options(
12507 &atn,
12508 0,
12509 ParserRuntimeOptions {
12510 unknown_predicate_policy: UnknownSemanticPolicy::Error,
12511 ..ParserRuntimeOptions::default()
12512 },
12513 )
12514 .expect("hook supplies the missing predicate result");
12515
12516 assert_eq!(tree.text(), "xy");
12517 assert_eq!(
12518 parser.semantic_hooks.predicates,
12519 vec![(1, 0, 0, Some("y".to_owned()))]
12520 );
12521 }
12522
12523 #[test]
12524 fn runtime_options_default_preserves_semantic_hook_predicates() {
12525 let atn = predicate_after_token_atn();
12526 let mut parser = mini_parser_with_hooks(
12527 vec![
12528 CommonToken::new(1).with_text("x"),
12529 CommonToken::new(2).with_text("y"),
12530 CommonToken::eof("parser-test", 2, 1, 2),
12531 ],
12532 RejectingPredicateHooks::default(),
12533 );
12534
12535 let result =
12536 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
12537
12538 assert!(
12539 result.is_err(),
12540 "default runtime options must not bypass semantic hooks for predicate ATNs"
12541 );
12542 assert_eq!(
12543 parser.semantic_hooks.predicates,
12544 vec![(1, 0, 0, Some("y".to_owned()))]
12545 );
12546 }
12547
12548 #[test]
12549 fn semantic_hook_handles_committed_parser_action() {
12550 let atn = token_then_eof_atn();
12551 let mut parser = mini_parser_with_hooks(
12552 vec![
12553 CommonToken::new(1).with_text("x"),
12554 CommonToken::eof("parser-test", 1, 1, 1),
12555 ],
12556 RecordingHooks::default(),
12557 );
12558 let (tree, _) = parser
12559 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
12560 .expect("rule parses before action hook is tested");
12561
12562 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
12563 assert_eq!(
12564 parser.semantic_hooks.actions,
12565 vec![(42, "x".to_owned(), Some("s".to_owned()))]
12566 );
12567 }
12568
12569 #[test]
12570 fn unhandled_committed_action_fails_loud_under_error_policy() {
12571 let mut parser =
12575 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
12576 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
12577 let tree = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, -1)));
12578
12579 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
12581
12582 let error = parser
12583 .take_unknown_semantic_error()
12584 .expect("an unhandled committed action under Error policy must fail loud");
12585 let AntlrError::Unsupported(message) = error else {
12586 panic!("expected AntlrError::Unsupported, got {error:?}");
12587 };
12588 assert!(
12589 message.contains("unhandled semantic action") && message.contains("state=42"),
12590 "message should name the dropped action coordinate: {message}"
12591 );
12592
12593 let mut lenient =
12595 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
12596 let tree = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, -1)));
12597 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
12598 assert!(lenient.take_unknown_semantic_error().is_none());
12599 }
12600
12601 #[test]
12602 fn translated_predicate_is_unaffected_by_error_policy() {
12603 let atn = predicate_after_token_atn();
12604 let mut parser = mini_parser(vec![
12605 CommonToken::new(1).with_text("x"),
12606 CommonToken::new(2).with_text("y"),
12607 CommonToken::eof("parser-test", 2, 1, 2),
12608 ]);
12609
12610 let (tree, _) = parser
12611 .parse_atn_rule_with_runtime_options(
12612 &atn,
12613 0,
12614 ParserRuntimeOptions {
12615 predicates: &[(0, 0, ParserPredicate::True)],
12616 unknown_predicate_policy: UnknownSemanticPolicy::Error,
12617 ..ParserRuntimeOptions::default()
12618 },
12619 )
12620 .expect("a predicate covered by the table is not an unknown coordinate");
12621
12622 assert_eq!(tree.text(), "xy");
12623 }
12624
12625 fn hook_predicate_semantics() -> ParserSemantics {
12630 let mut ir = SemIr::new();
12631 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
12632 ParserSemantics {
12633 ir,
12634 predicates: vec![ParserSemanticPredicate {
12635 rule_index: 0,
12636 pred_index: 0,
12637 expr,
12638 failure_message: None,
12639 }],
12640 actions: Vec::new(),
12641 }
12642 }
12643
12644 #[derive(Debug, Default)]
12645 struct DecliningHooks;
12646
12647 impl SemanticHooks for DecliningHooks {}
12648
12649 #[test]
12650 fn semir_hook_none_falls_through_to_assume_true() {
12651 let atn = predicate_after_token_atn();
12652 let semantics = hook_predicate_semantics();
12653 let mut parser = mini_parser_with_hooks(
12654 vec![
12655 CommonToken::new(1).with_text("x"),
12656 CommonToken::new(2).with_text("y"),
12657 CommonToken::eof("parser-test", 2, 1, 2),
12658 ],
12659 DecliningHooks,
12660 );
12661
12662 let (tree, _) = parser
12663 .parse_atn_rule_with_runtime_options(
12664 &atn,
12665 0,
12666 ParserRuntimeOptions {
12667 semantics: Some(&semantics),
12668 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
12669 ..ParserRuntimeOptions::default()
12670 },
12671 )
12672 .expect("a declined SemIR hook must pass under assume-true");
12673
12674 assert_eq!(tree.text(), "xy");
12675 }
12676
12677 #[test]
12678 fn semir_hook_none_falls_through_to_assume_false() {
12679 let atn = predicate_after_token_atn();
12680 let semantics = hook_predicate_semantics();
12681 let mut parser = mini_parser_with_hooks(
12682 vec![
12683 CommonToken::new(1).with_text("x"),
12684 CommonToken::new(2).with_text("y"),
12685 CommonToken::eof("parser-test", 2, 1, 2),
12686 ],
12687 DecliningHooks,
12688 );
12689
12690 let result = parser.parse_atn_rule_with_runtime_options(
12691 &atn,
12692 0,
12693 ParserRuntimeOptions {
12694 semantics: Some(&semantics),
12695 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
12696 ..ParserRuntimeOptions::default()
12697 },
12698 );
12699
12700 assert!(
12701 result.is_err(),
12702 "a declined SemIR hook must fail the only guarded path under assume-false"
12703 );
12704 }
12705
12706 #[test]
12707 fn semir_hook_none_records_coordinate_under_error_policy() {
12708 let atn = predicate_after_token_atn();
12709 let semantics = hook_predicate_semantics();
12710 let mut parser = mini_parser_with_hooks(
12711 vec![
12712 CommonToken::new(1).with_text("x"),
12713 CommonToken::new(2).with_text("y"),
12714 CommonToken::eof("parser-test", 2, 1, 2),
12715 ],
12716 DecliningHooks,
12717 );
12718
12719 let error = parser
12720 .parse_atn_rule_with_runtime_options(
12721 &atn,
12722 0,
12723 ParserRuntimeOptions {
12724 semantics: Some(&semantics),
12725 unknown_predicate_policy: UnknownSemanticPolicy::Error,
12726 ..ParserRuntimeOptions::default()
12727 },
12728 )
12729 .expect_err("a declined SemIR hook under Error policy must fail the parse");
12730
12731 let AntlrError::Unsupported(message) = error else {
12732 panic!("expected AntlrError::Unsupported, got {error:?}");
12733 };
12734 assert!(
12735 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
12736 "message should name the unresolved coordinate: {message}"
12737 );
12738 }
12739
12740 #[test]
12741 fn generated_direct_predicate_honors_installed_policy() {
12742 let semantics = hook_predicate_semantics();
12748 let context = ParserRuleContext::new(0, -1);
12749
12750 let mut assume_true =
12751 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
12752 assert!(
12753 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
12754 &semantics, 0, 0, &context, 0
12755 ),
12756 "default AssumeTrue accepts a declined hook"
12757 );
12758 assert!(assume_true.take_unknown_semantic_error().is_none());
12759
12760 let mut error_policy =
12761 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
12762 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
12763 assert!(
12764 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
12765 &semantics, 0, 0, &context, 0
12766 ),
12767 "Error policy rejects a declined hook on the generated-direct path"
12768 );
12769 let error = error_policy
12770 .take_unknown_semantic_error()
12771 .expect("Error policy records the unresolved coordinate for the generated path");
12772 let AntlrError::Unsupported(message) = error else {
12773 panic!("expected AntlrError::Unsupported, got {error:?}");
12774 };
12775 assert!(message.contains("pred_index=0"), "message: {message}");
12776 }
12777
12778 #[test]
12779 fn parser_rule_start_skips_leading_hidden_tokens() {
12780 let atn = token_then_eof_atn();
12781 let mut parser = mini_parser(vec![
12782 CommonToken::new(99)
12783 .with_text(" ")
12784 .with_channel(HIDDEN_CHANNEL),
12785 CommonToken::new(1).with_text("x"),
12786 CommonToken::eof("parser-test", 2, 1, 2),
12787 ]);
12788
12789 let tree = parser
12790 .parse_atn_rule(&atn, 0)
12791 .expect("artificial parser rule should parse");
12792 let Some(ParseTree::Rule(rule)) = tree.first_rule(0) else {
12793 panic!("rule node should be present");
12794 };
12795 assert_eq!(
12796 rule.context()
12797 .start()
12798 .expect("rule should have a start token")
12799 .token_type(),
12800 1
12801 );
12802 }
12803
12804 #[test]
12805 fn parser_action_after_eof_stops_at_eof_token() {
12806 let atn = eof_then_action_atn();
12807 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
12808
12809 let (_, actions) = parser
12810 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
12811 .expect("EOF action rule should parse");
12812
12813 assert_eq!(actions.len(), 1);
12814 assert_eq!(actions[0].stop_index(), Some(0));
12815 assert_eq!(
12816 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
12817 ""
12818 );
12819 }
12820
12821 #[test]
12822 fn after_action_stop_uses_rule_context_stop_not_cursor() {
12823 let mut id = CommonToken::new(1).with_text("x");
12828 id.set_token_index(0);
12829 let mut eof = CommonToken::eof("parser-test", 1, 1, 1);
12830 eof.set_token_index(1);
12831 let mut parser = mini_parser(vec![id.clone(), eof]);
12832 parser.consume();
12834 assert_eq!(parser.la(1), TOKEN_EOF);
12835
12836 let mut ctx = ParserRuleContext::new(0, 0);
12839 ctx.set_stop(id);
12840 let tree = ParseTree::Rule(RuleNode::new(ctx));
12841
12842 let current_index = parser.input.index();
12843 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
12845 assert_eq!(
12847 parser.after_action_stop_index_for_tree(&tree, current_index),
12848 Some(0)
12849 );
12850 }
12851
12852 #[test]
12853 fn after_action_start_uses_rule_context_start_not_cursor() {
12854 let parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
12859 let mut id = CommonToken::new(1).with_text("x");
12860 id.set_token_index(2);
12862
12863 let mut ctx = ParserRuleContext::new(0, 0);
12864 ctx.set_start(id);
12865 let tree = ParseTree::Rule(RuleNode::new(ctx));
12866
12867 assert_eq!(parser.after_action_start_index_for_tree(&tree, 0), 2);
12870
12871 let empty = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, 0)));
12873 assert_eq!(parser.after_action_start_index_for_tree(&empty, 7), 7);
12874 }
12875
12876 #[test]
12877 fn fast_outcome_selection_respects_sll_tie_order() {
12878 let first = FastRecognizeOutcome {
12879 index: 1,
12880 consumed_eof: false,
12881 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
12882 line: 1,
12883 column: 0,
12884 message: "mismatched input 'x'".to_owned(),
12885 }]),
12886 nodes: NodeList::new(),
12887 };
12888 let second = FastRecognizeOutcome {
12889 index: first.index,
12890 consumed_eof: first.consumed_eof,
12891 diagnostics: FastDiagnostics::new(),
12892 nodes: NodeList::new(),
12893 };
12894
12895 let selected = select_best_fast_outcome(
12896 [first.clone(), second.clone()].into_iter(),
12897 PredictionMode::Sll,
12898 None,
12899 |_| panic!("caller-follow token probe should not run"),
12900 )
12901 .expect("one outcome should be selected");
12902 assert_eq!(selected.diagnostics.len(), 1);
12903 let eof_second = FastRecognizeOutcome {
12904 index: second.index,
12905 consumed_eof: true,
12906 diagnostics: FastDiagnostics::new(),
12907 nodes: NodeList::new(),
12908 };
12909 let selected = select_best_fast_outcome(
12910 [first.clone(), eof_second].into_iter(),
12911 PredictionMode::Sll,
12912 None,
12913 |_| panic!("caller-follow token probe should not run"),
12914 )
12915 .expect("one outcome should be selected");
12916 assert!(!selected.consumed_eof);
12917 let selected = select_best_fast_outcome(
12918 [first, second].into_iter(),
12919 PredictionMode::Ll,
12920 None,
12921 |_| panic!("caller-follow token probe should not run"),
12922 )
12923 .expect("one outcome should be selected");
12924 assert!(selected.diagnostics.is_empty());
12925 }
12926
12927 #[test]
12928 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
12929 let first = FastRecognizeOutcome {
12930 index: 3,
12931 consumed_eof: false,
12932 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
12933 line: 1,
12934 column: 0,
12935 message: "mismatched input 'x' expecting 'a'".to_owned(),
12936 }]),
12937 nodes: NodeList::new(),
12938 };
12939 let same_rank = FastRecognizeOutcome {
12940 index: first.index,
12941 consumed_eof: first.consumed_eof,
12942 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
12943 line: 1,
12944 column: 0,
12945 message: "mismatched input 'x' expecting 'b'".to_owned(),
12946 }]),
12947 nodes: NodeList::new(),
12948 };
12949 let better_rank = FastRecognizeOutcome {
12950 index: first.index,
12951 consumed_eof: first.consumed_eof,
12952 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
12953 line: 1,
12954 column: 0,
12955 message: "missing 'a' at 'x'".to_owned(),
12956 }]),
12957 nodes: NodeList::new(),
12958 };
12959 let mut outcomes = vec![first, same_rank, better_rank];
12960
12961 dedupe_fast_outcomes(&mut outcomes);
12962
12963 assert_eq!(outcomes.len(), 2);
12964 assert_eq!(
12965 outcomes[0].diagnostics[0].message,
12966 "mismatched input 'x' expecting 'a'"
12967 );
12968 assert_eq!(outcomes[1].diagnostics[0].message, "missing 'a' at 'x'");
12969 }
12970
12971 #[test]
12972 fn fast_outcome_selection_prefers_generated_caller_follow() {
12973 let earlier = FastRecognizeOutcome {
12974 index: 7,
12975 consumed_eof: false,
12976 diagnostics: FastDiagnostics::new(),
12977 nodes: NodeList::new(),
12978 };
12979 let later = FastRecognizeOutcome {
12980 index: 8,
12981 consumed_eof: false,
12982 diagnostics: FastDiagnostics::new(),
12983 nodes: NodeList::new(),
12984 };
12985 let mut follow = TokenBitSet::default();
12986 follow.insert(5);
12987
12988 let selected = select_best_fast_outcome(
12989 [later.clone(), earlier.clone()].into_iter(),
12990 PredictionMode::Ll,
12991 Some(&follow),
12992 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
12993 )
12994 .expect("one outcome should be selected");
12995 assert_eq!(selected.index, 7);
12996
12997 let selected = select_best_fast_outcome(
12998 [later.clone(), earlier.clone()].into_iter(),
12999 PredictionMode::Ll,
13000 Some(&follow),
13001 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
13002 )
13003 .expect("one outcome should be selected");
13004 assert_eq!(selected.index, 8);
13005
13006 let indented_next_statement = FastRecognizeOutcome {
13007 index: 9,
13008 consumed_eof: false,
13009 diagnostics: FastDiagnostics::new(),
13010 nodes: NodeList::new(),
13011 };
13012 let selected = select_best_fast_outcome(
13013 [indented_next_statement, earlier.clone()].into_iter(),
13014 PredictionMode::Ll,
13015 Some(&follow),
13016 |index| {
13017 let is_boundary = index == 7;
13018 let is_boundary_gap = matches!(index, 7 | 8);
13019 (
13020 if index == 7 { 5 } else { TOKEN_EOF },
13021 is_boundary,
13022 is_boundary_gap,
13023 )
13024 },
13025 )
13026 .expect("one outcome should be selected");
13027 assert_eq!(selected.index, 7);
13028
13029 let continuation = FastRecognizeOutcome {
13030 index: 10,
13031 consumed_eof: false,
13032 diagnostics: FastDiagnostics::new(),
13033 nodes: NodeList::new(),
13034 };
13035 let selected = select_best_fast_outcome(
13036 [continuation, earlier.clone()].into_iter(),
13037 PredictionMode::Ll,
13038 Some(&follow),
13039 |index| {
13040 let is_boundary = matches!(index, 7 | 9);
13041 (
13042 if index == 7 { 5 } else { TOKEN_EOF },
13043 is_boundary,
13044 is_boundary,
13045 )
13046 },
13047 )
13048 .expect("one outcome should be selected");
13049 assert_eq!(selected.index, 10);
13050
13051 let selected = select_best_fast_outcome(
13052 [earlier, later].into_iter(),
13053 PredictionMode::Sll,
13054 Some(&follow),
13055 |_| panic!("caller-follow token probe should not run in SLL mode"),
13056 )
13057 .expect("one outcome should be selected");
13058 assert_eq!(selected.index, 8);
13059 }
13060
13061 #[test]
13062 fn caller_follow_boundary_text_requires_separator_shape() {
13063 assert!(is_caller_follow_boundary_text(";"));
13064 assert!(is_caller_follow_boundary_text("\n"));
13065 assert!(is_caller_follow_boundary_text("\r\n "));
13066 assert!(is_caller_follow_boundary_text(";\n"));
13067 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
13068 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
13069 assert!(!is_caller_follow_boundary_text("identifier"));
13070 assert!(is_caller_follow_boundary_gap_text(" \t "));
13071 assert!(is_caller_follow_boundary_gap_text("\n "));
13072 assert!(is_caller_follow_boundary_gap_text(";\t"));
13073 assert!(!is_caller_follow_boundary_gap_text(
13074 "\"\"\"line1\nline2\"\"\""
13075 ));
13076 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
13077 }
13078
13079 #[test]
13080 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
13081 let mut parser = mini_parser(vec![
13082 CommonToken::new(5).with_text("\n"),
13083 CommonToken::new(6)
13084 .with_text("// comment\n")
13085 .with_channel(HIDDEN_CHANNEL),
13086 CommonToken::new(1).with_text("x"),
13087 CommonToken::eof("parser-test", 1, 2, 0),
13088 ]);
13089
13090 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
13091 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
13092 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
13093 }
13094
13095 #[test]
13096 fn caller_follow_token_info_uses_stream_visible_channel() {
13097 let source = Source {
13098 tokens: vec![
13099 CommonToken::new(5).with_text("\n").with_channel(2),
13100 CommonToken::new(1).with_text("x").with_channel(2),
13101 CommonToken::new(6)
13102 .with_text("// comment\n")
13103 .with_channel(HIDDEN_CHANNEL),
13104 CommonToken::eof("parser-test", 1, 2, 0),
13105 ],
13106 index: 0,
13107 };
13108 let data = RecognizerData::new(
13109 "Mini.g4",
13110 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
13111 );
13112 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
13113
13114 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
13115 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
13116 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
13117 }
13118
13119 #[test]
13120 fn reset_per_parse_caches_clears_state_expected_token_cache() {
13121 let atn = token_then_eof_atn();
13122 let mut parser = mini_parser(Vec::new());
13123
13124 let _ = parser.cached_state_expected_token_set(&atn, 0);
13125 assert!(!parser.state_expected_token_cache.is_empty());
13126
13127 parser.reset_per_parse_caches();
13128 assert!(parser.state_expected_token_cache.is_empty());
13129 }
13130
13131 #[test]
13132 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
13133 let source = Source {
13134 tokens: vec![
13135 CommonToken::new(1).with_text("x"),
13136 CommonToken::eof("parser-test", 1, 1, 1),
13137 ],
13138 index: 0,
13139 };
13140 let data = RecognizerData::new(
13141 "Mini.g4",
13142 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
13143 );
13144 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
13145 let expected = ExpectedTokens {
13146 index: Some(0),
13147 symbols: BTreeSet::new(),
13148 no_viable: None,
13149 };
13150
13151 let (_, message) = parser.expected_error_message(0, 0, &expected);
13152
13153 assert_eq!(message, "mismatched input 'x'");
13154 }
13155
13156 #[test]
13157 fn eof_rule_stop_index_points_at_eof_token() {
13158 let source = Source {
13159 tokens: vec![
13160 CommonToken::new(1).with_text("x"),
13161 CommonToken::eof("parser-test", 1, 1, 1),
13162 ],
13163 index: 0,
13164 };
13165 let data = RecognizerData::new(
13166 "Mini.g4",
13167 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
13168 );
13169 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
13170
13171 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
13172 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
13173 }
13174
13175 #[test]
13176 fn generated_parser_action_uses_current_rule_stop_boundary() {
13177 let mut parser = mini_parser(vec![
13178 CommonToken::new(1).with_text("x"),
13179 CommonToken::eof("parser-test", 1, 1, 1),
13180 ]);
13181
13182 parser.match_token(1).expect("token should match");
13183 let action = parser.parser_action_at_current(7, 0, 0, false);
13184 assert_eq!(action.source_state(), 7);
13185 assert_eq!(action.rule_index(), 0);
13186 assert_eq!(action.start_index(), 0);
13187 assert_eq!(action.stop_index(), Some(0));
13188
13189 parser.match_eof().expect("EOF should match");
13190 let action = parser.parser_action_at_current(8, 0, 0, true);
13191 assert_eq!(action.stop_index(), Some(1));
13192 }
13193
13194 #[test]
13195 fn folds_left_recursive_boundary_into_rule_node() {
13196 let nodes = fold_left_recursive_boundaries(vec![
13197 RecognizedNode::Token { index: 0 },
13198 RecognizedNode::LeftRecursiveBoundary { rule_index: 1 },
13199 RecognizedNode::Token { index: 1 },
13200 ]);
13201
13202 assert_eq!(
13203 nodes,
13204 vec![
13205 RecognizedNode::Rule {
13206 rule_index: 1,
13207 invoking_state: -1,
13208 alt_number: 0,
13209 start_index: 0,
13210 stop_index: Some(0),
13211 return_values: BTreeMap::new(),
13212 children: vec![RecognizedNode::Token { index: 0 }],
13213 },
13214 RecognizedNode::Token { index: 1 },
13215 ]
13216 );
13217 }
13218
13219 #[test]
13220 fn outcome_ties_keep_later_non_recursive_alternative() {
13221 let first = RecognizeOutcome {
13222 index: 1,
13223 consumed_eof: false,
13224 alt_number: 0,
13225 member_values: BTreeMap::new(),
13226 return_values: BTreeMap::new(),
13227 diagnostics: Vec::new(),
13228 decisions: Vec::new(),
13229 actions: vec![ParserAction::new(1, 0, 0, None)],
13230 nodes: vec![RecognizedNode::Token { index: 0 }],
13231 };
13232 let second = RecognizeOutcome {
13233 actions: vec![ParserAction::new(2, 0, 0, None)],
13234 ..first.clone()
13235 };
13236
13237 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
13238 .expect("one outcome should be selected");
13239 assert_eq!(selected.actions[0].source_state(), 2);
13240 }
13241
13242 #[test]
13243 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
13244 let first = RecognizeOutcome {
13245 index: 1,
13246 consumed_eof: false,
13247 alt_number: 0,
13248 member_values: BTreeMap::new(),
13249 return_values: BTreeMap::new(),
13250 diagnostics: Vec::new(),
13251 decisions: Vec::new(),
13252 actions: vec![ParserAction::new(1, 0, 0, None)],
13253 nodes: vec![RecognizedNode::Token { index: 0 }],
13254 };
13255 let second = RecognizeOutcome {
13256 actions: vec![
13257 ParserAction::new(2, 0, 0, None),
13258 ParserAction::new(3, 0, 0, None),
13259 ],
13260 ..first.clone()
13261 };
13262
13263 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll)
13264 .expect("one outcome should be selected");
13265 assert_eq!(selected.actions.len(), 2);
13266 }
13267
13268 #[test]
13269 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
13270 let first = RecognizeOutcome {
13271 index: 7,
13272 consumed_eof: false,
13273 alt_number: 0,
13274 member_values: BTreeMap::new(),
13275 return_values: BTreeMap::new(),
13276 diagnostics: Vec::new(),
13277 decisions: vec![1, 0],
13278 actions: vec![
13279 ParserAction::new(23, 2, 2, Some(4)),
13280 ParserAction::new(23, 2, 0, Some(6)),
13281 ],
13282 nodes: vec![RecognizedNode::Token { index: 0 }],
13283 };
13284 let second = RecognizeOutcome {
13285 decisions: vec![0, 1],
13286 actions: vec![
13287 ParserAction::new(23, 2, 2, Some(6)),
13288 ParserAction::new(23, 2, 0, Some(6)),
13289 ],
13290 ..first.clone()
13291 };
13292
13293 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
13294 .expect("one outcome should be selected");
13295 assert_eq!(selected.actions[0].stop_index(), Some(6));
13296 }
13297
13298 #[test]
13299 fn outcome_ties_keep_first_recursive_tree_shape() {
13300 let recursive_nodes = vec![RecognizedNode::Rule {
13301 rule_index: 1,
13302 invoking_state: -1,
13303 alt_number: 0,
13304 start_index: 0,
13305 stop_index: Some(0),
13306 return_values: BTreeMap::new(),
13307 children: vec![RecognizedNode::Rule {
13308 rule_index: 1,
13309 invoking_state: -1,
13310 alt_number: 0,
13311 start_index: 0,
13312 stop_index: Some(0),
13313 return_values: BTreeMap::new(),
13314 children: vec![RecognizedNode::Token { index: 0 }],
13315 }],
13316 }];
13317 let first = RecognizeOutcome {
13318 index: 1,
13319 consumed_eof: false,
13320 alt_number: 0,
13321 member_values: BTreeMap::new(),
13322 return_values: BTreeMap::new(),
13323 diagnostics: Vec::new(),
13324 decisions: Vec::new(),
13325 actions: vec![ParserAction::new(1, 0, 0, None)],
13326 nodes: recursive_nodes.clone(),
13327 };
13328 let second = RecognizeOutcome {
13329 index: 1,
13330 consumed_eof: false,
13331 alt_number: 0,
13332 member_values: BTreeMap::new(),
13333 return_values: BTreeMap::new(),
13334 diagnostics: Vec::new(),
13335 decisions: Vec::new(),
13336 actions: vec![ParserAction::new(2, 0, 0, None)],
13337 nodes: recursive_nodes,
13338 };
13339
13340 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
13341 .expect("one outcome should be selected");
13342 assert_eq!(selected.actions[0].source_state(), 1);
13343 }
13344
13345 #[test]
13346 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
13347 let first_alt = RecognizeOutcome {
13348 index: 2,
13349 consumed_eof: true,
13350 alt_number: 0,
13351 member_values: BTreeMap::new(),
13352 return_values: BTreeMap::new(),
13353 diagnostics: vec![ParserDiagnostic {
13354 line: 1,
13355 column: 3,
13356 message: "missing 'Y' at '<EOF>'".to_owned(),
13357 }],
13358 decisions: vec![0],
13359 actions: vec![ParserAction::new(1, 0, 0, None)],
13360 nodes: vec![RecognizedNode::Token { index: 0 }],
13361 };
13362 let second_alt = RecognizeOutcome {
13363 diagnostics: Vec::new(),
13364 decisions: vec![1],
13365 actions: vec![ParserAction::new(2, 0, 0, None)],
13366 ..first_alt.clone()
13367 };
13368
13369 let selected =
13370 select_best_outcome([second_alt, first_alt].into_iter(), PredictionMode::Sll)
13371 .expect("one outcome should be selected");
13372 assert_eq!(selected.diagnostics.len(), 1);
13373 assert_eq!(selected.decisions, [0]);
13374 }
13375}