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)]
987pub struct BaseParser<S, H = NoSemanticHooks> {
988 input: CommonTokenStream<S>,
989 data: RecognizerData,
990 semantic_hooks: H,
991 build_parse_trees: bool,
992 syntax_errors: usize,
993 report_diagnostic_errors: bool,
994 prediction_mode: PredictionMode,
995 prediction_diagnostics: Vec<ParserDiagnostic>,
996 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
997 generated_parser_diagnostics: Vec<ParserDiagnostic>,
998 generated_sync_expected: Option<TokenBitSet>,
999 int_members: BTreeMap<usize, i64>,
1000 rule_context_stack: Vec<RuleContextFrame>,
1001 rule_context_version: usize,
1002 prediction_context_cache: Option<CachedPredictionContext>,
1003 pending_invoking_states: Vec<isize>,
1004 precedence_stack: Vec<i32>,
1005 invoked_predicates: Vec<(usize, usize)>,
1009 bail_on_error: bool,
1013 unknown_predicate_policy: UnknownSemanticPolicy,
1016 unknown_predicate_hits: Vec<(usize, usize)>,
1019 unhandled_action_hits: Vec<(usize, usize)>,
1024 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1029 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1035 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1040 rule_stop_reach_cache: Vec<Option<bool>>,
1045 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1050 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1056 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1062 empty_cycle_cache: Vec<Option<bool>>,
1066 single_outcome_memo_mode: SingleOutcomeMemoMode,
1069 single_outcome_probe_seen: FxHashSet<FastRecognizeKey>,
1070 single_outcome_probe_samples: usize,
1071 single_outcome_probe_repeats: usize,
1072 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1075 fast_first_set_prefilter: bool,
1083 fast_recovery_enabled: bool,
1087 fast_token_nodes_enabled: bool,
1092}
1093
1094#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1096pub struct GeneratedDiagnosticsCheckpoint {
1097 diagnostics_len: usize,
1098 syntax_errors: usize,
1099}
1100
1101#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1102struct RuleContextFrame {
1103 rule_index: usize,
1104 invoking_state: isize,
1105}
1106
1107#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1108struct RecognizeOutcome {
1109 index: usize,
1110 consumed_eof: bool,
1111 alt_number: usize,
1112 member_values: BTreeMap<usize, i64>,
1113 return_values: BTreeMap<String, i64>,
1114 diagnostics: Vec<ParserDiagnostic>,
1115 decisions: Vec<usize>,
1116 actions: Vec<ParserAction>,
1117 nodes: Vec<RecognizedNode>,
1118}
1119
1120#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1121enum RecognizedNode {
1122 Token {
1123 index: usize,
1124 },
1125 ErrorToken {
1126 index: usize,
1127 },
1128 MissingToken {
1129 token_type: i32,
1130 at_index: usize,
1131 text: String,
1132 },
1133 Rule {
1134 rule_index: usize,
1135 invoking_state: isize,
1136 alt_number: usize,
1137 start_index: usize,
1138 stop_index: Option<usize>,
1139 return_values: BTreeMap<String, i64>,
1140 children: Vec<Self>,
1141 },
1142 LeftRecursiveBoundary {
1143 rule_index: usize,
1144 },
1145}
1146
1147#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1148struct FastRecognizeOutcome {
1149 index: usize,
1150 consumed_eof: bool,
1151 diagnostics: FastDiagnostics,
1152 nodes: NodeList,
1161}
1162
1163#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
1164#[allow(clippy::box_collection)]
1165struct FastDiagnostics(Option<Box<Vec<ParserDiagnostic>>>);
1166
1167impl FastDiagnostics {
1168 const fn new() -> Self {
1169 Self(None)
1170 }
1171
1172 #[cfg(test)]
1173 fn from_vec(diagnostics: Vec<ParserDiagnostic>) -> Self {
1174 if diagnostics.is_empty() {
1175 Self::new()
1176 } else {
1177 Self(Some(Box::new(diagnostics)))
1178 }
1179 }
1180
1181 fn is_empty(&self) -> bool {
1182 self.0
1183 .as_ref()
1184 .is_none_or(|diagnostics| diagnostics.is_empty())
1185 }
1186
1187 fn as_slice(&self) -> &[ParserDiagnostic] {
1188 self.0.as_deref().map_or(&[], Vec::as_slice)
1189 }
1190
1191 fn insert(&mut self, index: usize, diagnostic: ParserDiagnostic) {
1192 self.0
1193 .get_or_insert_with(Box::default)
1194 .insert(index, diagnostic);
1195 }
1196
1197 fn append(&mut self, other: &mut Self) {
1198 if other.is_empty() {
1199 return;
1200 }
1201 self.0
1202 .get_or_insert_with(Box::default)
1203 .append(other.0.get_or_insert_with(Box::default));
1204 if other.is_empty() {
1205 other.0 = None;
1206 }
1207 }
1208}
1209
1210impl std::ops::Deref for FastDiagnostics {
1211 type Target = [ParserDiagnostic];
1212
1213 fn deref(&self) -> &Self::Target {
1214 self.as_slice()
1215 }
1216}
1217
1218#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
1227enum NodeList {
1228 #[default]
1229 Empty,
1230 One(Rc<FastRecognizedNode>),
1231 Cons {
1232 head: Rc<FastRecognizedNode>,
1233 tail: Rc<Self>,
1234 },
1235}
1236
1237impl NodeList {
1238 const fn new() -> Self {
1240 Self::Empty
1241 }
1242
1243 fn cons(self, node: Rc<FastRecognizedNode>) -> Self {
1246 match self {
1247 Self::Empty => Self::One(node),
1248 existing @ (Self::One(_) | Self::Cons { .. }) => Self::Cons {
1249 head: node,
1250 tail: Rc::new(existing),
1251 },
1252 }
1253 }
1254
1255 fn prepend(&mut self, node: Rc<FastRecognizedNode>) {
1258 let owned = std::mem::take(self);
1259 *self = owned.cons(node);
1260 }
1261
1262 fn to_vec(&self) -> Vec<Rc<FastRecognizedNode>> {
1267 let mut out = Vec::new();
1268 let mut cursor = self;
1269 loop {
1270 match cursor {
1271 Self::Empty => break,
1272 Self::One(node) => {
1273 out.push(Rc::clone(node));
1274 break;
1275 }
1276 Self::Cons { head, tail } => {
1277 out.push(Rc::clone(head));
1278 cursor = tail.as_ref();
1279 }
1280 }
1281 }
1282 out
1283 }
1284
1285 const fn iter(&self) -> NodeListIter<'_> {
1286 NodeListIter { cursor: self }
1287 }
1288
1289 fn len(&self) -> usize {
1290 self.iter().count()
1291 }
1292
1293 fn has_left_recursive_boundary(&self) -> bool {
1294 self.iter()
1295 .any(|node| fast_node_has_left_recursive_boundary(node.as_ref()))
1296 }
1297
1298 fn has_explicit_token_node(&self) -> bool {
1299 self.iter().any(|node| {
1300 matches!(
1301 node.as_ref(),
1302 FastRecognizedNode::Token { .. }
1303 | FastRecognizedNode::ErrorToken { .. }
1304 | FastRecognizedNode::MissingToken { .. }
1305 )
1306 })
1307 }
1308
1309 fn from_vec(nodes: Vec<Rc<FastRecognizedNode>>) -> Self {
1311 let mut list = Self::new();
1312 for node in nodes.into_iter().rev() {
1313 list.prepend(node);
1314 }
1315 list
1316 }
1317}
1318
1319struct NodeListIter<'a> {
1320 cursor: &'a NodeList,
1321}
1322
1323impl<'a> Iterator for NodeListIter<'a> {
1324 type Item = &'a Rc<FastRecognizedNode>;
1325
1326 fn next(&mut self) -> Option<Self::Item> {
1327 match self.cursor {
1328 NodeList::Empty => None,
1329 NodeList::One(node) => {
1330 self.cursor = &NodeList::Empty;
1331 Some(node)
1332 }
1333 NodeList::Cons { head, tail } => {
1334 self.cursor = tail.as_ref();
1335 Some(head)
1336 }
1337 }
1338 }
1339}
1340
1341#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1345enum FastRecognizedNode {
1346 Token {
1347 index: usize,
1348 },
1349 ErrorToken {
1350 index: usize,
1351 },
1352 MissingToken {
1353 token_type: i32,
1354 at_index: usize,
1355 text: String,
1356 },
1357 Rule {
1358 rule_index: usize,
1359 invoking_state: isize,
1360 start_index: usize,
1361 stop_index: Option<usize>,
1362 children: NodeList,
1363 },
1364 LeftRecursiveBoundary {
1368 rule_index: usize,
1369 },
1370}
1371
1372#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1373struct ParserDiagnostic {
1374 line: usize,
1375 column: usize,
1376 message: String,
1377}
1378
1379#[derive(Clone, Debug, Default, Eq, PartialEq)]
1380struct ExpectedTokens {
1381 index: Option<usize>,
1382 symbols: BTreeSet<i32>,
1383 no_viable: Option<NoViableAlternative>,
1384}
1385
1386#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1387struct NoViableAlternative {
1388 start_index: usize,
1389 error_index: usize,
1390}
1391
1392impl ExpectedTokens {
1393 fn record_transition(&mut self, index: usize, transition: &Transition, max_token_type: i32) {
1396 let symbols = transition_expected_symbols(transition, max_token_type);
1397 match self.index {
1398 Some(current) if index < current => {}
1399 Some(current) if index == current => self.symbols.extend(symbols),
1400 _ => {
1401 self.index = Some(index);
1402 self.symbols = symbols;
1403 }
1404 }
1405 }
1406
1407 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
1410 match self.no_viable {
1411 Some(current) if error_index < current.error_index => {}
1412 _ => {
1413 self.no_viable = Some(NoViableAlternative {
1414 start_index,
1415 error_index,
1416 });
1417 }
1418 }
1419 }
1420}
1421
1422#[derive(Clone, Debug, Default, Eq, PartialEq)]
1429struct TokenBitSet {
1430 words: Vec<u64>,
1431}
1432
1433impl TokenBitSet {
1434 fn insert(&mut self, symbol: i32) {
1435 let Some(slot) = token_bit_slot(symbol) else {
1436 return;
1437 };
1438 let word = slot / u64::BITS as usize;
1439 if word >= self.words.len() {
1440 self.words.resize(word + 1, 0);
1441 }
1442 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
1443 }
1444
1445 fn extend_range(&mut self, start: i32, stop: i32) {
1446 let (start, stop) = if start <= stop {
1447 (start, stop)
1448 } else {
1449 (stop, start)
1450 };
1451 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
1452 self.insert(TOKEN_EOF);
1453 }
1454 let positive_start = start.max(1);
1455 if positive_start > stop {
1456 return;
1457 }
1458 let Some(start_slot) = token_bit_slot(positive_start) else {
1459 return;
1460 };
1461 let Some(stop_slot) = token_bit_slot(stop) else {
1462 return;
1463 };
1464 self.extend_slot_range(start_slot, stop_slot);
1465 }
1466
1467 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
1468 if start_slot > stop_slot {
1469 return;
1470 }
1471 let start_word = start_slot / u64::BITS as usize;
1472 let stop_word = stop_slot / u64::BITS as usize;
1473 if stop_word >= self.words.len() {
1474 self.words.resize(stop_word + 1, 0);
1475 }
1476 let start_offset = start_slot % u64::BITS as usize;
1477 let stop_offset = stop_slot % u64::BITS as usize;
1478 if start_word == stop_word {
1479 self.words[start_word] |=
1480 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
1481 return;
1482 }
1483 self.words[start_word] |= !0_u64 << start_offset;
1484 for word in &mut self.words[(start_word + 1)..stop_word] {
1485 *word = !0_u64;
1486 }
1487 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
1488 }
1489
1490 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
1491 for symbol in symbols {
1492 self.insert(symbol);
1493 }
1494 }
1495
1496 fn extend_from(&mut self, other: &Self) {
1497 if other.words.len() > self.words.len() {
1498 self.words.resize(other.words.len(), 0);
1499 }
1500 for (left, right) in self.words.iter_mut().zip(&other.words) {
1501 *left |= *right;
1502 }
1503 }
1504
1505 fn contains(&self, symbol: i32) -> bool {
1506 let Some(slot) = token_bit_slot(symbol) else {
1507 return false;
1508 };
1509 let word = slot / u64::BITS as usize;
1510 self.words
1511 .get(word)
1512 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
1513 }
1514
1515 fn is_empty(&self) -> bool {
1516 self.words.iter().all(|word| *word == 0)
1517 }
1518
1519 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
1520 for (word_index, word) in self.words.iter().copied().enumerate() {
1521 let mut bits = word;
1522 while bits != 0 {
1523 let bit = bits.trailing_zeros() as usize;
1524 if let Some(symbol) = token_bit_symbol(word_index * u64::BITS as usize + bit) {
1525 target.insert(symbol);
1526 }
1527 bits &= bits - 1;
1528 }
1529 }
1530 }
1531
1532 fn to_btree_set(&self) -> BTreeSet<i32> {
1533 let mut out = BTreeSet::new();
1534 self.extend_btree_set(&mut out);
1535 out
1536 }
1537}
1538
1539fn token_bit_slot(symbol: i32) -> Option<usize> {
1540 if symbol == TOKEN_EOF {
1541 Some(0)
1542 } else if symbol > 0 {
1543 usize::try_from(symbol).ok()
1544 } else {
1545 None
1546 }
1547}
1548
1549fn token_bit_symbol(slot: usize) -> Option<i32> {
1550 if slot == 0 {
1551 Some(TOKEN_EOF)
1552 } else {
1553 i32::try_from(slot).ok()
1554 }
1555}
1556
1557fn transition_expected_symbols(transition: &Transition, max_token_type: i32) -> BTreeSet<i32> {
1560 let mut symbols = BTreeSet::new();
1561 match transition {
1562 Transition::Atom { label, .. } => {
1563 symbols.insert(*label);
1564 }
1565 Transition::Range { start, stop, .. } => {
1566 symbols.extend(*start..=*stop);
1567 }
1568 Transition::Set { set, .. } => {
1569 for (start, stop) in set.ranges() {
1570 symbols.extend(*start..=*stop);
1571 }
1572 }
1573 Transition::NotSet { set, .. } => {
1574 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
1575 }
1576 Transition::Wildcard { .. } => {
1577 symbols.extend(1..=max_token_type);
1578 }
1579 Transition::Epsilon { .. }
1580 | Transition::Rule { .. }
1581 | Transition::Predicate { .. }
1582 | Transition::Action { .. }
1583 | Transition::Precedence { .. } => {}
1584 }
1585 symbols
1586}
1587
1588fn transition_expected_token_set(transition: &Transition, max_token_type: i32) -> TokenBitSet {
1589 let mut symbols = TokenBitSet::default();
1590 match transition {
1591 Transition::Atom { label, .. } => {
1592 symbols.insert(*label);
1593 }
1594 Transition::Range { start, stop, .. } => {
1595 symbols.extend_range(*start, *stop);
1596 }
1597 Transition::Set { set, .. } => {
1598 for (start, stop) in set.ranges() {
1599 symbols.extend_range(*start, *stop);
1600 }
1601 }
1602 Transition::NotSet { set, .. } => {
1603 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
1604 }
1605 Transition::Wildcard { .. } => {
1606 symbols.extend_range(1, max_token_type);
1607 }
1608 Transition::Epsilon { .. }
1609 | Transition::Rule { .. }
1610 | Transition::Predicate { .. }
1611 | Transition::Action { .. }
1612 | Transition::Precedence { .. } => {}
1613 }
1614 symbols
1615}
1616
1617fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
1621 let mut symbols = BTreeSet::new();
1622 let mut stack = vec![state_number];
1623 let mut visited = BTreeSet::new();
1624 while let Some(current) = stack.pop() {
1625 if !visited.insert(current) {
1626 continue;
1627 }
1628 let Some(state) = atn.state(current) else {
1629 continue;
1630 };
1631 for transition in &state.transitions {
1632 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1633 if transition_symbols.is_empty() {
1634 if transition.is_epsilon() {
1635 stack.push(transition.target());
1636 }
1637 } else {
1638 symbols.extend(transition_symbols);
1639 }
1640 }
1641 }
1642 symbols
1643}
1644
1645fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
1646 let mut symbols = TokenBitSet::default();
1647 let mut stack = vec![state_number];
1648 let mut visited = BTreeSet::new();
1649 while let Some(current) = stack.pop() {
1650 if !visited.insert(current) {
1651 continue;
1652 }
1653 let Some(state) = atn.state(current) else {
1654 continue;
1655 };
1656 for transition in &state.transitions {
1657 let transition_symbols =
1658 transition_expected_token_set(transition, atn.max_token_type());
1659 if transition_symbols.is_empty() {
1660 if transition.is_epsilon() {
1661 stack.push(transition.target());
1662 }
1663 } else {
1664 symbols.extend_from(&transition_symbols);
1665 }
1666 }
1667 }
1668 symbols
1669}
1670
1671fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
1672 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
1673 return false;
1674 };
1675 let Some(&stop_state) = atn.rule_to_stop_state().get(rule_index) else {
1676 return false;
1677 };
1678 epsilon_reaches_state(atn, state_number, stop_state)
1679}
1680
1681fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
1682 let mut stack = vec![start];
1683 let mut visited = BTreeSet::new();
1684 while let Some(current) = stack.pop() {
1685 if current == target {
1686 return true;
1687 }
1688 if !visited.insert(current) {
1689 continue;
1690 }
1691 let Some(state) = atn.state(current) else {
1692 continue;
1693 };
1694 stack.extend(
1695 state
1696 .transitions
1697 .iter()
1698 .filter(|transition| transition.is_epsilon())
1699 .map(Transition::target),
1700 );
1701 }
1702 false
1703}
1704
1705#[derive(Clone, Debug, Default, Eq, PartialEq)]
1712struct FirstSet {
1713 symbols: TokenBitSet,
1714 nullable: bool,
1715}
1716
1717type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
1724
1725type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
1732
1733#[derive(Default)]
1734struct SharedAtnCache {
1735 first_set: FirstSetCache,
1736 decision_lookahead: DecisionLookaheadCache,
1737 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
1738 rule_stop_reach: FxHashMap<usize, bool>,
1739 observable_action_transitions: Option<bool>,
1740 predicate_transitions: Option<bool>,
1741}
1742
1743thread_local! {
1744 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
1745 RefCell::new(FxHashMap::default());
1746}
1747
1748#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1759struct SharedAtnCacheKey {
1760 atn: usize,
1761 states: usize,
1762 state_count: usize,
1763 max_token_type: i32,
1764}
1765
1766impl SharedAtnCacheKey {
1767 fn for_atn(atn: &Atn) -> Self {
1768 Self {
1769 atn: std::ptr::from_ref::<Atn>(atn) as usize,
1770 states: atn.states().as_ptr() as usize,
1771 state_count: atn.states().len(),
1772 max_token_type: atn.max_token_type(),
1773 }
1774 }
1775}
1776
1777fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
1778 SHARED_ATN_CACHES.with(|cell| {
1779 let key = SharedAtnCacheKey::for_atn(atn);
1780 let mut map = cell.borrow_mut();
1781 let cache = map.entry(key).or_default();
1782 f(&mut cache.first_set)
1783 })
1784}
1785
1786fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
1787 SHARED_ATN_CACHES.with(|cell| {
1788 let key = SharedAtnCacheKey::for_atn(atn);
1789 let mut map = cell.borrow_mut();
1790 let cache = map.entry(key).or_default();
1791 f(cache)
1792 })
1793}
1794
1795#[derive(Debug, Default)]
1804struct DecisionLookahead {
1805 transitions: Vec<TransitionLookSet>,
1806}
1807
1808#[derive(Clone, Debug, Default)]
1815struct TransitionLookSet {
1816 symbols: TokenBitSet,
1817 nullable: bool,
1818}
1819
1820struct FirstSetCtx<'a> {
1824 cache: &'a mut FirstSetCache,
1825 in_progress: BTreeSet<(usize, usize)>,
1826 hit_cycle: bool,
1827}
1828
1829fn rule_first_set(
1838 atn: &Atn,
1839 target: usize,
1840 rule_stop_state: usize,
1841 cache: &mut FirstSetCache,
1842) -> Rc<FirstSet> {
1843 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
1844 return Rc::clone(cached);
1845 }
1846 let mut ctx = FirstSetCtx {
1847 cache,
1848 in_progress: BTreeSet::new(),
1849 hit_cycle: false,
1850 };
1851 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
1852}
1853
1854fn rule_first_set_cached(
1855 atn: &Atn,
1856 target: usize,
1857 rule_stop_state: usize,
1858 ctx: &mut FirstSetCtx<'_>,
1859) -> Rc<FirstSet> {
1860 let key = (target, rule_stop_state);
1861 if let Some(cached) = ctx.cache.get(&key) {
1862 return Rc::clone(cached);
1863 }
1864 if !ctx.in_progress.insert(key) {
1865 return Rc::new(FirstSet::default());
1869 }
1870 let saved_hit_cycle = ctx.hit_cycle;
1871 ctx.hit_cycle = false;
1872 let mut first = FirstSet::default();
1873 let mut visited = BTreeSet::new();
1874 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
1875 ctx.in_progress.remove(&key);
1876 let entry = Rc::new(first);
1877 if !ctx.hit_cycle {
1878 ctx.cache.insert(key, Rc::clone(&entry));
1879 }
1880 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
1881 entry
1882}
1883
1884fn transition_first_set(
1888 atn: &Atn,
1889 transition: &Transition,
1890 rule_stop_state: usize,
1891 cache: &mut FirstSetCache,
1892) -> TransitionLookSet {
1893 match transition {
1894 Transition::Atom { label, .. } => {
1895 let mut symbols = TokenBitSet::default();
1896 symbols.insert(*label);
1897 TransitionLookSet {
1898 symbols,
1899 nullable: false,
1900 }
1901 }
1902 Transition::Range { start, stop, .. } => {
1903 let mut symbols = TokenBitSet::default();
1904 symbols.extend_range(*start, *stop);
1905 TransitionLookSet {
1906 symbols,
1907 nullable: false,
1908 }
1909 }
1910 Transition::Set { set, .. } => {
1911 let mut symbols = TokenBitSet::default();
1912 for (start, stop) in set.ranges() {
1913 symbols.extend_range(*start, *stop);
1914 }
1915 TransitionLookSet {
1916 symbols,
1917 nullable: false,
1918 }
1919 }
1920 Transition::NotSet { set, .. } => {
1921 let max = atn.max_token_type();
1922 let mut symbols = TokenBitSet::default();
1923 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
1924 TransitionLookSet {
1925 symbols,
1926 nullable: false,
1927 }
1928 }
1929 Transition::Wildcard { .. } => {
1930 let mut symbols = TokenBitSet::default();
1931 symbols.extend_range(1, atn.max_token_type());
1932 TransitionLookSet {
1933 symbols,
1934 nullable: false,
1935 }
1936 }
1937 Transition::Epsilon { target }
1938 | Transition::Action { target, .. }
1939 | Transition::Predicate { target, .. }
1940 | Transition::Precedence { target, .. } => {
1941 let first = rule_first_set(atn, *target, rule_stop_state, cache);
1944 TransitionLookSet {
1945 symbols: first.symbols.clone(),
1946 nullable: first.nullable,
1947 }
1948 }
1949 Transition::Rule {
1950 target,
1951 rule_index,
1952 follow_state,
1953 ..
1954 } => {
1955 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
1956 return TransitionLookSet::default();
1957 };
1958 let child = rule_first_set(atn, *target, child_stop, cache);
1959 let mut symbols = child.symbols.clone();
1960 let nullable = if child.nullable {
1961 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
1962 symbols.extend_from(&follow.symbols);
1963 follow.nullable
1964 } else {
1965 false
1966 };
1967 TransitionLookSet { symbols, nullable }
1968 }
1969 }
1970}
1971
1972fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
1993 let mut chosen: Option<usize> = None;
1994 for (index, transition) in entry.transitions.iter().enumerate() {
1995 if transition.nullable {
1996 return None;
1997 }
1998 if transition.symbols.contains(symbol) {
1999 if chosen.is_some() {
2000 return None;
2001 }
2002 chosen = Some(index);
2003 }
2004 }
2005 chosen
2006}
2007
2008fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2017 let mut matching_non_nullable_alt = None;
2018 let mut nullable_alt = None;
2019 for (index, transition) in entry.transitions.iter().enumerate() {
2020 if transition.nullable {
2021 if nullable_alt.is_some() {
2022 return None;
2023 }
2024 nullable_alt = Some(index);
2025 }
2026 if transition.symbols.contains(symbol) {
2027 if transition.nullable {
2028 continue;
2029 }
2030 if matching_non_nullable_alt.is_some() {
2031 return None;
2032 }
2033 matching_non_nullable_alt = Some(index);
2034 }
2035 }
2036 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2037 return None;
2038 }
2039 if non_greedy {
2040 nullable_alt.or(matching_non_nullable_alt)
2041 } else {
2042 matching_non_nullable_alt.or(nullable_alt)
2043 }
2044}
2045
2046fn should_skip_via_lookahead(
2047 transition: &Transition,
2048 transition_index: usize,
2049 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2050 index: usize,
2051 record_expected: bool,
2052 expected: &mut ExpectedTokens,
2053) -> bool {
2054 let prune_non_consuming = matches!(
2055 transition,
2056 Transition::Epsilon { .. }
2057 | Transition::Action { .. }
2058 | Transition::Predicate { .. }
2059 | Transition::Rule { .. }
2060 | Transition::Precedence { .. }
2061 );
2062 if !prune_non_consuming {
2063 return false;
2064 }
2065 let Some((symbol, entry)) = lookahead_filter else {
2066 return false;
2067 };
2068 let Some(set) = entry.transitions.get(transition_index) else {
2069 return false;
2070 };
2071 if set.symbols.contains(*symbol) || set.nullable {
2072 return false;
2073 }
2074 if record_expected && !set.symbols.is_empty() {
2075 record_pruned_transition_expected(set, index, expected);
2076 }
2077 true
2078}
2079
2080fn should_skip_rule_via_first_set(
2081 first: &FirstSet,
2082 symbol: i32,
2083 record_expected: bool,
2084 index: usize,
2085 expected: &mut ExpectedTokens,
2086) -> bool {
2087 if first.nullable || first.symbols.contains(symbol) {
2088 return false;
2089 }
2090 if record_expected && !first.symbols.is_empty() {
2091 record_token_bit_expected(&first.symbols, index, expected);
2092 }
2093 true
2094}
2095
2096fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2097 match expected.index {
2098 Some(current) if index < current => {}
2099 Some(current) if index == current => {
2100 symbols.extend_btree_set(&mut expected.symbols);
2101 }
2102 _ => {
2103 expected.index = Some(index);
2104 expected.symbols = symbols.to_btree_set();
2105 }
2106 }
2107}
2108
2109fn record_pruned_transition_expected(
2111 set: &TransitionLookSet,
2112 index: usize,
2113 expected: &mut ExpectedTokens,
2114) {
2115 match expected.index {
2116 Some(current) if index < current => {}
2117 Some(current) if index == current => {
2118 set.symbols.extend_btree_set(&mut expected.symbols);
2119 }
2120 _ => {
2121 expected.index = Some(index);
2122 expected.symbols = set.symbols.to_btree_set();
2123 }
2124 }
2125}
2126
2127fn rule_first_set_inner(
2128 atn: &Atn,
2129 state_number: usize,
2130 rule_stop_state: usize,
2131 ctx: &mut FirstSetCtx<'_>,
2132 visited: &mut BTreeSet<usize>,
2133 first: &mut FirstSet,
2134) {
2135 if !visited.insert(state_number) {
2136 return;
2137 }
2138 if state_number == rule_stop_state {
2139 first.nullable = true;
2140 return;
2141 }
2142 let Some(state) = atn.state(state_number) else {
2143 return;
2144 };
2145 for transition in &state.transitions {
2146 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2147 if !transition_symbols.is_empty() {
2148 first.symbols.extend_iter(transition_symbols);
2149 continue;
2150 }
2151 match transition {
2152 Transition::Epsilon { target }
2153 | Transition::Action { target, .. }
2154 | Transition::Predicate { target, .. }
2155 | Transition::Precedence { target, .. } => {
2156 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2157 }
2158 Transition::Rule {
2159 target,
2160 rule_index,
2161 follow_state,
2162 ..
2163 } => {
2164 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
2165 continue;
2166 };
2167 let child_key = (*target, child_stop);
2168 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2169 ctx.hit_cycle = true;
2170 }
2171 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2172 first.symbols.extend_from(&child.symbols);
2173 if child.nullable {
2174 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2175 }
2176 }
2177 Transition::Atom { .. }
2178 | Transition::Range { .. }
2179 | Transition::Set { .. }
2180 | Transition::NotSet { .. }
2181 | Transition::Wildcard { .. } => {}
2182 }
2183 }
2184}
2185
2186fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2189 let mut symbols = BTreeSet::new();
2190 state_sync_symbols_inner(
2191 atn,
2192 state_number,
2193 stop_state,
2194 &mut BTreeSet::new(),
2195 &mut symbols,
2196 );
2197 symbols
2198}
2199
2200fn state_sync_symbols_inner(
2203 atn: &Atn,
2204 state_number: usize,
2205 stop_state: usize,
2206 visited: &mut BTreeSet<usize>,
2207 symbols: &mut BTreeSet<i32>,
2208) {
2209 if !visited.insert(state_number) {
2210 return;
2211 }
2212 if state_number == stop_state {
2213 symbols.insert(TOKEN_EOF);
2214 return;
2215 }
2216 let Some(state) = atn.state(state_number) else {
2217 return;
2218 };
2219 for transition in &state.transitions {
2220 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2221 if transition_symbols.is_empty() {
2222 match transition {
2223 Transition::Rule { target, .. }
2224 | Transition::Epsilon { target }
2225 | Transition::Action { target, .. }
2226 | Transition::Predicate { target, .. }
2227 | Transition::Precedence { target, .. } => {
2228 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
2229 }
2230 Transition::Atom { .. }
2231 | Transition::Range { .. }
2232 | Transition::Set { .. }
2233 | Transition::NotSet { .. }
2234 | Transition::Wildcard { .. } => {}
2235 }
2236 } else {
2237 symbols.extend(transition_symbols);
2238 }
2239 }
2240}
2241
2242fn state_can_reach_symbol_with_precedence(
2243 atn: &Atn,
2244 state_number: usize,
2245 symbol: i32,
2246 precedence: i32,
2247 visited: &mut BTreeSet<usize>,
2248) -> bool {
2249 if !visited.insert(state_number) {
2250 return false;
2251 }
2252 let Some(state) = atn.state(state_number) else {
2253 return false;
2254 };
2255 state.transitions.iter().any(|transition| {
2256 if transition.matches(symbol, 1, atn.max_token_type()) {
2257 return true;
2258 }
2259 if !transition.is_epsilon() {
2260 return false;
2261 }
2262 if matches!(
2263 transition,
2264 Transition::Precedence {
2265 precedence: transition_precedence,
2266 ..
2267 } if *transition_precedence < precedence
2268 ) {
2269 return false;
2270 }
2271 state_can_reach_symbol_with_precedence(
2272 atn,
2273 transition.target(),
2274 symbol,
2275 precedence,
2276 visited,
2277 )
2278 })
2279}
2280
2281fn context_can_match_symbol_before_state(
2282 atn: &Atn,
2283 context: &PredictionContext,
2284 stop_state_number: usize,
2285 symbol: i32,
2286) -> bool {
2287 (0..context.len()).any(|index| {
2288 context.return_state(index).is_some_and(|return_state| {
2289 let parent = context
2290 .parent(index)
2291 .unwrap_or_else(PredictionContext::empty);
2292 state_or_parent_can_match_symbol_before_state(
2293 atn,
2294 return_state,
2295 &parent,
2296 stop_state_number,
2297 symbol,
2298 &mut BTreeSet::new(),
2299 )
2300 })
2301 })
2302}
2303
2304fn state_or_parent_can_match_symbol_before_state(
2305 atn: &Atn,
2306 state_number: usize,
2307 parent: &Rc<PredictionContext>,
2308 stop_state_number: usize,
2309 symbol: i32,
2310 visited: &mut BTreeSet<usize>,
2311) -> bool {
2312 if state_number == EMPTY_RETURN_STATE {
2313 return false;
2314 }
2315 if state_number == stop_state_number {
2316 return context_can_match_symbol_before_state(atn, parent, stop_state_number, symbol);
2317 }
2318 if !visited.insert(state_number) {
2319 return false;
2320 }
2321 let Some(state) = atn.state(state_number) else {
2322 return false;
2323 };
2324 state.transitions.iter().any(|transition| {
2325 if transition.matches(symbol, 1, atn.max_token_type()) {
2326 return true;
2327 }
2328 transition.is_epsilon()
2329 && state_or_parent_can_match_symbol_before_state(
2330 atn,
2331 transition.target(),
2332 parent,
2333 stop_state_number,
2334 symbol,
2335 visited,
2336 )
2337 })
2338}
2339
2340fn next_recovery_context(
2344 atn: &Atn,
2345 state: &AtnState,
2346 inherited: &BTreeSet<i32>,
2347 inherited_state: Option<usize>,
2348) -> (BTreeSet<i32>, Option<usize>) {
2349 let state_symbols = state_expected_symbols(atn, state.state_number);
2350 if state.transitions.len() > 1 && !state_symbols.is_empty() {
2351 let mut symbols = state_symbols;
2352 symbols.extend(inherited.iter().copied());
2353 return (symbols, Some(state.state_number));
2354 }
2355 (inherited.clone(), inherited_state)
2356}
2357
2358fn recovery_expected_symbols(
2359 atn: &Atn,
2360 state_number: usize,
2361 inherited: &BTreeSet<i32>,
2362) -> BTreeSet<i32> {
2363 let mut symbols = state_expected_symbols(atn, state_number);
2364 symbols.extend(inherited.iter().copied());
2365 symbols
2366}
2367
2368fn fast_next_recovery_context<S, H>(
2372 parser: &mut BaseParser<S, H>,
2373 atn: &Atn,
2374 state: &AtnState,
2375 inherited: &Rc<BTreeSet<i32>>,
2376 inherited_state: Option<usize>,
2377) -> (Rc<BTreeSet<i32>>, Option<usize>)
2378where
2379 S: TokenSource,
2380 H: SemanticHooks,
2381{
2382 if state.transitions.len() <= 1 {
2383 return (Rc::clone(inherited), inherited_state);
2384 }
2385 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number);
2386 if state_symbols.is_empty() {
2387 return (Rc::clone(inherited), inherited_state);
2388 }
2389 if inherited.is_empty() {
2390 return (state_symbols, Some(state.state_number));
2391 }
2392 if Rc::ptr_eq(&state_symbols, inherited) {
2393 return (state_symbols, Some(state.state_number));
2394 }
2395 let mut combined = (*state_symbols).clone();
2396 combined.extend(inherited.iter().copied());
2397 (
2398 parser.intern_recovery_symbols(combined),
2399 Some(state.state_number),
2400 )
2401}
2402
2403fn fast_recovery_expected_symbols<S, H>(
2407 parser: &mut BaseParser<S, H>,
2408 atn: &Atn,
2409 state_number: usize,
2410 inherited: &Rc<BTreeSet<i32>>,
2411) -> Rc<BTreeSet<i32>>
2412where
2413 S: TokenSource,
2414 H: SemanticHooks,
2415{
2416 let cached = parser.cached_state_expected_symbols(atn, state_number);
2417 if inherited.is_empty() {
2418 return cached;
2419 }
2420 if cached.is_empty() {
2421 return Rc::clone(inherited);
2422 }
2423 if Rc::ptr_eq(&cached, inherited) {
2424 return cached;
2425 }
2426 let mut combined = (*cached).clone();
2427 combined.extend(inherited.iter().copied());
2428 parser.intern_recovery_symbols(combined)
2429}
2430
2431struct ParserTableSemCtx<'a> {
2432 member_values: &'a mut BTreeMap<usize, i64>,
2433 return_values: &'a mut BTreeMap<String, i64>,
2434}
2435
2436impl semir::PredContext for ParserTableSemCtx<'_> {
2437 fn la(&mut self, _offset: isize) -> i64 {
2438 i64::from(TOKEN_EOF)
2439 }
2440
2441 fn token_text(&mut self, _offset: isize) -> Option<&str> {
2442 None
2443 }
2444
2445 fn token_index_adjacent(&mut self) -> bool {
2446 false
2447 }
2448
2449 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
2450 None
2451 }
2452
2453 fn member(&self, member: usize) -> Option<i64> {
2454 Some(self.member_values.get(&member).copied().unwrap_or_default())
2455 }
2456
2457 fn local_arg(&self) -> Option<i64> {
2458 None
2459 }
2460
2461 fn column(&self) -> Option<i64> {
2462 None
2463 }
2464
2465 fn token_start_column(&self) -> Option<i64> {
2466 None
2467 }
2468
2469 fn token_text_so_far(&self) -> Option<String> {
2470 None
2471 }
2472
2473 fn hook(&mut self, _hook: HookId) -> bool {
2474 false
2475 }
2476}
2477
2478impl semir::ActContext for ParserTableSemCtx<'_> {
2479 fn set_member(&mut self, member: usize, value: i64) {
2480 self.member_values.insert(member, value);
2481 }
2482
2483 fn set_return(&mut self, name: &str, value: i64) {
2484 self.return_values.insert(name.to_owned(), value);
2485 }
2486
2487 fn action_hook(&mut self, _hook: HookId) {}
2488}
2489
2490fn apply_member_actions(
2492 source_state: usize,
2493 actions: &[ParserMemberAction],
2494 semantics: Option<&ParserSemantics>,
2495 values: &mut BTreeMap<usize, i64>,
2496) {
2497 for action in actions
2498 .iter()
2499 .filter(|action| action.source_state == source_state)
2500 {
2501 *values.entry(action.member).or_default() += action.delta;
2502 }
2503 let Some(semantics) = semantics else {
2504 return;
2505 };
2506 let mut return_values = BTreeMap::new();
2507 let mut ctx = ParserTableSemCtx {
2508 member_values: values,
2509 return_values: &mut return_values,
2510 };
2511 for action in semantics
2512 .actions
2513 .iter()
2514 .filter(|action| action.source_state == source_state && action.speculative)
2515 {
2516 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
2517 }
2518}
2519
2520fn member_values_after_action(
2522 source_state: usize,
2523 actions: &[ParserMemberAction],
2524 semantics: Option<&ParserSemantics>,
2525 values: &BTreeMap<usize, i64>,
2526) -> BTreeMap<usize, i64> {
2527 let mut values = values.clone();
2528 apply_member_actions(source_state, actions, semantics, &mut values);
2529 values
2530}
2531
2532fn return_values_after_action(
2534 source_state: usize,
2535 rule_index: usize,
2536 actions: &[ParserReturnAction],
2537 semantics: Option<&ParserSemantics>,
2538 values: &BTreeMap<String, i64>,
2539) -> BTreeMap<String, i64> {
2540 let mut values = values.clone();
2541 for action in actions
2542 .iter()
2543 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
2544 {
2545 values.insert(action.name.to_owned(), action.value);
2546 }
2547 if let Some(semantics) = semantics {
2548 let mut member_values = BTreeMap::new();
2549 let mut ctx = ParserTableSemCtx {
2550 member_values: &mut member_values,
2551 return_values: &mut values,
2552 };
2553 for action in semantics.actions.iter().filter(|action| {
2554 action.source_state == source_state
2555 && action.rule_index == rule_index
2556 && !action.speculative
2557 }) {
2558 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
2559 }
2560 }
2561 values
2562}
2563
2564fn rule_local_int_arg(
2566 rule_args: &[ParserRuleArg],
2567 source_state: usize,
2568 rule_index: usize,
2569 local_int_arg: Option<(usize, i64)>,
2570) -> Option<(usize, i64)> {
2571 rule_args
2572 .iter()
2573 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
2574 .map(|arg| {
2575 let value = if arg.inherit_local {
2576 local_int_arg.map_or(arg.value, |(_, value)| value)
2577 } else {
2578 arg.value
2579 };
2580 (rule_index, value)
2581 })
2582}
2583
2584fn stop_outcome(
2587 index: usize,
2588 consumed_eof: bool,
2589 rule_alt_number: usize,
2590 member_values: BTreeMap<usize, i64>,
2591 return_values: BTreeMap<String, i64>,
2592) -> Vec<RecognizeOutcome> {
2593 vec![RecognizeOutcome {
2594 index,
2595 consumed_eof,
2596 alt_number: rule_alt_number,
2597 member_values,
2598 return_values,
2599 diagnostics: Vec::new(),
2600 decisions: Vec::new(),
2601 actions: Vec::new(),
2602 nodes: Vec::new(),
2603 }]
2604}
2605
2606fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
2607 with_shared_atn_caches(atn, |cache| {
2608 *cache.observable_action_transitions.get_or_insert_with(|| {
2609 atn.states().iter().any(|state| {
2610 state.transitions.iter().any(|transition| {
2611 matches!(
2612 transition,
2613 Transition::Action {
2614 action_index: Some(_),
2615 ..
2616 }
2617 )
2618 })
2619 })
2620 })
2621 })
2622}
2623
2624fn atn_has_predicate_transitions(atn: &Atn) -> bool {
2625 with_shared_atn_caches(atn, |cache| {
2626 *cache.predicate_transitions.get_or_insert_with(|| {
2627 atn.states().iter().any(|state| {
2628 state
2629 .transitions
2630 .iter()
2631 .any(|transition| matches!(transition, Transition::Predicate { .. }))
2632 })
2633 })
2634 })
2635}
2636
2637#[derive(Clone, Debug, Eq, PartialEq)]
2638struct RecognizeRequest<'a> {
2639 state_number: usize,
2640 stop_state: usize,
2641 index: usize,
2642 rule_start_index: usize,
2643 decision_start_index: Option<usize>,
2644 init_action_rules: &'a BTreeSet<usize>,
2645 predicates: &'a [(usize, usize, ParserPredicate)],
2646 semantics: Option<&'a ParserSemantics>,
2647 rule_args: &'a [ParserRuleArg],
2648 member_actions: &'a [ParserMemberAction],
2649 return_actions: &'a [ParserReturnAction],
2650 local_int_arg: Option<(usize, i64)>,
2651 member_values: BTreeMap<usize, i64>,
2652 return_values: BTreeMap<String, i64>,
2653 rule_alt_number: usize,
2654 track_alt_numbers: bool,
2655 consumed_eof: bool,
2656 precedence: i32,
2659 depth: usize,
2660 recovery_symbols: BTreeSet<i32>,
2661 recovery_state: Option<usize>,
2662}
2663
2664#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2665struct RecognizeKey {
2666 state_number: usize,
2667 stop_state: usize,
2668 index: usize,
2669 rule_start_index: usize,
2670 decision_start_index: Option<usize>,
2671 local_int_arg: Option<(usize, i64)>,
2672 member_values: BTreeMap<usize, i64>,
2673 return_values: BTreeMap<String, i64>,
2674 rule_alt_number: usize,
2675 track_alt_numbers: bool,
2676 consumed_eof: bool,
2677 precedence: i32,
2678 recovery_symbols: BTreeSet<i32>,
2679 recovery_state: Option<usize>,
2680}
2681
2682#[derive(Clone, Debug, Eq, PartialEq)]
2683struct EpsilonActionStep {
2684 source_state: usize,
2685 target: usize,
2686 action_rule_index: Option<usize>,
2687 left_recursive_boundary: Option<usize>,
2688 decision: Option<usize>,
2689 decision_start_index: Option<usize>,
2690 alt_number: usize,
2691 recovery_symbols: BTreeSet<i32>,
2692 recovery_state: Option<usize>,
2693}
2694
2695struct RecognizeScratch<'a> {
2696 visiting: &'a mut BTreeSet<RecognizeKey>,
2697 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2698 expected: &'a mut ExpectedTokens,
2699}
2700
2701#[derive(Clone, Debug, Eq, PartialEq)]
2702struct FastRecognizeRequest {
2703 state_number: usize,
2704 stop_state: usize,
2705 index: usize,
2706 rule_start_index: usize,
2707 decision_start_index: Option<usize>,
2708 precedence: i32,
2709 depth: usize,
2710 recovery_symbols: Rc<BTreeSet<i32>>,
2711 recovery_state: Option<usize>,
2712}
2713
2714#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2715struct FastRecognizeTopRequest {
2716 start_state: usize,
2717 stop_state: usize,
2718 start_index: usize,
2719 precedence: i32,
2720 caller_follow_state: Option<usize>,
2721}
2722
2723#[derive(Clone, Debug)]
2730struct FastRecognizeKey {
2731 state_number: usize,
2732 stop_state: usize,
2733 index: usize,
2734 rule_start_index: usize,
2735 decision_start_index: Option<usize>,
2736 precedence: i32,
2737 recovery_symbols_id: usize,
2738 recovery_state: Option<usize>,
2739}
2740
2741impl PartialEq for FastRecognizeKey {
2742 fn eq(&self, other: &Self) -> bool {
2743 if self.state_number != other.state_number
2744 || self.stop_state != other.stop_state
2745 || self.index != other.index
2746 || self.rule_start_index != other.rule_start_index
2747 || self.decision_start_index != other.decision_start_index
2748 || self.precedence != other.precedence
2749 || self.recovery_state != other.recovery_state
2750 || self.recovery_symbols_id != other.recovery_symbols_id
2751 {
2752 return false;
2753 }
2754 true
2755 }
2756}
2757
2758impl Eq for FastRecognizeKey {}
2759
2760impl Hash for FastRecognizeKey {
2761 fn hash<H: Hasher>(&self, hasher: &mut H) {
2762 self.state_number.hash(hasher);
2763 self.stop_state.hash(hasher);
2764 self.index.hash(hasher);
2765 self.rule_start_index.hash(hasher);
2766 self.decision_start_index.hash(hasher);
2767 self.precedence.hash(hasher);
2768 self.recovery_state.hash(hasher);
2769 self.recovery_symbols_id.hash(hasher);
2770 }
2771}
2772
2773struct FastRecoveryRequest<'a, 'b> {
2774 atn: &'a Atn,
2775 transition: &'a Transition,
2776 expected_symbols: Rc<BTreeSet<i32>>,
2777 target: usize,
2778 request: FastRecognizeRequest,
2779 visiting: &'b mut FxHashSet<FastRecognizeKey>,
2780 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
2781 expected: &'b mut ExpectedTokens,
2782}
2783
2784struct FastCurrentTokenDeletionRequest<'a, 'b> {
2785 atn: &'a Atn,
2786 expected_symbols: Rc<BTreeSet<i32>>,
2787 request: FastRecognizeRequest,
2788 visiting: &'b mut FxHashSet<FastRecognizeKey>,
2789 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
2790 expected: &'b mut ExpectedTokens,
2791}
2792
2793#[derive(Clone, Copy)]
2794struct FastChildRuleFailureRecoveryRequest<'a> {
2795 atn: &'a Atn,
2796 rule_index: usize,
2797 start_index: usize,
2798 follow_state: usize,
2799 stop_state: usize,
2800 expected: &'a ExpectedTokens,
2801}
2802
2803struct RecoveryRequest<'a, 'b> {
2804 atn: &'a Atn,
2805 transition: &'a Transition,
2806 expected_symbols: BTreeSet<i32>,
2807 target: usize,
2808 request: RecognizeRequest<'a>,
2809 visiting: &'b mut BTreeSet<RecognizeKey>,
2810 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2811 expected: &'b mut ExpectedTokens,
2812}
2813
2814struct CurrentTokenDeletionRequest<'a, 'b> {
2815 atn: &'a Atn,
2816 expected_symbols: BTreeSet<i32>,
2817 request: RecognizeRequest<'a>,
2818 visiting: &'b mut BTreeSet<RecognizeKey>,
2819 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2820 expected: &'b mut ExpectedTokens,
2821}
2822
2823struct ConsumingFailureFallback<'a> {
2826 atn: &'a Atn,
2827 target: usize,
2828 request: RecognizeRequest<'a>,
2829 symbol: i32,
2830 expected_symbols: BTreeSet<i32>,
2831 decision_start_index: Option<usize>,
2832 decision: Option<usize>,
2833}
2834
2835struct ChildRuleFailureRecovery<'a> {
2838 atn: &'a Atn,
2839 rule_index: usize,
2840 start_index: usize,
2841 follow_state: usize,
2842 stop_state: usize,
2843 member_values: BTreeMap<usize, i64>,
2844 expected: &'a ExpectedTokens,
2845}
2846
2847#[derive(Clone, Copy, Debug)]
2849struct PredicateEval<'a> {
2850 index: usize,
2851 rule_index: usize,
2852 pred_index: usize,
2853 predicates: &'a [(usize, usize, ParserPredicate)],
2854 semantics: Option<&'a ParserSemantics>,
2855 context: Option<&'a ParserRuleContext>,
2856 local_int_arg: Option<(usize, i64)>,
2857 member_values: &'a BTreeMap<usize, i64>,
2858}
2859
2860#[derive(Clone, Copy, Debug)]
2861struct ParserSemanticHookRequest<'a> {
2862 index: usize,
2863 rule_index: usize,
2864 pred_index: usize,
2865 context: Option<&'a ParserRuleContext>,
2866 local_int_arg: Option<(usize, i64)>,
2867 member_values: &'a BTreeMap<usize, i64>,
2868}
2869
2870struct ParserSemIrCtx<'a, S, H>
2879where
2880 S: TokenSource,
2881 H: SemanticHooks,
2882{
2883 input: &'a mut CommonTokenStream<S>,
2884 semantic_hooks: &'a mut H,
2885 rule_index: usize,
2886 coordinate_index: usize,
2887 rule_name: Option<&'a str>,
2888 context: Option<&'a ParserRuleContext>,
2889 local_int_arg: Option<(usize, i64)>,
2890 member_values: &'a BTreeMap<usize, i64>,
2891 invoked_predicates: &'a mut Vec<(usize, usize)>,
2892 unknown_predicate_policy: UnknownSemanticPolicy,
2896 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
2897}
2898
2899impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
2900where
2901 S: TokenSource,
2902 H: SemanticHooks,
2903{
2904 fn la(&mut self, offset: isize) -> i64 {
2905 i64::from(self.input.la(offset))
2906 }
2907
2908 fn token_text(&mut self, offset: isize) -> Option<&str> {
2909 self.input.lt(offset).and_then(Token::text)
2910 }
2911
2912 fn token_index_adjacent(&mut self) -> bool {
2913 let Some(first) = self.input.lt(-2).map(Token::token_index) else {
2914 return false;
2915 };
2916 let Some(second) = self.input.lt(-1).map(Token::token_index) else {
2917 return false;
2918 };
2919 first + 1 == second
2920 }
2921
2922 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
2923 self.context.and_then(|context| {
2924 context.children().iter().find_map(|child| match child {
2925 ParseTree::Rule(rule) if rule.context().rule_index() == rule_index => {
2926 Some(child.text())
2927 }
2928 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
2929 })
2930 })
2931 }
2932
2933 fn member(&self, member: usize) -> Option<i64> {
2934 Some(self.member_values.get(&member).copied().unwrap_or_default())
2935 }
2936
2937 fn local_arg(&self) -> Option<i64> {
2938 self.local_int_arg.map(|(_, value)| value)
2939 }
2940
2941 fn column(&self) -> Option<i64> {
2942 None
2943 }
2944
2945 fn token_start_column(&self) -> Option<i64> {
2946 None
2947 }
2948
2949 fn token_text_so_far(&self) -> Option<String> {
2950 None
2951 }
2952
2953 fn hook(&mut self, _hook: HookId) -> bool {
2954 let mut ctx = ParserSemCtx {
2955 input: &mut *self.input,
2956 rule_index: self.rule_index,
2957 coordinate_index: self.coordinate_index,
2958 rule_name: self.rule_name.map(str::to_owned),
2959 context: self.context,
2960 tree: None,
2961 local_int_arg: self.local_int_arg,
2962 member_values: self.member_values,
2963 action: None,
2964 };
2965 match self
2966 .semantic_hooks
2967 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
2968 {
2969 Some(result) => result,
2970 None => apply_unknown_predicate_policy(
2974 self.unknown_predicate_policy,
2975 self.rule_index,
2976 self.coordinate_index,
2977 self.unknown_predicate_hits,
2978 ),
2979 }
2980 }
2981
2982 fn trace_bool(&mut self, value: bool) -> bool {
2983 let key = (self.rule_index, self.coordinate_index);
2984 if !self.invoked_predicates.contains(&key) {
2985 self.invoked_predicates.push(key);
2986 use std::io::Write as _;
2987 let mut stdout = std::io::stdout().lock();
2988 let _ = writeln!(stdout, "eval={value}");
2989 }
2990 value
2991 }
2992}
2993
2994struct PredicateFailureRecovery<'a> {
2996 rule_index: usize,
2997 index: usize,
2998 message: &'a str,
2999 member_values: BTreeMap<usize, i64>,
3000 return_values: BTreeMap<String, i64>,
3001 rule_alt_number: usize,
3002}
3003
3004#[derive(Debug)]
3005enum DirectAdaptiveParseControl {
3006 Fallback(DirectAdaptiveFallback),
3007}
3008
3009#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3010enum DirectAdaptiveFallback {
3011 Action,
3012 InvalidAlt,
3013 LeftRecursiveBoundary,
3014 MissingAtn,
3015 NoTransition,
3016 Predicate,
3017 Prediction,
3018 Precedence,
3019 RuleStop,
3020 SemanticContext,
3021 StepLimit,
3022 TokenMismatch,
3023 UnknownDecision,
3024}
3025
3026type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
3027
3028struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
3029where
3030 S: TokenSource,
3031 H: SemanticHooks,
3032{
3033 parser: &'sim mut BaseParser<S, H>,
3034 atn: &'atn Atn,
3035 simulator: &'sim mut ParserAtnSimulator<'atn>,
3036 decision_by_state: Vec<Option<usize>>,
3037 steps: usize,
3038}
3039
3040#[derive(Clone, Debug, Eq, PartialEq)]
3050pub struct GeneratedMatch {
3051 children: Vec<ParseTree>,
3052 consumed_eof: bool,
3053}
3054
3055impl GeneratedMatch {
3056 #[must_use]
3060 pub fn children(&self) -> &[ParseTree] {
3061 &self.children
3062 }
3063
3064 #[must_use]
3067 pub fn into_children(self) -> Vec<ParseTree> {
3068 self.children
3069 }
3070
3071 #[must_use]
3073 pub const fn consumed_eof(&self) -> bool {
3074 self.consumed_eof
3075 }
3076}
3077
3078impl<S> BaseParser<S, NoSemanticHooks>
3079where
3080 S: TokenSource,
3081{
3082 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
3085 Self::with_semantic_hooks(input, data, NoSemanticHooks)
3086 }
3087}
3088
3089impl<S, H> BaseParser<S, H>
3090where
3091 S: TokenSource,
3092 H: SemanticHooks,
3093{
3094 pub fn with_semantic_hooks(
3096 input: CommonTokenStream<S>,
3097 data: RecognizerData,
3098 semantic_hooks: H,
3099 ) -> Self {
3100 Self {
3101 input,
3102 data,
3103 semantic_hooks,
3104 build_parse_trees: true,
3105 syntax_errors: 0,
3106 report_diagnostic_errors: false,
3107 prediction_mode: PredictionMode::Ll,
3108 prediction_diagnostics: Vec::new(),
3109 reported_prediction_diagnostics: BTreeSet::new(),
3110 generated_parser_diagnostics: Vec::new(),
3111 generated_sync_expected: None,
3112 int_members: BTreeMap::new(),
3113 rule_context_stack: Vec::new(),
3114 rule_context_version: 0,
3115 prediction_context_cache: None,
3116 pending_invoking_states: Vec::new(),
3117 precedence_stack: vec![0],
3118 invoked_predicates: Vec::new(),
3119 bail_on_error: false,
3120 unknown_predicate_policy: UnknownSemanticPolicy::default(),
3121 unknown_predicate_hits: Vec::new(),
3122 unhandled_action_hits: Vec::new(),
3123 rule_first_set_cache: Vec::new(),
3124 state_expected_cache: FxHashMap::default(),
3125 state_expected_token_cache: FxHashMap::default(),
3126 rule_stop_reach_cache: Vec::new(),
3127 recovery_symbols_intern: FxHashMap::default(),
3128 decision_lookahead_cache: FxHashMap::default(),
3129 ll1_decision_cache: FxHashMap::default(),
3130 empty_cycle_cache: Vec::new(),
3131 single_outcome_memo_mode: SingleOutcomeMemoMode::Probe,
3132 single_outcome_probe_seen: FxHashSet::default(),
3133 single_outcome_probe_samples: 0,
3134 single_outcome_probe_repeats: 0,
3135 empty_recovery_symbols: Rc::new(BTreeSet::new()),
3136 fast_first_set_prefilter: true,
3137 fast_recovery_enabled: true,
3138 fast_token_nodes_enabled: true,
3139 }
3140 }
3141
3142 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
3143 &mut self.input
3144 }
3145
3146 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
3157 self.unknown_predicate_policy = policy;
3158 }
3159
3160 #[must_use]
3166 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
3167 let error = self.unknown_semantic_error();
3168 self.unknown_predicate_hits.clear();
3169 self.unhandled_action_hits.clear();
3170 error
3171 }
3172
3173 pub fn reset_unknown_semantic_hits(&mut self) {
3180 self.unknown_predicate_hits.clear();
3181 self.unhandled_action_hits.clear();
3182 }
3183
3184 #[must_use]
3186 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
3187 &self.input
3188 }
3189
3190 #[must_use]
3192 pub fn into_token_stream(self) -> CommonTokenStream<S> {
3193 self.input
3194 }
3195
3196 pub const fn number_of_syntax_errors(&self) -> usize {
3199 self.syntax_errors
3200 }
3201
3202 pub const fn record_generated_syntax_error(&mut self) {
3205 self.record_syntax_errors(1);
3206 }
3207
3208 const fn record_syntax_errors(&mut self, count: usize) {
3209 self.syntax_errors = self.syntax_errors.saturating_add(count);
3210 }
3211
3212 pub fn report_token_source_errors(&mut self) {
3215 report_token_source_errors(&self.input.drain_source_errors());
3216 }
3217
3218 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
3221 GeneratedDiagnosticsCheckpoint {
3222 diagnostics_len: self.generated_parser_diagnostics.len(),
3223 syntax_errors: self.syntax_errors,
3224 }
3225 }
3226
3227 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
3229 self.generated_parser_diagnostics
3230 .truncate(marker.diagnostics_len);
3231 self.syntax_errors = marker.syntax_errors;
3232 self.generated_sync_expected = None;
3233 }
3234
3235 pub fn report_generated_parser_diagnostics(&mut self) {
3237 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
3238 let token_errors = self.input.drain_source_errors();
3239 report_generated_diagnostics(&parser_diagnostics, &token_errors);
3240 }
3241
3242 pub fn record_generated_ambiguity_diagnostic(
3245 &mut self,
3246 atn: &Atn,
3247 state_number: usize,
3248 start_index: usize,
3249 stop_index: usize,
3250 alts: &[usize],
3251 ) {
3252 if !self.report_diagnostic_errors || alts.len() < 2 {
3253 return;
3254 }
3255 let Some(decision) = atn
3256 .decision_to_state()
3257 .iter()
3258 .position(|candidate| *candidate == state_number)
3259 else {
3260 return;
3261 };
3262 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
3263 return;
3264 };
3265 let rule_name = self
3266 .rule_names()
3267 .get(rule_index)
3268 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
3269 let input = display_input_text(&self.input.text(start_index, stop_index));
3270 let alts = alts
3271 .iter()
3272 .map(usize::to_string)
3273 .collect::<Vec<_>>()
3274 .join(", ");
3275 let key = (decision, start_index, format!("{alts}:{input}"));
3276 if !self.reported_prediction_diagnostics.insert(key) {
3277 return;
3278 }
3279 let start_token = self.token_at(start_index);
3280 let stop_token = self.token_at(stop_index);
3281 self.generated_parser_diagnostics.push(diagnostic_for_token(
3282 start_token.as_ref(),
3283 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
3284 ));
3285 self.generated_parser_diagnostics.push(diagnostic_for_token(
3286 stop_token.as_ref(),
3287 format!(
3288 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
3289 ),
3290 ));
3291 }
3292
3293 pub fn record_generated_prediction_diagnostic(
3296 &mut self,
3297 atn: &Atn,
3298 state_number: usize,
3299 prediction: &ParserAtnPrediction,
3300 ) {
3301 let Some(diagnostic) = &prediction.diagnostic else {
3302 return;
3303 };
3304 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
3305 return;
3306 }
3307 let Some(decision) = atn
3308 .decision_to_state()
3309 .iter()
3310 .position(|candidate| *candidate == state_number)
3311 else {
3312 return;
3313 };
3314 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
3315 return;
3316 };
3317 let rule_name = self
3318 .rule_names()
3319 .get(rule_index)
3320 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
3321 let attempt_input = display_input_text(
3322 &self
3323 .input
3324 .text(diagnostic.start_index, diagnostic.sll_stop_index),
3325 );
3326 let result_input = display_input_text(
3327 &self
3328 .input
3329 .text(diagnostic.start_index, diagnostic.ll_stop_index),
3330 );
3331 let alts = diagnostic
3332 .conflicting_alts
3333 .iter()
3334 .map(usize::to_string)
3335 .collect::<Vec<_>>()
3336 .join(", ");
3337 let key = (
3338 decision,
3339 diagnostic.start_index,
3340 format!(
3341 "{:?}:{alts}:{attempt_input}:{result_input}",
3342 diagnostic.kind
3343 ),
3344 );
3345 if !self.reported_prediction_diagnostics.insert(key) {
3346 return;
3347 }
3348 let attempt_token = self.token_at(diagnostic.sll_stop_index);
3349 self.generated_parser_diagnostics.push(diagnostic_for_token(
3350 attempt_token.as_ref(),
3351 format!(
3352 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
3353 ),
3354 ));
3355 let result_token = self.token_at(diagnostic.ll_stop_index);
3356 let message = match diagnostic.kind {
3357 ParserAtnPredictionDiagnosticKind::Ambiguity => {
3358 if !diagnostic.exact {
3363 return;
3364 }
3365 format!(
3366 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
3367 )
3368 }
3369 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
3370 format!(
3371 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
3372 )
3373 }
3374 };
3375 self.generated_parser_diagnostics
3376 .push(diagnostic_for_token(result_token.as_ref(), message));
3377 }
3378
3379 pub fn la(&mut self, offset: isize) -> i32 {
3380 self.input.la_token(offset)
3381 }
3382
3383 pub fn consume(&mut self) {
3384 IntStream::consume(&mut self.input);
3385 }
3386
3387 pub fn set_int_member(&mut self, member: usize, value: i64) {
3389 self.int_members.insert(member, value);
3390 }
3391
3392 pub fn int_member(&self, member: usize) -> Option<i64> {
3394 self.int_members.get(&member).copied()
3395 }
3396
3397 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
3400 self.int_members.clone()
3401 }
3402
3403 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
3405 self.int_members = members;
3406 }
3407
3408 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
3410 let value = self.int_members.entry(member).or_default();
3411 *value += delta;
3412 *value
3413 }
3414
3415 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
3422 let current = self
3423 .input
3424 .lt_ref(1)
3425 .ok_or_else(|| AntlrError::ParserError {
3426 line: 0,
3427 column: 0,
3428 message: "missing current token".to_owned(),
3429 })?;
3430 if current.token_type() == token_type {
3431 self.consume();
3432 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
3433 } else {
3434 Err(AntlrError::MismatchedInput {
3435 expected: self.vocabulary().display_name(token_type),
3436 found: self.vocabulary().display_name(current.token_type()),
3437 })
3438 }
3439 }
3440
3441 pub fn match_token_recovering(
3445 &mut self,
3446 token_type: i32,
3447 follow_state: usize,
3448 atn: &Atn,
3449 ) -> Result<GeneratedMatch, AntlrError> {
3450 let current = self
3451 .input
3452 .lt_ref(1)
3453 .ok_or_else(|| AntlrError::ParserError {
3454 line: 0,
3455 column: 0,
3456 message: "missing current token".to_owned(),
3457 })?;
3458 if current.token_type() == token_type {
3459 self.generated_sync_expected = None;
3460 let consumed_eof = current.token_type() == TOKEN_EOF;
3461 self.consume();
3462 return Ok(GeneratedMatch {
3463 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
3464 consumed_eof,
3465 });
3466 }
3467 let mut expected_symbols = BTreeSet::new();
3468 expected_symbols.insert(token_type);
3469 self.recover_generated_match(
3470 current.as_ref().clone(),
3471 &expected_symbols,
3472 follow_state,
3473 atn,
3474 |symbol| symbol == token_type,
3475 )
3476 }
3477
3478 pub fn match_set_recovering(
3479 &mut self,
3480 intervals: &[(i32, i32)],
3481 follow_state: usize,
3482 atn: &Atn,
3483 ) -> Result<GeneratedMatch, AntlrError> {
3484 let current = self
3485 .input
3486 .lt_ref(1)
3487 .ok_or_else(|| AntlrError::ParserError {
3488 line: 0,
3489 column: 0,
3490 message: "missing current token".to_owned(),
3491 })?;
3492 if interval_set_contains(intervals, current.token_type()) {
3493 self.generated_sync_expected = None;
3494 let consumed_eof = current.token_type() == TOKEN_EOF;
3495 self.consume();
3496 return Ok(GeneratedMatch {
3497 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
3498 consumed_eof,
3499 });
3500 }
3501 let expected_symbols = interval_symbols(intervals);
3502 self.recover_generated_match(
3503 current.as_ref().clone(),
3504 &expected_symbols,
3505 follow_state,
3506 atn,
3507 |symbol| interval_set_contains(intervals, symbol),
3508 )
3509 }
3510
3511 pub fn match_not_set_recovering(
3512 &mut self,
3513 intervals: &[(i32, i32)],
3514 min_vocabulary: i32,
3515 max_vocabulary: i32,
3516 follow_state: usize,
3517 atn: &Atn,
3518 ) -> Result<GeneratedMatch, AntlrError> {
3519 let current = self
3520 .input
3521 .lt_ref(1)
3522 .ok_or_else(|| AntlrError::ParserError {
3523 line: 0,
3524 column: 0,
3525 message: "missing current token".to_owned(),
3526 })?;
3527 if (min_vocabulary..=max_vocabulary).contains(¤t.token_type())
3528 && !interval_set_contains(intervals, current.token_type())
3529 {
3530 self.generated_sync_expected = None;
3531 let consumed_eof = current.token_type() == TOKEN_EOF;
3532 self.consume();
3533 return Ok(GeneratedMatch {
3534 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
3535 consumed_eof,
3536 });
3537 }
3538 let expected_symbols =
3539 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
3540 self.recover_generated_match(
3541 current.as_ref().clone(),
3542 &expected_symbols,
3543 follow_state,
3544 atn,
3545 |symbol| {
3546 (min_vocabulary..=max_vocabulary).contains(&symbol)
3547 && !interval_set_contains(intervals, symbol)
3548 },
3549 )
3550 }
3551
3552 fn recover_generated_match(
3553 &mut self,
3554 current: CommonToken,
3555 expected_symbols: &BTreeSet<i32>,
3556 follow_state: usize,
3557 atn: &Atn,
3558 matches: impl Fn(i32) -> bool,
3559 ) -> Result<GeneratedMatch, AntlrError> {
3560 let expected_display = self.expected_symbols_display(expected_symbols);
3561 if self.bail_on_error {
3562 return Err(AntlrError::ParserError {
3563 line: current.line(),
3564 column: current.column(),
3565 message: format!(
3566 "mismatched input {} expecting {expected_display}",
3567 token_input_display(¤t)
3568 ),
3569 });
3570 }
3571 if current.token_type() != TOKEN_EOF
3572 && let Some(next) = self.input.lt(2).cloned()
3573 && matches(next.token_type())
3574 {
3575 let message = format!(
3576 "extraneous input {} expecting {expected_display}",
3577 token_input_display(¤t)
3578 );
3579 self.push_generated_parser_diagnostic(diagnostic_for_token(Some(¤t), message));
3580 self.record_syntax_errors(1);
3581 self.generated_sync_expected = None;
3582 let consumed_eof = next.token_type() == TOKEN_EOF;
3585 self.consume();
3586 self.consume();
3587 return Ok(GeneratedMatch {
3588 children: vec![
3589 ParseTree::Error(ErrorNode::new(current)),
3590 ParseTree::Terminal(TerminalNode::new(next)),
3591 ],
3592 consumed_eof,
3593 });
3594 }
3595 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
3596 let follow_explicitly_expects_eof = current.token_type() == TOKEN_EOF
3605 && self
3606 .cached_state_expected_symbols(atn, follow_state)
3607 .contains(&TOKEN_EOF);
3608 if follow_symbols.contains(¤t.token_type())
3609 && (current.token_type() != TOKEN_EOF
3610 || self.rule_context_stack.len() > 1
3611 || expected_symbols.is_empty()
3612 || follow_explicitly_expects_eof)
3613 {
3614 let message = format!(
3615 "missing {expected_display} at {}",
3616 token_input_display(¤t)
3617 );
3618 self.push_generated_parser_diagnostic(diagnostic_for_token(Some(¤t), message));
3619 self.record_syntax_errors(1);
3620 self.generated_sync_expected = None;
3621 let token_type = expected_symbols.iter().next().copied().unwrap_or(TOKEN_EOF);
3622 let mut missing_symbol = BTreeSet::new();
3623 missing_symbol.insert(token_type);
3624 let missing_display = self.expected_symbols_display(&missing_symbol);
3625 let token = CommonToken::new(token_type)
3626 .with_text(format!("<missing {missing_display}>"))
3627 .with_span(usize::MAX, usize::MAX)
3628 .with_position(current.line(), current.column());
3629 return Ok(GeneratedMatch {
3634 children: vec![ParseTree::Error(ErrorNode::new(token))],
3635 consumed_eof: false,
3636 });
3637 }
3638 let mismatch_expected = self.generated_sync_expected.take().map_or_else(
3639 || expected_symbols.clone(),
3640 |symbols| symbols.to_btree_set(),
3641 );
3642 let mismatch_expected_display = self.expected_symbols_display(&mismatch_expected);
3643 Err(AntlrError::ParserError {
3644 line: current.line(),
3645 column: current.column(),
3646 message: format!(
3647 "mismatched input {} expecting {mismatch_expected_display}",
3648 token_input_display(¤t)
3649 ),
3650 })
3651 }
3652
3653 fn generated_recovery_follow_symbols(
3654 &mut self,
3655 atn: &Atn,
3656 follow_state: usize,
3657 ) -> BTreeSet<i32> {
3658 let mut follow = self
3659 .cached_state_expected_symbols(atn, follow_state)
3660 .as_ref()
3661 .clone();
3662 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
3663 follow.extend(self.context_expected_symbols(atn));
3664 }
3665 follow
3666 }
3667
3668 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
3669 self.match_token(TOKEN_EOF)
3670 }
3671
3672 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
3673 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
3674 }
3675
3676 pub fn match_not_set(
3677 &mut self,
3678 intervals: &[(i32, i32)],
3679 min_vocabulary: i32,
3680 max_vocabulary: i32,
3681 ) -> Result<ParseTree, AntlrError> {
3682 self.match_interval_condition(intervals, |symbol| {
3683 (min_vocabulary..=max_vocabulary).contains(&symbol)
3684 && !interval_set_contains(intervals, symbol)
3685 })
3686 }
3687
3688 fn match_interval_condition(
3689 &mut self,
3690 intervals: &[(i32, i32)],
3691 matches: impl FnOnce(i32) -> bool,
3692 ) -> Result<ParseTree, AntlrError> {
3693 let current = self
3694 .input
3695 .lt_ref(1)
3696 .ok_or_else(|| AntlrError::ParserError {
3697 line: 0,
3698 column: 0,
3699 message: "missing current token".to_owned(),
3700 })?;
3701 if matches(current.token_type()) {
3702 self.consume();
3703 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
3704 } else {
3705 Err(AntlrError::MismatchedInput {
3706 expected: self.interval_display(intervals),
3707 found: self.vocabulary().display_name(current.token_type()),
3708 })
3709 }
3710 }
3711
3712 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
3713 let values = intervals
3714 .iter()
3715 .map(|(start, stop)| {
3716 if start == stop {
3717 self.vocabulary().display_name(*start)
3718 } else {
3719 format!(
3720 "{}..{}",
3721 self.vocabulary().display_name(*start),
3722 self.vocabulary().display_name(*stop)
3723 )
3724 }
3725 })
3726 .collect::<Vec<_>>()
3727 .join(", ");
3728 format!("{{{values}}}")
3729 }
3730
3731 pub const fn rule_node(&self, context: ParserRuleContext) -> ParseTree {
3732 ParseTree::Rule(RuleNode::new(context))
3733 }
3734
3735 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
3738 self.set_state(state);
3739 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
3740 self.rule_context_stack.push(RuleContextFrame {
3741 rule_index,
3742 invoking_state,
3743 });
3744 self.invalidate_prediction_context_cache();
3745 let start_index = self.current_visible_index();
3746 let mut context = ParserRuleContext::new(rule_index, invoking_state);
3747 if let Some(token) = self.token_ref_at(start_index) {
3748 context.set_start_ref(token);
3749 }
3750 context
3751 }
3752
3753 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
3760 let marker = self.pending_invoking_states.len();
3761 self.pending_invoking_states.push(invoking_state);
3762 marker
3763 }
3764
3765 pub fn discard_invoking_state(&mut self, marker: usize) {
3767 self.pending_invoking_states.truncate(marker);
3768 }
3769
3770 pub fn exit_rule(&mut self) {
3772 self.rule_context_stack.pop();
3773 self.invalidate_prediction_context_cache();
3774 }
3775
3776 pub fn prediction_context(&mut self, atn: &Atn) -> Rc<PredictionContext> {
3779 let atn_ptr: *const Atn = atn;
3780 let atn_key = atn_ptr as usize;
3781 if let Some(cached) = &self.prediction_context_cache
3782 && cached.version == self.rule_context_version
3783 && cached.atn_key == atn_key
3784 {
3785 return Rc::clone(&cached.context);
3786 }
3787 let mut context = PredictionContext::empty();
3788 for frame in self.rule_context_stack.iter().skip(1) {
3789 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
3790 continue;
3791 };
3792 let Some(Transition::Rule { follow_state, .. }) = atn
3793 .state(state_number)
3794 .and_then(|state| state.transitions.first())
3795 else {
3796 continue;
3797 };
3798 context = PredictionContext::singleton(context, *follow_state);
3799 }
3800 self.prediction_context_cache = Some(CachedPredictionContext {
3801 version: self.rule_context_version,
3802 atn_key,
3803 context: Rc::clone(&context),
3804 });
3805 context
3806 }
3807
3808 fn invalidate_prediction_context_cache(&mut self) {
3809 self.rule_context_version = self.rule_context_version.wrapping_add(1);
3810 self.prediction_context_cache = None;
3811 }
3812
3813 pub fn add_parse_child(&self, context: &mut ParserRuleContext, child: ParseTree) {
3818 if self.build_parse_trees {
3819 context.add_child(child);
3820 } else {
3821 context.note_matched_child();
3822 }
3823 }
3824
3825 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
3827 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
3828 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
3829 context.set_stop_ref(token);
3830 }
3831 self.exit_rule();
3832 self.rule_node(context)
3833 }
3834
3835 pub fn recover_generated_rule(
3842 &mut self,
3843 context: &mut ParserRuleContext,
3844 atn: &Atn,
3845 error: AntlrError,
3846 ) {
3847 let diagnostic = self.generated_rule_error_diagnostic(error);
3848 self.push_generated_parser_diagnostic(diagnostic);
3849 self.generated_sync_expected = None;
3850 let recovery_symbols = self.context_expected_symbols(atn);
3851 loop {
3852 let symbol = self.la(1);
3853 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
3854 break;
3855 }
3856 let Some(token) = self.input.lt(1).cloned() else {
3857 break;
3858 };
3859 self.consume();
3860 self.add_parse_child(context, ParseTree::Error(ErrorNode::new(token)));
3861 }
3862 self.record_syntax_errors(1);
3863 }
3864
3865 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
3866 if self
3867 .generated_parser_diagnostics
3868 .iter()
3869 .any(|existing| existing == &diagnostic)
3870 {
3871 return;
3872 }
3873 self.generated_parser_diagnostics.push(diagnostic);
3874 }
3875
3876 fn generated_rule_error_diagnostic(&mut self, error: AntlrError) -> ParserDiagnostic {
3877 match error {
3878 AntlrError::ParserError {
3879 line,
3880 column,
3881 message,
3882 } => ParserDiagnostic {
3883 line,
3884 column,
3885 message,
3886 },
3887 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
3888 self.input.lt(1),
3889 format!("mismatched input {found} expecting {expected}"),
3890 ),
3891 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
3892 self.input.lt(1),
3893 format!("no viable alternative at input {input}"),
3894 ),
3895 AntlrError::LexerError {
3896 line,
3897 column,
3898 message,
3899 } => ParserDiagnostic {
3900 line,
3901 column,
3902 message,
3903 },
3904 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
3905 }
3906 }
3907
3908 pub fn finish_recursion_rule(
3910 &mut self,
3911 mut context: ParserRuleContext,
3912 consumed_eof: bool,
3913 ) -> ParseTree {
3914 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
3915 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
3916 context.set_stop_ref(token);
3917 }
3918 self.unroll_recursion_context();
3919 self.rule_node(context)
3920 }
3921
3922 pub fn enter_recursion_rule(
3924 &mut self,
3925 state: isize,
3926 rule_index: usize,
3927 precedence: i32,
3928 ) -> ParserRuleContext {
3929 self.precedence_stack.push(precedence);
3930 self.enter_rule(state, rule_index)
3931 }
3932
3933 pub fn push_new_recursion_context(
3935 &mut self,
3936 state: isize,
3937 rule_index: usize,
3938 ) -> ParserRuleContext {
3939 self.set_state(state);
3940 ParserRuleContext::new(rule_index, state)
3941 }
3942
3943 pub fn push_new_recursion_context_with_previous(
3946 &mut self,
3947 state: isize,
3948 rule_index: usize,
3949 current: &mut ParserRuleContext,
3950 ) {
3951 self.set_state(state);
3952 if let Some(stop) = self
3953 .rule_stop_token_index(self.input.index(), false)
3954 .and_then(|index| self.token_ref_at(index))
3955 {
3956 current.set_stop_ref(stop);
3957 }
3958 let invoking_state = current.invoking_state();
3959 let start = current.start_ref();
3960 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
3961 if let Some(start) = start {
3962 replacement.set_start_ref(start);
3963 }
3964 let previous = std::mem::replace(current, replacement);
3965 if self.build_parse_trees {
3966 current.add_child(self.rule_node(previous));
3967 }
3968 }
3969
3970 pub fn unroll_recursion_context(&mut self) {
3972 if self.precedence_stack.len() > 1 {
3973 self.precedence_stack.pop();
3974 }
3975 self.exit_rule();
3976 }
3977
3978 pub fn left_recursive_loop_enter_matches(
3983 &mut self,
3984 atn: &Atn,
3985 state_number: usize,
3986 precedence: i32,
3987 ) -> bool {
3988 let symbol = self.la(1);
3989 if symbol == TOKEN_EOF {
3990 return false;
3991 }
3992 let Some(state) = atn.state(state_number) else {
3993 return false;
3994 };
3995 let context = self.prediction_context(atn);
3996 if context_can_match_symbol_before_state(atn, &context, state_number, symbol) {
3997 return false;
3998 }
3999 state.transitions.iter().any(|transition| {
4000 let target = transition.target();
4001 if atn
4002 .state(target)
4003 .is_some_and(|state| state.kind == AtnStateKind::LoopEnd)
4004 {
4005 return false;
4006 }
4007 state_can_reach_symbol_with_precedence(
4008 atn,
4009 target,
4010 symbol,
4011 precedence,
4012 &mut BTreeSet::new(),
4013 )
4014 })
4015 }
4016
4017 pub fn precpred(&self, precedence: i32) -> bool {
4019 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
4020 }
4021
4022 pub fn parser_semantic_predicate_matches(
4025 &mut self,
4026 predicates: &[(usize, usize, ParserPredicate)],
4027 rule_index: usize,
4028 pred_index: usize,
4029 ) -> bool {
4030 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
4031 }
4032
4033 pub fn parser_semantic_predicate_matches_with_local(
4036 &mut self,
4037 predicates: &[(usize, usize, ParserPredicate)],
4038 rule_index: usize,
4039 pred_index: usize,
4040 local_int_arg: i32,
4041 ) -> bool {
4042 self.parser_semantic_predicate_matches_inner(
4043 predicates,
4044 rule_index,
4045 pred_index,
4046 Some((rule_index, i64::from(local_int_arg))),
4047 )
4048 }
4049
4050 fn parser_semantic_predicate_matches_inner(
4051 &mut self,
4052 predicates: &[(usize, usize, ParserPredicate)],
4053 rule_index: usize,
4054 pred_index: usize,
4055 local_int_arg: Option<(usize, i64)>,
4056 ) -> bool {
4057 let index = self.input.index();
4058 let member_values = self.int_members.clone();
4059 self.parser_predicate_matches(PredicateEval {
4060 index,
4061 rule_index,
4062 pred_index,
4063 predicates,
4064 semantics: None,
4065 context: None,
4066 local_int_arg,
4067 member_values: &member_values,
4068 })
4069 }
4070
4071 pub fn parser_semantic_predicate_matches_with_context_and_local(
4074 &mut self,
4075 predicates: &[(usize, usize, ParserPredicate)],
4076 rule_index: usize,
4077 pred_index: usize,
4078 context: &ParserRuleContext,
4079 local_int_arg: i32,
4080 ) -> bool {
4081 let index = self.input.index();
4082 let member_values = self.int_members.clone();
4083 self.parser_predicate_matches(PredicateEval {
4084 index,
4085 rule_index,
4086 pred_index,
4087 predicates,
4088 semantics: None,
4089 context: Some(context),
4090 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
4091 member_values: &member_values,
4092 })
4093 }
4094
4095 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
4098 &mut self,
4099 semantics: &ParserSemantics,
4100 rule_index: usize,
4101 pred_index: usize,
4102 context: &ParserRuleContext,
4103 local_int_arg: i32,
4104 ) -> bool {
4105 let index = self.input.index();
4106 let member_values = self.int_members.clone();
4107 self.parser_predicate_matches(PredicateEval {
4108 index,
4109 rule_index,
4110 pred_index,
4111 predicates: &[],
4112 semantics: Some(semantics),
4113 context: Some(context),
4114 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
4115 member_values: &member_values,
4116 })
4117 }
4118
4119 pub fn parser_semantic_predicate_failure_message(
4122 &self,
4123 rule_index: usize,
4124 pred_index: usize,
4125 predicates: &[(usize, usize, ParserPredicate)],
4126 ) -> Option<&'static str> {
4127 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
4128 }
4129
4130 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
4132 let current = self
4133 .input
4134 .lt_ref(1)
4135 .ok_or_else(|| AntlrError::ParserError {
4136 line: 0,
4137 column: 0,
4138 message: "missing current token".to_owned(),
4139 })?;
4140 if current.token_type() == TOKEN_EOF {
4141 return Err(AntlrError::MismatchedInput {
4142 expected: "wildcard".to_owned(),
4143 found: self.vocabulary().display_name(TOKEN_EOF),
4144 });
4145 }
4146 self.consume();
4147 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
4148 }
4149
4150 #[allow(clippy::unnecessary_wraps)]
4154 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
4155 self.set_state(state);
4156 Ok(())
4157 }
4158
4159 pub fn sync_decision(
4167 &mut self,
4168 atn: &Atn,
4169 state_number: usize,
4170 current_context_empty: bool,
4171 loop_back: bool,
4172 ) -> Result<Vec<ParseTree>, AntlrError> {
4173 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
4174 self.generated_sync_expected = None;
4175 let Some(state) = atn.state(state_number) else {
4176 return Ok(Vec::new());
4177 };
4178 let Some(rule_index) = state.rule_index else {
4179 return Ok(Vec::new());
4180 };
4181 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index).copied() else {
4182 return Ok(Vec::new());
4183 };
4184 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
4185 let symbol = self.la(1);
4186 let mut has_expected_symbols = false;
4187 let mut nullable = false;
4188 let mut explicit_eof_expected = false;
4196 for transition in &entry.transitions {
4197 if transition.symbols.contains(symbol) {
4198 return Ok(Vec::new());
4199 }
4200 has_expected_symbols |= !transition.symbols.is_empty();
4201 nullable |= transition.nullable;
4202 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
4203 }
4204 if nullable && self.context_expected_contains(atn, symbol) {
4209 return Ok(Vec::new());
4210 }
4211 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
4212 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
4213 return Ok(Vec::new());
4214 }
4215 let mut expected = TokenBitSet::default();
4216 for transition in &entry.transitions {
4217 expected.extend_from(&transition.symbols);
4218 }
4219 if let Some(context_expected) = context_expected {
4220 expected.extend_from(&context_expected);
4221 }
4222 let can_delete_in_place =
4223 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
4224 let loop_sync = loop_back;
4241 if symbol != TOKEN_EOF && can_delete_in_place {
4242 let mut cursor = self.input.index();
4243 let mut skipped = Vec::new();
4244 loop {
4245 let current = self.token_type_at(cursor);
4246 if current == TOKEN_EOF {
4247 break;
4248 }
4249 skipped.push(cursor);
4250 let next = self.consume_index(cursor, current);
4251 if next == cursor {
4252 break;
4253 }
4254 let next_symbol = self.token_type_at(next);
4255 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
4263 explicit_eof_expected
4264 } else {
4265 expected.contains(next_symbol)
4266 };
4267 if next_is_expected_stop {
4268 let current_token = self.input.lt(1).cloned();
4269 let expected_symbols = expected.to_btree_set();
4270 let message = format!(
4271 "extraneous input {} expecting {}",
4272 current_token
4273 .as_ref()
4274 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4275 self.expected_symbols_display(&expected_symbols)
4276 );
4277 self.push_generated_parser_diagnostic(diagnostic_for_token(
4278 current_token.as_ref(),
4279 message,
4280 ));
4281 self.record_syntax_errors(1);
4282 let mut children = Vec::with_capacity(skipped.len());
4283 for index in skipped {
4284 if let Some(token) = self.token_at(index) {
4285 self.consume();
4286 children.push(ParseTree::Error(ErrorNode::new(token)));
4287 }
4288 }
4289 return Ok(children);
4290 }
4291 if !loop_sync {
4295 break;
4296 }
4297 cursor = next;
4298 }
4299 }
4300 if nullable {
4301 self.generated_sync_expected = Some(expected);
4302 return Ok(Vec::new());
4303 }
4304 let current = self.input.lt(1).cloned();
4305 let expected_symbols = expected.to_btree_set();
4306 Err(AntlrError::ParserError {
4307 line: current.as_ref().map(Token::line).unwrap_or_default(),
4308 column: current.as_ref().map(Token::column).unwrap_or_default(),
4309 message: format!(
4310 "mismatched input {} expecting {}",
4311 current
4312 .as_ref()
4313 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4314 self.expected_symbols_display(&expected_symbols)
4315 ),
4316 })
4317 }
4318
4319 pub fn ll1_decision_prediction(
4326 &mut self,
4327 atn: &Atn,
4328 state_number: usize,
4329 ) -> Option<ParserAtnPrediction> {
4330 let state = atn.state(state_number)?;
4331 if state.precedence_rule_decision {
4332 return None;
4333 }
4334 let rule_stop = state
4335 .rule_index
4336 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())?;
4337 let symbol = self.la(1);
4338 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
4339 ll1_greedy_alt(&entry, symbol, state.non_greedy).map(|alt| ParserAtnPrediction {
4340 alt: alt + 1,
4341 requires_full_context: false,
4342 has_semantic_context: false,
4343 diagnostic: None,
4344 })
4345 }
4346
4347 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
4348 let context = self.prediction_context(atn);
4349 let mut expected = BTreeSet::new();
4350 self.collect_context_expected_symbols(atn, &context, &mut expected);
4351 expected
4352 }
4353
4354 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
4355 let context = self.prediction_context(atn);
4356 let mut expected = TokenBitSet::default();
4357 self.collect_context_expected_token_set(atn, &context, &mut expected);
4358 expected
4359 }
4360
4361 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
4372 for index in (1..self.rule_context_stack.len()).rev() {
4373 let invoking_state = self.rule_context_stack[index].invoking_state;
4374 let Ok(state_number) = usize::try_from(invoking_state) else {
4375 continue;
4376 };
4377 let Some(Transition::Rule { follow_state, .. }) = atn
4378 .state(state_number)
4379 .and_then(|state| state.transitions.first())
4380 else {
4381 continue;
4382 };
4383 let follow_state = *follow_state;
4384 if self
4385 .cached_state_expected_token_set(atn, follow_state)
4386 .contains(symbol)
4387 {
4388 return true;
4389 }
4390 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
4391 return false;
4392 }
4393 }
4394 symbol == TOKEN_EOF
4395 }
4396
4397 fn collect_context_expected_symbols(
4398 &mut self,
4399 atn: &Atn,
4400 context: &Rc<PredictionContext>,
4401 expected: &mut BTreeSet<i32>,
4402 ) {
4403 if context.is_empty() {
4404 expected.insert(TOKEN_EOF);
4405 return;
4406 }
4407 for index in 0..context.len() {
4408 let Some(return_state) = context.return_state(index) else {
4409 continue;
4410 };
4411 if return_state == EMPTY_RETURN_STATE {
4412 expected.insert(TOKEN_EOF);
4413 continue;
4414 }
4415 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
4416 if self.cached_state_can_reach_rule_stop(atn, return_state)
4417 && let Some(parent) = context.parent(index)
4418 {
4419 self.collect_context_expected_symbols(atn, &parent, expected);
4420 }
4421 }
4422 }
4423
4424 fn collect_context_expected_token_set(
4425 &mut self,
4426 atn: &Atn,
4427 context: &Rc<PredictionContext>,
4428 expected: &mut TokenBitSet,
4429 ) {
4430 if context.is_empty() {
4431 expected.insert(TOKEN_EOF);
4432 return;
4433 }
4434 for index in 0..context.len() {
4435 let Some(return_state) = context.return_state(index) else {
4436 continue;
4437 };
4438 if return_state == EMPTY_RETURN_STATE {
4439 expected.insert(TOKEN_EOF);
4440 continue;
4441 }
4442 let state_expected = self.cached_state_expected_token_set(atn, return_state);
4443 expected.extend_from(&state_expected);
4444 if self.cached_state_can_reach_rule_stop(atn, return_state)
4445 && let Some(parent) = context.parent(index)
4446 {
4447 self.collect_context_expected_token_set(atn, &parent, expected);
4448 }
4449 }
4450 }
4451
4452 pub fn no_viable_alternative_error(&mut self, start_index: usize) -> AntlrError {
4454 let error_index = self.input.index();
4455 self.no_viable_alternative_error_at(start_index, error_index)
4456 }
4457
4458 pub fn no_viable_alternative_error_at(
4463 &mut self,
4464 start_index: usize,
4465 error_index: usize,
4466 ) -> AntlrError {
4467 let diagnostic = self.no_viable_alternative(start_index, error_index);
4468 AntlrError::ParserError {
4469 line: diagnostic.line,
4470 column: diagnostic.column,
4471 message: diagnostic.message,
4472 }
4473 }
4474
4475 pub fn failed_predicate_error(&mut self, message: impl Into<String>) -> AntlrError {
4477 let current = self.input.lt(1).cloned();
4478 AntlrError::ParserError {
4479 line: current.as_ref().map(Token::line).unwrap_or_default(),
4480 column: current.as_ref().map(Token::column).unwrap_or_default(),
4481 message: format!("rule failed predicate: {}", message.into()),
4482 }
4483 }
4484
4485 pub fn failed_predicate_option_error(
4488 &mut self,
4489 rule_index: usize,
4490 message: impl Into<String>,
4491 ) -> AntlrError {
4492 let current = self.input.lt(1).cloned();
4493 let rule_name = self
4494 .rule_names()
4495 .get(rule_index)
4496 .map_or_else(|| rule_index.to_string(), Clone::clone);
4497 AntlrError::ParserError {
4498 line: current.as_ref().map(Token::line).unwrap_or_default(),
4499 column: current.as_ref().map(Token::column).unwrap_or_default(),
4500 message: format!("rule {rule_name} {}", message.into()),
4501 }
4502 }
4503
4504 pub fn parser_action_at_current(
4506 &mut self,
4507 source_state: usize,
4508 rule_index: usize,
4509 start_index: usize,
4510 consumed_eof: bool,
4511 ) -> ParserAction {
4512 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
4513 ParserAction::new(source_state, rule_index, start_index, stop_index)
4514 }
4515
4516 pub fn parser_action_hook(&mut self, action: ParserAction, tree: &ParseTree) -> bool {
4521 let rule_index = action.rule_index();
4522 let rule_name = self.rule_names().get(rule_index).cloned();
4523 let context = match tree {
4524 ParseTree::Rule(rule) if rule.context().rule_index() == rule_index => {
4525 Some(rule.context())
4526 }
4527 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
4528 };
4529 let input = &mut self.input;
4530 let semantic_hooks = &mut self.semantic_hooks;
4531 let member_values = &self.int_members;
4532 let mut ctx = ParserSemCtx {
4533 input,
4534 rule_index,
4535 coordinate_index: usize::MAX,
4536 rule_name,
4537 context,
4538 tree: Some(tree),
4539 local_int_arg: None,
4540 member_values,
4541 action: Some(action),
4542 };
4543 let handled = semantic_hooks.action(&mut ctx, action);
4544 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
4550 let coordinate = (rule_index, action.source_state());
4551 if !self.unhandled_action_hits.contains(&coordinate) {
4552 self.unhandled_action_hits.push(coordinate);
4553 }
4554 }
4555 handled
4556 }
4557
4558 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
4563 &mut self,
4564 atn: &'atn Atn,
4565 simulator: &mut ParserAtnSimulator<'atn>,
4566 rule_index: usize,
4567 ) -> Result<ParseTree, AntlrError> {
4568 let start_index = self.current_visible_index();
4569 self.clear_prediction_diagnostics();
4570 self.reset_per_parse_caches();
4571 let mut decision_by_state = vec![None; atn.states().len()];
4572 for (decision, &state_number) in atn.decision_to_state().iter().enumerate() {
4573 if let Some(slot) = decision_by_state.get_mut(state_number) {
4574 *slot = Some(decision);
4575 }
4576 }
4577
4578 let result = DirectAdaptiveParser {
4579 parser: self,
4580 atn,
4581 simulator,
4582 decision_by_state,
4583 steps: 0,
4584 }
4585 .parse_rule(rule_index, -1, 0);
4586
4587 match result {
4588 Ok(tree) => {
4589 report_token_source_errors(&self.input.drain_source_errors());
4590 Ok(tree)
4591 }
4592 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
4593 let _ = reason;
4594 self.input.seek(start_index);
4595 self.parse_atn_rule(atn, rule_index)
4596 }
4597 }
4598 }
4599
4600 pub fn parse_atn_rule(
4610 &mut self,
4611 atn: &Atn,
4612 rule_index: usize,
4613 ) -> Result<ParseTree, AntlrError> {
4614 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
4615 }
4616
4617 pub fn parse_atn_rule_with_precedence(
4620 &mut self,
4621 atn: &Atn,
4622 rule_index: usize,
4623 precedence: i32,
4624 ) -> Result<ParseTree, AntlrError> {
4625 let start_state = atn
4626 .rule_to_start_state()
4627 .get(rule_index)
4628 .copied()
4629 .ok_or_else(|| {
4630 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
4631 })?;
4632 let stop_state = atn
4633 .rule_to_stop_state()
4634 .get(rule_index)
4635 .copied()
4636 .filter(|state| *state != usize::MAX)
4637 .ok_or_else(|| {
4638 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
4639 })?;
4640
4641 let start_index = self.current_visible_index();
4642 self.clear_prediction_diagnostics();
4643 self.reset_per_parse_caches();
4644 let caller_follow_state = self.pending_invoking_follow_state(atn);
4645 self.fast_recovery_enabled = false;
4646 self.fast_token_nodes_enabled = false;
4647 let top_request = FastRecognizeTopRequest {
4648 start_state,
4649 stop_state,
4650 start_index,
4651 precedence,
4652 caller_follow_state,
4653 };
4654 let first_pass = self.fast_recognize_top(atn, top_request);
4655 self.fast_token_nodes_enabled = true;
4656 let needs_tree_retry = matches!(
4657 &first_pass,
4658 Ok((outcome, _)) if self.build_parse_trees && outcome.nodes.has_left_recursive_boundary()
4659 );
4660 let needs_retry = match &first_pass {
4661 Err(_) => true,
4674 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
4675 };
4676 let (outcome, _expected) = if needs_retry {
4677 self.fast_first_set_prefilter = false;
4678 self.fast_recovery_enabled = false;
4679 let clean_retry = self.fast_recognize_top(atn, top_request);
4680 let clean_selected = if needs_tree_retry {
4681 match clean_retry {
4682 ok @ Ok(_) => ok,
4683 Err(_) => first_pass,
4684 }
4685 } else {
4686 select_better_top_outcome(first_pass, clean_retry)
4687 };
4688 let selected = if clean_selected.is_err()
4689 || matches!(&clean_selected, Ok((outcome, _)) if !outcome.diagnostics.is_empty())
4690 {
4691 self.fast_recovery_enabled = true;
4692 let recovery_retry = self.fast_recognize_top(atn, top_request);
4693 select_better_top_outcome(clean_selected, recovery_retry)
4694 } else {
4695 clean_selected
4696 };
4697 self.fast_first_set_prefilter = true;
4698 self.fast_recovery_enabled = true;
4699 selected.map_err(|expected| {
4700 let error = self.recognition_error(rule_index, start_index, &expected);
4701 self.record_syntax_errors(1);
4702 report_token_source_errors(&self.input.drain_source_errors());
4703 error
4704 })?
4705 } else {
4706 first_pass.expect("first_pass is Ok in the no-retry branch")
4707 };
4708 self.record_syntax_errors(outcome.diagnostics.len());
4709 report_parser_diagnostics(&self.prediction_diagnostics);
4710 report_parser_diagnostics(&outcome.diagnostics);
4711 report_token_source_errors(&self.input.drain_source_errors());
4712 let mut context = ParserRuleContext::with_child_capacity(
4713 rule_index,
4714 self.state(),
4715 if self.build_parse_trees {
4716 outcome.nodes.len()
4717 } else {
4718 0
4719 },
4720 );
4721 if let Some(token) = self.token_ref_at(start_index) {
4722 context.set_start_ref(token);
4723 }
4724 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
4725 if let Some(token) = stop_index.and_then(|token_index| self.token_ref_at(token_index)) {
4726 context.set_stop_ref(token);
4727 }
4728 if self.build_parse_trees {
4729 if outcome.nodes.has_left_recursive_boundary() {
4730 let folded = fold_fast_left_recursive_boundaries(outcome.nodes.to_vec());
4731 if folded.iter().any(|node| {
4732 matches!(
4733 node.as_ref(),
4734 FastRecognizedNode::Token { .. }
4735 | FastRecognizedNode::ErrorToken { .. }
4736 | FastRecognizedNode::MissingToken { .. }
4737 )
4738 }) {
4739 for node in &folded {
4740 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
4741 }
4742 } else {
4743 self.add_fast_implicit_token_children(
4744 &mut context,
4745 start_index,
4746 stop_index,
4747 &folded,
4748 )?;
4749 }
4750 } else if outcome.nodes.has_explicit_token_node() {
4751 for node in outcome.nodes.iter() {
4752 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
4753 }
4754 } else {
4755 self.add_fast_implicit_token_children_iter(
4756 &mut context,
4757 start_index,
4758 stop_index,
4759 outcome.nodes.iter(),
4760 )?;
4761 }
4762 }
4763 self.input.seek(outcome.index);
4764
4765 Ok(self.rule_node(context))
4766 }
4767
4768 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
4769 let invoking_state = self.pending_invoking_states.last().copied()?;
4770 let state_number = usize::try_from(invoking_state).ok()?;
4771 match atn.state(state_number)?.transitions.first()? {
4772 Transition::Rule { follow_state, .. } => Some(*follow_state),
4773 _ => None,
4774 }
4775 }
4776
4777 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
4778 let token_type = self.token_type_at(index);
4781 let visible_channel = self.input.channel();
4782 let token = self.token_at(index);
4783 let is_boundary = token
4784 .as_ref()
4785 .and_then(Token::text)
4786 .is_some_and(is_caller_follow_boundary_text);
4787 let is_boundary_gap = token.as_ref().is_some_and(|token| {
4788 token.channel() != visible_channel || is_caller_follow_boundary_gap_text(token.text())
4789 });
4790 (token_type, is_boundary, is_boundary_gap)
4791 }
4792
4793 fn fast_recognize_top(
4798 &mut self,
4799 atn: &Atn,
4800 request: FastRecognizeTopRequest,
4801 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
4802 let FastRecognizeTopRequest {
4803 start_state,
4804 stop_state,
4805 start_index,
4806 precedence,
4807 caller_follow_state,
4808 } = request;
4809 let memo_capacity = self.input.size().saturating_mul(8).clamp(65_536, 524_288);
4818 let mut visiting = FxHashSet::with_capacity_and_hasher(256, FxBuildHasher::default());
4819 let mut memo = FxHashMap::with_capacity_and_hasher(memo_capacity, FxBuildHasher::default());
4820 let mut expected = ExpectedTokens::default();
4821 let empty_recovery = self.empty_recovery_symbols();
4822 let outcomes = self.recognize_state_fast(
4823 atn,
4824 FastRecognizeRequest {
4825 state_number: start_state,
4826 stop_state,
4827 index: start_index,
4828 rule_start_index: start_index,
4829 decision_start_index: None,
4830 precedence,
4831 depth: 0,
4832 recovery_symbols: empty_recovery,
4833 recovery_state: None,
4834 },
4835 &mut visiting,
4836 &mut memo,
4837 &mut expected,
4838 );
4839 #[cfg(feature = "perf-counters")]
4840 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
4841 perf_counters::dump();
4842 perf_counters::reset();
4843 }
4844 let caller_follow =
4845 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
4846 match select_best_fast_outcome(
4847 outcomes.into_iter(),
4848 self.prediction_mode,
4849 caller_follow.as_deref(),
4850 |index| self.caller_follow_token_info(index),
4851 ) {
4852 Some(outcome) => Ok((outcome, expected)),
4853 None => Err(expected),
4854 }
4855 }
4856
4857 fn fast_recognized_node_tree(
4860 &mut self,
4861 node: &FastRecognizedNode,
4862 ) -> Result<ParseTree, AntlrError> {
4863 match node {
4864 FastRecognizedNode::Token { index } => {
4865 let token = self
4866 .input
4867 .get_ref(*index)
4868 .ok_or_else(|| AntlrError::ParserError {
4869 line: 0,
4870 column: 0,
4871 message: format!("missing token at index {index}"),
4872 })?;
4873 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
4874 }
4875 FastRecognizedNode::ErrorToken { index } => {
4876 let token = self
4877 .input
4878 .get_ref(*index)
4879 .ok_or_else(|| AntlrError::ParserError {
4880 line: 0,
4881 column: 0,
4882 message: format!("missing error token at index {index}"),
4883 })?;
4884 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
4885 }
4886 FastRecognizedNode::MissingToken {
4887 token_type,
4888 at_index,
4889 text,
4890 } => {
4891 let current = self.token_at(*at_index);
4892 let token = CommonToken::new(*token_type)
4893 .with_text(text.as_str())
4894 .with_span(usize::MAX, usize::MAX)
4895 .with_position(
4896 current.as_ref().map(Token::line).unwrap_or_default(),
4897 current.as_ref().map(Token::column).unwrap_or_default(),
4898 );
4899 Ok(ParseTree::Error(ErrorNode::new(token)))
4900 }
4901 FastRecognizedNode::Rule {
4902 rule_index,
4903 invoking_state,
4904 start_index,
4905 stop_index,
4906 children,
4907 } => {
4908 let mut context = ParserRuleContext::with_child_capacity(
4909 *rule_index,
4910 *invoking_state,
4911 children.len(),
4912 );
4913 if let Some(token) = self.token_ref_at(*start_index) {
4914 context.set_start_ref(token);
4915 }
4916 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
4917 context.set_stop_ref(token);
4918 }
4919 if children.has_left_recursive_boundary() {
4920 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
4921 for child in &folded {
4922 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
4923 }
4924 } else {
4925 for child in children.iter() {
4926 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
4927 }
4928 }
4929 Ok(self.rule_node(context))
4930 }
4931 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
4932 Err(AntlrError::Unsupported(format!(
4933 "unfolded left-recursive boundary for rule {rule_index}"
4934 )))
4935 }
4936 }
4937 }
4938
4939 fn fast_recognized_node_tree_with_implicit_tokens(
4940 &mut self,
4941 node: &FastRecognizedNode,
4942 ) -> Result<ParseTree, AntlrError> {
4943 match node {
4944 FastRecognizedNode::Rule {
4945 rule_index,
4946 invoking_state,
4947 start_index,
4948 stop_index,
4949 children,
4950 } => {
4951 let mut context = ParserRuleContext::with_child_capacity(
4952 *rule_index,
4953 *invoking_state,
4954 children.len(),
4955 );
4956 if let Some(token) = self.token_ref_at(*start_index) {
4957 context.set_start_ref(token);
4958 }
4959 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
4960 context.set_stop_ref(token);
4961 }
4962 if children.has_left_recursive_boundary() {
4963 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
4964 self.add_fast_implicit_token_children(
4965 &mut context,
4966 *start_index,
4967 *stop_index,
4968 &folded,
4969 )?;
4970 } else {
4971 self.add_fast_implicit_token_children_iter(
4972 &mut context,
4973 *start_index,
4974 *stop_index,
4975 children.iter(),
4976 )?;
4977 }
4978 Ok(self.rule_node(context))
4979 }
4980 _ => self.fast_recognized_node_tree(node),
4981 }
4982 }
4983
4984 fn add_fast_implicit_token_children(
4985 &mut self,
4986 context: &mut ParserRuleContext,
4987 start_index: usize,
4988 stop_index: Option<usize>,
4989 children: &[Rc<FastRecognizedNode>],
4990 ) -> Result<(), AntlrError> {
4991 self.add_fast_implicit_token_children_iter(
4992 context,
4993 start_index,
4994 stop_index,
4995 children.iter(),
4996 )
4997 }
4998
4999 fn add_fast_implicit_token_children_iter<'a>(
5000 &mut self,
5001 context: &mut ParserRuleContext,
5002 start_index: usize,
5003 stop_index: Option<usize>,
5004 children: impl IntoIterator<Item = &'a Rc<FastRecognizedNode>>,
5005 ) -> Result<(), AntlrError> {
5006 let mut cursor = Some(start_index);
5007 for child in children {
5008 if let Some((child_start, child_stop)) = fast_recognized_node_span(child.as_ref()) {
5009 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
5010 context.add_child(
5011 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
5012 );
5013 if let Some(child_stop) = child_stop {
5014 cursor = self.next_visible_after_token(child_stop);
5015 }
5016 } else {
5017 context.add_child(
5018 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
5019 );
5020 }
5021 }
5022 if let Some(stop) = stop_index {
5023 self.add_visible_terminals_through(context, cursor, stop)?;
5024 }
5025 Ok(())
5026 }
5027
5028 fn add_visible_terminals_before(
5029 &mut self,
5030 context: &mut ParserRuleContext,
5031 cursor: &mut Option<usize>,
5032 before: usize,
5033 ) -> Result<(), AntlrError> {
5034 let Some(stop) = before.checked_sub(1) else {
5035 return Ok(());
5036 };
5037 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
5038 *cursor = next;
5039 Ok(())
5040 }
5041
5042 fn add_visible_terminals_through(
5043 &mut self,
5044 context: &mut ParserRuleContext,
5045 mut cursor: Option<usize>,
5046 stop: usize,
5047 ) -> Result<Option<usize>, AntlrError> {
5048 while let Some(index) = cursor {
5049 if index > stop {
5050 return Ok(Some(index));
5051 }
5052 let token = self
5053 .input
5054 .get_ref(index)
5055 .ok_or_else(|| AntlrError::ParserError {
5056 line: 0,
5057 column: 0,
5058 message: format!("missing token at index {index}"),
5059 })?;
5060 let is_eof = token.token_type() == TOKEN_EOF;
5061 context.add_child(ParseTree::Terminal(TerminalNode::from_ref(token)));
5062 if is_eof {
5063 return Ok(None);
5064 }
5065 cursor = self.next_visible_after_token(index);
5066 }
5067 Ok(None)
5068 }
5069
5070 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
5071 let next = self.input.next_visible_after(index);
5072 (next != index).then_some(next)
5073 }
5074
5075 pub fn parse_atn_rule_with_actions(
5082 &mut self,
5083 atn: &Atn,
5084 rule_index: usize,
5085 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5086 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
5087 }
5088
5089 pub fn parse_atn_rule_with_action_inits(
5097 &mut self,
5098 atn: &Atn,
5099 rule_index: usize,
5100 init_action_rules: &[usize],
5101 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5102 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
5103 }
5104
5105 pub fn parse_atn_rule_with_action_options(
5111 &mut self,
5112 atn: &Atn,
5113 rule_index: usize,
5114 init_action_rules: &[usize],
5115 track_alt_numbers: bool,
5116 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5117 self.parse_atn_rule_with_runtime_options(
5118 atn,
5119 rule_index,
5120 ParserRuntimeOptions {
5121 init_action_rules,
5122 track_alt_numbers,
5123 ..ParserRuntimeOptions::default()
5124 },
5125 )
5126 }
5127
5128 pub fn parse_atn_rule_with_runtime_options(
5135 &mut self,
5136 atn: &Atn,
5137 rule_index: usize,
5138 options: ParserRuntimeOptions<'_>,
5139 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5140 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
5141 }
5142
5143 pub fn parse_atn_rule_with_runtime_options_and_precedence(
5146 &mut self,
5147 atn: &Atn,
5148 rule_index: usize,
5149 precedence: i32,
5150 options: ParserRuntimeOptions<'_>,
5151 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5152 let ParserRuntimeOptions {
5153 init_action_rules,
5154 track_alt_numbers,
5155 predicates,
5156 semantics,
5157 rule_args,
5158 member_actions,
5159 return_actions,
5160 unknown_predicate_policy,
5161 } = options;
5162 if init_action_rules.is_empty()
5163 && !track_alt_numbers
5164 && predicates.is_empty()
5165 && semantics.is_none()
5166 && rule_args.is_empty()
5167 && member_actions.is_empty()
5168 && return_actions.is_empty()
5169 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
5170 && !atn_has_observable_action_transitions(atn)
5171 && (!self.semantic_hooks.observes_parser_predicates()
5172 || !atn_has_predicate_transitions(atn))
5173 {
5174 return self
5175 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
5176 .map(|tree| (tree, Vec::new()));
5177 }
5178 self.unknown_predicate_policy = unknown_predicate_policy;
5179 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
5186 let start_state = atn
5187 .rule_to_start_state()
5188 .get(rule_index)
5189 .copied()
5190 .ok_or_else(|| {
5191 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
5192 })?;
5193 let stop_state = atn
5194 .rule_to_stop_state()
5195 .get(rule_index)
5196 .copied()
5197 .filter(|state| *state != usize::MAX)
5198 .ok_or_else(|| {
5199 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
5200 })?;
5201
5202 let start_index = self.current_visible_index();
5203 self.clear_prediction_diagnostics();
5204 self.reset_per_parse_caches();
5205 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
5206 let invoking_state = self.pending_invoking_states.pop();
5207 let local_int_arg = invoking_state
5208 .and_then(|state| usize::try_from(state).ok())
5209 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
5210 let mut visiting = BTreeSet::new();
5211 let mut memo = BTreeMap::new();
5212 let mut expected = ExpectedTokens::default();
5213 let member_values = self.int_members.clone();
5214 let return_values = BTreeMap::new();
5215 let outcomes = self.recognize_state(
5216 atn,
5217 RecognizeRequest {
5218 state_number: start_state,
5219 stop_state,
5220 index: start_index,
5221 rule_start_index: start_index,
5222 decision_start_index: None,
5223 init_action_rules: &init_action_rules,
5224 predicates,
5225 semantics,
5226 rule_args,
5227 member_actions,
5228 return_actions,
5229 local_int_arg,
5230 member_values,
5231 return_values,
5232 rule_alt_number: 0,
5233 track_alt_numbers,
5234 consumed_eof: false,
5235 precedence,
5236 depth: 0,
5237 recovery_symbols: BTreeSet::new(),
5238 recovery_state: None,
5239 },
5240 &mut visiting,
5241 &mut memo,
5242 &mut expected,
5243 );
5244 if let Some(error) = self.unknown_semantic_error() {
5245 report_token_source_errors(&self.input.drain_source_errors());
5246 return Err(error);
5253 }
5254 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
5257 let Some(outcome) = select_best_outcome(outcomes.into_iter(), self.prediction_mode) else {
5258 let error = self.recognition_error(rule_index, start_index, &expected);
5259 self.record_syntax_errors(1);
5260 report_token_source_errors(&self.input.drain_source_errors());
5261 return Err(error);
5262 };
5263
5264 self.record_syntax_errors(outcome.diagnostics.len());
5265 report_parser_diagnostics(&self.prediction_diagnostics);
5266 report_parser_diagnostics(&outcome.diagnostics);
5267 report_token_source_errors(&self.input.drain_source_errors());
5268 let mut actions = outcome.actions;
5269 if init_action_rules.contains(&rule_index) {
5270 actions.insert(
5271 0,
5272 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
5273 );
5274 }
5275 let mut context =
5276 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
5277 if track_alt_numbers {
5278 context.set_alt_number(outcome.alt_number);
5279 }
5280 for (name, value) in outcome.return_values {
5281 context.set_int_return(name, value);
5282 }
5283 if let Some(token) = self.token_ref_at(start_index) {
5284 context.set_start_ref(token);
5285 }
5286 if let Some(token) = self.rule_stop_token_ref(outcome.index, outcome.consumed_eof) {
5287 context.set_stop_ref(token);
5288 }
5289 if self.build_parse_trees {
5290 let nodes = fold_left_recursive_boundaries(outcome.nodes);
5291 for node in &nodes {
5292 context.add_child(self.recognized_node_tree(node, track_alt_numbers)?);
5293 }
5294 }
5295 self.input.seek(outcome.index);
5296
5297 Ok((self.rule_node(context), actions))
5298 }
5299
5300 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
5307 let mut context = ParserRuleContext::new(rule_index, self.state());
5308 while self.la(1) != TOKEN_EOF {
5309 let token_type = self.la(1);
5310 let child = self.match_token(token_type)?;
5311 if self.build_parse_trees {
5312 context.add_child(child);
5313 }
5314 }
5315 if self.build_parse_trees {
5316 context.add_child(self.match_eof()?);
5317 }
5318 Ok(self.rule_node(context))
5319 }
5320
5321 fn recognition_error(
5324 &mut self,
5325 rule_index: usize,
5326 start_index: usize,
5327 expected: &ExpectedTokens,
5328 ) -> AntlrError {
5329 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
5330 self.input.seek(index);
5331 let current = self.input.lt(1).cloned();
5332 let line = current.as_ref().map(Token::line).unwrap_or_default();
5333 let column = current.as_ref().map(Token::column).unwrap_or_default();
5334 AntlrError::ParserError {
5335 line,
5336 column,
5337 message,
5338 }
5339 }
5340
5341 fn expected_error_message(
5343 &mut self,
5344 rule_index: usize,
5345 start_index: usize,
5346 expected: &ExpectedTokens,
5347 ) -> (usize, String) {
5348 let index = expected
5349 .index
5350 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
5351 .unwrap_or_else(|| self.input.index());
5352 self.input.seek(index);
5353 let current = self.input.lt(1).cloned();
5354 let message = if expected
5355 .no_viable
5356 .as_ref()
5357 .is_some_and(|no_viable| no_viable.error_index == index)
5358 {
5359 let start = expected
5360 .no_viable
5361 .as_ref()
5362 .map_or(start_index, |no_viable| no_viable.start_index);
5363 let text = display_input_text(&self.input.text(start, index));
5364 format!("no viable alternative at input '{text}'")
5365 } else if expected.symbols.is_empty() {
5366 if expected.index.is_some() {
5367 let found = current
5368 .as_ref()
5369 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
5370 if current
5371 .as_ref()
5372 .is_some_and(|token| token.token_type() == TOKEN_EOF)
5373 {
5374 format!(
5375 "missing {} at {found}",
5376 self.expected_symbols_display(&expected.symbols)
5377 )
5378 } else {
5379 format!("mismatched input {found}")
5380 }
5381 } else {
5382 format!("no viable alternative while parsing rule {rule_index}")
5383 }
5384 } else {
5385 format!(
5386 "mismatched input {} expecting {}",
5387 current
5388 .as_ref()
5389 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5390 self.expected_symbols_display(&expected.symbols)
5391 )
5392 };
5393 (index, message)
5394 }
5395
5396 fn child_rule_failure_recovery(
5399 &mut self,
5400 rule_index: usize,
5401 start_index: usize,
5402 sync_symbols: &BTreeSet<i32>,
5403 member_values: BTreeMap<usize, i64>,
5404 expected: &ExpectedTokens,
5405 ) -> Option<RecognizeOutcome> {
5406 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
5407 let token = self.token_at(error_index);
5408 let mut next_index = error_index;
5409 loop {
5410 let symbol = self.token_type_at(next_index);
5411 if sync_symbols.contains(&symbol) {
5412 if next_index == error_index {
5413 return None;
5414 }
5415 break;
5416 }
5417 if symbol == TOKEN_EOF {
5418 break;
5419 }
5420 let after = self.consume_index(next_index, symbol);
5421 if after == next_index {
5422 break;
5423 }
5424 next_index = after;
5425 }
5426 Some(RecognizeOutcome {
5427 index: next_index,
5428 consumed_eof: false,
5429 alt_number: 0,
5430 member_values,
5431 return_values: BTreeMap::new(),
5432 diagnostics: vec![diagnostic_for_token(token.as_ref(), message)],
5433 decisions: Vec::new(),
5434 actions: Vec::new(),
5435 nodes: vec![RecognizedNode::ErrorToken { index: error_index }],
5436 })
5437 }
5438
5439 fn child_rule_failure_recovery_outcomes(
5442 &mut self,
5443 request: ChildRuleFailureRecovery<'_>,
5444 ) -> Vec<RecognizeOutcome> {
5445 let sync_symbols =
5446 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
5447 self.child_rule_failure_recovery(
5448 request.rule_index,
5449 request.start_index,
5450 &sync_symbols,
5451 request.member_values,
5452 request.expected,
5453 )
5454 .into_iter()
5455 .collect()
5456 }
5457
5458 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
5460 expected_symbols_display(symbols, self.vocabulary())
5461 }
5462
5463 fn single_token_deletion(
5466 &mut self,
5467 transition: &Transition,
5468 index: usize,
5469 max_token_type: i32,
5470 expected_symbols: &BTreeSet<i32>,
5471 ) -> Option<(ParserDiagnostic, usize, i32)> {
5472 let current_symbol = self.token_type_at(index);
5473 if current_symbol == TOKEN_EOF {
5474 return None;
5475 }
5476 let next_index = self.consume_index(index, current_symbol);
5477 if next_index == index {
5478 return None;
5479 }
5480 let next_symbol = self.token_type_at(next_index);
5481 if !transition.matches(next_symbol, 1, max_token_type) {
5482 return None;
5483 }
5484 let transition_expected = transition_expected_symbols(transition, max_token_type);
5485 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
5486 &transition_expected
5487 } else {
5488 expected_symbols
5489 });
5490 let current = self.token_at(index);
5491 let message = format!(
5492 "extraneous input {} expecting {expected_display}",
5493 current
5494 .as_ref()
5495 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
5496 );
5497 Some((
5498 diagnostic_for_token(current.as_ref(), message),
5499 next_index,
5500 next_symbol,
5501 ))
5502 }
5503
5504 fn current_token_deletion(
5507 &mut self,
5508 index: usize,
5509 expected_symbols: &BTreeSet<i32>,
5510 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
5511 if expected_symbols.is_empty() {
5512 return None;
5513 }
5514 let current_symbol = self.token_type_at(index);
5515 if current_symbol == TOKEN_EOF {
5516 return None;
5517 }
5518 let current = self.token_at(index);
5519 let message = format!(
5520 "extraneous input {} expecting {}",
5521 current
5522 .as_ref()
5523 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5524 self.expected_symbols_display(expected_symbols)
5525 );
5526 let diagnostic = diagnostic_for_token(current.as_ref(), message);
5527 let mut skipped = Vec::new();
5528 let mut cursor = index;
5529 loop {
5530 let symbol = self.token_type_at(cursor);
5531 if symbol == TOKEN_EOF {
5532 return None;
5533 }
5534 skipped.push(cursor);
5535 let next_index = self.consume_index(cursor, symbol);
5536 if next_index == cursor {
5537 return None;
5538 }
5539 let next_symbol = self.token_type_at(next_index);
5540 if expected_symbols.contains(&next_symbol) {
5541 return Some((diagnostic, next_index, skipped));
5542 }
5543 cursor = next_index;
5544 }
5545 }
5546
5547 fn single_token_insertion(
5551 &mut self,
5552 transition: &Transition,
5553 index: usize,
5554 max_token_type: i32,
5555 expected_symbols: &BTreeSet<i32>,
5556 follow_symbols: &BTreeSet<i32>,
5557 ) -> Option<(ParserDiagnostic, i32, String)> {
5558 let current_symbol = self.token_type_at(index);
5559 if !follow_symbols.contains(¤t_symbol) {
5560 return None;
5561 }
5562 let transition_expected = transition_expected_symbols(transition, max_token_type);
5563 let token_type = transition_expected.iter().next().copied()?;
5564 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
5565 &transition_expected
5566 } else {
5567 expected_symbols
5568 });
5569 let mut token_symbols = BTreeSet::new();
5570 token_symbols.insert(token_type);
5571 let missing_token_display = self.expected_symbols_display(&token_symbols);
5572 let current = self.token_at(index);
5573 let message = format!(
5574 "missing {expected_display} at {}",
5575 current
5576 .as_ref()
5577 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
5578 );
5579 let text = format!("<missing {missing_token_display}>");
5580 Some((
5581 diagnostic_for_token(current.as_ref(), message),
5582 token_type,
5583 text,
5584 ))
5585 }
5586
5587 fn fast_single_token_deletion_recovery(
5591 &mut self,
5592 recovery: FastRecoveryRequest<'_, '_>,
5593 ) -> Vec<FastRecognizeOutcome> {
5594 let FastRecoveryRequest {
5595 atn,
5596 transition,
5597 expected_symbols,
5598 target,
5599 request,
5600 visiting,
5601 memo,
5602 expected,
5603 } = recovery;
5604 let FastRecognizeRequest {
5605 stop_state,
5606 index,
5607 rule_start_index,
5608 decision_start_index,
5609 precedence,
5610 depth,
5611 ..
5612 } = request;
5613 let Some((diagnostic, next_index, next_symbol)) =
5614 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
5615 else {
5616 return Vec::new();
5617 };
5618 let after_next = self.consume_index(next_index, next_symbol);
5619 let empty_recovery = self.empty_recovery_symbols();
5620 self.recognize_state_fast(
5621 atn,
5622 FastRecognizeRequest {
5623 state_number: target,
5624 stop_state,
5625 index: after_next,
5626 rule_start_index,
5627 decision_start_index,
5628 precedence,
5629 depth: depth + 1,
5630 recovery_symbols: empty_recovery,
5631 recovery_state: None,
5632 },
5633 visiting,
5634 memo,
5635 expected,
5636 )
5637 .into_iter()
5638 .map(|mut outcome| {
5639 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
5640 outcome.diagnostics.insert(0, diagnostic.clone());
5641 if self.fast_token_nodes_enabled {
5642 outcome
5643 .nodes
5644 .prepend(Rc::new(FastRecognizedNode::Token { index: next_index }));
5645 outcome
5646 .nodes
5647 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index }));
5648 }
5649 outcome
5650 })
5651 .collect()
5652 }
5653
5654 fn fast_single_token_insertion_recovery(
5658 &mut self,
5659 recovery: FastRecoveryRequest<'_, '_>,
5660 ) -> Vec<FastRecognizeOutcome> {
5661 let FastRecoveryRequest {
5662 atn,
5663 transition,
5664 expected_symbols,
5665 target,
5666 request,
5667 visiting,
5668 memo,
5669 expected,
5670 } = recovery;
5671 let FastRecognizeRequest {
5672 stop_state,
5673 index,
5674 rule_start_index,
5675 decision_start_index,
5676 precedence,
5677 depth,
5678 ..
5679 } = request;
5680 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
5681 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
5682 transition,
5683 index,
5684 atn.max_token_type(),
5685 &expected_symbols,
5686 &follow_symbols,
5687 ) else {
5688 return Vec::new();
5689 };
5690 let empty_recovery = self.empty_recovery_symbols();
5691 self.recognize_state_fast(
5692 atn,
5693 FastRecognizeRequest {
5694 state_number: target,
5695 stop_state,
5696 index,
5697 rule_start_index,
5698 decision_start_index,
5699 precedence,
5700 depth: depth + 1,
5701 recovery_symbols: empty_recovery,
5702 recovery_state: None,
5703 },
5704 visiting,
5705 memo,
5706 expected,
5707 )
5708 .into_iter()
5709 .map(|mut outcome| {
5710 outcome.diagnostics.insert(0, diagnostic.clone());
5711 outcome
5712 .nodes
5713 .prepend(Rc::new(FastRecognizedNode::MissingToken {
5714 token_type,
5715 at_index: index,
5716 text: text.clone(),
5717 }));
5718 outcome
5719 })
5720 .collect()
5721 }
5722
5723 fn fast_current_token_deletion_recovery(
5726 &mut self,
5727 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
5728 ) -> Vec<FastRecognizeOutcome> {
5729 let FastCurrentTokenDeletionRequest {
5730 atn,
5731 expected_symbols,
5732 mut request,
5733 visiting,
5734 memo,
5735 expected,
5736 } = recovery;
5737 if request.index == request.rule_start_index {
5738 return Vec::new();
5739 }
5740 let Some((diagnostic, next_index, skipped)) =
5741 self.current_token_deletion(request.index, &expected_symbols)
5742 else {
5743 return Vec::new();
5744 };
5745 request.state_number = request.recovery_state.unwrap_or(request.state_number);
5746 request.index = next_index;
5747 request.depth += 1;
5748 request.recovery_state = None;
5749 self.recognize_state_fast(atn, request, visiting, memo, expected)
5750 .into_iter()
5751 .map(|mut outcome| {
5752 outcome.diagnostics.insert(0, diagnostic.clone());
5753 for index in skipped.iter().rev() {
5754 outcome
5755 .nodes
5756 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index: *index }));
5757 }
5758 outcome
5759 })
5760 .collect()
5761 }
5762
5763 fn fast_child_rule_failure_recovery(
5766 &mut self,
5767 rule_index: usize,
5768 start_index: usize,
5769 sync_symbols: &BTreeSet<i32>,
5770 expected: &ExpectedTokens,
5771 ) -> Option<FastRecognizeOutcome> {
5772 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
5773 let token = self.token_at(error_index);
5774 let mut next_index = error_index;
5775 loop {
5776 let symbol = self.token_type_at(next_index);
5777 if sync_symbols.contains(&symbol) {
5778 if next_index == error_index {
5779 return None;
5780 }
5781 break;
5782 }
5783 if symbol == TOKEN_EOF {
5784 break;
5785 }
5786 let after = self.consume_index(next_index, symbol);
5787 if after == next_index {
5788 break;
5789 }
5790 next_index = after;
5791 }
5792 let mut diagnostics = FastDiagnostics::new();
5793 diagnostics.insert(0, diagnostic_for_token(token.as_ref(), message));
5794 let mut nodes = NodeList::new();
5795 if self.fast_token_nodes_enabled {
5796 nodes.prepend(Rc::new(FastRecognizedNode::ErrorToken {
5797 index: error_index,
5798 }));
5799 }
5800 Some(FastRecognizeOutcome {
5801 index: next_index,
5802 consumed_eof: false,
5803 diagnostics,
5804 nodes,
5805 })
5806 }
5807
5808 fn fast_child_rule_failure_recovery_outcomes(
5811 &mut self,
5812 request: FastChildRuleFailureRecoveryRequest<'_>,
5813 ) -> Vec<FastRecognizeOutcome> {
5814 let FastChildRuleFailureRecoveryRequest {
5815 atn,
5816 rule_index,
5817 start_index,
5818 follow_state,
5819 stop_state,
5820 expected,
5821 } = request;
5822 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
5823 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
5824 .into_iter()
5825 .collect()
5826 }
5827
5828 #[allow(clippy::too_many_lines)]
5831 fn recognize_state_fast(
5832 &mut self,
5833 atn: &Atn,
5834 request: FastRecognizeRequest,
5835 visiting: &mut FxHashSet<FastRecognizeKey>,
5836 memo: &mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
5837 expected: &mut ExpectedTokens,
5838 ) -> Vec<FastRecognizeOutcome> {
5839 #[cfg(feature = "perf-counters")]
5840 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
5841 let FastRecognizeRequest {
5842 mut state_number,
5843 stop_state,
5844 mut index,
5845 rule_start_index,
5846 decision_start_index,
5847 precedence,
5848 mut depth,
5849 recovery_symbols,
5850 recovery_state,
5851 } = request;
5852 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
5871 let mut inline_consumed_eof = false;
5872 loop {
5873 if depth > RECOGNITION_DEPTH_LIMIT {
5874 return Vec::new();
5875 }
5876 if state_number == stop_state {
5877 let mut nodes = NodeList::new();
5878 if self.fast_token_nodes_enabled {
5879 for token_index in inline_consumed_tokens.iter().rev() {
5880 nodes.prepend(Rc::new(FastRecognizedNode::Token {
5881 index: *token_index,
5882 }));
5883 }
5884 }
5885 return vec![FastRecognizeOutcome {
5886 index,
5887 consumed_eof: inline_consumed_eof,
5888 diagnostics: FastDiagnostics::new(),
5889 nodes,
5890 }];
5891 }
5892 let Some(state) = atn.state(state_number) else {
5893 return Vec::new();
5894 };
5895 if state.transitions.len() == 1
5896 && !starts_prediction_decision(state)
5897 && !state.precedence_rule_decision
5898 {
5899 match &state.transitions[0] {
5900 Transition::Epsilon { target }
5901 | Transition::Predicate { target, .. }
5902 | Transition::Action { target, .. }
5903 if left_recursive_boundary(atn, state, *target).is_none() =>
5904 {
5905 #[cfg(feature = "perf-counters")]
5906 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
5907 state_number = *target;
5908 depth += 1;
5909 continue;
5910 }
5911 Transition::Precedence {
5912 target,
5913 precedence: transition_precedence,
5914 } if *transition_precedence >= precedence
5915 && left_recursive_boundary(atn, state, *target).is_none() =>
5916 {
5917 #[cfg(feature = "perf-counters")]
5918 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
5919 state_number = *target;
5920 depth += 1;
5921 continue;
5922 }
5923 Transition::Atom { target, .. }
5933 | Transition::Range { target, .. }
5934 | Transition::Set { target, .. }
5935 | Transition::NotSet { target, .. }
5936 | Transition::Wildcard { target, .. }
5937 if !self.fast_recovery_enabled =>
5938 {
5939 let symbol = self.token_type_at(index);
5940 let transition = &state.transitions[0];
5941 if transition.matches(symbol, 1, atn.max_token_type()) {
5942 #[cfg(feature = "perf-counters")]
5943 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
5944 if self.fast_token_nodes_enabled {
5945 inline_consumed_tokens.push(index);
5946 }
5947 inline_consumed_eof |= symbol == TOKEN_EOF;
5948 index = self.consume_index(index, symbol);
5949 state_number = *target;
5950 depth += 1;
5951 continue;
5952 }
5953 }
5956 _ => {}
5957 }
5958 }
5959 break;
5960 }
5961 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
5965 let Some(state) = atn.state(state_number) else {
5966 return Vec::new();
5967 };
5968 let transition_count = state.transitions.len();
5969 let memo_lookup_enabled = self.fast_recovery_enabled || transition_count > 1;
5970 let key = if self.fast_recovery_enabled {
5980 FastRecognizeKey {
5981 state_number,
5982 stop_state,
5983 index,
5984 rule_start_index,
5985 decision_start_index,
5986 precedence,
5987 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
5988 recovery_state,
5989 }
5990 } else {
5991 FastRecognizeKey {
5992 state_number,
5993 stop_state,
5994 index,
5995 rule_start_index: 0,
5996 decision_start_index: None,
5997 precedence,
5998 recovery_symbols_id: 0,
5999 recovery_state: None,
6000 }
6001 };
6002 if memo_lookup_enabled {
6003 if let Some(outcomes) = memo.get(&key) {
6004 #[cfg(feature = "perf-counters")]
6005 {
6006 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
6007 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
6008 }
6009 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
6013 let inline_eof = inline_consumed_eof;
6014 let inline_tokens = &inline_consumed_tokens;
6015 return outcomes
6016 .iter()
6017 .cloned()
6018 .map(|mut outcome| {
6019 if inline_eof {
6020 outcome.consumed_eof = true;
6021 }
6022 if self.fast_token_nodes_enabled {
6023 for token_index in inline_tokens.iter().rev() {
6024 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
6025 index: *token_index,
6026 }));
6027 }
6028 }
6029 outcome
6030 })
6031 .collect();
6032 }
6033 return outcomes.to_vec();
6034 }
6035 #[cfg(feature = "perf-counters")]
6036 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
6037 }
6038
6039 let needs_cycle_guard = if self.fast_recovery_enabled {
6044 state.transitions.iter().any(Transition::is_epsilon)
6045 } else {
6046 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
6047 };
6048 #[cfg(feature = "perf-counters")]
6049 if needs_cycle_guard {
6050 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
6051 } else {
6052 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
6053 match &state.transitions[0] {
6054 Transition::Rule { .. } => {
6055 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
6056 }
6057 Transition::Atom { .. }
6058 | Transition::Range { .. }
6059 | Transition::Set { .. }
6060 | Transition::NotSet { .. }
6061 | Transition::Wildcard { .. } => {
6062 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
6063 }
6064 _ => {
6065 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
6066 }
6067 }
6068 }
6069 let has_inserted_cycle_guard = if needs_cycle_guard {
6070 if !visiting.insert(key.clone()) {
6071 #[cfg(feature = "perf-counters")]
6072 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
6073 return Vec::new();
6074 }
6075 true
6076 } else {
6077 false
6078 };
6079 let next_decision_start_index = if starts_prediction_decision(state) {
6080 Some(index)
6081 } else {
6082 decision_start_index
6083 };
6084 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
6085 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
6086 } else {
6087 (Rc::clone(&recovery_symbols), recovery_state)
6088 };
6089
6090 let transition_count = state.transitions.len();
6109 let lookahead_filter = if transition_count > 1
6110 && self.fast_first_set_prefilter
6111 && !state.precedence_rule_decision
6112 && (!self.fast_recovery_enabled || state.kind != AtnStateKind::RuleStart)
6113 {
6114 state
6115 .rule_index
6116 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())
6117 .map(|rule_stop| {
6118 let symbol = self.token_type_at(index);
6119 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6120 (symbol, entry)
6121 })
6122 } else {
6123 None
6124 };
6125 let ll1_only_alt: Option<usize> = if transition_count > 1
6134 && let Some((symbol, entry)) = lookahead_filter.as_ref()
6135 {
6136 let key = (state.state_number, *symbol);
6137 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
6138 cached
6139 } else {
6140 let result = ll1_unique_alt(entry, *symbol);
6141 self.ll1_decision_cache.insert(key, result);
6142 result
6143 }
6144 } else {
6145 None
6146 };
6147 let lookahead_filter = lookahead_filter.as_ref();
6148 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
6154 for (transition_index, transition) in state.transitions.iter().enumerate() {
6155 if let Some(alt) = ll1_only_alt {
6156 if alt != transition_index {
6158 continue;
6159 }
6160 } else if should_skip_via_lookahead(
6161 transition,
6162 transition_index,
6163 lookahead_filter,
6164 index,
6165 self.fast_recovery_enabled,
6166 expected,
6167 ) {
6168 continue;
6169 }
6170 match transition {
6171 Transition::Epsilon { target }
6172 | Transition::Predicate { target, .. }
6173 | Transition::Action { target, .. } => {
6174 #[cfg(feature = "perf-counters")]
6175 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
6176 let boundary = left_recursive_boundary(atn, state, *target);
6177 outcomes.extend(
6178 self.recognize_state_fast(
6179 atn,
6180 FastRecognizeRequest {
6181 state_number: *target,
6182 stop_state,
6183 index,
6184 rule_start_index,
6185 decision_start_index: next_decision_start_index,
6186 precedence,
6187 depth: depth + 1,
6188 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6189 recovery_state: epsilon_recovery_state,
6190 },
6191 visiting,
6192 memo,
6193 expected,
6194 )
6195 .into_iter()
6196 .map(|mut outcome| {
6197 if let Some(rule_index) = boundary {
6198 outcome.nodes.prepend(Rc::new(
6199 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
6200 ));
6201 }
6202 outcome
6203 }),
6204 );
6205 }
6206 Transition::Precedence {
6207 target,
6208 precedence: transition_precedence,
6209 } => {
6210 if *transition_precedence >= precedence {
6211 let boundary = left_recursive_boundary(atn, state, *target);
6212 outcomes.extend(
6213 self.recognize_state_fast(
6214 atn,
6215 FastRecognizeRequest {
6216 state_number: *target,
6217 stop_state,
6218 index,
6219 rule_start_index,
6220 decision_start_index: next_decision_start_index,
6221 precedence,
6222 depth: depth + 1,
6223 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6224 recovery_state: epsilon_recovery_state,
6225 },
6226 visiting,
6227 memo,
6228 expected,
6229 )
6230 .into_iter()
6231 .map(|mut outcome| {
6232 if let Some(rule_index) = boundary {
6233 outcome.nodes.prepend(Rc::new(
6234 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
6235 ));
6236 }
6237 outcome
6238 }),
6239 );
6240 }
6241 }
6242 Transition::Rule {
6243 target,
6244 rule_index,
6245 follow_state,
6246 precedence: rule_precedence,
6247 ..
6248 } => {
6249 #[cfg(feature = "perf-counters")]
6250 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
6251 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
6252 else {
6253 continue;
6254 };
6255 let symbol = self.token_type_at(index);
6267 if self.fast_first_set_prefilter {
6268 let first = self.cached_rule_first_set(atn, *target, child_stop);
6281 if should_skip_rule_via_first_set(
6282 &first,
6283 symbol,
6284 self.fast_recovery_enabled,
6285 index,
6286 expected,
6287 ) {
6288 continue;
6289 }
6290 }
6291 let expected_before_child =
6292 self.fast_recovery_enabled.then(|| expected.clone());
6293 let mut children = self.recognize_state_fast(
6294 atn,
6295 FastRecognizeRequest {
6296 state_number: *target,
6297 stop_state: child_stop,
6298 index,
6299 rule_start_index: index,
6300 decision_start_index: None,
6301 precedence: *rule_precedence,
6302 depth: depth + 1,
6303 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6304 recovery_state: epsilon_recovery_state,
6305 },
6306 visiting,
6307 memo,
6308 expected,
6309 );
6310 if children.is_empty() && self.fast_recovery_enabled {
6311 children = self.fast_child_rule_failure_recovery_outcomes(
6312 FastChildRuleFailureRecoveryRequest {
6313 atn,
6314 rule_index: *rule_index,
6315 start_index: index,
6316 follow_state: *follow_state,
6317 stop_state,
6318 expected,
6319 },
6320 );
6321 }
6322 if let Some(expected_before_child) = expected_before_child {
6323 if children
6324 .iter()
6325 .any(|child| child.diagnostics.is_empty() && child.index > index)
6326 {
6327 *expected = expected_before_child;
6328 }
6329 }
6330 for child in children {
6331 let child_index = child.index;
6332 let child_consumed_eof = child.consumed_eof;
6333 let child_diagnostics = child.diagnostics;
6334 let empty_recovery = self.empty_recovery_symbols();
6335 let follow_outcomes = self.recognize_state_fast(
6336 atn,
6337 FastRecognizeRequest {
6338 state_number: *follow_state,
6339 stop_state,
6340 index: child_index,
6341 rule_start_index,
6342 decision_start_index: next_decision_start_index,
6343 precedence,
6344 depth: depth + 1,
6345 recovery_symbols: empty_recovery,
6346 recovery_state: None,
6347 },
6348 visiting,
6349 memo,
6350 expected,
6351 );
6352 if follow_outcomes.is_empty() {
6353 continue;
6354 }
6355 let child_node = Rc::new(FastRecognizedNode::Rule {
6356 rule_index: *rule_index,
6357 invoking_state: invoking_state_number(state_number),
6358 start_index: index,
6359 stop_index: self.rule_stop_token_index(child_index, child_consumed_eof),
6360 children: child.nodes,
6361 });
6362 let child_diags_empty = child_diagnostics.is_empty();
6363 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
6364 outcome.consumed_eof |= child_consumed_eof;
6365 if !child_diags_empty {
6368 let mut diagnostics = child_diagnostics.clone();
6369 diagnostics.append(&mut outcome.diagnostics);
6370 outcome.diagnostics = diagnostics;
6371 }
6372 outcome.nodes.prepend(Rc::clone(&child_node));
6373 outcome
6374 }));
6375 }
6376 }
6377 Transition::Atom { target, .. }
6378 | Transition::Range { target, .. }
6379 | Transition::Set { target, .. }
6380 | Transition::NotSet { target, .. }
6381 | Transition::Wildcard { target, .. } => {
6382 #[cfg(feature = "perf-counters")]
6383 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
6384 let symbol = self.token_type_at(index);
6385 if transition.matches(symbol, 1, atn.max_token_type()) {
6386 let next_index = self.consume_index(index, symbol);
6387 let empty_recovery = self.empty_recovery_symbols();
6388 outcomes.extend(
6389 self.recognize_state_fast(
6390 atn,
6391 FastRecognizeRequest {
6392 state_number: *target,
6393 stop_state,
6394 index: next_index,
6395 rule_start_index,
6396 decision_start_index: next_decision_start_index,
6397 precedence,
6398 depth: depth + 1,
6399 recovery_symbols: empty_recovery,
6400 recovery_state: None,
6401 },
6402 visiting,
6403 memo,
6404 expected,
6405 )
6406 .into_iter()
6407 .map(|mut outcome| {
6408 outcome.consumed_eof |= symbol == TOKEN_EOF;
6409 if self.fast_token_nodes_enabled {
6410 outcome
6411 .nodes
6412 .prepend(Rc::new(FastRecognizedNode::Token { index }));
6413 }
6414 outcome
6415 }),
6416 );
6417 } else {
6418 if !self.fast_recovery_enabled {
6419 continue;
6427 }
6428 let expected_symbols = fast_recovery_expected_symbols(
6429 self,
6430 atn,
6431 state.state_number,
6432 &recovery_symbols,
6433 );
6434 if expected_symbols.contains(&symbol) {
6435 continue;
6436 }
6437 {
6438 expected.record_transition(index, transition, atn.max_token_type());
6439 record_no_viable_if_ambiguous(
6440 expected,
6441 next_decision_start_index,
6442 index,
6443 );
6444 outcomes.extend(self.fast_single_token_deletion_recovery(
6445 FastRecoveryRequest {
6446 atn,
6447 transition,
6448 expected_symbols: Rc::clone(&expected_symbols),
6449 target: *target,
6450 request: FastRecognizeRequest {
6451 state_number,
6452 stop_state,
6453 index,
6454 rule_start_index,
6455 decision_start_index,
6456 precedence,
6457 depth,
6458 recovery_symbols: Rc::clone(&recovery_symbols),
6459 recovery_state,
6460 },
6461 visiting,
6462 memo,
6463 expected,
6464 },
6465 ));
6466 if !state_is_left_recursive_rule(atn, state) {
6467 outcomes.extend(self.fast_single_token_insertion_recovery(
6468 FastRecoveryRequest {
6469 atn,
6470 transition,
6471 expected_symbols: Rc::clone(&expected_symbols),
6472 target: *target,
6473 request: FastRecognizeRequest {
6474 state_number,
6475 stop_state,
6476 index,
6477 rule_start_index,
6478 decision_start_index,
6479 precedence,
6480 depth,
6481 recovery_symbols: Rc::clone(&recovery_symbols),
6482 recovery_state,
6483 },
6484 visiting,
6485 memo,
6486 expected,
6487 },
6488 ));
6489 }
6490 outcomes.extend(self.fast_current_token_deletion_recovery(
6491 FastCurrentTokenDeletionRequest {
6492 atn,
6493 expected_symbols,
6494 request: FastRecognizeRequest {
6495 state_number,
6496 stop_state,
6497 index,
6498 rule_start_index,
6499 decision_start_index,
6500 precedence,
6501 depth,
6502 recovery_symbols: Rc::clone(&recovery_symbols),
6503 recovery_state,
6504 },
6505 visiting,
6506 memo,
6507 expected,
6508 },
6509 ));
6510 }
6511 }
6512 }
6513 }
6514 }
6515
6516 if has_inserted_cycle_guard {
6517 visiting.remove(&key);
6518 }
6519 if matches!(
6520 self.prediction_mode,
6521 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
6522 ) && self.fast_recovery_enabled
6523 {
6524 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
6528 }
6529 if self.fast_recovery_enabled {
6530 dedupe_fast_outcomes(&mut outcomes);
6531 } else {
6532 dedupe_clean_fast_outcomes(&mut outcomes);
6533 }
6534 let should_memoize = self.fast_recovery_enabled
6544 || (transition_count > 1
6545 && (outcomes.is_empty()
6546 || outcomes.len() > 1
6547 || (outcomes.len() == 1 && self.should_memoize_single_outcome(&key))));
6548 let apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
6552 if inline_consumed_eof {
6553 outcome.consumed_eof = true;
6554 }
6555 if !inline_consumed_tokens.is_empty() {
6556 for token_index in inline_consumed_tokens.iter().rev() {
6557 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
6558 index: *token_index,
6559 }));
6560 }
6561 }
6562 outcome
6563 };
6564 if should_memoize {
6565 #[cfg(feature = "perf-counters")]
6566 {
6567 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
6568 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
6569 match outcomes.len() {
6570 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
6571 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
6572 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
6573 }
6574 }
6575 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
6580 memo.insert(key, Rc::clone(&stored));
6581 if inline_pending {
6582 return stored.iter().cloned().map(apply_inline_pending).collect();
6583 }
6584 return stored.to_vec();
6585 }
6586 #[cfg(feature = "perf-counters")]
6587 match outcomes.len() {
6588 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
6589 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
6590 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
6591 }
6592 if inline_pending {
6593 return outcomes.into_iter().map(apply_inline_pending).collect();
6594 }
6595 outcomes
6596 }
6597
6598 fn single_token_deletion_recovery(
6601 &mut self,
6602 recovery: RecoveryRequest<'_, '_>,
6603 ) -> Vec<RecognizeOutcome> {
6604 let RecoveryRequest {
6605 atn,
6606 transition,
6607 expected_symbols,
6608 target,
6609 request,
6610 visiting,
6611 memo,
6612 expected,
6613 } = recovery;
6614 let RecognizeRequest {
6615 stop_state,
6616 index,
6617 rule_start_index,
6618 decision_start_index,
6619 init_action_rules,
6620 predicates,
6621 semantics,
6622 rule_args,
6623 member_actions,
6624 return_actions,
6625 local_int_arg,
6626 member_values,
6627 return_values,
6628 rule_alt_number,
6629 track_alt_numbers,
6630 consumed_eof,
6631 precedence,
6632 depth,
6633 ..
6634 } = request;
6635 let Some((diagnostic, next_index, next_symbol)) =
6636 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
6637 else {
6638 return Vec::new();
6639 };
6640 let after_next = self.consume_index(next_index, next_symbol);
6641 self.recognize_state(
6642 atn,
6643 RecognizeRequest {
6644 state_number: target,
6645 stop_state,
6646 index: after_next,
6647 rule_start_index,
6648 decision_start_index,
6649 init_action_rules,
6650 predicates,
6651 semantics,
6652 rule_args,
6653 member_actions,
6654 return_actions,
6655 local_int_arg,
6656 member_values,
6657 return_values,
6658 rule_alt_number,
6659 track_alt_numbers,
6660 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
6661 precedence,
6662 depth: depth + 1,
6663 recovery_symbols: BTreeSet::new(),
6664 recovery_state: None,
6665 },
6666 visiting,
6667 memo,
6668 expected,
6669 )
6670 .into_iter()
6671 .map(|mut outcome| {
6672 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
6673 outcome.diagnostics.insert(0, diagnostic.clone());
6674 outcome
6675 .nodes
6676 .insert(0, RecognizedNode::Token { index: next_index });
6677 outcome
6678 .nodes
6679 .insert(0, RecognizedNode::ErrorToken { index });
6680 outcome
6681 })
6682 .collect()
6683 }
6684
6685 fn current_token_deletion_recovery(
6688 &mut self,
6689 recovery: CurrentTokenDeletionRequest<'_, '_>,
6690 ) -> Vec<RecognizeOutcome> {
6691 let CurrentTokenDeletionRequest {
6692 atn,
6693 expected_symbols,
6694 mut request,
6695 visiting,
6696 memo,
6697 expected,
6698 } = recovery;
6699 let error_index = request.index;
6700 if error_index == request.rule_start_index {
6701 return Vec::new();
6702 }
6703 let Some((diagnostic, next_index, skipped)) =
6704 self.current_token_deletion(error_index, &expected_symbols)
6705 else {
6706 return Vec::new();
6707 };
6708 request.state_number = request.recovery_state.unwrap_or(request.state_number);
6709 request.index = next_index;
6710 request.depth += 1;
6711 request.recovery_state = None;
6712 self.recognize_state(atn, request, visiting, memo, expected)
6713 .into_iter()
6714 .map(|mut outcome| {
6715 outcome.diagnostics.insert(0, diagnostic.clone());
6716 for index in skipped.iter().rev() {
6717 outcome
6718 .nodes
6719 .insert(0, RecognizedNode::ErrorToken { index: *index });
6720 }
6721 outcome
6722 })
6723 .collect()
6724 }
6725
6726 fn consuming_failure_fallback(
6729 &mut self,
6730 fallback: ConsumingFailureFallback<'_>,
6731 visiting: &mut BTreeSet<RecognizeKey>,
6732 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
6733 expected: &mut ExpectedTokens,
6734 ) -> Vec<RecognizeOutcome> {
6735 if fallback.expected_symbols.is_empty() {
6736 return Vec::new();
6737 }
6738 if fallback.symbol == TOKEN_EOF {
6739 return self.eof_consuming_failure_fallback(fallback, expected);
6740 }
6741 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
6742 }
6743
6744 fn non_eof_consuming_failure_fallback(
6747 &mut self,
6748 fallback: ConsumingFailureFallback<'_>,
6749 visiting: &mut BTreeSet<RecognizeKey>,
6750 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
6751 expected: &mut ExpectedTokens,
6752 ) -> Vec<RecognizeOutcome> {
6753 let ConsumingFailureFallback {
6754 atn,
6755 target,
6756 request,
6757 symbol,
6758 expected_symbols,
6759 decision_start_index,
6760 decision,
6761 } = fallback;
6762 let error_index = request.index;
6763 let diagnostic =
6764 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
6765 let next_index = self.consume_index(error_index, symbol);
6766 self.recognize_state(
6767 atn,
6768 RecognizeRequest {
6769 state_number: target,
6770 stop_state: request.stop_state,
6771 index: next_index,
6772 rule_start_index: request.rule_start_index,
6773 decision_start_index,
6774 init_action_rules: request.init_action_rules,
6775 predicates: request.predicates,
6776 semantics: request.semantics,
6777 rule_args: request.rule_args,
6778 member_actions: request.member_actions,
6779 return_actions: request.return_actions,
6780 local_int_arg: request.local_int_arg,
6781 member_values: request.member_values,
6782 return_values: request.return_values,
6783 rule_alt_number: request.rule_alt_number,
6784 track_alt_numbers: request.track_alt_numbers,
6785 consumed_eof: request.consumed_eof,
6786 precedence: request.precedence,
6787 depth: request.depth + 1,
6788 recovery_symbols: BTreeSet::new(),
6789 recovery_state: None,
6790 },
6791 visiting,
6792 memo,
6793 expected,
6794 )
6795 .into_iter()
6796 .map(|mut outcome| {
6797 prepend_decision(&mut outcome, decision);
6798 outcome.diagnostics.insert(0, diagnostic.clone());
6799 outcome
6800 .nodes
6801 .insert(0, RecognizedNode::ErrorToken { index: error_index });
6802 outcome
6803 })
6804 .collect()
6805 }
6806
6807 fn eof_consuming_failure_fallback(
6810 &mut self,
6811 fallback: ConsumingFailureFallback<'_>,
6812 expected: &ExpectedTokens,
6813 ) -> Vec<RecognizeOutcome> {
6814 let request = fallback.request;
6815 if request.index == request.rule_start_index {
6816 return Vec::new();
6817 }
6818 let diagnostic =
6819 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
6820 vec![RecognizeOutcome {
6821 index: request.index,
6822 consumed_eof: request.consumed_eof,
6823 alt_number: request.rule_alt_number,
6824 member_values: request.member_values,
6825 return_values: request.return_values,
6826 diagnostics: vec![diagnostic],
6827 decisions: Vec::new(),
6828 actions: Vec::new(),
6829 nodes: Vec::new(),
6830 }]
6831 }
6832
6833 fn single_token_insertion_recovery(
6836 &mut self,
6837 recovery: RecoveryRequest<'_, '_>,
6838 ) -> Vec<RecognizeOutcome> {
6839 let RecoveryRequest {
6840 atn,
6841 transition,
6842 expected_symbols,
6843 target,
6844 request,
6845 visiting,
6846 memo,
6847 expected,
6848 } = recovery;
6849 let RecognizeRequest {
6850 stop_state,
6851 index,
6852 rule_start_index,
6853 decision_start_index,
6854 init_action_rules,
6855 predicates,
6856 semantics,
6857 rule_args,
6858 member_actions,
6859 return_actions,
6860 local_int_arg,
6861 member_values,
6862 return_values,
6863 rule_alt_number,
6864 track_alt_numbers,
6865 consumed_eof,
6866 precedence,
6867 depth,
6868 ..
6869 } = request;
6870 let follow_symbols = state_expected_symbols(atn, transition.target());
6871 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
6872 transition,
6873 index,
6874 atn.max_token_type(),
6875 &expected_symbols,
6876 &follow_symbols,
6877 ) else {
6878 return Vec::new();
6879 };
6880 self.recognize_state(
6881 atn,
6882 RecognizeRequest {
6883 state_number: target,
6884 stop_state,
6885 index,
6886 rule_start_index,
6887 decision_start_index,
6888 init_action_rules,
6889 predicates,
6890 semantics,
6891 rule_args,
6892 member_actions,
6893 return_actions,
6894 local_int_arg,
6895 member_values,
6896 return_values,
6897 rule_alt_number,
6898 track_alt_numbers,
6899 consumed_eof,
6900 precedence,
6901 depth: depth + 1,
6902 recovery_symbols: BTreeSet::new(),
6903 recovery_state: None,
6904 },
6905 visiting,
6906 memo,
6907 expected,
6908 )
6909 .into_iter()
6910 .map(|mut outcome| {
6911 outcome.diagnostics.insert(0, diagnostic.clone());
6912 outcome.nodes.insert(
6913 0,
6914 RecognizedNode::MissingToken {
6915 token_type,
6916 at_index: index,
6917 text: text.clone(),
6918 },
6919 );
6920 outcome
6921 })
6922 .collect()
6923 }
6924
6925 #[allow(clippy::too_many_lines)]
6928 fn recognize_state(
6929 &mut self,
6930 atn: &Atn,
6931 request: RecognizeRequest<'_>,
6932 visiting: &mut BTreeSet<RecognizeKey>,
6933 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
6934 expected: &mut ExpectedTokens,
6935 ) -> Vec<RecognizeOutcome> {
6936 let request_template = request.clone();
6937 let RecognizeRequest {
6938 state_number,
6939 stop_state,
6940 index,
6941 rule_start_index,
6942 decision_start_index,
6943 init_action_rules,
6944 predicates,
6945 semantics,
6946 rule_args,
6947 member_actions,
6948 return_actions,
6949 local_int_arg,
6950 member_values,
6951 return_values,
6952 rule_alt_number,
6953 track_alt_numbers,
6954 consumed_eof,
6955 precedence,
6956 depth,
6957 recovery_symbols,
6958 recovery_state,
6959 } = request;
6960 if depth > RECOGNITION_DEPTH_LIMIT {
6961 return Vec::new();
6962 }
6963 if state_number == stop_state {
6964 return stop_outcome(
6965 index,
6966 consumed_eof,
6967 rule_alt_number,
6968 member_values,
6969 return_values,
6970 );
6971 }
6972 let key = RecognizeKey {
6973 state_number,
6974 stop_state,
6975 index,
6976 rule_start_index,
6977 decision_start_index,
6978 local_int_arg,
6979 member_values: member_values.clone(),
6980 return_values: return_values.clone(),
6981 rule_alt_number,
6982 track_alt_numbers,
6983 consumed_eof,
6984 precedence,
6985 recovery_symbols: recovery_symbols.clone(),
6986 recovery_state,
6987 };
6988 if let Some(outcomes) = memo.get(&key) {
6989 return outcomes.clone();
6990 }
6991
6992 let visit_key = key.clone();
6993 if !visiting.insert(visit_key.clone()) {
6994 return Vec::new();
6995 }
6996
6997 let Some(state) = atn.state(state_number) else {
6998 visiting.remove(&visit_key);
6999 return Vec::new();
7000 };
7001 let next_decision_start_index = if starts_prediction_decision(state) {
7002 Some(index)
7003 } else {
7004 decision_start_index
7005 };
7006 let (epsilon_recovery_symbols, epsilon_recovery_state) =
7007 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
7008 let mut outcomes = Vec::new();
7009 for (transition_index, transition) in state.transitions.iter().enumerate() {
7010 let decision = transition_decision(atn, state, transition_index, predicates);
7011 let next_alt_number =
7012 next_alt_number(state, transition_index, rule_alt_number, track_alt_numbers);
7013 match transition {
7014 Transition::Epsilon { target } | Transition::Action { target, .. } => {
7015 let action_rule_index = match transition {
7016 Transition::Action { rule_index, .. } => Some(*rule_index),
7017 _ => None,
7018 };
7019 outcomes.extend(self.recognize_epsilon_or_action_step(
7020 atn,
7021 &request_template,
7022 EpsilonActionStep {
7023 source_state: state_number,
7024 target: *target,
7025 action_rule_index,
7026 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
7027 decision,
7028 decision_start_index: next_decision_start_index,
7029 alt_number: next_alt_number,
7030 recovery_symbols: epsilon_recovery_symbols.clone(),
7031 recovery_state: epsilon_recovery_state,
7032 },
7033 RecognizeScratch {
7034 visiting,
7035 memo,
7036 expected,
7037 },
7038 ));
7039 }
7040 Transition::Predicate {
7041 target,
7042 rule_index,
7043 pred_index,
7044 ..
7045 } => {
7046 let predicate = PredicateEval {
7047 index,
7048 rule_index: *rule_index,
7049 pred_index: *pred_index,
7050 predicates,
7051 semantics,
7052 context: None,
7053 local_int_arg,
7054 member_values: &member_values,
7055 };
7056 if self.parser_predicate_matches(predicate) {
7057 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
7058 outcomes.extend(
7059 self.recognize_state(
7060 atn,
7061 RecognizeRequest {
7062 state_number: *target,
7063 stop_state,
7064 index,
7065 rule_start_index,
7066 decision_start_index: next_decision_start_index,
7067 init_action_rules,
7068 predicates,
7069 semantics,
7070 rule_args,
7071 member_actions,
7072 return_actions,
7073 local_int_arg,
7074 member_values: member_values.clone(),
7075 return_values: return_values.clone(),
7076 rule_alt_number: next_alt_number,
7077 track_alt_numbers,
7078 consumed_eof,
7079 precedence,
7080 depth: depth + 1,
7081 recovery_symbols: epsilon_recovery_symbols.clone(),
7082 recovery_state: epsilon_recovery_state,
7083 },
7084 visiting,
7085 memo,
7086 expected,
7087 )
7088 .into_iter()
7089 .map(|mut outcome| {
7090 prepend_decision(&mut outcome, decision);
7091 if let Some(rule_index) = left_recursive_boundary {
7092 outcome.nodes.insert(
7093 0,
7094 RecognizedNode::LeftRecursiveBoundary { rule_index },
7095 );
7096 }
7097 outcome
7098 }),
7099 );
7100 } else if let Some(message) = semantics
7101 .and_then(|semantics| {
7102 self.parser_semantic_ir_predicate_failure_message(
7103 *rule_index,
7104 *pred_index,
7105 semantics,
7106 )
7107 })
7108 .or_else(|| {
7109 self.parser_predicate_failure_message(
7110 *rule_index,
7111 *pred_index,
7112 predicates,
7113 )
7114 })
7115 {
7116 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
7117 rule_index: *rule_index,
7118 index,
7119 message,
7120 member_values: member_values.clone(),
7121 return_values: return_values.clone(),
7122 rule_alt_number,
7123 }));
7124 } else {
7125 record_predicate_no_viable(expected, next_decision_start_index, index);
7126 }
7127 }
7128 Transition::Precedence {
7129 target,
7130 precedence: transition_precedence,
7131 } => {
7132 if *transition_precedence >= precedence {
7133 outcomes.extend(
7134 self.recognize_state(
7135 atn,
7136 RecognizeRequest {
7137 state_number: *target,
7138 stop_state,
7139 index,
7140 rule_start_index,
7141 decision_start_index: next_decision_start_index,
7142 init_action_rules,
7143 predicates,
7144 semantics,
7145 rule_args,
7146 member_actions,
7147 return_actions,
7148 local_int_arg,
7149 member_values: member_values.clone(),
7150 return_values: return_values.clone(),
7151 rule_alt_number: next_alt_number,
7152 track_alt_numbers,
7153 consumed_eof,
7154 precedence,
7155 depth: depth + 1,
7156 recovery_symbols: epsilon_recovery_symbols.clone(),
7157 recovery_state: epsilon_recovery_state,
7158 },
7159 visiting,
7160 memo,
7161 expected,
7162 )
7163 .into_iter()
7164 .map(|mut outcome| {
7165 prepend_decision(&mut outcome, decision);
7166 outcome
7167 }),
7168 );
7169 }
7170 }
7171 Transition::Rule {
7172 target,
7173 rule_index,
7174 follow_state,
7175 precedence: rule_precedence,
7176 ..
7177 } => {
7178 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
7179 else {
7180 continue;
7181 };
7182 let child_local_int_arg =
7183 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
7184 let expected_before_child = expected.clone();
7185 let children = self.recognize_state(
7186 atn,
7187 RecognizeRequest {
7188 state_number: *target,
7189 stop_state: child_stop,
7190 index,
7191 rule_start_index: index,
7192 decision_start_index: None,
7193 init_action_rules,
7194 predicates,
7195 semantics,
7196 rule_args,
7197 member_actions,
7198 return_actions,
7199 local_int_arg: child_local_int_arg,
7200 member_values: member_values.clone(),
7201 return_values: BTreeMap::new(),
7202 rule_alt_number: 0,
7203 track_alt_numbers,
7204 consumed_eof: false,
7205 precedence: *rule_precedence,
7206 depth: depth + 1,
7207 recovery_symbols: epsilon_recovery_symbols.clone(),
7208 recovery_state: epsilon_recovery_state,
7209 },
7210 visiting,
7211 memo,
7212 expected,
7213 );
7214 let children = if children.is_empty() {
7215 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
7216 atn,
7217 rule_index: *rule_index,
7218 start_index: index,
7219 follow_state: *follow_state,
7220 stop_state,
7221 member_values: member_values.clone(),
7222 expected,
7223 })
7224 } else {
7225 children
7226 };
7227 let preserve_child_expected =
7228 self.child_expected_reaches_clean_eof(&children, expected);
7229 restore_expected(
7230 &children,
7231 index,
7232 expected,
7233 expected_before_child,
7234 preserve_child_expected,
7235 );
7236 for child in children {
7237 let child_node = RecognizedNode::Rule {
7238 rule_index: *rule_index,
7239 invoking_state: invoking_state_number(state_number),
7240 alt_number: child.alt_number,
7241 start_index: index,
7242 stop_index: self.rule_stop_token_index(child.index, child.consumed_eof),
7243 return_values: child.return_values.clone(),
7244 children: fold_left_recursive_boundaries(child.nodes.clone()),
7245 };
7246 outcomes.extend(
7247 self.recognize_state(
7248 atn,
7249 RecognizeRequest {
7250 state_number: *follow_state,
7251 stop_state,
7252 index: child.index,
7253 rule_start_index,
7254 decision_start_index: next_decision_start_index,
7255 init_action_rules,
7256 predicates,
7257 semantics,
7258 rule_args,
7259 member_actions,
7260 return_actions,
7261 local_int_arg,
7262 member_values: child.member_values.clone(),
7263 return_values: return_values.clone(),
7264 rule_alt_number,
7265 track_alt_numbers,
7266 consumed_eof: consumed_eof || child.consumed_eof,
7267 precedence,
7268 depth: depth + 1,
7269 recovery_symbols: BTreeSet::new(),
7270 recovery_state: None,
7271 },
7272 visiting,
7273 memo,
7274 expected,
7275 )
7276 .into_iter()
7277 .map(|mut outcome| {
7278 outcome.consumed_eof |= child.consumed_eof;
7279 let mut diagnostics = child.diagnostics.clone();
7280 diagnostics.append(&mut outcome.diagnostics);
7281 outcome.diagnostics = diagnostics;
7282 let mut decisions = child.decisions.clone();
7283 decisions.append(&mut outcome.decisions);
7284 outcome.decisions = decisions;
7285 prepend_decision(&mut outcome, decision);
7286 let mut actions = child.actions.clone();
7287 if init_action_rules.contains(rule_index) {
7288 actions.insert(
7289 0,
7290 ParserAction::new_rule_init(
7291 *rule_index,
7292 index,
7293 Some(*follow_state),
7294 ),
7295 );
7296 }
7297 actions.append(&mut outcome.actions);
7298 outcome.actions = actions;
7299 outcome.nodes.insert(0, child_node.clone());
7300 outcome
7301 }),
7302 );
7303 }
7304 }
7305 Transition::Atom { target, .. }
7306 | Transition::Range { target, .. }
7307 | Transition::Set { target, .. }
7308 | Transition::NotSet { target, .. }
7309 | Transition::Wildcard { target, .. } => {
7310 let symbol = self.token_type_at(index);
7311 if transition.matches(symbol, 1, atn.max_token_type()) {
7312 let next_index = self.consume_index(index, symbol);
7313 outcomes.extend(
7314 self.recognize_state(
7315 atn,
7316 RecognizeRequest {
7317 state_number: *target,
7318 stop_state,
7319 index: next_index,
7320 rule_start_index,
7321 decision_start_index: next_decision_start_index,
7322 init_action_rules,
7323 predicates,
7324 semantics,
7325 rule_args,
7326 member_actions,
7327 return_actions,
7328 local_int_arg,
7329 member_values: member_values.clone(),
7330 return_values: return_values.clone(),
7331 rule_alt_number: next_alt_number,
7332 track_alt_numbers,
7333 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
7334 precedence,
7335 depth: depth + 1,
7336 recovery_symbols: BTreeSet::new(),
7337 recovery_state: None,
7338 },
7339 visiting,
7340 memo,
7341 expected,
7342 )
7343 .into_iter()
7344 .map(|mut outcome| {
7345 prepend_decision(&mut outcome, decision);
7346 outcome.consumed_eof |= symbol == TOKEN_EOF;
7347 outcome.nodes.insert(0, RecognizedNode::Token { index });
7348 outcome
7349 }),
7350 );
7351 } else {
7352 let expected_symbols =
7353 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
7354 if expected_symbols.contains(&symbol) {
7355 continue;
7356 }
7357 expected.record_transition(index, transition, atn.max_token_type());
7358 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
7359 let before_recovery = outcomes.len();
7360 let recovery_request = request_template.clone();
7361 outcomes.extend(
7362 self.single_token_deletion_recovery(RecoveryRequest {
7363 atn,
7364 transition,
7365 expected_symbols: expected_symbols.clone(),
7366 target: *target,
7367 request: recovery_request.clone(),
7368 visiting,
7369 memo,
7370 expected,
7371 })
7372 .into_iter()
7373 .map(|mut outcome| {
7374 prepend_decision(&mut outcome, decision);
7375 outcome
7376 }),
7377 );
7378 if !state_is_left_recursive_rule(atn, state) {
7379 outcomes.extend(
7380 self.single_token_insertion_recovery(RecoveryRequest {
7381 atn,
7382 transition,
7383 expected_symbols: expected_symbols.clone(),
7384 target: *target,
7385 request: recovery_request.clone(),
7386 visiting,
7387 memo,
7388 expected,
7389 })
7390 .into_iter()
7391 .map(|mut outcome| {
7392 prepend_decision(&mut outcome, decision);
7393 outcome
7394 }),
7395 );
7396 }
7397 outcomes.extend(self.current_token_deletion_recovery(
7398 CurrentTokenDeletionRequest {
7399 atn,
7400 expected_symbols: expected_symbols.clone(),
7401 request: recovery_request.clone(),
7402 visiting,
7403 memo,
7404 expected,
7405 },
7406 ));
7407 if outcomes.len() == before_recovery {
7408 outcomes.extend(self.consuming_failure_fallback(
7409 ConsumingFailureFallback {
7410 atn,
7411 target: *target,
7412 request: recovery_request,
7413 symbol,
7414 expected_symbols,
7415 decision_start_index: next_decision_start_index,
7416 decision,
7417 },
7418 visiting,
7419 memo,
7420 expected,
7421 ));
7422 }
7423 }
7424 }
7425 }
7426 }
7427
7428 visiting.remove(&visit_key);
7429 self.record_prediction_diagnostics(atn, state, index, &outcomes);
7430 if matches!(
7431 self.prediction_mode,
7432 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
7433 ) {
7434 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes);
7435 }
7436 dedupe_outcomes(&mut outcomes);
7437 memo.insert(key, outcomes.clone());
7438 outcomes
7439 }
7440
7441 fn recognize_epsilon_or_action_step(
7444 &mut self,
7445 atn: &Atn,
7446 request: &RecognizeRequest<'_>,
7447 step: EpsilonActionStep,
7448 scratch: RecognizeScratch<'_>,
7449 ) -> Vec<RecognizeOutcome> {
7450 let RecognizeScratch {
7451 visiting,
7452 memo,
7453 expected,
7454 } = scratch;
7455 let action = step.action_rule_index.map(|rule_index| {
7456 ParserAction::new(
7457 step.source_state,
7458 rule_index,
7459 request.rule_start_index,
7460 self.rule_stop_token_index(request.index, request.consumed_eof),
7461 )
7462 });
7463 let next_member_values = if action.is_some() {
7464 member_values_after_action(
7465 step.source_state,
7466 request.member_actions,
7467 request.semantics,
7468 &request.member_values,
7469 )
7470 } else {
7471 request.member_values.clone()
7472 };
7473 let next_return_values = action.map_or_else(
7474 || request.return_values.clone(),
7475 |action| {
7476 return_values_after_action(
7477 step.source_state,
7478 action.rule_index(),
7479 request.return_actions,
7480 request.semantics,
7481 &request.return_values,
7482 )
7483 },
7484 );
7485
7486 self.recognize_state(
7487 atn,
7488 RecognizeRequest {
7489 state_number: step.target,
7490 stop_state: request.stop_state,
7491 index: request.index,
7492 rule_start_index: request.rule_start_index,
7493 decision_start_index: step.decision_start_index,
7494 init_action_rules: request.init_action_rules,
7495 predicates: request.predicates,
7496 semantics: request.semantics,
7497 rule_args: request.rule_args,
7498 member_actions: request.member_actions,
7499 return_actions: request.return_actions,
7500 local_int_arg: request.local_int_arg,
7501 member_values: next_member_values,
7502 return_values: next_return_values,
7503 rule_alt_number: step.alt_number,
7504 track_alt_numbers: request.track_alt_numbers,
7505 consumed_eof: request.consumed_eof,
7506 precedence: request.precedence,
7507 depth: request.depth + 1,
7508 recovery_symbols: step.recovery_symbols,
7509 recovery_state: step.recovery_state,
7510 },
7511 visiting,
7512 memo,
7513 expected,
7514 )
7515 .into_iter()
7516 .map(|mut outcome| {
7517 prepend_decision(&mut outcome, step.decision);
7518 if let Some(rule_index) = step.left_recursive_boundary {
7519 outcome
7520 .nodes
7521 .insert(0, RecognizedNode::LeftRecursiveBoundary { rule_index });
7522 }
7523 if let Some(action) = action {
7524 outcome.actions.insert(0, action);
7525 }
7526 outcome
7527 })
7528 .collect()
7529 }
7530
7531 fn token_type_at(&mut self, index: usize) -> i32 {
7536 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
7537 self.input.fill();
7538 }
7539 self.input.token_type_at_index(index)
7540 }
7541
7542 fn cached_state_expected_symbols(
7554 &mut self,
7555 atn: &Atn,
7556 state_number: usize,
7557 ) -> Rc<BTreeSet<i32>> {
7558 if let Some(cached) = self.state_expected_cache.get(&state_number) {
7559 return Rc::clone(cached);
7560 }
7561 let symbols = state_expected_symbols(atn, state_number);
7562 let entry = self.intern_recovery_symbols(symbols);
7563 self.state_expected_cache
7564 .insert(state_number, Rc::clone(&entry));
7565 entry
7566 }
7567
7568 fn cached_state_expected_token_set(
7569 &mut self,
7570 atn: &Atn,
7571 state_number: usize,
7572 ) -> Rc<TokenBitSet> {
7573 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
7574 return Rc::clone(cached);
7575 }
7576 let symbols = with_shared_atn_caches(atn, |cache| {
7580 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
7581 return Rc::clone(cached);
7582 }
7583 let symbols = Rc::new(state_expected_token_set(atn, state_number));
7584 cache
7585 .state_expected_tokens
7586 .insert(state_number, Rc::clone(&symbols));
7587 symbols
7588 });
7589 self.state_expected_token_cache
7590 .insert(state_number, Rc::clone(&symbols));
7591 symbols
7592 }
7593
7594 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
7595 if self.rule_stop_reach_cache.len() <= state_number {
7596 self.rule_stop_reach_cache
7597 .resize_with(atn.states().len().max(state_number + 1), || None);
7598 }
7599 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
7600 return reaches;
7601 }
7602 let reaches = with_shared_atn_caches(atn, |cache| {
7603 *cache
7604 .rule_stop_reach
7605 .entry(state_number)
7606 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
7607 });
7608 self.rule_stop_reach_cache[state_number] = Some(reaches);
7609 reaches
7610 }
7611
7612 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
7615 Rc::clone(&self.empty_recovery_symbols)
7616 }
7617
7618 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
7627 if set.is_empty() {
7628 return Rc::clone(&self.empty_recovery_symbols);
7629 }
7630 let candidate = Rc::new(set);
7631 match self.recovery_symbols_intern.get(&candidate) {
7632 Some(existing) => Rc::clone(existing),
7633 None => {
7634 self.recovery_symbols_intern
7635 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
7636 candidate
7637 }
7638 }
7639 }
7640
7641 fn cached_decision_lookahead(
7646 &mut self,
7647 atn: &Atn,
7648 state: &AtnState,
7649 rule_stop_state: usize,
7650 ) -> Rc<DecisionLookahead> {
7651 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number) {
7658 return Rc::clone(cached);
7659 }
7660 let entry = with_shared_atn_caches(atn, |cache| {
7661 if let Some(cached) = cache.decision_lookahead.get(&state.state_number) {
7662 return Rc::clone(cached);
7663 }
7664 let mut entry = DecisionLookahead {
7665 transitions: Vec::with_capacity(state.transitions.len()),
7666 };
7667 for transition in &state.transitions {
7668 entry.transitions.push(transition_first_set(
7669 atn,
7670 transition,
7671 rule_stop_state,
7672 &mut cache.first_set,
7673 ));
7674 }
7675 let entry = Rc::new(entry);
7676 cache
7677 .decision_lookahead
7678 .insert(state.state_number, Rc::clone(&entry));
7679 entry
7680 });
7681 self.decision_lookahead_cache
7682 .insert(state.state_number, Rc::clone(&entry));
7683 entry
7684 }
7685
7686 fn cached_rule_first_set(
7687 &mut self,
7688 atn: &Atn,
7689 target: usize,
7690 child_stop: usize,
7691 ) -> Rc<FirstSet> {
7692 if self.rule_first_set_cache.len() <= target {
7693 self.rule_first_set_cache
7694 .resize_with(atn.states().len().max(target + 1), || None);
7695 }
7696 if let Some(cached) = self
7697 .rule_first_set_cache
7698 .get(target)
7699 .and_then(Option::as_ref)
7700 {
7701 return Rc::clone(cached);
7702 }
7703 let first = with_shared_first_set_cache(atn, |cache| {
7704 rule_first_set(atn, target, child_stop, cache)
7705 });
7706 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
7707 first
7708 }
7709
7710 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
7711 if self.empty_cycle_cache.len() <= state_number {
7712 self.empty_cycle_cache
7713 .resize_with(atn.states().len().max(state_number + 1), || None);
7714 }
7715 if let Some(cached) = self.empty_cycle_cache[state_number] {
7716 return cached;
7717 }
7718 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
7719 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
7720 self.empty_cycle_cache[state_number] = Some(result);
7721 result
7722 }
7723
7724 fn empty_path_reaches_state(
7725 &mut self,
7726 atn: &Atn,
7727 state_number: usize,
7728 target_state: usize,
7729 visited: &mut FxHashSet<usize>,
7730 ) -> bool {
7731 if !visited.insert(state_number) {
7732 return false;
7733 }
7734 let Some(state) = atn.state(state_number) else {
7735 return false;
7736 };
7737 for transition in &state.transitions {
7738 match transition {
7739 Transition::Atom { .. }
7740 | Transition::Range { .. }
7741 | Transition::Set { .. }
7742 | Transition::NotSet { .. }
7743 | Transition::Wildcard { .. } => {}
7744 Transition::Rule {
7745 target,
7746 rule_index,
7747 follow_state,
7748 ..
7749 } => {
7750 if *target == target_state
7751 || self.empty_path_reaches_state(atn, *target, target_state, visited)
7752 {
7753 return true;
7754 }
7755 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
7756 else {
7757 continue;
7758 };
7759 if self
7760 .cached_rule_first_set(atn, *target, child_stop)
7761 .nullable
7762 && (*follow_state == target_state
7763 || self.empty_path_reaches_state(
7764 atn,
7765 *follow_state,
7766 target_state,
7767 visited,
7768 ))
7769 {
7770 return true;
7771 }
7772 }
7773 Transition::Epsilon { target }
7774 | Transition::Predicate { target, .. }
7775 | Transition::Action { target, .. }
7776 | Transition::Precedence { target, .. } => {
7777 if *target == target_state
7778 || self.empty_path_reaches_state(atn, *target, target_state, visited)
7779 {
7780 return true;
7781 }
7782 }
7783 }
7784 }
7785 false
7786 }
7787
7788 fn should_memoize_single_outcome(&mut self, key: &FastRecognizeKey) -> bool {
7791 match self.single_outcome_memo_mode {
7792 SingleOutcomeMemoMode::Promote => true,
7793 SingleOutcomeMemoMode::Sparse => false,
7794 SingleOutcomeMemoMode::Probe => {
7795 self.single_outcome_probe_samples += 1;
7796 if !self.single_outcome_probe_seen.insert(key.clone()) {
7797 self.single_outcome_probe_repeats += 1;
7798 }
7799 if self.single_outcome_probe_repeats >= CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
7800 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Promote;
7801 self.single_outcome_probe_seen.clear();
7802 return true;
7803 }
7804 if self.single_outcome_probe_samples >= CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT {
7805 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Sparse;
7806 self.single_outcome_probe_seen.clear();
7807 return false;
7808 }
7809 true
7810 }
7811 }
7812 }
7813
7814 fn token_at(&mut self, index: usize) -> Option<CommonToken> {
7816 self.input.get(index).cloned()
7817 }
7818
7819 fn token_ref_at(&mut self, index: usize) -> Option<TokenRef> {
7821 self.input.get_ref(index)
7822 }
7823
7824 fn current_visible_index(&mut self) -> usize {
7827 let index = self.input.index();
7828 self.input.seek(index);
7829 self.input.index()
7830 }
7831
7832 fn child_expected_reaches_clean_eof(
7835 &mut self,
7836 children: &[RecognizeOutcome],
7837 expected: &ExpectedTokens,
7838 ) -> bool {
7839 let Some(index) = expected.index else {
7840 return false;
7841 };
7842 self.token_type_at(index) == TOKEN_EOF
7843 && children
7844 .iter()
7845 .any(|child| child.diagnostics.is_empty() && child.index == index)
7846 }
7847
7848 fn previous_token_index(&mut self, index: usize) -> Option<usize> {
7855 self.input.previous_visible_token_index(index)
7856 }
7857
7858 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
7863 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
7864 Some(index)
7865 } else {
7866 self.previous_token_index(index)
7867 }
7868 }
7869
7870 #[must_use]
7887 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
7888 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
7889 self.rule_stop_token_index(current_index, consumed_eof)
7890 }
7891
7892 #[must_use]
7901 pub fn after_action_stop_index_for_tree(
7902 &mut self,
7903 tree: &ParseTree,
7904 current_index: usize,
7905 ) -> Option<usize> {
7906 if let ParseTree::Rule(rule) = tree {
7907 if let Some(stop) = rule.context().stop() {
7908 let token_index = stop.token_index();
7909 if token_index >= 0 {
7910 return Some(token_index.unsigned_abs());
7911 }
7912 }
7913 }
7914 self.after_action_stop_index(current_index)
7915 }
7916
7917 #[must_use]
7927 pub fn after_action_start_index_for_tree(
7928 &self,
7929 tree: &ParseTree,
7930 fallback_index: usize,
7931 ) -> usize {
7932 if let ParseTree::Rule(rule) = tree {
7933 if let Some(start) = rule.context().start() {
7934 let token_index = start.token_index();
7935 if token_index >= 0 {
7936 return token_index.unsigned_abs();
7937 }
7938 }
7939 }
7940 fallback_index
7941 }
7942
7943 fn rule_stop_token_ref(&mut self, index: usize, consumed_eof: bool) -> Option<TokenRef> {
7948 self.rule_stop_token_index(index, consumed_eof)
7949 .and_then(|token_index| self.token_ref_at(token_index))
7950 }
7951
7952 fn predicate_failure_recovery(
7959 &mut self,
7960 request: PredicateFailureRecovery<'_>,
7961 ) -> RecognizeOutcome {
7962 let PredicateFailureRecovery {
7963 rule_index,
7964 index,
7965 message,
7966 member_values,
7967 return_values,
7968 rule_alt_number,
7969 } = request;
7970 let rule_name = self
7971 .rule_names()
7972 .get(rule_index)
7973 .map_or_else(|| rule_index.to_string(), Clone::clone);
7974 let diagnostic = diagnostic_for_token(
7975 self.token_at(index).as_ref(),
7976 format!("rule {rule_name} {message}"),
7977 );
7978 let mut nodes = Vec::new();
7979 let mut next_index = index;
7980 loop {
7981 let symbol = self.token_type_at(next_index);
7982 if symbol == TOKEN_EOF {
7983 break;
7984 }
7985 nodes.push(RecognizedNode::ErrorToken { index: next_index });
7986 let after = self.consume_index(next_index, symbol);
7987 if after == next_index {
7988 break;
7989 }
7990 next_index = after;
7991 }
7992 RecognizeOutcome {
7993 index: next_index,
7994 consumed_eof: false,
7995 alt_number: rule_alt_number,
7996 member_values,
7997 return_values,
7998 diagnostics: vec![diagnostic],
7999 decisions: Vec::new(),
8000 actions: Vec::new(),
8001 nodes,
8002 }
8003 }
8004
8005 fn parser_semantic_hook_result(
8008 &mut self,
8009 request: ParserSemanticHookRequest<'_>,
8010 ) -> Option<bool> {
8011 let ParserSemanticHookRequest {
8012 index,
8013 rule_index,
8014 pred_index,
8015 context,
8016 local_int_arg,
8017 member_values,
8018 } = request;
8019 let rule_name = self.rule_names().get(rule_index).cloned();
8020 self.input.seek(index);
8021 let input = &mut self.input;
8022 let semantic_hooks = &mut self.semantic_hooks;
8023 let mut ctx = ParserSemCtx {
8024 input,
8025 rule_index,
8026 coordinate_index: pred_index,
8027 rule_name,
8028 context,
8029 tree: None,
8030 local_int_arg,
8031 member_values,
8032 action: None,
8033 };
8034 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
8035 }
8036
8037 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
8042 if prior.is_empty() {
8043 return;
8044 }
8045 let mut merged = prior;
8046 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
8047 if !merged.contains(&coordinate) {
8048 merged.push(coordinate);
8049 }
8050 }
8051 self.unknown_predicate_hits = merged;
8052 }
8053
8054 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
8063 apply_unknown_predicate_policy(
8064 self.unknown_predicate_policy,
8065 rule_index,
8066 pred_index,
8067 &mut self.unknown_predicate_hits,
8068 )
8069 }
8070
8071 fn unknown_semantic_error(&self) -> Option<AntlrError> {
8074 use std::fmt::Write as _;
8075 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
8076 return None;
8077 }
8078 let mut message = String::new();
8079 for (rule_index, pred_index) in &self.unknown_predicate_hits {
8080 if !message.is_empty() {
8081 message.push_str("; ");
8082 }
8083 let _ = match self.rule_names().get(*rule_index) {
8084 Some(rule_name) => write!(
8085 message,
8086 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
8087 ),
8088 None => write!(
8089 message,
8090 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
8091 ),
8092 };
8093 }
8094 for (rule_index, source_state) in &self.unhandled_action_hits {
8095 if !message.is_empty() {
8096 message.push_str("; ");
8097 }
8098 let _ = match self.rule_names().get(*rule_index) {
8099 Some(rule_name) => write!(
8100 message,
8101 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
8102 ),
8103 None => write!(
8104 message,
8105 "unhandled semantic action: rule_index={rule_index} state={source_state}"
8106 ),
8107 };
8108 }
8109 Some(AntlrError::Unsupported(message))
8110 }
8111
8112 fn parser_semir_predicate_matches(
8120 &mut self,
8121 semantics: &ParserSemantics,
8122 predicate: &ParserSemanticPredicate,
8123 request: ParserSemanticHookRequest<'_>,
8124 ) -> bool {
8125 self.input.seek(request.index);
8126 let rule_name = self
8127 .data
8128 .rule_names()
8129 .get(request.rule_index)
8130 .map(String::as_str);
8131 let unknown_predicate_policy = self.unknown_predicate_policy;
8132 let mut ctx = ParserSemIrCtx {
8133 input: &mut self.input,
8134 semantic_hooks: &mut self.semantic_hooks,
8135 rule_index: request.rule_index,
8136 coordinate_index: request.pred_index,
8137 rule_name,
8138 context: request.context,
8139 local_int_arg: request.local_int_arg,
8140 member_values: request.member_values,
8141 invoked_predicates: &mut self.invoked_predicates,
8142 unknown_predicate_policy,
8143 unknown_predicate_hits: &mut self.unknown_predicate_hits,
8144 };
8145 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
8146 }
8147
8148 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
8149 let PredicateEval {
8150 index,
8151 rule_index,
8152 pred_index,
8153 predicates,
8154 semantics,
8155 context,
8156 local_int_arg,
8157 member_values,
8158 } = eval;
8159 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
8160 semantics
8161 .predicates
8162 .iter()
8163 .find(|predicate| {
8164 predicate.rule_index == rule_index && predicate.pred_index == pred_index
8165 })
8166 .map(|predicate| (semantics, predicate))
8167 }) {
8168 return self.parser_semir_predicate_matches(
8169 semantics,
8170 predicate,
8171 ParserSemanticHookRequest {
8172 index,
8173 rule_index,
8174 pred_index,
8175 context,
8176 local_int_arg,
8177 member_values,
8178 },
8179 );
8180 }
8181 let Some((_, _, predicate)) = predicates
8182 .iter()
8183 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
8184 else {
8185 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
8186 index,
8187 rule_index,
8188 pred_index,
8189 context,
8190 local_int_arg,
8191 member_values,
8192 }) {
8193 return result;
8194 }
8195 return self.unknown_predicate_result(rule_index, pred_index);
8196 };
8197 self.input.seek(index);
8198 match predicate {
8199 ParserPredicate::True => true,
8200 ParserPredicate::False => false,
8201 ParserPredicate::FalseWithMessage { .. } => false,
8202 ParserPredicate::Invoke { value } => {
8203 let key = (rule_index, pred_index);
8204 if !self.invoked_predicates.contains(&key) {
8205 self.invoked_predicates.push(key);
8206 use std::io::Write as _;
8207 let mut stdout = std::io::stdout().lock();
8208 let _ = writeln!(stdout, "eval={value}");
8209 }
8210 *value
8211 }
8212 ParserPredicate::LookaheadTextEquals { offset, text } => {
8213 self.input.lt(*offset).and_then(Token::text) == Some(*text)
8214 }
8215 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
8216 self.la(*offset) != *token_type
8217 }
8218 ParserPredicate::TokenPairAdjacent => {
8219 let Some(first) = self.input.lt(-2).map(Token::token_index) else {
8220 return false;
8221 };
8222 let Some(second) = self.input.lt(-1).map(Token::token_index) else {
8223 return false;
8224 };
8225 first + 1 == second
8226 }
8227 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
8228 .and_then(|context| {
8229 context.children().iter().find_map(|child| match child {
8230 ParseTree::Rule(rule) if rule.context().rule_index() == *rule_index => {
8231 Some(child.text())
8232 }
8233 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
8234 })
8235 })
8236 .is_none_or(|actual| actual != *text),
8237 ParserPredicate::LocalIntEquals { value } => {
8238 local_int_arg.is_none_or(|(_, actual)| actual == *value)
8239 }
8240 ParserPredicate::LocalIntLessOrEqual { value } => {
8241 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
8242 }
8243 ParserPredicate::MemberModuloEquals {
8244 member,
8245 modulus,
8246 value,
8247 equals,
8248 } => {
8249 if *modulus == 0 {
8250 return false;
8251 }
8252 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
8253 (actual == *value) == *equals
8254 }
8255 ParserPredicate::MemberEquals {
8256 member,
8257 value,
8258 equals,
8259 } => {
8260 let actual = member_values.get(member).copied().unwrap_or_default();
8261 (actual == *value) == *equals
8262 }
8263 }
8264 }
8265
8266 fn parser_predicate_failure_message(
8268 &self,
8269 rule_index: usize,
8270 pred_index: usize,
8271 predicates: &[(usize, usize, ParserPredicate)],
8272 ) -> Option<&'static str> {
8273 predicates
8274 .iter()
8275 .find_map(|(rule, pred, predicate)| match predicate {
8276 ParserPredicate::FalseWithMessage { message }
8277 if *rule == rule_index && *pred == pred_index =>
8278 {
8279 Some(*message)
8280 }
8281 _ => None,
8282 })
8283 }
8284
8285 pub fn parser_semantic_ir_predicate_failure_message(
8288 &self,
8289 rule_index: usize,
8290 pred_index: usize,
8291 semantics: &ParserSemantics,
8292 ) -> Option<&'static str> {
8293 semantics
8294 .predicates
8295 .iter()
8296 .find(|predicate| {
8297 predicate.rule_index == rule_index && predicate.pred_index == pred_index
8298 })
8299 .and_then(|predicate| predicate.failure_message)
8300 }
8301
8302 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
8311 if symbol == TOKEN_EOF {
8312 return index;
8313 }
8314 self.input.next_visible_after(index)
8315 }
8316
8317 fn no_viable_alternative(
8320 &mut self,
8321 start_index: usize,
8322 error_index: usize,
8323 ) -> ParserDiagnostic {
8324 let text = display_input_text(&self.input.text(start_index, error_index));
8325 diagnostic_for_token(
8326 self.token_at(error_index).as_ref(),
8327 format!("no viable alternative at input '{text}'"),
8328 )
8329 }
8330
8331 fn recovery_failure_diagnostic(
8334 &mut self,
8335 index: usize,
8336 decision_start_index: Option<usize>,
8337 expected_symbols: &BTreeSet<i32>,
8338 ) -> ParserDiagnostic {
8339 if expected_symbols.len() > 1 {
8340 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
8341 return self.no_viable_alternative(decision_start, index);
8342 }
8343 }
8344 diagnostic_for_token(
8345 self.token_at(index).as_ref(),
8346 format!(
8347 "mismatched input {} expecting {}",
8348 self.token_at(index)
8349 .as_ref()
8350 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8351 self.expected_symbols_display(expected_symbols)
8352 ),
8353 )
8354 }
8355
8356 fn eof_rule_recovery_diagnostic(
8359 &mut self,
8360 index: usize,
8361 expected_symbols: &BTreeSet<i32>,
8362 expected: &ExpectedTokens,
8363 ) -> ParserDiagnostic {
8364 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
8365 &expected.symbols
8366 } else {
8367 expected_symbols
8368 };
8369 diagnostic_for_token(
8370 self.token_at(index).as_ref(),
8371 format!(
8372 "mismatched input {} expecting {}",
8373 self.token_at(index)
8374 .as_ref()
8375 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8376 self.expected_symbols_display(symbols)
8377 ),
8378 )
8379 }
8380
8381 pub fn text_interval(&mut self, start: usize, stop: Option<usize>) -> String {
8387 let Some(stop) = stop else {
8388 return String::new();
8389 };
8390 let stop = if self
8391 .token_at(stop)
8392 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8393 {
8394 let Some(previous) = self.previous_token_index(stop) else {
8395 return String::new();
8396 };
8397 previous
8398 } else {
8399 stop
8400 };
8401 self.input.text(start, stop)
8402 }
8403
8404 fn clear_prediction_diagnostics(&mut self) {
8407 self.prediction_diagnostics.clear();
8408 self.reported_prediction_diagnostics.clear();
8409 }
8410
8411 fn reset_per_parse_caches(&mut self) {
8433 self.rule_first_set_cache.clear();
8434 self.decision_lookahead_cache.clear();
8435 self.ll1_decision_cache.clear();
8436 self.empty_cycle_cache.clear();
8437 self.rule_stop_reach_cache.clear();
8438 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Probe;
8439 self.single_outcome_probe_seen.clear();
8440 self.single_outcome_probe_samples = 0;
8441 self.single_outcome_probe_repeats = 0;
8442 self.recovery_symbols_intern.clear();
8443 self.state_expected_cache.clear();
8444 self.state_expected_token_cache.clear();
8445 }
8446
8447 fn record_prediction_diagnostics(
8450 &mut self,
8451 atn: &Atn,
8452 state: &AtnState,
8453 start_index: usize,
8454 outcomes: &[RecognizeOutcome],
8455 ) {
8456 if !self.report_diagnostic_errors || state.transitions.len() < 2 {
8457 return;
8458 }
8459 let Some(decision) = atn
8460 .decision_to_state()
8461 .iter()
8462 .position(|state_number| *state_number == state.state_number)
8463 else {
8464 return;
8465 };
8466 let Some(rule_index) = state.rule_index else {
8467 return;
8468 };
8469 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
8470 for outcome in outcomes
8471 .iter()
8472 .filter(|outcome| outcome.diagnostics.is_empty())
8473 {
8474 let Some(alt) = outcome.decisions.first() else {
8475 continue;
8476 };
8477 alts_by_end
8478 .entry(outcome.index)
8479 .or_default()
8480 .insert(alt + 1);
8481 }
8482 let Some((&end_index, ambig_alts)) = alts_by_end
8483 .iter()
8484 .filter(|(_, alts)| alts.len() > 1)
8485 .max_by_key(|(end, _)| *end)
8486 else {
8487 return;
8488 };
8489 let rule_name = self
8490 .rule_names()
8491 .get(rule_index)
8492 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
8493 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
8494 let input = display_input_text(&self.input.text(start_index, stop_index));
8495 let alts = ambig_alts
8496 .iter()
8497 .map(usize::to_string)
8498 .collect::<Vec<_>>()
8499 .join(", ");
8500 let key = (decision, start_index, format!("{alts}:{input}"));
8501 if !self.reported_prediction_diagnostics.insert(key) {
8502 return;
8503 }
8504 let start_token = self.token_at(start_index);
8505 let stop_token = self.token_at(stop_index);
8506 self.prediction_diagnostics.push(diagnostic_for_token(
8507 start_token.as_ref(),
8508 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
8509 ));
8510 self.prediction_diagnostics.push(diagnostic_for_token(
8511 stop_token.as_ref(),
8512 format!(
8513 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
8514 ),
8515 ));
8516 }
8517
8518 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
8520 expected_symbols_display(
8521 &state_expected_symbols(atn, state_number),
8522 self.vocabulary(),
8523 )
8524 }
8525
8526 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
8531 let state = usize::try_from(self.data().state()).unwrap_or(0);
8532 ExpectedTokenSet {
8533 symbols: state_expected_symbols(atn, state),
8534 }
8535 }
8536
8537 pub const fn set_bail_on_error(&mut self, bail: bool) {
8540 self.bail_on_error = bail;
8541 }
8542
8543 #[must_use]
8545 pub const fn bail_on_error(&self) -> bool {
8546 self.bail_on_error
8547 }
8548
8549 pub fn rule_invocation_stack(&self) -> Vec<String> {
8552 self.rule_context_stack
8553 .iter()
8554 .rev()
8555 .map(|frame| {
8556 self.data()
8557 .rule_names()
8558 .get(frame.rule_index)
8559 .cloned()
8560 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
8561 })
8562 .collect()
8563 }
8564
8565 pub fn token_display_at(&mut self, index: usize) -> Option<String> {
8567 self.token_at(index).map(|token| format!("{token}"))
8568 }
8569
8570 fn recognized_node_tree(
8572 &mut self,
8573 node: &RecognizedNode,
8574 track_alt_numbers: bool,
8575 ) -> Result<ParseTree, AntlrError> {
8576 match node {
8577 RecognizedNode::Token { index } => {
8578 let token = self
8579 .input
8580 .get_ref(*index)
8581 .ok_or_else(|| AntlrError::ParserError {
8582 line: 0,
8583 column: 0,
8584 message: format!("missing token at index {index}"),
8585 })?;
8586 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
8587 }
8588 RecognizedNode::ErrorToken { index } => {
8589 let token = self
8590 .input
8591 .get_ref(*index)
8592 .ok_or_else(|| AntlrError::ParserError {
8593 line: 0,
8594 column: 0,
8595 message: format!("missing error token at index {index}"),
8596 })?;
8597 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
8598 }
8599 RecognizedNode::MissingToken {
8600 token_type,
8601 at_index,
8602 text,
8603 } => {
8604 let current = self.token_at(*at_index);
8605 let token = CommonToken::new(*token_type)
8606 .with_text(text.as_str())
8607 .with_span(usize::MAX, usize::MAX)
8608 .with_position(
8609 current.as_ref().map(Token::line).unwrap_or_default(),
8610 current.as_ref().map(Token::column).unwrap_or_default(),
8611 );
8612 Ok(ParseTree::Error(ErrorNode::new(token)))
8613 }
8614 RecognizedNode::Rule {
8615 rule_index,
8616 invoking_state,
8617 alt_number,
8618 start_index,
8619 stop_index,
8620 return_values,
8621 children,
8622 } => {
8623 let mut context = ParserRuleContext::new(*rule_index, *invoking_state);
8624 if track_alt_numbers {
8625 context.set_alt_number(*alt_number);
8626 }
8627 for (name, value) in return_values {
8628 context.set_int_return(name.clone(), *value);
8629 }
8630 if let Some(token) = self.token_ref_at(*start_index) {
8631 context.set_start_ref(token);
8632 }
8633 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
8634 context.set_stop_ref(token);
8635 }
8636 for child in children {
8637 context.add_child(self.recognized_node_tree(child, track_alt_numbers)?);
8638 }
8639 Ok(self.rule_node(context))
8640 }
8641 RecognizedNode::LeftRecursiveBoundary { rule_index } => Err(AntlrError::Unsupported(
8642 format!("unfolded left-recursive boundary for rule {rule_index}"),
8643 )),
8644 }
8645 }
8646}
8647
8648impl<S, H> DirectAdaptiveParser<'_, '_, S, H>
8649where
8650 S: TokenSource,
8651 H: SemanticHooks,
8652{
8653 fn parse_rule(
8654 &mut self,
8655 rule_index: usize,
8656 invoking_state: isize,
8657 precedence: i32,
8658 ) -> DirectAdaptiveParseResult<ParseTree> {
8659 let start_state = *self.atn.rule_to_start_state().get(rule_index).ok_or(
8660 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
8661 )?;
8662 let stop_state = *self
8663 .atn
8664 .rule_to_stop_state()
8665 .get(rule_index)
8666 .filter(|state| **state != usize::MAX)
8667 .ok_or(DirectAdaptiveParseControl::Fallback(
8668 DirectAdaptiveFallback::MissingAtn,
8669 ))?;
8670 let start_index = self.parser.current_visible_index();
8671 let mut children = Vec::new();
8672 let mut state_number = start_state;
8673 let mut consumed_eof = false;
8674 while state_number != stop_state {
8675 self.step()?;
8676 let (transition, boundary) = self.next_transition(state_number, precedence)?;
8677 if boundary.is_some() {
8678 return Err(DirectAdaptiveParseControl::Fallback(
8679 DirectAdaptiveFallback::LeftRecursiveBoundary,
8680 ));
8681 }
8682 match transition {
8683 Transition::Epsilon { target } => {
8684 state_number = target;
8685 }
8686 Transition::Precedence {
8687 target,
8688 precedence: transition_precedence,
8689 } => {
8690 if transition_precedence < precedence {
8691 return Err(DirectAdaptiveParseControl::Fallback(
8692 DirectAdaptiveFallback::Precedence,
8693 ));
8694 }
8695 state_number = target;
8696 }
8697 Transition::Rule {
8698 rule_index,
8699 follow_state,
8700 precedence: rule_precedence,
8701 ..
8702 } => {
8703 let child = self.parse_rule(
8704 rule_index,
8705 invoking_state_number(state_number),
8706 rule_precedence,
8707 )?;
8708 if self.parser.build_parse_trees {
8709 children.push(child);
8710 }
8711 state_number = follow_state;
8712 }
8713 Transition::Atom { .. }
8714 | Transition::Range { .. }
8715 | Transition::Set { .. }
8716 | Transition::NotSet { .. }
8717 | Transition::Wildcard { .. } => {
8718 let (matched_eof, child) = self.consume_transition(&transition)?;
8719 consumed_eof |= matched_eof;
8720 if let Some(child) = child {
8721 children.push(child);
8722 }
8723 state_number = transition.target();
8724 }
8725 Transition::Predicate { .. } => {
8726 return Err(DirectAdaptiveParseControl::Fallback(
8727 DirectAdaptiveFallback::Predicate,
8728 ));
8729 }
8730 Transition::Action { .. } => {
8731 return Err(DirectAdaptiveParseControl::Fallback(
8732 DirectAdaptiveFallback::Action,
8733 ));
8734 }
8735 }
8736 }
8737
8738 let mut context = ParserRuleContext::with_child_capacity(
8739 rule_index,
8740 invoking_state,
8741 if self.parser.build_parse_trees {
8742 children.len()
8743 } else {
8744 0
8745 },
8746 );
8747 if let Some(token) = self.parser.token_ref_at(start_index) {
8748 context.set_start_ref(token);
8749 }
8750 let stop_index = self
8751 .parser
8752 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
8753 if let Some(token) = stop_index.and_then(|index| self.parser.token_ref_at(index)) {
8754 context.set_stop_ref(token);
8755 }
8756 if self.parser.build_parse_trees {
8757 for child in children {
8758 context.add_child(child);
8759 }
8760 }
8761 Ok(self.parser.rule_node(context))
8762 }
8763
8764 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
8765 self.steps += 1;
8766 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
8767 return Err(DirectAdaptiveParseControl::Fallback(
8768 DirectAdaptiveFallback::StepLimit,
8769 ));
8770 }
8771 Ok(())
8772 }
8773
8774 fn next_transition(
8775 &mut self,
8776 state_number: usize,
8777 precedence: i32,
8778 ) -> DirectAdaptiveParseResult<(Transition, Option<usize>)> {
8779 let state = self
8780 .atn
8781 .state(state_number)
8782 .ok_or(DirectAdaptiveParseControl::Fallback(
8783 DirectAdaptiveFallback::MissingAtn,
8784 ))?;
8785 if state.is_rule_stop() {
8786 return Err(DirectAdaptiveParseControl::Fallback(
8787 DirectAdaptiveFallback::RuleStop,
8788 ));
8789 }
8790 let transition_index =
8791 self.transition_index(state_number, state.transitions.len(), precedence)?;
8792 let transition = state.transitions.get(transition_index).cloned().ok_or(
8793 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
8794 )?;
8795 let boundary = match &transition {
8796 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
8797 left_recursive_boundary(self.atn, state, *target)
8798 }
8799 _ => None,
8800 };
8801 Ok((transition, boundary))
8802 }
8803
8804 fn transition_index(
8805 &mut self,
8806 state_number: usize,
8807 transition_count: usize,
8808 precedence: i32,
8809 ) -> DirectAdaptiveParseResult<usize> {
8810 match transition_count {
8811 0 => Err(DirectAdaptiveParseControl::Fallback(
8812 DirectAdaptiveFallback::NoTransition,
8813 )),
8814 1 => Ok(0),
8815 _ => {
8816 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
8817 return Ok(alt);
8818 }
8819 let decision = self
8820 .decision_by_state
8821 .get(state_number)
8822 .and_then(|decision| *decision)
8823 .ok_or(DirectAdaptiveParseControl::Fallback(
8824 DirectAdaptiveFallback::UnknownDecision,
8825 ))?;
8826 let prediction = self
8827 .simulator
8828 .adaptive_predict_stream_info_with_precedence(
8829 decision,
8830 direct_precedence(precedence),
8831 &mut self.parser.input,
8832 )
8833 .map_err(|_| {
8834 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
8835 })?;
8836 if prediction.has_semantic_context {
8837 return Err(DirectAdaptiveParseControl::Fallback(
8838 DirectAdaptiveFallback::SemanticContext,
8839 ));
8840 }
8841 prediction
8842 .alt
8843 .checked_sub(1)
8844 .filter(|index| *index < transition_count)
8845 .ok_or(DirectAdaptiveParseControl::Fallback(
8846 DirectAdaptiveFallback::InvalidAlt,
8847 ))
8848 }
8849 }
8850 }
8851
8852 fn ll1_transition_index(
8853 &mut self,
8854 state_number: usize,
8855 transition_count: usize,
8856 ) -> DirectAdaptiveParseResult<Option<usize>> {
8857 let state = self
8858 .atn
8859 .state(state_number)
8860 .ok_or(DirectAdaptiveParseControl::Fallback(
8861 DirectAdaptiveFallback::MissingAtn,
8862 ))?;
8863 if state.precedence_rule_decision {
8864 return Ok(None);
8865 }
8866 let Some(rule_stop) = state
8867 .rule_index
8868 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index).copied())
8869 else {
8870 return Ok(None);
8871 };
8872 let symbol = self.parser.input.la_token(1);
8873 let entry = self
8874 .parser
8875 .cached_decision_lookahead(self.atn, state, rule_stop);
8876 Ok(ll1_greedy_alt(&entry, symbol, state.non_greedy).filter(|alt| *alt < transition_count))
8877 }
8878
8879 fn consume_transition(
8880 &mut self,
8881 transition: &Transition,
8882 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
8883 let symbol = self.parser.input.la_token(1);
8884 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
8885 return Err(DirectAdaptiveParseControl::Fallback(
8886 DirectAdaptiveFallback::TokenMismatch,
8887 ));
8888 }
8889 let token = self
8890 .parser
8891 .input
8892 .lt_ref(1)
8893 .ok_or(DirectAdaptiveParseControl::Fallback(
8894 DirectAdaptiveFallback::TokenMismatch,
8895 ))?;
8896 let matched_eof = symbol == TOKEN_EOF;
8897 if !matched_eof {
8898 self.parser.consume();
8899 }
8900 let child = self
8901 .parser
8902 .build_parse_trees
8903 .then(|| ParseTree::Terminal(TerminalNode::from_ref(token)));
8904 Ok((matched_eof, child))
8905 }
8906}
8907
8908fn left_recursive_boundary(atn: &Atn, state: &AtnState, target: usize) -> Option<usize> {
8911 if !state.precedence_rule_decision {
8912 return None;
8913 }
8914 let target_state = atn.state(target)?;
8915 if target_state.kind == AtnStateKind::LoopEnd {
8916 return None;
8917 }
8918 state.rule_index
8919}
8920
8921const fn next_alt_number(
8928 state: &AtnState,
8929 transition_index: usize,
8930 current_alt_number: usize,
8931 track_alt_numbers: bool,
8932) -> usize {
8933 if !track_alt_numbers || current_alt_number != 0 || state.transitions.len() <= 1 {
8934 return current_alt_number;
8935 }
8936 if matches!(
8937 state.kind,
8938 AtnStateKind::Basic
8939 | AtnStateKind::BlockStart
8940 | AtnStateKind::PlusBlockStart
8941 | AtnStateKind::StarBlockStart
8942 | AtnStateKind::StarLoopEntry
8943 ) && !state.precedence_rule_decision
8944 {
8945 return transition_index + 1;
8946 }
8947 current_alt_number
8948}
8949
8950fn fold_left_recursive_boundaries(nodes: Vec<RecognizedNode>) -> Vec<RecognizedNode> {
8953 let mut folded = Vec::new();
8954 for node in nodes {
8955 match node {
8956 RecognizedNode::LeftRecursiveBoundary { rule_index } => {
8957 if !folded.is_empty() {
8958 let children = std::mem::take(&mut folded);
8959 let start_index = recognized_nodes_start_index(&children).unwrap_or_default();
8960 let stop_index = recognized_nodes_stop_index(&children);
8961 folded.push(RecognizedNode::Rule {
8962 rule_index,
8963 invoking_state: -1,
8964 alt_number: 0,
8965 start_index,
8966 stop_index,
8967 return_values: BTreeMap::new(),
8968 children,
8969 });
8970 }
8971 }
8972 node => folded.push(node),
8973 }
8974 }
8975 folded
8976}
8977
8978fn fold_fast_left_recursive_boundaries(
8980 nodes: Vec<Rc<FastRecognizedNode>>,
8981) -> Vec<Rc<FastRecognizedNode>> {
8982 if !nodes.iter().any(|node| {
8987 matches!(
8988 node.as_ref(),
8989 FastRecognizedNode::LeftRecursiveBoundary { .. }
8990 )
8991 }) {
8992 return nodes;
8993 }
8994 let mut folded: Vec<Rc<FastRecognizedNode>> = Vec::with_capacity(nodes.len());
8995 for node in nodes {
8996 match node.as_ref() {
8997 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
8998 if !folded.is_empty() {
8999 let children = std::mem::take(&mut folded);
9000 let start_index =
9001 fast_recognized_nodes_start_index(&children).unwrap_or_default();
9002 let stop_index = fast_recognized_nodes_stop_index(&children);
9003 folded.push(Rc::new(FastRecognizedNode::Rule {
9004 rule_index: *rule_index,
9005 invoking_state: -1,
9006 start_index,
9007 stop_index,
9008 children: NodeList::from_vec(children),
9009 }));
9010 }
9011 }
9012 _ => folded.push(node),
9013 }
9014 }
9015 folded
9016}
9017
9018fn fast_node_has_left_recursive_boundary(node: &FastRecognizedNode) -> bool {
9019 match node {
9020 FastRecognizedNode::LeftRecursiveBoundary { .. } => true,
9021 FastRecognizedNode::Rule { children, .. } => children.has_left_recursive_boundary(),
9022 FastRecognizedNode::Token { .. }
9023 | FastRecognizedNode::ErrorToken { .. }
9024 | FastRecognizedNode::MissingToken { .. } => false,
9025 }
9026}
9027
9028fn fast_recognized_nodes_start_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
9029 nodes
9030 .iter()
9031 .find_map(|node| fast_recognized_node_start_index(node.as_ref()))
9032}
9033
9034const fn fast_recognized_node_start_index(node: &FastRecognizedNode) -> Option<usize> {
9035 match node {
9036 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
9037 Some(*index)
9038 }
9039 FastRecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
9040 FastRecognizedNode::Rule { start_index, .. } => Some(*start_index),
9041 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
9042 }
9043}
9044
9045const fn fast_recognized_node_span(node: &FastRecognizedNode) -> Option<(usize, Option<usize>)> {
9046 match node {
9047 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
9048 Some((*index, Some(*index)))
9049 }
9050 FastRecognizedNode::MissingToken { at_index, .. } => Some((*at_index, None)),
9051 FastRecognizedNode::Rule {
9052 start_index,
9053 stop_index,
9054 ..
9055 } => Some((*start_index, *stop_index)),
9056 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
9057 }
9058}
9059
9060fn fast_recognized_nodes_stop_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
9061 nodes
9062 .iter()
9063 .rev()
9064 .find_map(|node| fast_recognized_node_stop_index(node.as_ref()))
9065}
9066
9067const fn fast_recognized_node_stop_index(node: &FastRecognizedNode) -> Option<usize> {
9068 match node {
9069 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
9070 Some(*index)
9071 }
9072 FastRecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
9073 FastRecognizedNode::Rule { stop_index, .. } => *stop_index,
9074 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
9075 }
9076}
9077
9078fn recognized_nodes_start_index(nodes: &[RecognizedNode]) -> Option<usize> {
9079 nodes.iter().find_map(recognized_node_start_index)
9080}
9081
9082const fn recognized_node_start_index(node: &RecognizedNode) -> Option<usize> {
9083 match node {
9084 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
9085 RecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
9086 RecognizedNode::Rule { start_index, .. } => Some(*start_index),
9087 RecognizedNode::LeftRecursiveBoundary { .. } => None,
9088 }
9089}
9090
9091fn recognized_nodes_stop_index(nodes: &[RecognizedNode]) -> Option<usize> {
9092 nodes.iter().rev().find_map(recognized_node_stop_index)
9093}
9094
9095fn invoking_state_number(state_number: usize) -> isize {
9098 isize::try_from(state_number).unwrap_or(isize::MAX)
9099}
9100
9101fn direct_precedence(precedence: i32) -> usize {
9102 usize::try_from(precedence.max(0)).unwrap_or_default()
9103}
9104
9105const fn recognized_node_stop_index(node: &RecognizedNode) -> Option<usize> {
9106 match node {
9107 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
9108 RecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
9109 RecognizedNode::Rule { stop_index, .. } => *stop_index,
9110 RecognizedNode::LeftRecursiveBoundary { .. } => None,
9111 }
9112}
9113
9114fn token_input_display(token: &impl Token) -> String {
9115 format!("'{}'", token.text().unwrap_or("<EOF>"))
9116}
9117
9118fn display_input_text(text: &str) -> String {
9119 let mut out = String::new();
9120 for ch in text.chars() {
9121 match ch {
9122 '\n' => out.push_str("\\n"),
9123 '\r' => out.push_str("\\r"),
9124 '\t' => out.push_str("\\t"),
9125 other => out.push(other),
9126 }
9127 }
9128 out
9129}
9130
9131fn diagnostic_for_token(token: Option<&impl Token>, message: String) -> ParserDiagnostic {
9132 ParserDiagnostic {
9133 line: token.map(Token::line).unwrap_or_default(),
9134 column: token.map(Token::column).unwrap_or_default(),
9135 message,
9136 }
9137}
9138
9139#[allow(clippy::print_stderr)]
9141fn report_parser_diagnostics(diagnostics: &[ParserDiagnostic]) {
9142 for diagnostic in diagnostics {
9143 eprintln!(
9144 "line {}:{} {}",
9145 diagnostic.line, diagnostic.column, diagnostic.message
9146 );
9147 }
9148}
9149
9150#[allow(clippy::print_stderr)]
9153fn report_generated_diagnostics(
9154 parser_diagnostics: &[ParserDiagnostic],
9155 token_errors: &[TokenSourceError],
9156) {
9157 let mut token_iter = token_errors.iter().peekable();
9164 for diagnostic in parser_diagnostics {
9165 while let Some(error) = token_iter.peek() {
9166 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
9167 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9168 token_iter.next();
9169 } else {
9170 break;
9171 }
9172 }
9173 eprintln!(
9174 "line {}:{} {}",
9175 diagnostic.line, diagnostic.column, diagnostic.message
9176 );
9177 }
9178 for error in token_iter {
9179 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9180 }
9181}
9182
9183#[allow(clippy::print_stderr)]
9186fn report_token_source_errors(errors: &[TokenSourceError]) {
9187 for error in errors {
9188 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9189 }
9190}
9191
9192fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
9193 let items = symbols
9194 .iter()
9195 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
9196 .collect::<Vec<_>>();
9197 if let [single] = items.as_slice() {
9198 return single.clone();
9199 }
9200 format!("{{{}}}", items.join(", "))
9201}
9202
9203fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
9204 if symbol == TOKEN_EOF {
9205 return "<EOF>".to_owned();
9206 }
9207 vocabulary.display_name(symbol)
9208}
9209
9210fn is_caller_follow_boundary_text(text: &str) -> bool {
9211 text.chars().any(|ch| ch == ';' || ch == '\n')
9212 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
9213}
9214
9215fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
9216 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
9217}
9218
9219fn state_is_left_recursive_rule(atn: &Atn, state: &AtnState) -> bool {
9223 let Some(rule_index) = state.rule_index else {
9224 return false;
9225 };
9226 atn.rule_to_start_state()
9227 .get(rule_index)
9228 .and_then(|state_number| atn.state(*state_number))
9229 .is_some_and(|rule_start| rule_start.left_recursive_rule)
9230}
9231
9232fn select_better_top_outcome(
9239 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
9240 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
9241) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
9242 match (first, second) {
9243 (Ok(first), Ok(second)) => {
9244 if first.0.diagnostics.is_empty() {
9245 Ok(first)
9246 } else {
9247 Ok(second)
9248 }
9249 }
9250 (Ok(first), Err(_)) => Ok(first),
9251 (Err(_), Ok(second)) => Ok(second),
9252 (Err(_), Err(second_expected)) => Err(second_expected),
9253 }
9254}
9255
9256fn select_best_fast_outcome(
9262 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
9263 prediction_mode: PredictionMode,
9264 caller_follow: Option<&TokenBitSet>,
9265 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
9266) -> Option<FastRecognizeOutcome> {
9267 let mut best = None;
9268 let mut best_caller_follow = None;
9269 for outcome in outcomes {
9270 if matches!(
9271 prediction_mode,
9272 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9273 ) && outcome.diagnostics.is_empty()
9274 && let Some(follow) = caller_follow
9275 {
9276 let (token_type, is_boundary, _) = token_info_at(outcome.index);
9277 if is_boundary && follow.contains(token_type) {
9278 let replace =
9279 best_caller_follow
9280 .as_ref()
9281 .is_none_or(|existing: &FastRecognizeOutcome| {
9282 (outcome.index, outcome.consumed_eof)
9283 < (existing.index, existing.consumed_eof)
9284 });
9285 if replace {
9286 best_caller_follow = Some(outcome.clone());
9287 }
9288 }
9289 }
9290 let Some(existing) = best else {
9291 best = Some(outcome);
9292 continue;
9293 };
9294 let outcome_position = (outcome.index, outcome.consumed_eof);
9295 let best_position = (existing.index, existing.consumed_eof);
9296 let better = match prediction_mode {
9297 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
9298 outcome_position,
9299 &outcome.diagnostics,
9300 best_position,
9301 &existing.diagnostics,
9302 ),
9303 PredictionMode::Sll => outcome.index > existing.index,
9304 };
9305 best = Some(if better { outcome } else { existing });
9306 }
9307 let should_use_caller_follow =
9308 best_caller_follow
9309 .as_ref()
9310 .zip(best.as_ref())
9311 .is_some_and(|(candidate, selected)| {
9312 if !selected.diagnostics.is_empty() {
9313 return true;
9314 }
9315 candidate.index < selected.index
9316 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
9317 });
9318 if should_use_caller_follow {
9319 best_caller_follow
9320 } else {
9321 best
9322 }
9323}
9324
9325fn select_best_outcome(
9326 outcomes: impl Iterator<Item = RecognizeOutcome>,
9327 prediction_mode: PredictionMode,
9328) -> Option<RecognizeOutcome> {
9329 let outcomes = outcomes.collect::<Vec<_>>();
9330 let prefer_first_tie = outcomes
9331 .iter()
9332 .any(|outcome| nodes_need_stable_tie(&outcome.nodes));
9333 outcomes.into_iter().reduce(|best, outcome| {
9334 let outcome_position = (outcome.index, outcome.consumed_eof);
9335 let best_position = (best.index, best.consumed_eof);
9336 let better = match prediction_mode {
9337 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
9338 outcome_is_better(
9339 outcome_position,
9340 &outcome.diagnostics,
9341 best_position,
9342 &best.diagnostics,
9343 ) || (!prefer_first_tie
9344 && outcome_position == best_position
9345 && outcome.diagnostics.len() == best.diagnostics.len()
9346 && diagnostic_recovery_rank(&outcome.diagnostics)
9347 == diagnostic_recovery_rank(&best.diagnostics)
9348 && (outcome.decisions < best.decisions
9349 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
9350 }
9351 PredictionMode::Sll => {
9352 outcome_position > best_position
9353 || (outcome_position == best_position
9354 && !prefer_first_tie
9355 && (outcome.decisions < best.decisions
9356 || (outcome.decisions == best.decisions
9357 && outcome_is_better(
9358 outcome_position,
9359 &outcome.diagnostics,
9360 best_position,
9361 &best.diagnostics,
9362 ))))
9363 }
9364 };
9365 if better {
9366 return outcome;
9367 }
9368 best
9369 })
9370}
9371
9372fn transition_decision(
9379 atn: &Atn,
9380 state: &AtnState,
9381 transition_index: usize,
9382 predicates: &[(usize, usize, ParserPredicate)],
9383) -> Option<usize> {
9384 if state.transitions.len() <= 1
9385 || state.precedence_rule_decision
9386 || decision_reaches_unsupported_predicate(atn, state, predicates)
9387 {
9388 return None;
9389 }
9390 Some(transition_index)
9391}
9392
9393const fn starts_prediction_decision(state: &AtnState) -> bool {
9399 state.transitions.len() > 1
9400 && !matches!(
9401 state.kind,
9402 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
9403 )
9404}
9405
9406fn record_no_viable_if_ambiguous(
9409 expected: &mut ExpectedTokens,
9410 decision_start_index: Option<usize>,
9411 index: usize,
9412) {
9413 if expected.index == Some(index) && expected.symbols.len() > 1 {
9414 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
9415 expected.record_no_viable(decision_start, index);
9416 }
9417 }
9418}
9419
9420const fn record_predicate_no_viable(
9423 expected: &mut ExpectedTokens,
9424 decision_start_index: Option<usize>,
9425 index: usize,
9426) {
9427 if let Some(decision_start) = decision_start_index {
9428 expected.record_no_viable(decision_start, index);
9429 }
9430}
9431
9432const fn no_viable_decision_start(
9434 decision_start_index: Option<usize>,
9435 index: usize,
9436) -> Option<usize> {
9437 match decision_start_index {
9438 Some(start) if index > start => Some(start),
9439 _ => None,
9440 }
9441}
9442
9443fn restore_expected(
9447 children: &[RecognizeOutcome],
9448 child_start_index: usize,
9449 expected: &mut ExpectedTokens,
9450 snapshot: ExpectedTokens,
9451 preserve_child_expected: bool,
9452) {
9453 if preserve_child_expected {
9454 return;
9455 }
9456 if children
9457 .iter()
9458 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
9459 {
9460 *expected = snapshot;
9461 }
9462}
9463
9464fn decision_reaches_unsupported_predicate(
9467 atn: &Atn,
9468 state: &AtnState,
9469 predicates: &[(usize, usize, ParserPredicate)],
9470) -> bool {
9471 state.transitions.iter().any(|transition| {
9472 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
9473 })
9474}
9475
9476fn transition_reaches_unsupported_predicate(
9478 atn: &Atn,
9479 transition: &Transition,
9480 predicates: &[(usize, usize, ParserPredicate)],
9481 visited: &mut BTreeSet<usize>,
9482) -> bool {
9483 match transition {
9484 Transition::Predicate {
9485 rule_index,
9486 pred_index,
9487 ..
9488 } => !predicates
9489 .iter()
9490 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
9491 Transition::Epsilon { target }
9492 | Transition::Action { target, .. }
9493 | Transition::Rule { target, .. } => {
9494 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
9495 }
9496 Transition::Precedence { .. }
9497 | Transition::Atom { .. }
9498 | Transition::Range { .. }
9499 | Transition::Set { .. }
9500 | Transition::NotSet { .. }
9501 | Transition::Wildcard { .. } => false,
9502 }
9503}
9504
9505fn state_reaches_unsupported_predicate(
9507 atn: &Atn,
9508 state_number: usize,
9509 predicates: &[(usize, usize, ParserPredicate)],
9510 visited: &mut BTreeSet<usize>,
9511) -> bool {
9512 if !visited.insert(state_number) {
9513 return false;
9514 }
9515 let Some(state) = atn.state(state_number) else {
9516 return false;
9517 };
9518 state.transitions.iter().any(|transition| {
9519 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
9520 })
9521}
9522
9523fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
9525 if let Some(decision) = decision {
9526 outcome.decisions.insert(0, decision);
9527 }
9528}
9529
9530fn outcome_is_better(
9531 outcome_position: (usize, bool),
9532 outcome_diagnostics: &[ParserDiagnostic],
9533 best_position: (usize, bool),
9534 best_diagnostics: &[ParserDiagnostic],
9535) -> bool {
9536 outcome_position > best_position
9537 || (outcome_position == best_position
9538 && (outcome_diagnostics.len() < best_diagnostics.len()
9539 || (outcome_diagnostics.len() == best_diagnostics.len()
9540 && diagnostic_recovery_rank(outcome_diagnostics)
9541 < diagnostic_recovery_rank(best_diagnostics))))
9542}
9543
9544fn diagnostic_recovery_rank(diagnostics: &[ParserDiagnostic]) -> usize {
9547 diagnostics
9548 .iter()
9549 .filter(|diagnostic| {
9550 diagnostic.message.starts_with("mismatched input ")
9551 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
9552 })
9553 .count()
9554}
9555
9556fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
9557 if outcomes
9558 .iter()
9559 .any(|outcome| outcome.diagnostics.is_empty())
9560 {
9561 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
9562 }
9563}
9564
9565fn discard_recovered_outcomes_if_clean_path_exists(outcomes: &mut Vec<RecognizeOutcome>) {
9566 if outcomes.iter().any(outcome_has_rule_failure_diagnostic) {
9567 return;
9568 }
9569 if outcomes
9570 .iter()
9571 .any(|outcome| outcome.diagnostics.is_empty())
9572 {
9573 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
9574 }
9575}
9576
9577fn outcome_has_rule_failure_diagnostic(outcome: &RecognizeOutcome) -> bool {
9580 outcome
9581 .diagnostics
9582 .iter()
9583 .any(|diagnostic| diagnostic.message.starts_with("rule "))
9584}
9585
9586fn nodes_need_stable_tie(nodes: &[RecognizedNode]) -> bool {
9589 nodes.iter().any(node_needs_stable_tie)
9590}
9591
9592fn node_needs_stable_tie(node: &RecognizedNode) -> bool {
9593 match node {
9594 RecognizedNode::Token { .. }
9595 | RecognizedNode::ErrorToken { .. }
9596 | RecognizedNode::MissingToken { .. } => false,
9597 RecognizedNode::LeftRecursiveBoundary { .. } => true,
9598 RecognizedNode::Rule {
9599 rule_index,
9600 children,
9601 ..
9602 } => children.iter().any(|child| {
9603 matches!(
9604 child,
9605 RecognizedNode::Rule {
9606 rule_index: child_rule,
9607 ..
9608 } if child_rule == rule_index
9609 ) || node_needs_stable_tie(child)
9610 }),
9611 }
9612}
9613
9614fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
9628 if outcomes.len() < 2 {
9629 return;
9630 }
9631 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
9632 outcomes.retain(|outcome| {
9633 seen.insert((
9634 outcome.index,
9635 outcome.consumed_eof,
9636 outcome.diagnostics.len(),
9637 diagnostic_recovery_rank(&outcome.diagnostics),
9638 ))
9639 });
9640}
9641
9642fn dedupe_clean_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
9643 if outcomes.len() < 2 {
9644 return;
9645 }
9646 let mut inline_keys: [(usize, bool); 8] = [(0, false); 8];
9656 let mut inline_len = 0_usize;
9657 let mut overflow: Vec<(usize, bool)> = Vec::new();
9658 outcomes.retain(|outcome| {
9659 let key = (outcome.index, outcome.consumed_eof);
9660 for &existing in &inline_keys[..inline_len] {
9661 if existing == key {
9662 return false;
9663 }
9664 }
9665 if !overflow.is_empty() {
9666 for &existing in &overflow {
9667 if existing == key {
9668 return false;
9669 }
9670 }
9671 }
9672 if inline_len < inline_keys.len() {
9673 inline_keys[inline_len] = key;
9674 inline_len += 1;
9675 } else {
9676 overflow.push(key);
9677 }
9678 true
9679 });
9680}
9681
9682fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>) {
9684 outcomes.sort_unstable();
9685 outcomes.dedup();
9686}
9687
9688impl<S, H> Recognizer for BaseParser<S, H>
9689where
9690 S: TokenSource,
9691 H: SemanticHooks,
9692{
9693 fn data(&self) -> &RecognizerData {
9694 &self.data
9695 }
9696
9697 fn data_mut(&mut self) -> &mut RecognizerData {
9698 &mut self.data
9699 }
9700}
9701
9702impl<S, H> Parser for BaseParser<S, H>
9703where
9704 S: TokenSource,
9705 H: SemanticHooks,
9706{
9707 fn build_parse_trees(&self) -> bool {
9708 self.build_parse_trees
9709 }
9710
9711 fn set_build_parse_trees(&mut self, build: bool) {
9712 self.build_parse_trees = build;
9713 }
9714
9715 fn number_of_syntax_errors(&self) -> usize {
9716 Self::number_of_syntax_errors(self)
9717 }
9718
9719 fn report_diagnostic_errors(&self) -> bool {
9720 self.report_diagnostic_errors
9721 }
9722
9723 fn set_report_diagnostic_errors(&mut self, report: bool) {
9724 self.report_diagnostic_errors = report;
9725 }
9726
9727 fn prediction_mode(&self) -> PredictionMode {
9728 self.prediction_mode
9729 }
9730
9731 fn set_prediction_mode(&mut self, mode: PredictionMode) {
9732 self.prediction_mode = mode;
9733 }
9734}
9735
9736#[cfg(test)]
9737mod tests {
9738 use super::*;
9739 use crate::atn::AtnType;
9740 use crate::atn::IntervalSet;
9741 use crate::atn::parser::{
9742 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
9743 };
9744 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
9745 use crate::token::{CommonToken, HIDDEN_CHANNEL, Token};
9746 use crate::token_stream::CommonTokenStream;
9747 use crate::vocabulary::Vocabulary;
9748
9749 #[test]
9750 fn fx_hasher_write_matches_typed_methods_for_full_words() {
9751 let value: u64 = 0x0102_0304_0506_0708;
9758 let mut typed = FxHasher::default();
9759 typed.write_u64(value);
9760 let mut bytewise = FxHasher::default();
9761 bytewise.write(&value.to_le_bytes());
9762 assert_eq!(typed.finish(), bytewise.finish());
9763 }
9764
9765 #[derive(Debug)]
9766 struct Source {
9767 tokens: Vec<CommonToken>,
9768 index: usize,
9769 }
9770
9771 impl TokenSource for Source {
9772 fn next_token(&mut self) -> CommonToken {
9773 let token = self
9774 .tokens
9775 .get(self.index)
9776 .cloned()
9777 .unwrap_or_else(|| CommonToken::eof("parser-test", self.index, 1, self.index));
9778 self.index += 1;
9779 token
9780 }
9781
9782 fn line(&self) -> usize {
9783 1
9784 }
9785
9786 fn column(&self) -> usize {
9787 self.index
9788 }
9789
9790 fn source_name(&self) -> &'static str {
9791 "parser-test"
9792 }
9793 }
9794
9795 fn mini_parser_data() -> RecognizerData {
9796 RecognizerData::new(
9797 "Mini.g4",
9798 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
9799 )
9800 .with_rule_names(["s"])
9801 }
9802
9803 fn mini_parser(tokens: Vec<CommonToken>) -> BaseParser<Source> {
9804 let data = mini_parser_data();
9805 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
9806 }
9807
9808 fn mini_parser_with_hooks<H>(tokens: Vec<CommonToken>, hooks: H) -> BaseParser<Source, H>
9809 where
9810 H: SemanticHooks,
9811 {
9812 BaseParser::with_semantic_hooks(
9813 CommonTokenStream::new(Source { tokens, index: 0 }),
9814 mini_parser_data(),
9815 hooks,
9816 )
9817 }
9818
9819 fn token_then_eof_atn() -> Atn {
9820 AtnDeserializer::new(&SerializedAtn::from_i32(&[
9821 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, ]))
9837 .deserialize()
9838 .expect("artificial parser ATN should deserialize")
9839 }
9840
9841 fn eof_then_action_atn() -> Atn {
9842 AtnDeserializer::new(&SerializedAtn::from_i32(&[
9843 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, ]))
9859 .deserialize()
9860 .expect("artificial parser ATN should deserialize")
9861 }
9862
9863 fn noop_action_then_token_then_eof_atn() -> Atn {
9864 AtnDeserializer::new(&SerializedAtn::from_i32(&[
9865 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, ]))
9883 .deserialize()
9884 .expect("artificial no-op action ATN should deserialize")
9885 }
9886
9887 fn two_alt_decision_atn() -> Atn {
9888 let mut atn = Atn::new(AtnType::Parser, 2);
9889 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9890 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
9891 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
9892 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
9893 atn.add_state(AtnState::new(4, AtnStateKind::BlockEnd).with_rule_index(0));
9894 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
9895 atn.set_rule_to_start_state(vec![0]);
9896 atn.set_rule_to_stop_state(vec![5]);
9897 atn.add_decision_state(1);
9898 atn.state_mut(0)
9899 .expect("state 0")
9900 .add_transition(Transition::Epsilon { target: 1 });
9901 atn.state_mut(1)
9902 .expect("state 1")
9903 .add_transition(Transition::Atom {
9904 target: 2,
9905 label: 1,
9906 });
9907 atn.state_mut(1)
9908 .expect("state 1")
9909 .add_transition(Transition::Atom {
9910 target: 3,
9911 label: 2,
9912 });
9913 atn.state_mut(2)
9914 .expect("state 2")
9915 .add_transition(Transition::Epsilon { target: 4 });
9916 atn.state_mut(3)
9917 .expect("state 3")
9918 .add_transition(Transition::Epsilon { target: 4 });
9919 atn.state_mut(4)
9920 .expect("state 4")
9921 .add_transition(Transition::Epsilon { target: 5 });
9922 atn
9923 }
9924
9925 fn optional_then_b_eof_atn() -> Atn {
9928 let mut atn = Atn::new(AtnType::Parser, 3);
9929 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9930 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
9931 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
9932 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
9933 atn.add_state(AtnState::new(4, AtnStateKind::Basic).with_rule_index(0));
9934 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
9935 atn.set_rule_to_start_state(vec![0]);
9936 atn.set_rule_to_stop_state(vec![5]);
9937 atn.add_decision_state(1);
9938 atn.state_mut(0)
9939 .expect("state 0")
9940 .add_transition(Transition::Epsilon { target: 1 });
9941 atn.state_mut(1)
9943 .expect("state 1")
9944 .add_transition(Transition::Atom {
9945 target: 3,
9946 label: 1,
9947 });
9948 atn.state_mut(1)
9949 .expect("state 1")
9950 .add_transition(Transition::Epsilon { target: 3 });
9951 atn.state_mut(3)
9953 .expect("state 3")
9954 .add_transition(Transition::Atom {
9955 target: 4,
9956 label: 2,
9957 });
9958 atn.state_mut(4)
9959 .expect("state 4")
9960 .add_transition(Transition::Atom {
9961 target: 5,
9962 label: TOKEN_EOF,
9963 });
9964 atn
9965 }
9966
9967 #[test]
9968 fn sync_decision_deletes_only_a_single_token() {
9969 let atn = optional_then_b_eof_atn();
9977
9978 let mut single = mini_parser(vec![
9979 CommonToken::new(3).with_text("c"),
9980 CommonToken::new(2).with_text("b"),
9981 CommonToken::eof("parser-test", 1, 2, 2),
9982 ]);
9983 single.rule_context_stack = vec![RuleContextFrame {
9984 rule_index: 0,
9985 invoking_state: 0,
9986 }];
9987 let children = single
9988 .sync_decision(&atn, 1, true, false)
9989 .expect("single extraneous token recovers");
9990 assert_eq!(children.len(), 1);
9991 assert!(matches!(children[0], ParseTree::Error(_)));
9992 assert_eq!(single.number_of_syntax_errors(), 1);
9993 assert_eq!(single.la(1), 2);
9995
9996 let mut double = mini_parser(vec![
9997 CommonToken::new(3).with_text("c"),
9998 CommonToken::new(3).with_text("c"),
9999 CommonToken::new(2).with_text("b"),
10000 CommonToken::eof("parser-test", 1, 3, 3),
10001 ]);
10002 double.rule_context_stack = vec![RuleContextFrame {
10003 rule_index: 0,
10004 invoking_state: 0,
10005 }];
10006 let result = double.sync_decision(&atn, 1, true, false);
10007 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
10012 match error {
10013 AntlrError::ParserError { message, .. } => {
10014 assert!(message.starts_with("mismatched input"), "got: {message}");
10015 }
10016 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
10017 }
10018 assert_eq!(double.la(1), 3);
10019 }
10020
10021 fn star_loop_then_eof_atn() -> Atn {
10025 AtnDeserializer::new(&SerializedAtn::from_i32(&[
10026 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,
10027 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,
10028 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,
10029 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
10030 ]))
10031 .deserialize()
10032 .expect("star-loop-then-EOF ATN should deserialize")
10033 }
10034
10035 fn plus_loop_with_recovering_body_atn() -> Atn {
10041 let mut atn = Atn::new(AtnType::Parser, 2);
10042 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10043 let mut loop_start = AtnState::new(1, AtnStateKind::PlusBlockStart).with_rule_index(0);
10044 loop_start.end_state = Some(3);
10045 atn.add_state(loop_start);
10046 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10047 atn.add_state(AtnState::new(3, AtnStateKind::BlockEnd).with_rule_index(0));
10048 atn.add_state(AtnState::new(4, AtnStateKind::PlusLoopBack).with_rule_index(0));
10049 let mut loop_end = AtnState::new(5, AtnStateKind::LoopEnd).with_rule_index(0);
10050 loop_end.loop_back_state = Some(4);
10051 atn.add_state(loop_end);
10052 atn.add_state(AtnState::new(6, AtnStateKind::RuleStop).with_rule_index(0));
10053 atn.add_state(AtnState::new(7, AtnStateKind::RuleStart).with_rule_index(1));
10054 atn.add_state(AtnState::new(8, AtnStateKind::Basic).with_rule_index(1));
10055 atn.add_state(AtnState::new(9, AtnStateKind::RuleStop).with_rule_index(1));
10056 atn.set_rule_to_start_state(vec![0, 7]);
10057 atn.set_rule_to_stop_state(vec![6, 9]);
10058 atn.state_mut(0)
10059 .expect("state 0")
10060 .add_transition(Transition::Epsilon { target: 1 });
10061 atn.state_mut(1)
10062 .expect("state 1")
10063 .add_transition(Transition::Epsilon { target: 2 });
10064 atn.state_mut(2)
10065 .expect("state 2")
10066 .add_transition(Transition::Rule {
10067 target: 7,
10068 rule_index: 1,
10069 follow_state: 3,
10070 precedence: 0,
10071 });
10072 atn.state_mut(3)
10073 .expect("state 3")
10074 .add_transition(Transition::Epsilon { target: 4 });
10075 atn.state_mut(4)
10076 .expect("state 4")
10077 .add_transition(Transition::Epsilon { target: 1 });
10078 atn.state_mut(4)
10079 .expect("state 4")
10080 .add_transition(Transition::Epsilon { target: 5 });
10081 atn.state_mut(5)
10082 .expect("state 5")
10083 .add_transition(Transition::Atom {
10084 target: 6,
10085 label: 2,
10086 });
10087 atn.state_mut(7)
10088 .expect("state 7")
10089 .add_transition(Transition::Atom {
10090 target: 8,
10091 label: 1,
10092 });
10093 atn.state_mut(8)
10094 .expect("state 8")
10095 .add_transition(Transition::Epsilon { target: 9 });
10096 atn
10097 }
10098
10099 #[test]
10100 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
10101 let atn = plus_loop_with_recovering_body_atn();
10102 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10103
10104 let error = parser
10105 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
10106 .expect_err("EOF recovery should report a bounded mismatch");
10107
10108 let AntlrError::ParserError { message, .. } = error else {
10109 panic!("expected ParserError, got {error:?}");
10110 };
10111 assert_eq!(message, "mismatched input '<EOF>' expecting {'x', 2}");
10112 assert_eq!(parser.number_of_syntax_errors(), 1);
10113 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
10114 }
10115
10116 #[test]
10117 fn sync_decision_deletes_token_before_eof_at_loop_back() {
10118 let atn = star_loop_then_eof_atn();
10124 let mut parser = mini_parser(vec![
10125 CommonToken::new(2).with_text("c"),
10126 CommonToken::eof("parser-test", 1, 1, 1),
10127 ]);
10128 parser.rule_context_stack = vec![RuleContextFrame {
10129 rule_index: 0,
10130 invoking_state: 0,
10131 }];
10132 let children = parser
10133 .sync_decision(&atn, 5, true, false)
10134 .expect("single token before EOF recovers");
10135 assert_eq!(children.len(), 1);
10136 assert!(matches!(children[0], ParseTree::Error(_)));
10137 assert_eq!(parser.number_of_syntax_errors(), 1);
10138 assert_eq!(
10139 parser.la(1),
10140 TOKEN_EOF,
10141 "EOF is left for the rule's EOF match"
10142 );
10143 }
10144
10145 #[test]
10146 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
10147 let atn = star_loop_then_eof_atn();
10152 let mut parser = mini_parser(vec![
10153 CommonToken::new(2).with_text("c"),
10154 CommonToken::new(2).with_text("c"),
10155 CommonToken::eof("parser-test", 1, 2, 2),
10156 ]);
10157 parser.rule_context_stack = vec![RuleContextFrame {
10158 rule_index: 0,
10159 invoking_state: 0,
10160 }];
10161 let error = parser
10162 .sync_decision(&atn, 5, true, false)
10163 .expect_err("two tokens at the loop entry must not be deleted");
10164 match error {
10165 AntlrError::ParserError { message, .. } => {
10166 assert!(message.starts_with("mismatched input"), "got: {message}");
10167 }
10168 other => panic!("expected mismatched-input ParserError, got {other:?}"),
10169 }
10170 assert_eq!(
10171 parser.la(1),
10172 2,
10173 "nothing consumed; cursor still on first `c`"
10174 );
10175 }
10176
10177 #[test]
10178 fn sync_decision_consumes_until_eof_at_loop_back() {
10179 let atn = star_loop_then_eof_atn();
10185 let mut parser = mini_parser(vec![
10186 CommonToken::new(2).with_text("c"),
10187 CommonToken::new(2).with_text("c"),
10188 CommonToken::eof("parser-test", 1, 2, 2),
10189 ]);
10190 parser.rule_context_stack = vec![RuleContextFrame {
10191 rule_index: 0,
10192 invoking_state: 0,
10193 }];
10194 let children = parser
10195 .sync_decision(&atn, 5, false, true)
10196 .expect("loop-back multi-token deletion recovers onto EOF");
10197 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
10198 assert!(children.iter().all(|c| matches!(c, ParseTree::Error(_))));
10199 assert_eq!(parser.number_of_syntax_errors(), 1);
10200 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
10201 }
10202
10203 fn predicate_after_token_atn() -> Atn {
10204 let mut atn = Atn::new(AtnType::Parser, 2);
10205 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10206 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
10207 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10208 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
10209 atn.add_state(AtnState::new(4, AtnStateKind::RuleStop).with_rule_index(0));
10210 atn.set_rule_to_start_state(vec![0]);
10211 atn.set_rule_to_stop_state(vec![4]);
10212 atn.state_mut(0)
10213 .expect("state 0")
10214 .add_transition(Transition::Atom {
10215 target: 1,
10216 label: 1,
10217 });
10218 atn.state_mut(1)
10219 .expect("state 1")
10220 .add_transition(Transition::Predicate {
10221 target: 2,
10222 rule_index: 0,
10223 pred_index: 0,
10224 context_dependent: false,
10225 });
10226 atn.state_mut(2)
10227 .expect("state 2")
10228 .add_transition(Transition::Atom {
10229 target: 3,
10230 label: 2,
10231 });
10232 atn.state_mut(3)
10233 .expect("state 3")
10234 .add_transition(Transition::Epsilon { target: 4 });
10235 atn
10236 }
10237
10238 fn nested_nullable_context_atn() -> Atn {
10239 let mut atn = Atn::new(AtnType::Parser, 1);
10240 for state_number in 0..=20 {
10241 let kind = match state_number {
10242 0 | 10 | 16 => AtnStateKind::RuleStart,
10243 9 | 15 | 20 => AtnStateKind::RuleStop,
10244 _ => AtnStateKind::Basic,
10245 };
10246 let rule_index = match state_number {
10247 0..=9 => 0,
10248 10..=15 => 1,
10249 _ => 2,
10250 };
10251 atn.add_state(AtnState::new(state_number, kind).with_rule_index(rule_index));
10252 }
10253 atn.set_rule_to_start_state(vec![0, 10, 16]);
10254 atn.set_rule_to_stop_state(vec![9, 15, 20]);
10255 atn.state_mut(1)
10256 .expect("state 1")
10257 .add_transition(Transition::Rule {
10258 target: 10,
10259 rule_index: 1,
10260 follow_state: 8,
10261 precedence: 0,
10262 });
10263 atn.state_mut(8)
10264 .expect("state 8")
10265 .add_transition(Transition::Atom {
10266 target: 9,
10267 label: 1,
10268 });
10269 atn.state_mut(8)
10270 .expect("state 8")
10271 .add_transition(Transition::Epsilon { target: 9 });
10272 atn.state_mut(2)
10273 .expect("state 2")
10274 .add_transition(Transition::Rule {
10275 target: 16,
10276 rule_index: 2,
10277 follow_state: 14,
10278 precedence: 0,
10279 });
10280 atn.state_mut(14)
10281 .expect("state 14")
10282 .add_transition(Transition::Epsilon { target: 15 });
10283 atn
10284 }
10285
10286 fn generated_match_recovery_atn() -> Atn {
10287 let mut atn = Atn::new(AtnType::Parser, 2);
10288 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10289 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
10290 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10291 atn.add_state(AtnState::new(3, AtnStateKind::RuleStop).with_rule_index(0));
10292 atn.add_state(AtnState::new(4, AtnStateKind::RuleStart).with_rule_index(1));
10293 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(1));
10294 atn.set_rule_to_start_state(vec![0, 4]);
10295 atn.set_rule_to_stop_state(vec![3, 5]);
10296 atn.state_mut(1)
10297 .expect("state 1")
10298 .add_transition(Transition::Rule {
10299 target: 4,
10300 rule_index: 1,
10301 follow_state: 2,
10302 precedence: 0,
10303 });
10304 atn.state_mut(2)
10305 .expect("state 2")
10306 .add_transition(Transition::Atom {
10307 target: 3,
10308 label: TOKEN_EOF,
10309 });
10310 atn
10311 }
10312
10313 fn complement_set_atn() -> Atn {
10314 let mut atn = Atn::new(AtnType::Parser, 1);
10315 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10316 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
10317 atn.set_rule_to_start_state(vec![0]);
10318 atn.set_rule_to_stop_state(vec![1]);
10319 let mut excluded = IntervalSet::new();
10320 excluded.add(1);
10321 atn.state_mut(0)
10322 .expect("state 0")
10323 .add_transition(Transition::NotSet {
10324 target: 1,
10325 set: excluded,
10326 });
10327 atn
10328 }
10329
10330 fn wildcard_then_eof_atn() -> Atn {
10333 let mut atn = Atn::new(AtnType::Parser, 1);
10334 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10335 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
10336 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10337 atn.set_rule_to_start_state(vec![0]);
10338 atn.set_rule_to_stop_state(vec![1]);
10339 atn.state_mut(0)
10340 .expect("state 0")
10341 .add_transition(Transition::Wildcard { target: 2 });
10342 atn.state_mut(2)
10343 .expect("state 2")
10344 .add_transition(Transition::Atom {
10345 target: 1,
10346 label: TOKEN_EOF,
10347 });
10348 atn
10349 }
10350
10351 #[test]
10352 fn parser_matches_token_and_reports_mismatch() {
10353 let source = Source {
10354 tokens: vec![
10355 CommonToken::new(1).with_text("x"),
10356 CommonToken::eof("parser-test", 1, 1, 1),
10357 ],
10358 index: 0,
10359 };
10360 let data = RecognizerData::new(
10361 "Mini.g4",
10362 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10363 );
10364 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
10365 assert_eq!(
10366 parser.match_token(1).expect("token 1 should match").text(),
10367 "x"
10368 );
10369 assert!(parser.match_token(1).is_err());
10370 }
10371
10372 #[test]
10373 fn parser_matches_token_sets() {
10374 let mut parser = mini_parser(vec![
10375 CommonToken::new(1).with_text("x"),
10376 CommonToken::eof("parser-test", 1, 1, 1),
10377 ]);
10378
10379 assert_eq!(
10380 parser
10381 .match_set(&[(1, 1), (3, 4)])
10382 .expect("token set should match")
10383 .text(),
10384 "x"
10385 );
10386 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
10387 }
10388
10389 #[test]
10390 fn generated_rule_api_tracks_state_and_precedence() {
10391 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10392
10393 let context = parser.enter_rule(7, 2);
10394 assert_eq!(context.rule_index(), 2);
10395 assert_eq!(parser.state(), 7);
10396 assert_eq!(
10397 parser.rule_context_stack,
10398 vec![RuleContextFrame {
10399 rule_index: 2,
10400 invoking_state: 7
10401 }]
10402 );
10403
10404 let recursive = parser.enter_recursion_rule(11, 3, 4);
10405 assert_eq!(recursive.rule_index(), 3);
10406 assert!(parser.precpred(4));
10407 assert!(parser.precpred(5));
10408 assert!(!parser.precpred(3));
10409
10410 let next = parser.push_new_recursion_context(13, 3);
10411 assert_eq!(next.invoking_state(), 13);
10412 parser.unroll_recursion_context();
10413 assert_eq!(parser.precedence_stack, vec![0]);
10414 assert_eq!(
10415 parser.rule_context_stack,
10416 vec![RuleContextFrame {
10417 rule_index: 2,
10418 invoking_state: 7
10419 }]
10420 );
10421
10422 parser.exit_rule();
10423 assert!(parser.rule_context_stack.is_empty());
10424 }
10425
10426 #[test]
10427 fn parser_predicates_support_token_adjacency() {
10428 let mut parser = mini_parser(vec![
10429 CommonToken::new(1).with_text("=").with_span(0, 0),
10430 CommonToken::new(1).with_text(">").with_span(1, 1),
10431 CommonToken::eof("parser-test", 2, 1, 2),
10432 ]);
10433 parser.consume();
10434 parser.consume();
10435
10436 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
10437
10438 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
10439
10440 let mut parser = mini_parser(vec![
10441 CommonToken::new(1).with_text("=").with_span(0, 0),
10442 CommonToken::new(1)
10443 .with_text(" ")
10444 .with_channel(HIDDEN_CHANNEL)
10445 .with_span(1, 1),
10446 CommonToken::new(1).with_text(">").with_span(2, 2),
10447 CommonToken::eof("parser-test", 3, 1, 3),
10448 ]);
10449 parser.consume();
10450 parser.consume();
10451
10452 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
10453 }
10454
10455 #[test]
10456 fn parser_predicates_support_context_child_text_checks() {
10457 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10458 let mut context = ParserRuleContext::new(1, 0);
10459 let mut child_context = ParserRuleContext::new(2, 0);
10460 child_context.add_child(ParseTree::Terminal(TerminalNode::new(
10461 CommonToken::new(1).with_text("var"),
10462 )));
10463 context.add_child(ParseTree::Rule(RuleNode::new(child_context)));
10464 let predicates = [(
10465 1,
10466 0,
10467 ParserPredicate::ContextChildRuleTextNotEquals {
10468 rule_index: 2,
10469 text: "var",
10470 },
10471 )];
10472
10473 assert!(
10474 !parser.parser_semantic_predicate_matches_with_context_and_local(
10475 &predicates,
10476 1,
10477 0,
10478 &context,
10479 0,
10480 )
10481 );
10482 }
10483
10484 #[test]
10485 fn context_expected_symbols_walks_nullable_parent_contexts() {
10486 let atn = nested_nullable_context_atn();
10487 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10488 parser.rule_context_stack = vec![
10489 RuleContextFrame {
10490 rule_index: 0,
10491 invoking_state: 0,
10492 },
10493 RuleContextFrame {
10494 rule_index: 1,
10495 invoking_state: 1,
10496 },
10497 RuleContextFrame {
10498 rule_index: 2,
10499 invoking_state: 2,
10500 },
10501 ];
10502
10503 let expected = parser.context_expected_symbols(&atn);
10504
10505 assert!(expected.contains(&1));
10506 assert!(expected.contains(&TOKEN_EOF));
10507 }
10508
10509 #[test]
10510 fn prediction_context_reuses_cached_stack_until_rule_stack_changes() {
10511 let atn = nested_nullable_context_atn();
10512 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10513 parser.rule_context_stack = vec![
10514 RuleContextFrame {
10515 rule_index: 0,
10516 invoking_state: 0,
10517 },
10518 RuleContextFrame {
10519 rule_index: 1,
10520 invoking_state: 1,
10521 },
10522 RuleContextFrame {
10523 rule_index: 2,
10524 invoking_state: 2,
10525 },
10526 ];
10527
10528 let first = parser.prediction_context(&atn);
10529 let second = parser.prediction_context(&atn);
10530 assert!(Rc::ptr_eq(&first, &second));
10531
10532 parser.exit_rule();
10533 let after_pop = parser.prediction_context(&atn);
10534 assert!(!Rc::ptr_eq(&first, &after_pop));
10535 }
10536
10537 #[test]
10538 fn generated_match_token_recovers_missing_token_from_context_follow() {
10539 let atn = generated_match_recovery_atn();
10540 let data = RecognizerData::new(
10541 "Mini.g4",
10542 Vocabulary::new(
10543 [None, Some("'X'"), Some("'Y'")],
10544 [None, Some("X"), Some("Y")],
10545 [None::<&str>, None, None],
10546 ),
10547 );
10548 let mut parser = BaseParser::new(
10549 CommonTokenStream::new(Source {
10550 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
10551 index: 0,
10552 }),
10553 data,
10554 );
10555 parser.rule_context_stack = vec![
10556 RuleContextFrame {
10557 rule_index: 0,
10558 invoking_state: 0,
10559 },
10560 RuleContextFrame {
10561 rule_index: 1,
10562 invoking_state: 1,
10563 },
10564 ];
10565 assert_eq!(parser.number_of_syntax_errors(), 0);
10566
10567 let node = parser
10568 .match_token_recovering(2, 5, &atn)
10569 .expect("generated match should insert missing token");
10570
10571 assert_eq!(node.children().len(), 1);
10572 assert_eq!(node.children()[0].text(), "<missing 'Y'>");
10573 assert!(!node.consumed_eof());
10576 assert_eq!(parser.la(1), TOKEN_EOF);
10577 assert_eq!(parser.number_of_syntax_errors(), 1);
10578 assert_eq!(
10579 parser.generated_parser_diagnostics,
10580 [ParserDiagnostic {
10581 line: 1,
10582 column: 3,
10583 message: "missing 'Y' at '<EOF>'".to_owned(),
10584 }]
10585 );
10586 }
10587
10588 #[test]
10589 fn generated_match_token_counts_single_token_deletion_recovery() {
10590 let atn = generated_match_recovery_atn();
10591 let data = RecognizerData::new(
10592 "Mini.g4",
10593 Vocabulary::new(
10594 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
10595 [None, Some("X"), Some("Y"), Some("Z")],
10596 [None::<&str>, None, None, None],
10597 ),
10598 );
10599 let mut parser = BaseParser::new(
10600 CommonTokenStream::new(Source {
10601 tokens: vec![
10602 CommonToken::new(3).with_text("z"),
10603 CommonToken::new(2).with_text("y"),
10604 CommonToken::eof("parser-test", 3, 1, 3),
10605 ],
10606 index: 0,
10607 }),
10608 data,
10609 );
10610
10611 let node = parser
10612 .match_token_recovering(2, 5, &atn)
10613 .expect("generated match should delete the extraneous token");
10614
10615 assert_eq!(node.children().len(), 2);
10616 assert!(matches!(node.children()[0], ParseTree::Error(_)));
10617 assert_eq!(node.children()[0].text(), "z");
10618 assert_eq!(node.children()[1].text(), "y");
10619 assert_eq!(parser.number_of_syntax_errors(), 1);
10620 }
10621
10622 #[test]
10623 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
10624 let atn = generated_match_recovery_atn();
10625 let data = RecognizerData::new(
10626 "Mini.g4",
10627 Vocabulary::new(
10628 [None, Some("'X'"), Some("'Y'")],
10629 [None, Some("X"), Some("Y")],
10630 [None::<&str>, None, None],
10631 ),
10632 );
10633 let mut parser = BaseParser::new(
10634 CommonTokenStream::new(Source {
10635 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
10636 index: 0,
10637 }),
10638 data,
10639 );
10640 parser.rule_context_stack = vec![
10641 RuleContextFrame {
10642 rule_index: 0,
10643 invoking_state: 0,
10644 },
10645 RuleContextFrame {
10646 rule_index: 1,
10647 invoking_state: 1,
10648 },
10649 ];
10650 let marker = parser.generated_diagnostics_checkpoint();
10651
10652 let _ = parser
10653 .match_token_recovering(2, 5, &atn)
10654 .expect("generated match should insert missing token");
10655 assert_eq!(parser.number_of_syntax_errors(), 1);
10656
10657 parser.restore_generated_diagnostics(marker);
10658
10659 assert_eq!(parser.number_of_syntax_errors(), 0);
10660 assert!(parser.generated_parser_diagnostics.is_empty());
10661 }
10662
10663 #[test]
10664 fn generated_prediction_diagnostics_use_adaptive_context() {
10665 let atn = two_alt_decision_atn();
10666 let data = RecognizerData::new(
10667 "Mini.g4",
10668 Vocabulary::new(
10669 [None, Some("'x'"), Some("'y'")],
10670 [None, Some("X"), Some("Y")],
10671 [None::<&str>, None, None],
10672 ),
10673 )
10674 .with_rule_names(["s"]);
10675 let mut parser = BaseParser::new(
10676 CommonTokenStream::new(Source {
10677 tokens: vec![
10678 CommonToken::new(1)
10679 .with_text("x")
10680 .with_position(1, 0)
10681 .with_span(0, 0),
10682 CommonToken::new(2)
10683 .with_text("y")
10684 .with_position(1, 2)
10685 .with_span(1, 1),
10686 CommonToken::eof("parser-test", 2, 1, 3),
10687 ],
10688 index: 0,
10689 }),
10690 data,
10691 );
10692 parser.set_report_diagnostic_errors(true);
10693
10694 parser.record_generated_prediction_diagnostic(
10695 &atn,
10696 1,
10697 &ParserAtnPrediction {
10698 alt: 1,
10699 requires_full_context: true,
10700 has_semantic_context: false,
10701 diagnostic: Some(ParserAtnPredictionDiagnostic {
10702 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
10703 start_index: 0,
10704 sll_stop_index: 1,
10705 ll_stop_index: 0,
10706 conflicting_alts: vec![1, 2],
10707 exact: false,
10708 }),
10709 },
10710 );
10711 parser.record_generated_prediction_diagnostic(
10716 &atn,
10717 1,
10718 &ParserAtnPrediction {
10719 alt: 1,
10720 requires_full_context: true,
10721 has_semantic_context: false,
10722 diagnostic: Some(ParserAtnPredictionDiagnostic {
10723 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
10724 start_index: 0,
10725 sll_stop_index: 1,
10726 ll_stop_index: 1,
10727 conflicting_alts: vec![1, 2],
10728 exact: false,
10729 }),
10730 },
10731 );
10732
10733 assert_eq!(
10734 parser.generated_parser_diagnostics,
10735 [
10736 ParserDiagnostic {
10737 line: 1,
10738 column: 2,
10739 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
10740 },
10741 ParserDiagnostic {
10742 line: 1,
10743 column: 0,
10744 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
10745 },
10746 ParserDiagnostic {
10747 line: 1,
10748 column: 2,
10749 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
10750 },
10751 ]
10752 );
10753 }
10754
10755 #[test]
10756 fn generated_match_not_set_recovers_empty_complement_at_eof() {
10757 let atn = complement_set_atn();
10758 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10759 parser.rule_context_stack = vec![RuleContextFrame {
10760 rule_index: 0,
10761 invoking_state: 0,
10762 }];
10763
10764 let node = parser
10765 .match_not_set_recovering(&[(1, 1)], 1, 1, 1, &atn)
10766 .expect("empty complement should recover at EOF");
10767
10768 assert_eq!(node.children().len(), 1);
10769 assert!(!node.consumed_eof());
10772 assert_eq!(parser.la(1), TOKEN_EOF);
10773 assert_eq!(
10774 parser.generated_parser_diagnostics,
10775 [ParserDiagnostic {
10776 line: 1,
10777 column: 1,
10778 message: "missing {} at '<EOF>'".to_owned(),
10779 }]
10780 );
10781 }
10782
10783 #[test]
10784 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
10785 let atn = wildcard_then_eof_atn();
10791 let data = RecognizerData::new(
10792 "Mini.g4",
10793 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10794 );
10795 let mut parser = BaseParser::new(
10796 CommonTokenStream::new(Source {
10797 tokens: vec![CommonToken::eof("parser-test", 1, 1, 1)],
10798 index: 0,
10799 }),
10800 data,
10801 );
10802 parser.rule_context_stack = vec![RuleContextFrame {
10803 rule_index: 0,
10804 invoking_state: 0,
10805 }];
10806
10807 let node = parser
10808 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
10809 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
10810
10811 assert_eq!(node.children().len(), 1);
10813 assert!(!node.consumed_eof());
10814 assert!(node.children()[0].text().starts_with("<missing"));
10815 assert_eq!(parser.la(1), TOKEN_EOF);
10816 assert_eq!(
10817 parser.generated_parser_diagnostics,
10818 [ParserDiagnostic {
10819 line: 1,
10820 column: 1,
10821 message: "missing 'x' at '<EOF>'".to_owned(),
10822 }]
10823 );
10824 }
10825
10826 #[test]
10827 fn generated_rule_recovery_consumes_to_parent_follow() {
10828 let atn = generated_match_recovery_atn();
10829 let data = RecognizerData::new(
10830 "Mini.g4",
10831 Vocabulary::new(
10832 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
10833 [None, Some("X"), Some("Y"), Some("Z")],
10834 [None::<&str>, None, None, None],
10835 ),
10836 );
10837 let mut parser = BaseParser::new(
10838 CommonTokenStream::new(Source {
10839 tokens: vec![
10840 CommonToken::new(3).with_text("z"),
10841 CommonToken::eof("parser-test", 1, 1, 1),
10842 ],
10843 index: 0,
10844 }),
10845 data,
10846 );
10847 let _parent = parser.enter_rule(0, 0);
10848 let marker = parser.push_invoking_state(1);
10849 let mut child = parser.enter_rule(4, 1);
10850 parser.discard_invoking_state(marker);
10851
10852 parser.recover_generated_rule(
10853 &mut child,
10854 &atn,
10855 AntlrError::ParserError {
10856 line: 1,
10857 column: 0,
10858 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
10859 },
10860 );
10861 let tree = parser.finish_rule(child, false);
10862
10863 assert_eq!(parser.la(1), TOKEN_EOF);
10864 assert_eq!(tree.to_string_tree_with_names(&["s", "a"]), "(a z)");
10865 assert_eq!(parser.number_of_syntax_errors(), 1);
10866 assert_eq!(
10867 parser.generated_parser_diagnostics,
10868 [ParserDiagnostic {
10869 line: 1,
10870 column: 0,
10871 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
10872 }]
10873 );
10874 parser.exit_rule();
10875 }
10876
10877 #[test]
10878 fn greedy_ll1_alt_handles_nullable_loop_exit() {
10879 let mut body_symbols = TokenBitSet::default();
10880 body_symbols.insert(1);
10881 let entry = DecisionLookahead {
10882 transitions: vec![
10883 TransitionLookSet {
10884 symbols: body_symbols,
10885 nullable: false,
10886 },
10887 TransitionLookSet {
10888 symbols: TokenBitSet::default(),
10889 nullable: true,
10890 },
10891 ],
10892 };
10893
10894 assert_eq!(ll1_unique_alt(&entry, 2), None);
10895 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
10896 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
10897 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
10898 }
10899
10900 #[test]
10901 fn single_outcome_memo_probe_selects_sparse_or_promote_mode() {
10902 let key = |state_number| FastRecognizeKey {
10903 state_number,
10904 stop_state: 10,
10905 index: state_number,
10906 rule_start_index: 0,
10907 decision_start_index: None,
10908 precedence: 0,
10909 recovery_symbols_id: 0,
10910 recovery_state: None,
10911 };
10912
10913 let mut sparse = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10914 for state_number in 0..(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT - 1) {
10915 assert!(sparse.should_memoize_single_outcome(&key(state_number)));
10916 }
10917 assert!(!sparse.should_memoize_single_outcome(&key(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT)));
10918 assert_eq!(
10919 sparse.single_outcome_memo_mode,
10920 SingleOutcomeMemoMode::Sparse
10921 );
10922
10923 let mut promote = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10924 let repeated = key(1);
10925 for _ in 0..=CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
10926 assert!(promote.should_memoize_single_outcome(&repeated));
10927 }
10928 assert_eq!(
10929 promote.single_outcome_memo_mode,
10930 SingleOutcomeMemoMode::Promote
10931 );
10932 }
10933
10934 #[test]
10935 fn clean_empty_multi_alt_outcomes_are_memoized() {
10936 let mut atn = Atn::new(AtnType::Parser, 2);
10937 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10938 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
10939 atn.add_state(AtnState::new(2, AtnStateKind::RuleStop).with_rule_index(0));
10940 atn.set_rule_to_start_state(vec![0]);
10941 atn.set_rule_to_stop_state(vec![2]);
10942 atn.state_mut(0)
10943 .expect("state 0")
10944 .add_transition(Transition::Epsilon { target: 1 });
10945 atn.state_mut(1)
10946 .expect("state 1")
10947 .add_transition(Transition::Atom {
10948 target: 2,
10949 label: 1,
10950 });
10951 atn.state_mut(1)
10952 .expect("state 1")
10953 .add_transition(Transition::Atom {
10954 target: 2,
10955 label: 2,
10956 });
10957
10958 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
10959 parser.fast_recovery_enabled = false;
10960 let mut visiting = FxHashSet::default();
10961 let mut memo = FxHashMap::default();
10962 let mut expected = ExpectedTokens::default();
10963 let outcomes = parser.recognize_state_fast(
10964 &atn,
10965 FastRecognizeRequest {
10966 state_number: 1,
10967 stop_state: 2,
10968 index: 0,
10969 rule_start_index: 0,
10970 decision_start_index: None,
10971 precedence: 0,
10972 depth: 0,
10973 recovery_symbols: parser.empty_recovery_symbols(),
10974 recovery_state: None,
10975 },
10976 &mut visiting,
10977 &mut memo,
10978 &mut expected,
10979 );
10980
10981 assert!(outcomes.is_empty());
10982 assert_eq!(memo.len(), 1);
10983 assert!(memo.values().next().expect("memo entry").is_empty());
10984 }
10985
10986 #[test]
10987 fn wildcard_matches_non_eof_only() {
10988 let mut parser = mini_parser(vec![
10989 CommonToken::new(1).with_text("x"),
10990 CommonToken::eof("parser-test", 1, 1, 1),
10991 ]);
10992 assert_eq!(parser.match_wildcard().expect("wildcard").text(), "x");
10993 assert!(parser.match_wildcard().is_err());
10994 }
10995
10996 #[test]
10997 fn add_parse_child_records_match_even_without_tree_building() {
10998 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11003 let token = CommonToken::new(1).with_text("x");
11004
11005 parser.set_build_parse_trees(false);
11006 let mut ctx = ParserRuleContext::new(0, 0);
11007 assert!(!ctx.has_matched_child());
11008 parser.add_parse_child(
11009 &mut ctx,
11010 ParseTree::Terminal(TerminalNode::new(token.clone())),
11011 );
11012 assert!(ctx.children().is_empty());
11014 assert!(ctx.has_matched_child());
11016
11017 parser.set_build_parse_trees(true);
11019 let mut ctx = ParserRuleContext::new(0, 0);
11020 parser.add_parse_child(&mut ctx, ParseTree::Terminal(TerminalNode::new(token)));
11021 assert_eq!(ctx.children().len(), 1);
11022 assert!(ctx.has_matched_child());
11023 }
11024
11025 #[test]
11026 fn parser_interprets_simple_atn_rule() {
11027 let atn = token_then_eof_atn();
11028 let mut parser = mini_parser(vec![
11029 CommonToken::new(1).with_text("x"),
11030 CommonToken::eof("parser-test", 1, 1, 1),
11031 ]);
11032
11033 let tree = parser
11034 .parse_atn_rule(&atn, 0)
11035 .expect("artificial parser rule should parse");
11036 assert_eq!(tree.text(), "x<EOF>");
11037 assert_eq!(parser.number_of_syntax_errors(), 0);
11038 assert_eq!(
11039 tree.first_rule_stop(0)
11040 .expect("rule should stop at EOF")
11041 .token_type(),
11042 TOKEN_EOF
11043 );
11044
11045 let mut parser = mini_parser(vec![
11046 CommonToken::new(1).with_text("x"),
11047 CommonToken::eof("parser-test", 1, 1, 1),
11048 ]);
11049 let (tree, actions) = parser
11050 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11051 .expect("runtime-option parser rule should parse");
11052 assert!(actions.is_empty());
11053 assert_eq!(
11054 tree.first_rule_stop(0)
11055 .expect("rule should stop at EOF")
11056 .token_type(),
11057 TOKEN_EOF
11058 );
11059 }
11060
11061 #[test]
11062 fn runtime_options_default_ignores_noop_action_transitions() {
11063 let atn = noop_action_then_token_then_eof_atn();
11064 let mut parser = mini_parser(vec![
11065 CommonToken::new(1).with_text("x"),
11066 CommonToken::eof("parser-test", 1, 1, 1),
11067 ]);
11068
11069 let (tree, actions) = parser
11070 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11071 .expect("no-op parser action should not force action replay");
11072
11073 assert_eq!(tree.text(), "x<EOF>");
11074 assert!(
11075 actions.is_empty(),
11076 "action_index=None transitions are ANTLR metadata, not replay actions"
11077 );
11078 assert_eq!(parser.number_of_syntax_errors(), 0);
11079 }
11080
11081 #[test]
11082 fn parser_exposes_buffered_token_stream_after_parse() {
11083 let atn = token_then_eof_atn();
11084 let mut parser = mini_parser(vec![
11085 CommonToken::new(1).with_text("x"),
11086 CommonToken::eof("parser-test", 1, 1, 1),
11087 ]);
11088
11089 let tree = parser
11090 .parse_atn_rule(&atn, 0)
11091 .expect("artificial parser rule should parse");
11092 assert_eq!(tree.text(), "x<EOF>");
11093
11094 let stream = parser.token_stream();
11095 let source_index_after_parse = stream.token_source().index;
11096 let buffered = stream.tokens();
11097 assert_eq!(buffered.len(), 2);
11098 assert_eq!(buffered[0].text(), "x");
11099 assert_eq!(buffered[0].token_index(), 0);
11100 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
11101 assert_eq!(stream.token_source().index, source_index_after_parse);
11102
11103 let stream = parser.into_token_stream();
11104 assert_eq!(stream.token_source().index, source_index_after_parse);
11105 assert_eq!(stream.tokens()[0].text(), "x");
11106 assert_eq!(stream.tokens()[1].token_type(), TOKEN_EOF);
11107 }
11108
11109 #[test]
11110 fn parser_syntax_error_count_tracks_interpreted_recovery() {
11111 let atn = token_then_eof_atn();
11112 let mut parser = mini_parser(vec![
11113 CommonToken::new(1).with_text("x"),
11114 CommonToken::new(2).with_text("y"),
11115 CommonToken::eof("parser-test", 2, 1, 2),
11116 ]);
11117
11118 let tree = parser
11119 .parse_atn_rule(&atn, 0)
11120 .expect("invalid token should recover into an error node");
11121
11122 assert_eq!(parser.number_of_syntax_errors(), 1);
11123 assert_eq!(
11124 tree.first_error_token()
11125 .expect("recovery should embed an error token")
11126 .text(),
11127 "y"
11128 );
11129 }
11130
11131 #[test]
11132 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
11133 let atn = token_then_eof_atn();
11134 let mut parser = mini_parser(vec![
11135 CommonToken::new(2).with_text("y"),
11136 CommonToken::eof("parser-test", 1, 1, 1),
11137 ]);
11138
11139 let error = parser
11140 .parse_atn_rule(&atn, 0)
11141 .expect_err("start-rule mismatch should remain a parser error");
11142
11143 assert_eq!(parser.number_of_syntax_errors(), 1);
11144 assert!(matches!(error, AntlrError::ParserError { .. }));
11145 }
11146
11147 #[test]
11148 fn adaptive_direct_rule_uses_simulator_decision() {
11149 let atn = two_alt_decision_atn();
11150 let mut simulator = ParserAtnSimulator::new(&atn);
11151 let mut parser = mini_parser(vec![
11152 CommonToken::new(2).with_text("y"),
11153 CommonToken::eof("parser-test", 1, 1, 1),
11154 ]);
11155
11156 let tree = parser
11157 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
11158 .expect("direct adaptive rule should parse");
11159
11160 assert_eq!(tree.text(), "y");
11161 assert_eq!(parser.input.index(), 1);
11162 }
11163
11164 #[test]
11165 fn adaptive_direct_rule_restores_input_on_fallback() {
11166 let atn = predicate_after_token_atn();
11167 let mut simulator = ParserAtnSimulator::new(&atn);
11168 let mut parser = mini_parser(vec![
11169 CommonToken::new(1).with_text("x"),
11170 CommonToken::new(2).with_text("y"),
11171 CommonToken::eof("parser-test", 2, 1, 2),
11172 ]);
11173
11174 let tree = parser
11175 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
11176 .expect("fallback recognizer should parse");
11177
11178 assert_eq!(tree.text(), "xy");
11179 assert_eq!(parser.input.index(), 2);
11180 }
11181
11182 #[test]
11183 fn unknown_predicate_policy_defaults_to_assume_true() {
11184 let atn = predicate_after_token_atn();
11185 let mut parser = mini_parser(vec![
11186 CommonToken::new(1).with_text("x"),
11187 CommonToken::new(2).with_text("y"),
11188 CommonToken::eof("parser-test", 2, 1, 2),
11189 ]);
11190
11191 let (tree, _) = parser
11192 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11193 .expect("unknown predicate should pass under the default policy");
11194
11195 assert_eq!(tree.text(), "xy");
11196 assert_eq!(parser.number_of_syntax_errors(), 0);
11197 }
11198
11199 #[test]
11200 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
11201 let atn = token_then_eof_atn();
11205 let mut parser = mini_parser(vec![
11206 CommonToken::new(1).with_text("x"),
11207 CommonToken::eof("parser-test", 1, 1, 1),
11208 ]);
11209
11210 parser.unknown_predicate_hits.push((7, 3));
11212
11213 parser
11215 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11216 .expect("child rule parses");
11217
11218 let error = parser
11220 .take_unknown_semantic_error()
11221 .expect("parent's recorded coordinate must survive the nested interpreted parse");
11222 let AntlrError::Unsupported(message) = error else {
11223 panic!("expected AntlrError::Unsupported, got {error:?}");
11224 };
11225 assert!(message.contains("pred_index=3"), "message: {message}");
11226 }
11227
11228 #[test]
11229 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
11230 let atn = predicate_after_token_atn();
11231 let mut parser = mini_parser(vec![
11232 CommonToken::new(1).with_text("x"),
11233 CommonToken::new(2).with_text("y"),
11234 CommonToken::eof("parser-test", 2, 1, 2),
11235 ]);
11236
11237 let result = parser.parse_atn_rule_with_runtime_options(
11238 &atn,
11239 0,
11240 ParserRuntimeOptions {
11241 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
11242 ..ParserRuntimeOptions::default()
11243 },
11244 );
11245
11246 assert!(
11247 result.is_err(),
11248 "the only path is predicate-guarded, so assume-false must fail the parse"
11249 );
11250 }
11251
11252 #[test]
11253 fn unknown_predicate_policy_error_names_the_coordinate() {
11254 let atn = predicate_after_token_atn();
11255 let mut parser = mini_parser(vec![
11256 CommonToken::new(1).with_text("x"),
11257 CommonToken::new(2).with_text("y"),
11258 CommonToken::eof("parser-test", 2, 1, 2),
11259 ]);
11260
11261 let error = parser
11262 .parse_atn_rule_with_runtime_options(
11263 &atn,
11264 0,
11265 ParserRuntimeOptions {
11266 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11267 ..ParserRuntimeOptions::default()
11268 },
11269 )
11270 .expect_err("evaluating an unknown predicate under Error policy must fail");
11271
11272 let AntlrError::Unsupported(message) = error else {
11273 panic!("expected AntlrError::Unsupported, got {error:?}");
11274 };
11275 assert!(
11276 message.contains("unsupported semantic predicate"),
11277 "message should name the failure class: {message}"
11278 );
11279 assert!(
11280 message.contains("pred_index=0"),
11281 "message should carry the coordinate: {message}"
11282 );
11283 }
11284
11285 #[test]
11286 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
11287 let atn = predicate_after_token_atn();
11293 let mut parser = mini_parser(vec![
11294 CommonToken::new(1).with_text("x"),
11295 CommonToken::new(2).with_text("y"),
11296 CommonToken::eof("parser-test", 2, 1, 2),
11297 ]);
11298
11299 parser
11300 .parse_atn_rule_with_runtime_options(
11301 &atn,
11302 0,
11303 ParserRuntimeOptions {
11304 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11305 ..ParserRuntimeOptions::default()
11306 },
11307 )
11308 .expect_err("first parse fails loud under the Error policy");
11309
11310 parser.reset_unknown_semantic_hits();
11315 assert!(
11316 parser.take_unknown_semantic_error().is_none(),
11317 "reset must drop stale unknown-predicate coordinates before a reused parse"
11318 );
11319 }
11320
11321 #[derive(Debug, Default)]
11322 struct RecordingHooks {
11323 predicates: Vec<(usize, usize, usize, Option<String>)>,
11324 actions: Vec<(usize, String, Option<String>)>,
11325 }
11326
11327 impl SemanticHooks for RecordingHooks {
11328 fn sempred<S>(
11329 &mut self,
11330 ctx: &mut ParserSemCtx<'_, S>,
11331 rule_index: usize,
11332 pred_index: usize,
11333 ) -> Option<bool>
11334 where
11335 S: TokenSource,
11336 {
11337 self.predicates.push((
11338 ctx.input_index(),
11339 rule_index,
11340 pred_index,
11341 ctx.token_text(1).map(str::to_owned),
11342 ));
11343 Some(true)
11344 }
11345
11346 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
11347 where
11348 S: TokenSource,
11349 {
11350 self.actions.push((
11351 action.source_state(),
11352 ctx.action_text(),
11353 ctx.rule_name().map(str::to_owned),
11354 ));
11355 true
11356 }
11357 }
11358
11359 #[derive(Debug, Default)]
11360 struct RejectingPredicateHooks {
11361 predicates: Vec<(usize, usize, usize, Option<String>)>,
11362 }
11363
11364 impl SemanticHooks for RejectingPredicateHooks {
11365 fn sempred<S>(
11366 &mut self,
11367 ctx: &mut ParserSemCtx<'_, S>,
11368 rule_index: usize,
11369 pred_index: usize,
11370 ) -> Option<bool>
11371 where
11372 S: TokenSource,
11373 {
11374 self.predicates.push((
11375 ctx.input_index(),
11376 rule_index,
11377 pred_index,
11378 ctx.token_text(1).map(str::to_owned),
11379 ));
11380 Some(false)
11381 }
11382 }
11383
11384 #[test]
11385 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
11386 let atn = predicate_after_token_atn();
11387 let mut parser = mini_parser_with_hooks(
11388 vec![
11389 CommonToken::new(1).with_text("x"),
11390 CommonToken::new(2).with_text("y"),
11391 CommonToken::eof("parser-test", 2, 1, 2),
11392 ],
11393 RecordingHooks::default(),
11394 );
11395
11396 let (tree, _) = parser
11397 .parse_atn_rule_with_runtime_options(
11398 &atn,
11399 0,
11400 ParserRuntimeOptions {
11401 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11402 ..ParserRuntimeOptions::default()
11403 },
11404 )
11405 .expect("hook supplies the missing predicate result");
11406
11407 assert_eq!(tree.text(), "xy");
11408 assert_eq!(
11409 parser.semantic_hooks.predicates,
11410 vec![(1, 0, 0, Some("y".to_owned()))]
11411 );
11412 }
11413
11414 #[test]
11415 fn runtime_options_default_preserves_semantic_hook_predicates() {
11416 let atn = predicate_after_token_atn();
11417 let mut parser = mini_parser_with_hooks(
11418 vec![
11419 CommonToken::new(1).with_text("x"),
11420 CommonToken::new(2).with_text("y"),
11421 CommonToken::eof("parser-test", 2, 1, 2),
11422 ],
11423 RejectingPredicateHooks::default(),
11424 );
11425
11426 let result =
11427 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
11428
11429 assert!(
11430 result.is_err(),
11431 "default runtime options must not bypass semantic hooks for predicate ATNs"
11432 );
11433 assert_eq!(
11434 parser.semantic_hooks.predicates,
11435 vec![(1, 0, 0, Some("y".to_owned()))]
11436 );
11437 }
11438
11439 #[test]
11440 fn semantic_hook_handles_committed_parser_action() {
11441 let atn = token_then_eof_atn();
11442 let mut parser = mini_parser_with_hooks(
11443 vec![
11444 CommonToken::new(1).with_text("x"),
11445 CommonToken::eof("parser-test", 1, 1, 1),
11446 ],
11447 RecordingHooks::default(),
11448 );
11449 let (tree, _) = parser
11450 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11451 .expect("rule parses before action hook is tested");
11452
11453 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
11454 assert_eq!(
11455 parser.semantic_hooks.actions,
11456 vec![(42, "x".to_owned(), Some("s".to_owned()))]
11457 );
11458 }
11459
11460 #[test]
11461 fn unhandled_committed_action_fails_loud_under_error_policy() {
11462 let mut parser =
11466 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11467 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
11468 let tree = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, -1)));
11469
11470 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
11472
11473 let error = parser
11474 .take_unknown_semantic_error()
11475 .expect("an unhandled committed action under Error policy must fail loud");
11476 let AntlrError::Unsupported(message) = error else {
11477 panic!("expected AntlrError::Unsupported, got {error:?}");
11478 };
11479 assert!(
11480 message.contains("unhandled semantic action") && message.contains("state=42"),
11481 "message should name the dropped action coordinate: {message}"
11482 );
11483
11484 let mut lenient =
11486 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11487 let tree = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, -1)));
11488 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
11489 assert!(lenient.take_unknown_semantic_error().is_none());
11490 }
11491
11492 #[test]
11493 fn translated_predicate_is_unaffected_by_error_policy() {
11494 let atn = predicate_after_token_atn();
11495 let mut parser = mini_parser(vec![
11496 CommonToken::new(1).with_text("x"),
11497 CommonToken::new(2).with_text("y"),
11498 CommonToken::eof("parser-test", 2, 1, 2),
11499 ]);
11500
11501 let (tree, _) = parser
11502 .parse_atn_rule_with_runtime_options(
11503 &atn,
11504 0,
11505 ParserRuntimeOptions {
11506 predicates: &[(0, 0, ParserPredicate::True)],
11507 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11508 ..ParserRuntimeOptions::default()
11509 },
11510 )
11511 .expect("a predicate covered by the table is not an unknown coordinate");
11512
11513 assert_eq!(tree.text(), "xy");
11514 }
11515
11516 fn hook_predicate_semantics() -> ParserSemantics {
11521 let mut ir = SemIr::new();
11522 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
11523 ParserSemantics {
11524 ir,
11525 predicates: vec![ParserSemanticPredicate {
11526 rule_index: 0,
11527 pred_index: 0,
11528 expr,
11529 failure_message: None,
11530 }],
11531 actions: Vec::new(),
11532 }
11533 }
11534
11535 #[derive(Debug, Default)]
11536 struct DecliningHooks;
11537
11538 impl SemanticHooks for DecliningHooks {}
11539
11540 #[test]
11541 fn semir_hook_none_falls_through_to_assume_true() {
11542 let atn = predicate_after_token_atn();
11543 let semantics = hook_predicate_semantics();
11544 let mut parser = mini_parser_with_hooks(
11545 vec![
11546 CommonToken::new(1).with_text("x"),
11547 CommonToken::new(2).with_text("y"),
11548 CommonToken::eof("parser-test", 2, 1, 2),
11549 ],
11550 DecliningHooks,
11551 );
11552
11553 let (tree, _) = parser
11554 .parse_atn_rule_with_runtime_options(
11555 &atn,
11556 0,
11557 ParserRuntimeOptions {
11558 semantics: Some(&semantics),
11559 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
11560 ..ParserRuntimeOptions::default()
11561 },
11562 )
11563 .expect("a declined SemIR hook must pass under assume-true");
11564
11565 assert_eq!(tree.text(), "xy");
11566 }
11567
11568 #[test]
11569 fn semir_hook_none_falls_through_to_assume_false() {
11570 let atn = predicate_after_token_atn();
11571 let semantics = hook_predicate_semantics();
11572 let mut parser = mini_parser_with_hooks(
11573 vec![
11574 CommonToken::new(1).with_text("x"),
11575 CommonToken::new(2).with_text("y"),
11576 CommonToken::eof("parser-test", 2, 1, 2),
11577 ],
11578 DecliningHooks,
11579 );
11580
11581 let result = parser.parse_atn_rule_with_runtime_options(
11582 &atn,
11583 0,
11584 ParserRuntimeOptions {
11585 semantics: Some(&semantics),
11586 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
11587 ..ParserRuntimeOptions::default()
11588 },
11589 );
11590
11591 assert!(
11592 result.is_err(),
11593 "a declined SemIR hook must fail the only guarded path under assume-false"
11594 );
11595 }
11596
11597 #[test]
11598 fn semir_hook_none_records_coordinate_under_error_policy() {
11599 let atn = predicate_after_token_atn();
11600 let semantics = hook_predicate_semantics();
11601 let mut parser = mini_parser_with_hooks(
11602 vec![
11603 CommonToken::new(1).with_text("x"),
11604 CommonToken::new(2).with_text("y"),
11605 CommonToken::eof("parser-test", 2, 1, 2),
11606 ],
11607 DecliningHooks,
11608 );
11609
11610 let error = parser
11611 .parse_atn_rule_with_runtime_options(
11612 &atn,
11613 0,
11614 ParserRuntimeOptions {
11615 semantics: Some(&semantics),
11616 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11617 ..ParserRuntimeOptions::default()
11618 },
11619 )
11620 .expect_err("a declined SemIR hook under Error policy must fail the parse");
11621
11622 let AntlrError::Unsupported(message) = error else {
11623 panic!("expected AntlrError::Unsupported, got {error:?}");
11624 };
11625 assert!(
11626 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
11627 "message should name the unresolved coordinate: {message}"
11628 );
11629 }
11630
11631 #[test]
11632 fn generated_direct_predicate_honors_installed_policy() {
11633 let semantics = hook_predicate_semantics();
11639 let context = ParserRuleContext::new(0, -1);
11640
11641 let mut assume_true =
11642 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11643 assert!(
11644 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
11645 &semantics, 0, 0, &context, 0
11646 ),
11647 "default AssumeTrue accepts a declined hook"
11648 );
11649 assert!(assume_true.take_unknown_semantic_error().is_none());
11650
11651 let mut error_policy =
11652 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11653 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
11654 assert!(
11655 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
11656 &semantics, 0, 0, &context, 0
11657 ),
11658 "Error policy rejects a declined hook on the generated-direct path"
11659 );
11660 let error = error_policy
11661 .take_unknown_semantic_error()
11662 .expect("Error policy records the unresolved coordinate for the generated path");
11663 let AntlrError::Unsupported(message) = error else {
11664 panic!("expected AntlrError::Unsupported, got {error:?}");
11665 };
11666 assert!(message.contains("pred_index=0"), "message: {message}");
11667 }
11668
11669 #[test]
11670 fn parser_rule_start_skips_leading_hidden_tokens() {
11671 let atn = token_then_eof_atn();
11672 let mut parser = mini_parser(vec![
11673 CommonToken::new(99)
11674 .with_text(" ")
11675 .with_channel(HIDDEN_CHANNEL),
11676 CommonToken::new(1).with_text("x"),
11677 CommonToken::eof("parser-test", 2, 1, 2),
11678 ]);
11679
11680 let tree = parser
11681 .parse_atn_rule(&atn, 0)
11682 .expect("artificial parser rule should parse");
11683 let Some(ParseTree::Rule(rule)) = tree.first_rule(0) else {
11684 panic!("rule node should be present");
11685 };
11686 assert_eq!(
11687 rule.context()
11688 .start()
11689 .expect("rule should have a start token")
11690 .token_type(),
11691 1
11692 );
11693 }
11694
11695 #[test]
11696 fn parser_action_after_eof_stops_at_eof_token() {
11697 let atn = eof_then_action_atn();
11698 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
11699
11700 let (_, actions) = parser
11701 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11702 .expect("EOF action rule should parse");
11703
11704 assert_eq!(actions.len(), 1);
11705 assert_eq!(actions[0].stop_index(), Some(0));
11706 assert_eq!(
11707 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
11708 ""
11709 );
11710 }
11711
11712 #[test]
11713 fn after_action_stop_uses_rule_context_stop_not_cursor() {
11714 let mut id = CommonToken::new(1).with_text("x");
11719 id.set_token_index(0);
11720 let mut eof = CommonToken::eof("parser-test", 1, 1, 1);
11721 eof.set_token_index(1);
11722 let mut parser = mini_parser(vec![id.clone(), eof]);
11723 parser.consume();
11725 assert_eq!(parser.la(1), TOKEN_EOF);
11726
11727 let mut ctx = ParserRuleContext::new(0, 0);
11730 ctx.set_stop(id);
11731 let tree = ParseTree::Rule(RuleNode::new(ctx));
11732
11733 let current_index = parser.input.index();
11734 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
11736 assert_eq!(
11738 parser.after_action_stop_index_for_tree(&tree, current_index),
11739 Some(0)
11740 );
11741 }
11742
11743 #[test]
11744 fn after_action_start_uses_rule_context_start_not_cursor() {
11745 let parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11750 let mut id = CommonToken::new(1).with_text("x");
11751 id.set_token_index(2);
11753
11754 let mut ctx = ParserRuleContext::new(0, 0);
11755 ctx.set_start(id);
11756 let tree = ParseTree::Rule(RuleNode::new(ctx));
11757
11758 assert_eq!(parser.after_action_start_index_for_tree(&tree, 0), 2);
11761
11762 let empty = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, 0)));
11764 assert_eq!(parser.after_action_start_index_for_tree(&empty, 7), 7);
11765 }
11766
11767 #[test]
11768 fn fast_outcome_selection_respects_sll_tie_order() {
11769 let first = FastRecognizeOutcome {
11770 index: 1,
11771 consumed_eof: false,
11772 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
11773 line: 1,
11774 column: 0,
11775 message: "mismatched input 'x'".to_owned(),
11776 }]),
11777 nodes: NodeList::new(),
11778 };
11779 let second = FastRecognizeOutcome {
11780 index: first.index,
11781 consumed_eof: first.consumed_eof,
11782 diagnostics: FastDiagnostics::new(),
11783 nodes: NodeList::new(),
11784 };
11785
11786 let selected = select_best_fast_outcome(
11787 [first.clone(), second.clone()].into_iter(),
11788 PredictionMode::Sll,
11789 None,
11790 |_| panic!("caller-follow token probe should not run"),
11791 )
11792 .expect("one outcome should be selected");
11793 assert_eq!(selected.diagnostics.len(), 1);
11794 let eof_second = FastRecognizeOutcome {
11795 index: second.index,
11796 consumed_eof: true,
11797 diagnostics: FastDiagnostics::new(),
11798 nodes: NodeList::new(),
11799 };
11800 let selected = select_best_fast_outcome(
11801 [first.clone(), eof_second].into_iter(),
11802 PredictionMode::Sll,
11803 None,
11804 |_| panic!("caller-follow token probe should not run"),
11805 )
11806 .expect("one outcome should be selected");
11807 assert!(!selected.consumed_eof);
11808 let selected = select_best_fast_outcome(
11809 [first, second].into_iter(),
11810 PredictionMode::Ll,
11811 None,
11812 |_| panic!("caller-follow token probe should not run"),
11813 )
11814 .expect("one outcome should be selected");
11815 assert!(selected.diagnostics.is_empty());
11816 }
11817
11818 #[test]
11819 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
11820 let first = FastRecognizeOutcome {
11821 index: 3,
11822 consumed_eof: false,
11823 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
11824 line: 1,
11825 column: 0,
11826 message: "mismatched input 'x' expecting 'a'".to_owned(),
11827 }]),
11828 nodes: NodeList::new(),
11829 };
11830 let same_rank = FastRecognizeOutcome {
11831 index: first.index,
11832 consumed_eof: first.consumed_eof,
11833 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
11834 line: 1,
11835 column: 0,
11836 message: "mismatched input 'x' expecting 'b'".to_owned(),
11837 }]),
11838 nodes: NodeList::new(),
11839 };
11840 let better_rank = FastRecognizeOutcome {
11841 index: first.index,
11842 consumed_eof: first.consumed_eof,
11843 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
11844 line: 1,
11845 column: 0,
11846 message: "missing 'a' at 'x'".to_owned(),
11847 }]),
11848 nodes: NodeList::new(),
11849 };
11850 let mut outcomes = vec![first, same_rank, better_rank];
11851
11852 dedupe_fast_outcomes(&mut outcomes);
11853
11854 assert_eq!(outcomes.len(), 2);
11855 assert_eq!(
11856 outcomes[0].diagnostics[0].message,
11857 "mismatched input 'x' expecting 'a'"
11858 );
11859 assert_eq!(outcomes[1].diagnostics[0].message, "missing 'a' at 'x'");
11860 }
11861
11862 #[test]
11863 fn fast_outcome_selection_prefers_generated_caller_follow() {
11864 let earlier = FastRecognizeOutcome {
11865 index: 7,
11866 consumed_eof: false,
11867 diagnostics: FastDiagnostics::new(),
11868 nodes: NodeList::new(),
11869 };
11870 let later = FastRecognizeOutcome {
11871 index: 8,
11872 consumed_eof: false,
11873 diagnostics: FastDiagnostics::new(),
11874 nodes: NodeList::new(),
11875 };
11876 let mut follow = TokenBitSet::default();
11877 follow.insert(5);
11878
11879 let selected = select_best_fast_outcome(
11880 [later.clone(), earlier.clone()].into_iter(),
11881 PredictionMode::Ll,
11882 Some(&follow),
11883 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
11884 )
11885 .expect("one outcome should be selected");
11886 assert_eq!(selected.index, 7);
11887
11888 let selected = select_best_fast_outcome(
11889 [later.clone(), earlier.clone()].into_iter(),
11890 PredictionMode::Ll,
11891 Some(&follow),
11892 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
11893 )
11894 .expect("one outcome should be selected");
11895 assert_eq!(selected.index, 8);
11896
11897 let indented_next_statement = FastRecognizeOutcome {
11898 index: 9,
11899 consumed_eof: false,
11900 diagnostics: FastDiagnostics::new(),
11901 nodes: NodeList::new(),
11902 };
11903 let selected = select_best_fast_outcome(
11904 [indented_next_statement, earlier.clone()].into_iter(),
11905 PredictionMode::Ll,
11906 Some(&follow),
11907 |index| {
11908 let is_boundary = index == 7;
11909 let is_boundary_gap = matches!(index, 7 | 8);
11910 (
11911 if index == 7 { 5 } else { TOKEN_EOF },
11912 is_boundary,
11913 is_boundary_gap,
11914 )
11915 },
11916 )
11917 .expect("one outcome should be selected");
11918 assert_eq!(selected.index, 7);
11919
11920 let continuation = FastRecognizeOutcome {
11921 index: 10,
11922 consumed_eof: false,
11923 diagnostics: FastDiagnostics::new(),
11924 nodes: NodeList::new(),
11925 };
11926 let selected = select_best_fast_outcome(
11927 [continuation, earlier.clone()].into_iter(),
11928 PredictionMode::Ll,
11929 Some(&follow),
11930 |index| {
11931 let is_boundary = matches!(index, 7 | 9);
11932 (
11933 if index == 7 { 5 } else { TOKEN_EOF },
11934 is_boundary,
11935 is_boundary,
11936 )
11937 },
11938 )
11939 .expect("one outcome should be selected");
11940 assert_eq!(selected.index, 10);
11941
11942 let selected = select_best_fast_outcome(
11943 [earlier, later].into_iter(),
11944 PredictionMode::Sll,
11945 Some(&follow),
11946 |_| panic!("caller-follow token probe should not run in SLL mode"),
11947 )
11948 .expect("one outcome should be selected");
11949 assert_eq!(selected.index, 8);
11950 }
11951
11952 #[test]
11953 fn caller_follow_boundary_text_requires_separator_shape() {
11954 assert!(is_caller_follow_boundary_text(";"));
11955 assert!(is_caller_follow_boundary_text("\n"));
11956 assert!(is_caller_follow_boundary_text("\r\n "));
11957 assert!(is_caller_follow_boundary_text(";\n"));
11958 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
11959 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
11960 assert!(!is_caller_follow_boundary_text("identifier"));
11961 assert!(is_caller_follow_boundary_gap_text(" \t "));
11962 assert!(is_caller_follow_boundary_gap_text("\n "));
11963 assert!(is_caller_follow_boundary_gap_text(";\t"));
11964 assert!(!is_caller_follow_boundary_gap_text(
11965 "\"\"\"line1\nline2\"\"\""
11966 ));
11967 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
11968 }
11969
11970 #[test]
11971 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
11972 let mut parser = mini_parser(vec![
11973 CommonToken::new(5).with_text("\n"),
11974 CommonToken::new(6)
11975 .with_text("// comment\n")
11976 .with_channel(HIDDEN_CHANNEL),
11977 CommonToken::new(1).with_text("x"),
11978 CommonToken::eof("parser-test", 1, 2, 0),
11979 ]);
11980
11981 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
11982 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
11983 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
11984 }
11985
11986 #[test]
11987 fn caller_follow_token_info_uses_stream_visible_channel() {
11988 let source = Source {
11989 tokens: vec![
11990 CommonToken::new(5).with_text("\n").with_channel(2),
11991 CommonToken::new(1).with_text("x").with_channel(2),
11992 CommonToken::new(6)
11993 .with_text("// comment\n")
11994 .with_channel(HIDDEN_CHANNEL),
11995 CommonToken::eof("parser-test", 1, 2, 0),
11996 ],
11997 index: 0,
11998 };
11999 let data = RecognizerData::new(
12000 "Mini.g4",
12001 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12002 );
12003 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
12004
12005 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
12006 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
12007 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
12008 }
12009
12010 #[test]
12011 fn reset_per_parse_caches_clears_state_expected_token_cache() {
12012 let atn = token_then_eof_atn();
12013 let mut parser = mini_parser(Vec::new());
12014
12015 let _ = parser.cached_state_expected_token_set(&atn, 0);
12016 assert!(!parser.state_expected_token_cache.is_empty());
12017
12018 parser.reset_per_parse_caches();
12019 assert!(parser.state_expected_token_cache.is_empty());
12020 }
12021
12022 #[test]
12023 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
12024 let source = Source {
12025 tokens: vec![
12026 CommonToken::new(1).with_text("x"),
12027 CommonToken::eof("parser-test", 1, 1, 1),
12028 ],
12029 index: 0,
12030 };
12031 let data = RecognizerData::new(
12032 "Mini.g4",
12033 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12034 );
12035 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
12036 let expected = ExpectedTokens {
12037 index: Some(0),
12038 symbols: BTreeSet::new(),
12039 no_viable: None,
12040 };
12041
12042 let (_, message) = parser.expected_error_message(0, 0, &expected);
12043
12044 assert_eq!(message, "mismatched input 'x'");
12045 }
12046
12047 #[test]
12048 fn eof_rule_stop_index_points_at_eof_token() {
12049 let source = Source {
12050 tokens: vec![
12051 CommonToken::new(1).with_text("x"),
12052 CommonToken::eof("parser-test", 1, 1, 1),
12053 ],
12054 index: 0,
12055 };
12056 let data = RecognizerData::new(
12057 "Mini.g4",
12058 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12059 );
12060 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
12061
12062 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
12063 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
12064 }
12065
12066 #[test]
12067 fn generated_parser_action_uses_current_rule_stop_boundary() {
12068 let mut parser = mini_parser(vec![
12069 CommonToken::new(1).with_text("x"),
12070 CommonToken::eof("parser-test", 1, 1, 1),
12071 ]);
12072
12073 parser.match_token(1).expect("token should match");
12074 let action = parser.parser_action_at_current(7, 0, 0, false);
12075 assert_eq!(action.source_state(), 7);
12076 assert_eq!(action.rule_index(), 0);
12077 assert_eq!(action.start_index(), 0);
12078 assert_eq!(action.stop_index(), Some(0));
12079
12080 parser.match_eof().expect("EOF should match");
12081 let action = parser.parser_action_at_current(8, 0, 0, true);
12082 assert_eq!(action.stop_index(), Some(1));
12083 }
12084
12085 #[test]
12086 fn folds_left_recursive_boundary_into_rule_node() {
12087 let nodes = fold_left_recursive_boundaries(vec![
12088 RecognizedNode::Token { index: 0 },
12089 RecognizedNode::LeftRecursiveBoundary { rule_index: 1 },
12090 RecognizedNode::Token { index: 1 },
12091 ]);
12092
12093 assert_eq!(
12094 nodes,
12095 vec![
12096 RecognizedNode::Rule {
12097 rule_index: 1,
12098 invoking_state: -1,
12099 alt_number: 0,
12100 start_index: 0,
12101 stop_index: Some(0),
12102 return_values: BTreeMap::new(),
12103 children: vec![RecognizedNode::Token { index: 0 }],
12104 },
12105 RecognizedNode::Token { index: 1 },
12106 ]
12107 );
12108 }
12109
12110 #[test]
12111 fn outcome_ties_keep_later_non_recursive_alternative() {
12112 let first = RecognizeOutcome {
12113 index: 1,
12114 consumed_eof: false,
12115 alt_number: 0,
12116 member_values: BTreeMap::new(),
12117 return_values: BTreeMap::new(),
12118 diagnostics: Vec::new(),
12119 decisions: Vec::new(),
12120 actions: vec![ParserAction::new(1, 0, 0, None)],
12121 nodes: vec![RecognizedNode::Token { index: 0 }],
12122 };
12123 let second = RecognizeOutcome {
12124 actions: vec![ParserAction::new(2, 0, 0, None)],
12125 ..first.clone()
12126 };
12127
12128 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
12129 .expect("one outcome should be selected");
12130 assert_eq!(selected.actions[0].source_state(), 2);
12131 }
12132
12133 #[test]
12134 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
12135 let first = RecognizeOutcome {
12136 index: 1,
12137 consumed_eof: false,
12138 alt_number: 0,
12139 member_values: BTreeMap::new(),
12140 return_values: BTreeMap::new(),
12141 diagnostics: Vec::new(),
12142 decisions: Vec::new(),
12143 actions: vec![ParserAction::new(1, 0, 0, None)],
12144 nodes: vec![RecognizedNode::Token { index: 0 }],
12145 };
12146 let second = RecognizeOutcome {
12147 actions: vec![
12148 ParserAction::new(2, 0, 0, None),
12149 ParserAction::new(3, 0, 0, None),
12150 ],
12151 ..first.clone()
12152 };
12153
12154 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll)
12155 .expect("one outcome should be selected");
12156 assert_eq!(selected.actions.len(), 2);
12157 }
12158
12159 #[test]
12160 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
12161 let first = RecognizeOutcome {
12162 index: 7,
12163 consumed_eof: false,
12164 alt_number: 0,
12165 member_values: BTreeMap::new(),
12166 return_values: BTreeMap::new(),
12167 diagnostics: Vec::new(),
12168 decisions: vec![1, 0],
12169 actions: vec![
12170 ParserAction::new(23, 2, 2, Some(4)),
12171 ParserAction::new(23, 2, 0, Some(6)),
12172 ],
12173 nodes: vec![RecognizedNode::Token { index: 0 }],
12174 };
12175 let second = RecognizeOutcome {
12176 decisions: vec![0, 1],
12177 actions: vec![
12178 ParserAction::new(23, 2, 2, Some(6)),
12179 ParserAction::new(23, 2, 0, Some(6)),
12180 ],
12181 ..first.clone()
12182 };
12183
12184 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
12185 .expect("one outcome should be selected");
12186 assert_eq!(selected.actions[0].stop_index(), Some(6));
12187 }
12188
12189 #[test]
12190 fn outcome_ties_keep_first_recursive_tree_shape() {
12191 let recursive_nodes = vec![RecognizedNode::Rule {
12192 rule_index: 1,
12193 invoking_state: -1,
12194 alt_number: 0,
12195 start_index: 0,
12196 stop_index: Some(0),
12197 return_values: BTreeMap::new(),
12198 children: vec![RecognizedNode::Rule {
12199 rule_index: 1,
12200 invoking_state: -1,
12201 alt_number: 0,
12202 start_index: 0,
12203 stop_index: Some(0),
12204 return_values: BTreeMap::new(),
12205 children: vec![RecognizedNode::Token { index: 0 }],
12206 }],
12207 }];
12208 let first = RecognizeOutcome {
12209 index: 1,
12210 consumed_eof: false,
12211 alt_number: 0,
12212 member_values: BTreeMap::new(),
12213 return_values: BTreeMap::new(),
12214 diagnostics: Vec::new(),
12215 decisions: Vec::new(),
12216 actions: vec![ParserAction::new(1, 0, 0, None)],
12217 nodes: recursive_nodes.clone(),
12218 };
12219 let second = RecognizeOutcome {
12220 index: 1,
12221 consumed_eof: false,
12222 alt_number: 0,
12223 member_values: BTreeMap::new(),
12224 return_values: BTreeMap::new(),
12225 diagnostics: Vec::new(),
12226 decisions: Vec::new(),
12227 actions: vec![ParserAction::new(2, 0, 0, None)],
12228 nodes: recursive_nodes,
12229 };
12230
12231 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
12232 .expect("one outcome should be selected");
12233 assert_eq!(selected.actions[0].source_state(), 1);
12234 }
12235
12236 #[test]
12237 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
12238 let first_alt = RecognizeOutcome {
12239 index: 2,
12240 consumed_eof: true,
12241 alt_number: 0,
12242 member_values: BTreeMap::new(),
12243 return_values: BTreeMap::new(),
12244 diagnostics: vec![ParserDiagnostic {
12245 line: 1,
12246 column: 3,
12247 message: "missing 'Y' at '<EOF>'".to_owned(),
12248 }],
12249 decisions: vec![0],
12250 actions: vec![ParserAction::new(1, 0, 0, None)],
12251 nodes: vec![RecognizedNode::Token { index: 0 }],
12252 };
12253 let second_alt = RecognizeOutcome {
12254 diagnostics: Vec::new(),
12255 decisions: vec![1],
12256 actions: vec![ParserAction::new(2, 0, 0, None)],
12257 ..first_alt.clone()
12258 };
12259
12260 let selected =
12261 select_best_outcome([second_alt, first_alt].into_iter(), PredictionMode::Sll)
12262 .expect("one outcome should be selected");
12263 assert_eq!(selected.diagnostics.len(), 1);
12264 assert_eq!(selected.decisions, [0]);
12265 }
12266}