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 self.fast_recovery_enabled = true;
4657 let needs_tree_retry = matches!(
4658 &first_pass,
4659 Ok((outcome, _)) if self.build_parse_trees && outcome.nodes.has_left_recursive_boundary()
4660 );
4661 let needs_retry = match &first_pass {
4662 Err(_) => true,
4675 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
4676 };
4677 let (outcome, _expected) = if needs_retry {
4678 self.fast_first_set_prefilter = false;
4679 let retry = self.fast_recognize_top(atn, top_request);
4680 self.fast_first_set_prefilter = true;
4681 let selected = if needs_tree_retry {
4682 match retry {
4683 ok @ Ok(_) => ok,
4684 Err(_) => first_pass,
4685 }
4686 } else {
4687 select_better_top_outcome(first_pass, retry)
4688 };
4689 selected.map_err(|expected| {
4690 let error = self.recognition_error(rule_index, start_index, &expected);
4691 self.record_syntax_errors(1);
4692 report_token_source_errors(&self.input.drain_source_errors());
4693 error
4694 })?
4695 } else {
4696 first_pass.expect("first_pass is Ok in the no-retry branch")
4697 };
4698 self.record_syntax_errors(outcome.diagnostics.len());
4699 report_parser_diagnostics(&self.prediction_diagnostics);
4700 report_parser_diagnostics(&outcome.diagnostics);
4701 report_token_source_errors(&self.input.drain_source_errors());
4702 let mut context = ParserRuleContext::with_child_capacity(
4703 rule_index,
4704 self.state(),
4705 if self.build_parse_trees {
4706 outcome.nodes.len()
4707 } else {
4708 0
4709 },
4710 );
4711 if let Some(token) = self.token_ref_at(start_index) {
4712 context.set_start_ref(token);
4713 }
4714 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
4715 if let Some(token) = stop_index.and_then(|token_index| self.token_ref_at(token_index)) {
4716 context.set_stop_ref(token);
4717 }
4718 if self.build_parse_trees {
4719 if outcome.nodes.has_left_recursive_boundary() {
4720 let folded = fold_fast_left_recursive_boundaries(outcome.nodes.to_vec());
4721 if folded.iter().any(|node| {
4722 matches!(
4723 node.as_ref(),
4724 FastRecognizedNode::Token { .. }
4725 | FastRecognizedNode::ErrorToken { .. }
4726 | FastRecognizedNode::MissingToken { .. }
4727 )
4728 }) {
4729 for node in &folded {
4730 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
4731 }
4732 } else {
4733 self.add_fast_implicit_token_children(
4734 &mut context,
4735 start_index,
4736 stop_index,
4737 &folded,
4738 )?;
4739 }
4740 } else if outcome.nodes.has_explicit_token_node() {
4741 for node in outcome.nodes.iter() {
4742 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
4743 }
4744 } else {
4745 self.add_fast_implicit_token_children_iter(
4746 &mut context,
4747 start_index,
4748 stop_index,
4749 outcome.nodes.iter(),
4750 )?;
4751 }
4752 }
4753 self.input.seek(outcome.index);
4754
4755 Ok(self.rule_node(context))
4756 }
4757
4758 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
4759 let invoking_state = self.pending_invoking_states.last().copied()?;
4760 let state_number = usize::try_from(invoking_state).ok()?;
4761 match atn.state(state_number)?.transitions.first()? {
4762 Transition::Rule { follow_state, .. } => Some(*follow_state),
4763 _ => None,
4764 }
4765 }
4766
4767 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
4768 let token_type = self.token_type_at(index);
4771 let visible_channel = self.input.channel();
4772 let token = self.token_at(index);
4773 let is_boundary = token
4774 .as_ref()
4775 .and_then(Token::text)
4776 .is_some_and(is_caller_follow_boundary_text);
4777 let is_boundary_gap = token.as_ref().is_some_and(|token| {
4778 token.channel() != visible_channel || is_caller_follow_boundary_gap_text(token.text())
4779 });
4780 (token_type, is_boundary, is_boundary_gap)
4781 }
4782
4783 fn fast_recognize_top(
4788 &mut self,
4789 atn: &Atn,
4790 request: FastRecognizeTopRequest,
4791 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
4792 let FastRecognizeTopRequest {
4793 start_state,
4794 stop_state,
4795 start_index,
4796 precedence,
4797 caller_follow_state,
4798 } = request;
4799 let memo_capacity = self.input.size().saturating_mul(8).clamp(65_536, 524_288);
4808 let mut visiting = FxHashSet::with_capacity_and_hasher(256, FxBuildHasher::default());
4809 let mut memo = FxHashMap::with_capacity_and_hasher(memo_capacity, FxBuildHasher::default());
4810 let mut expected = ExpectedTokens::default();
4811 let empty_recovery = self.empty_recovery_symbols();
4812 let outcomes = self.recognize_state_fast(
4813 atn,
4814 FastRecognizeRequest {
4815 state_number: start_state,
4816 stop_state,
4817 index: start_index,
4818 rule_start_index: start_index,
4819 decision_start_index: None,
4820 precedence,
4821 depth: 0,
4822 recovery_symbols: empty_recovery,
4823 recovery_state: None,
4824 },
4825 &mut visiting,
4826 &mut memo,
4827 &mut expected,
4828 );
4829 #[cfg(feature = "perf-counters")]
4830 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
4831 perf_counters::dump();
4832 perf_counters::reset();
4833 }
4834 let caller_follow =
4835 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
4836 match select_best_fast_outcome(
4837 outcomes.into_iter(),
4838 self.prediction_mode,
4839 caller_follow.as_deref(),
4840 |index| self.caller_follow_token_info(index),
4841 ) {
4842 Some(outcome) => Ok((outcome, expected)),
4843 None => Err(expected),
4844 }
4845 }
4846
4847 fn fast_recognized_node_tree(
4850 &mut self,
4851 node: &FastRecognizedNode,
4852 ) -> Result<ParseTree, AntlrError> {
4853 match node {
4854 FastRecognizedNode::Token { index } => {
4855 let token = self
4856 .input
4857 .get_ref(*index)
4858 .ok_or_else(|| AntlrError::ParserError {
4859 line: 0,
4860 column: 0,
4861 message: format!("missing token at index {index}"),
4862 })?;
4863 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
4864 }
4865 FastRecognizedNode::ErrorToken { index } => {
4866 let token = self
4867 .input
4868 .get_ref(*index)
4869 .ok_or_else(|| AntlrError::ParserError {
4870 line: 0,
4871 column: 0,
4872 message: format!("missing error token at index {index}"),
4873 })?;
4874 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
4875 }
4876 FastRecognizedNode::MissingToken {
4877 token_type,
4878 at_index,
4879 text,
4880 } => {
4881 let current = self.token_at(*at_index);
4882 let token = CommonToken::new(*token_type)
4883 .with_text(text.as_str())
4884 .with_span(usize::MAX, usize::MAX)
4885 .with_position(
4886 current.as_ref().map(Token::line).unwrap_or_default(),
4887 current.as_ref().map(Token::column).unwrap_or_default(),
4888 );
4889 Ok(ParseTree::Error(ErrorNode::new(token)))
4890 }
4891 FastRecognizedNode::Rule {
4892 rule_index,
4893 invoking_state,
4894 start_index,
4895 stop_index,
4896 children,
4897 } => {
4898 let mut context = ParserRuleContext::with_child_capacity(
4899 *rule_index,
4900 *invoking_state,
4901 children.len(),
4902 );
4903 if let Some(token) = self.token_ref_at(*start_index) {
4904 context.set_start_ref(token);
4905 }
4906 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
4907 context.set_stop_ref(token);
4908 }
4909 if children.has_left_recursive_boundary() {
4910 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
4911 for child in &folded {
4912 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
4913 }
4914 } else {
4915 for child in children.iter() {
4916 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
4917 }
4918 }
4919 Ok(self.rule_node(context))
4920 }
4921 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
4922 Err(AntlrError::Unsupported(format!(
4923 "unfolded left-recursive boundary for rule {rule_index}"
4924 )))
4925 }
4926 }
4927 }
4928
4929 fn fast_recognized_node_tree_with_implicit_tokens(
4930 &mut self,
4931 node: &FastRecognizedNode,
4932 ) -> Result<ParseTree, AntlrError> {
4933 match node {
4934 FastRecognizedNode::Rule {
4935 rule_index,
4936 invoking_state,
4937 start_index,
4938 stop_index,
4939 children,
4940 } => {
4941 let mut context = ParserRuleContext::with_child_capacity(
4942 *rule_index,
4943 *invoking_state,
4944 children.len(),
4945 );
4946 if let Some(token) = self.token_ref_at(*start_index) {
4947 context.set_start_ref(token);
4948 }
4949 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
4950 context.set_stop_ref(token);
4951 }
4952 if children.has_left_recursive_boundary() {
4953 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
4954 self.add_fast_implicit_token_children(
4955 &mut context,
4956 *start_index,
4957 *stop_index,
4958 &folded,
4959 )?;
4960 } else {
4961 self.add_fast_implicit_token_children_iter(
4962 &mut context,
4963 *start_index,
4964 *stop_index,
4965 children.iter(),
4966 )?;
4967 }
4968 Ok(self.rule_node(context))
4969 }
4970 _ => self.fast_recognized_node_tree(node),
4971 }
4972 }
4973
4974 fn add_fast_implicit_token_children(
4975 &mut self,
4976 context: &mut ParserRuleContext,
4977 start_index: usize,
4978 stop_index: Option<usize>,
4979 children: &[Rc<FastRecognizedNode>],
4980 ) -> Result<(), AntlrError> {
4981 self.add_fast_implicit_token_children_iter(
4982 context,
4983 start_index,
4984 stop_index,
4985 children.iter(),
4986 )
4987 }
4988
4989 fn add_fast_implicit_token_children_iter<'a>(
4990 &mut self,
4991 context: &mut ParserRuleContext,
4992 start_index: usize,
4993 stop_index: Option<usize>,
4994 children: impl IntoIterator<Item = &'a Rc<FastRecognizedNode>>,
4995 ) -> Result<(), AntlrError> {
4996 let mut cursor = Some(start_index);
4997 for child in children {
4998 if let Some((child_start, child_stop)) = fast_recognized_node_span(child.as_ref()) {
4999 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
5000 context.add_child(
5001 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
5002 );
5003 if let Some(child_stop) = child_stop {
5004 cursor = self.next_visible_after_token(child_stop);
5005 }
5006 } else {
5007 context.add_child(
5008 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
5009 );
5010 }
5011 }
5012 if let Some(stop) = stop_index {
5013 self.add_visible_terminals_through(context, cursor, stop)?;
5014 }
5015 Ok(())
5016 }
5017
5018 fn add_visible_terminals_before(
5019 &mut self,
5020 context: &mut ParserRuleContext,
5021 cursor: &mut Option<usize>,
5022 before: usize,
5023 ) -> Result<(), AntlrError> {
5024 let Some(stop) = before.checked_sub(1) else {
5025 return Ok(());
5026 };
5027 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
5028 *cursor = next;
5029 Ok(())
5030 }
5031
5032 fn add_visible_terminals_through(
5033 &mut self,
5034 context: &mut ParserRuleContext,
5035 mut cursor: Option<usize>,
5036 stop: usize,
5037 ) -> Result<Option<usize>, AntlrError> {
5038 while let Some(index) = cursor {
5039 if index > stop {
5040 return Ok(Some(index));
5041 }
5042 let token = self
5043 .input
5044 .get_ref(index)
5045 .ok_or_else(|| AntlrError::ParserError {
5046 line: 0,
5047 column: 0,
5048 message: format!("missing token at index {index}"),
5049 })?;
5050 let is_eof = token.token_type() == TOKEN_EOF;
5051 context.add_child(ParseTree::Terminal(TerminalNode::from_ref(token)));
5052 if is_eof {
5053 return Ok(None);
5054 }
5055 cursor = self.next_visible_after_token(index);
5056 }
5057 Ok(None)
5058 }
5059
5060 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
5061 let next = self.input.next_visible_after(index);
5062 (next != index).then_some(next)
5063 }
5064
5065 pub fn parse_atn_rule_with_actions(
5072 &mut self,
5073 atn: &Atn,
5074 rule_index: usize,
5075 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5076 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
5077 }
5078
5079 pub fn parse_atn_rule_with_action_inits(
5087 &mut self,
5088 atn: &Atn,
5089 rule_index: usize,
5090 init_action_rules: &[usize],
5091 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5092 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
5093 }
5094
5095 pub fn parse_atn_rule_with_action_options(
5101 &mut self,
5102 atn: &Atn,
5103 rule_index: usize,
5104 init_action_rules: &[usize],
5105 track_alt_numbers: bool,
5106 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5107 self.parse_atn_rule_with_runtime_options(
5108 atn,
5109 rule_index,
5110 ParserRuntimeOptions {
5111 init_action_rules,
5112 track_alt_numbers,
5113 ..ParserRuntimeOptions::default()
5114 },
5115 )
5116 }
5117
5118 pub fn parse_atn_rule_with_runtime_options(
5125 &mut self,
5126 atn: &Atn,
5127 rule_index: usize,
5128 options: ParserRuntimeOptions<'_>,
5129 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5130 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
5131 }
5132
5133 pub fn parse_atn_rule_with_runtime_options_and_precedence(
5136 &mut self,
5137 atn: &Atn,
5138 rule_index: usize,
5139 precedence: i32,
5140 options: ParserRuntimeOptions<'_>,
5141 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5142 let ParserRuntimeOptions {
5143 init_action_rules,
5144 track_alt_numbers,
5145 predicates,
5146 semantics,
5147 rule_args,
5148 member_actions,
5149 return_actions,
5150 unknown_predicate_policy,
5151 } = options;
5152 if init_action_rules.is_empty()
5153 && !track_alt_numbers
5154 && predicates.is_empty()
5155 && semantics.is_none()
5156 && rule_args.is_empty()
5157 && member_actions.is_empty()
5158 && return_actions.is_empty()
5159 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
5160 && !atn_has_observable_action_transitions(atn)
5161 && (!self.semantic_hooks.observes_parser_predicates()
5162 || !atn_has_predicate_transitions(atn))
5163 {
5164 return self
5165 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
5166 .map(|tree| (tree, Vec::new()));
5167 }
5168 self.unknown_predicate_policy = unknown_predicate_policy;
5169 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
5176 let start_state = atn
5177 .rule_to_start_state()
5178 .get(rule_index)
5179 .copied()
5180 .ok_or_else(|| {
5181 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
5182 })?;
5183 let stop_state = atn
5184 .rule_to_stop_state()
5185 .get(rule_index)
5186 .copied()
5187 .filter(|state| *state != usize::MAX)
5188 .ok_or_else(|| {
5189 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
5190 })?;
5191
5192 let start_index = self.current_visible_index();
5193 self.clear_prediction_diagnostics();
5194 self.reset_per_parse_caches();
5195 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
5196 let invoking_state = self.pending_invoking_states.pop();
5197 let local_int_arg = invoking_state
5198 .and_then(|state| usize::try_from(state).ok())
5199 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
5200 let mut visiting = BTreeSet::new();
5201 let mut memo = BTreeMap::new();
5202 let mut expected = ExpectedTokens::default();
5203 let member_values = self.int_members.clone();
5204 let return_values = BTreeMap::new();
5205 let outcomes = self.recognize_state(
5206 atn,
5207 RecognizeRequest {
5208 state_number: start_state,
5209 stop_state,
5210 index: start_index,
5211 rule_start_index: start_index,
5212 decision_start_index: None,
5213 init_action_rules: &init_action_rules,
5214 predicates,
5215 semantics,
5216 rule_args,
5217 member_actions,
5218 return_actions,
5219 local_int_arg,
5220 member_values,
5221 return_values,
5222 rule_alt_number: 0,
5223 track_alt_numbers,
5224 consumed_eof: false,
5225 precedence,
5226 depth: 0,
5227 recovery_symbols: BTreeSet::new(),
5228 recovery_state: None,
5229 },
5230 &mut visiting,
5231 &mut memo,
5232 &mut expected,
5233 );
5234 if let Some(error) = self.unknown_semantic_error() {
5235 report_token_source_errors(&self.input.drain_source_errors());
5236 return Err(error);
5243 }
5244 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
5247 let Some(outcome) = select_best_outcome(outcomes.into_iter(), self.prediction_mode) else {
5248 let error = self.recognition_error(rule_index, start_index, &expected);
5249 self.record_syntax_errors(1);
5250 report_token_source_errors(&self.input.drain_source_errors());
5251 return Err(error);
5252 };
5253
5254 self.record_syntax_errors(outcome.diagnostics.len());
5255 report_parser_diagnostics(&self.prediction_diagnostics);
5256 report_parser_diagnostics(&outcome.diagnostics);
5257 report_token_source_errors(&self.input.drain_source_errors());
5258 let mut actions = outcome.actions;
5259 if init_action_rules.contains(&rule_index) {
5260 actions.insert(
5261 0,
5262 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
5263 );
5264 }
5265 let mut context =
5266 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
5267 if track_alt_numbers {
5268 context.set_alt_number(outcome.alt_number);
5269 }
5270 for (name, value) in outcome.return_values {
5271 context.set_int_return(name, value);
5272 }
5273 if let Some(token) = self.token_ref_at(start_index) {
5274 context.set_start_ref(token);
5275 }
5276 if let Some(token) = self.rule_stop_token_ref(outcome.index, outcome.consumed_eof) {
5277 context.set_stop_ref(token);
5278 }
5279 if self.build_parse_trees {
5280 let nodes = fold_left_recursive_boundaries(outcome.nodes);
5281 for node in &nodes {
5282 context.add_child(self.recognized_node_tree(node, track_alt_numbers)?);
5283 }
5284 }
5285 self.input.seek(outcome.index);
5286
5287 Ok((self.rule_node(context), actions))
5288 }
5289
5290 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
5297 let mut context = ParserRuleContext::new(rule_index, self.state());
5298 while self.la(1) != TOKEN_EOF {
5299 let token_type = self.la(1);
5300 let child = self.match_token(token_type)?;
5301 if self.build_parse_trees {
5302 context.add_child(child);
5303 }
5304 }
5305 if self.build_parse_trees {
5306 context.add_child(self.match_eof()?);
5307 }
5308 Ok(self.rule_node(context))
5309 }
5310
5311 fn recognition_error(
5314 &mut self,
5315 rule_index: usize,
5316 start_index: usize,
5317 expected: &ExpectedTokens,
5318 ) -> AntlrError {
5319 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
5320 self.input.seek(index);
5321 let current = self.input.lt(1).cloned();
5322 let line = current.as_ref().map(Token::line).unwrap_or_default();
5323 let column = current.as_ref().map(Token::column).unwrap_or_default();
5324 AntlrError::ParserError {
5325 line,
5326 column,
5327 message,
5328 }
5329 }
5330
5331 fn expected_error_message(
5333 &mut self,
5334 rule_index: usize,
5335 start_index: usize,
5336 expected: &ExpectedTokens,
5337 ) -> (usize, String) {
5338 let index = expected
5339 .index
5340 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
5341 .unwrap_or_else(|| self.input.index());
5342 self.input.seek(index);
5343 let current = self.input.lt(1).cloned();
5344 let message = if expected
5345 .no_viable
5346 .as_ref()
5347 .is_some_and(|no_viable| no_viable.error_index == index)
5348 {
5349 let start = expected
5350 .no_viable
5351 .as_ref()
5352 .map_or(start_index, |no_viable| no_viable.start_index);
5353 let text = display_input_text(&self.input.text(start, index));
5354 format!("no viable alternative at input '{text}'")
5355 } else if expected.symbols.is_empty() {
5356 if expected.index.is_some() {
5357 let found = current
5358 .as_ref()
5359 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
5360 if current
5361 .as_ref()
5362 .is_some_and(|token| token.token_type() == TOKEN_EOF)
5363 {
5364 format!(
5365 "missing {} at {found}",
5366 self.expected_symbols_display(&expected.symbols)
5367 )
5368 } else {
5369 format!("mismatched input {found}")
5370 }
5371 } else {
5372 format!("no viable alternative while parsing rule {rule_index}")
5373 }
5374 } else {
5375 format!(
5376 "mismatched input {} expecting {}",
5377 current
5378 .as_ref()
5379 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5380 self.expected_symbols_display(&expected.symbols)
5381 )
5382 };
5383 (index, message)
5384 }
5385
5386 fn child_rule_failure_recovery(
5389 &mut self,
5390 rule_index: usize,
5391 start_index: usize,
5392 sync_symbols: &BTreeSet<i32>,
5393 member_values: BTreeMap<usize, i64>,
5394 expected: &ExpectedTokens,
5395 ) -> Option<RecognizeOutcome> {
5396 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
5397 let token = self.token_at(error_index);
5398 let mut next_index = error_index;
5399 loop {
5400 let symbol = self.token_type_at(next_index);
5401 if sync_symbols.contains(&symbol) {
5402 if next_index == error_index {
5403 return None;
5404 }
5405 break;
5406 }
5407 if symbol == TOKEN_EOF {
5408 break;
5409 }
5410 let after = self.consume_index(next_index, symbol);
5411 if after == next_index {
5412 break;
5413 }
5414 next_index = after;
5415 }
5416 Some(RecognizeOutcome {
5417 index: next_index,
5418 consumed_eof: false,
5419 alt_number: 0,
5420 member_values,
5421 return_values: BTreeMap::new(),
5422 diagnostics: vec![diagnostic_for_token(token.as_ref(), message)],
5423 decisions: Vec::new(),
5424 actions: Vec::new(),
5425 nodes: vec![RecognizedNode::ErrorToken { index: error_index }],
5426 })
5427 }
5428
5429 fn child_rule_failure_recovery_outcomes(
5432 &mut self,
5433 request: ChildRuleFailureRecovery<'_>,
5434 ) -> Vec<RecognizeOutcome> {
5435 let sync_symbols =
5436 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
5437 self.child_rule_failure_recovery(
5438 request.rule_index,
5439 request.start_index,
5440 &sync_symbols,
5441 request.member_values,
5442 request.expected,
5443 )
5444 .into_iter()
5445 .collect()
5446 }
5447
5448 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
5450 expected_symbols_display(symbols, self.vocabulary())
5451 }
5452
5453 fn single_token_deletion(
5456 &mut self,
5457 transition: &Transition,
5458 index: usize,
5459 max_token_type: i32,
5460 expected_symbols: &BTreeSet<i32>,
5461 ) -> Option<(ParserDiagnostic, usize, i32)> {
5462 let current_symbol = self.token_type_at(index);
5463 if current_symbol == TOKEN_EOF {
5464 return None;
5465 }
5466 let next_index = self.consume_index(index, current_symbol);
5467 if next_index == index {
5468 return None;
5469 }
5470 let next_symbol = self.token_type_at(next_index);
5471 if !transition.matches(next_symbol, 1, max_token_type) {
5472 return None;
5473 }
5474 let transition_expected = transition_expected_symbols(transition, max_token_type);
5475 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
5476 &transition_expected
5477 } else {
5478 expected_symbols
5479 });
5480 let current = self.token_at(index);
5481 let message = format!(
5482 "extraneous input {} expecting {expected_display}",
5483 current
5484 .as_ref()
5485 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
5486 );
5487 Some((
5488 diagnostic_for_token(current.as_ref(), message),
5489 next_index,
5490 next_symbol,
5491 ))
5492 }
5493
5494 fn current_token_deletion(
5497 &mut self,
5498 index: usize,
5499 expected_symbols: &BTreeSet<i32>,
5500 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
5501 if expected_symbols.is_empty() {
5502 return None;
5503 }
5504 let current_symbol = self.token_type_at(index);
5505 if current_symbol == TOKEN_EOF {
5506 return None;
5507 }
5508 let current = self.token_at(index);
5509 let message = format!(
5510 "extraneous input {} expecting {}",
5511 current
5512 .as_ref()
5513 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5514 self.expected_symbols_display(expected_symbols)
5515 );
5516 let diagnostic = diagnostic_for_token(current.as_ref(), message);
5517 let mut skipped = Vec::new();
5518 let mut cursor = index;
5519 loop {
5520 let symbol = self.token_type_at(cursor);
5521 if symbol == TOKEN_EOF {
5522 return None;
5523 }
5524 skipped.push(cursor);
5525 let next_index = self.consume_index(cursor, symbol);
5526 if next_index == cursor {
5527 return None;
5528 }
5529 let next_symbol = self.token_type_at(next_index);
5530 if expected_symbols.contains(&next_symbol) {
5531 return Some((diagnostic, next_index, skipped));
5532 }
5533 cursor = next_index;
5534 }
5535 }
5536
5537 fn single_token_insertion(
5541 &mut self,
5542 transition: &Transition,
5543 index: usize,
5544 max_token_type: i32,
5545 expected_symbols: &BTreeSet<i32>,
5546 follow_symbols: &BTreeSet<i32>,
5547 ) -> Option<(ParserDiagnostic, i32, String)> {
5548 let current_symbol = self.token_type_at(index);
5549 if !follow_symbols.contains(¤t_symbol) {
5550 return None;
5551 }
5552 let transition_expected = transition_expected_symbols(transition, max_token_type);
5553 let token_type = transition_expected.iter().next().copied()?;
5554 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
5555 &transition_expected
5556 } else {
5557 expected_symbols
5558 });
5559 let mut token_symbols = BTreeSet::new();
5560 token_symbols.insert(token_type);
5561 let missing_token_display = self.expected_symbols_display(&token_symbols);
5562 let current = self.token_at(index);
5563 let message = format!(
5564 "missing {expected_display} at {}",
5565 current
5566 .as_ref()
5567 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
5568 );
5569 let text = format!("<missing {missing_token_display}>");
5570 Some((
5571 diagnostic_for_token(current.as_ref(), message),
5572 token_type,
5573 text,
5574 ))
5575 }
5576
5577 fn fast_single_token_deletion_recovery(
5581 &mut self,
5582 recovery: FastRecoveryRequest<'_, '_>,
5583 ) -> Vec<FastRecognizeOutcome> {
5584 let FastRecoveryRequest {
5585 atn,
5586 transition,
5587 expected_symbols,
5588 target,
5589 request,
5590 visiting,
5591 memo,
5592 expected,
5593 } = recovery;
5594 let FastRecognizeRequest {
5595 stop_state,
5596 index,
5597 rule_start_index,
5598 decision_start_index,
5599 precedence,
5600 depth,
5601 ..
5602 } = request;
5603 let Some((diagnostic, next_index, next_symbol)) =
5604 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
5605 else {
5606 return Vec::new();
5607 };
5608 let after_next = self.consume_index(next_index, next_symbol);
5609 let empty_recovery = self.empty_recovery_symbols();
5610 self.recognize_state_fast(
5611 atn,
5612 FastRecognizeRequest {
5613 state_number: target,
5614 stop_state,
5615 index: after_next,
5616 rule_start_index,
5617 decision_start_index,
5618 precedence,
5619 depth: depth + 1,
5620 recovery_symbols: empty_recovery,
5621 recovery_state: None,
5622 },
5623 visiting,
5624 memo,
5625 expected,
5626 )
5627 .into_iter()
5628 .map(|mut outcome| {
5629 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
5630 outcome.diagnostics.insert(0, diagnostic.clone());
5631 if self.fast_token_nodes_enabled {
5632 outcome
5633 .nodes
5634 .prepend(Rc::new(FastRecognizedNode::Token { index: next_index }));
5635 outcome
5636 .nodes
5637 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index }));
5638 }
5639 outcome
5640 })
5641 .collect()
5642 }
5643
5644 fn fast_single_token_insertion_recovery(
5648 &mut self,
5649 recovery: FastRecoveryRequest<'_, '_>,
5650 ) -> Vec<FastRecognizeOutcome> {
5651 let FastRecoveryRequest {
5652 atn,
5653 transition,
5654 expected_symbols,
5655 target,
5656 request,
5657 visiting,
5658 memo,
5659 expected,
5660 } = recovery;
5661 let FastRecognizeRequest {
5662 stop_state,
5663 index,
5664 rule_start_index,
5665 decision_start_index,
5666 precedence,
5667 depth,
5668 ..
5669 } = request;
5670 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
5671 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
5672 transition,
5673 index,
5674 atn.max_token_type(),
5675 &expected_symbols,
5676 &follow_symbols,
5677 ) else {
5678 return Vec::new();
5679 };
5680 let empty_recovery = self.empty_recovery_symbols();
5681 self.recognize_state_fast(
5682 atn,
5683 FastRecognizeRequest {
5684 state_number: target,
5685 stop_state,
5686 index,
5687 rule_start_index,
5688 decision_start_index,
5689 precedence,
5690 depth: depth + 1,
5691 recovery_symbols: empty_recovery,
5692 recovery_state: None,
5693 },
5694 visiting,
5695 memo,
5696 expected,
5697 )
5698 .into_iter()
5699 .map(|mut outcome| {
5700 outcome.diagnostics.insert(0, diagnostic.clone());
5701 outcome
5702 .nodes
5703 .prepend(Rc::new(FastRecognizedNode::MissingToken {
5704 token_type,
5705 at_index: index,
5706 text: text.clone(),
5707 }));
5708 outcome
5709 })
5710 .collect()
5711 }
5712
5713 fn fast_current_token_deletion_recovery(
5716 &mut self,
5717 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
5718 ) -> Vec<FastRecognizeOutcome> {
5719 let FastCurrentTokenDeletionRequest {
5720 atn,
5721 expected_symbols,
5722 mut request,
5723 visiting,
5724 memo,
5725 expected,
5726 } = recovery;
5727 if request.index == request.rule_start_index {
5728 return Vec::new();
5729 }
5730 let Some((diagnostic, next_index, skipped)) =
5731 self.current_token_deletion(request.index, &expected_symbols)
5732 else {
5733 return Vec::new();
5734 };
5735 request.state_number = request.recovery_state.unwrap_or(request.state_number);
5736 request.index = next_index;
5737 request.depth += 1;
5738 request.recovery_state = None;
5739 self.recognize_state_fast(atn, request, visiting, memo, expected)
5740 .into_iter()
5741 .map(|mut outcome| {
5742 outcome.diagnostics.insert(0, diagnostic.clone());
5743 for index in skipped.iter().rev() {
5744 outcome
5745 .nodes
5746 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index: *index }));
5747 }
5748 outcome
5749 })
5750 .collect()
5751 }
5752
5753 fn fast_child_rule_failure_recovery(
5756 &mut self,
5757 rule_index: usize,
5758 start_index: usize,
5759 sync_symbols: &BTreeSet<i32>,
5760 expected: &ExpectedTokens,
5761 ) -> Option<FastRecognizeOutcome> {
5762 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
5763 let token = self.token_at(error_index);
5764 let mut next_index = error_index;
5765 loop {
5766 let symbol = self.token_type_at(next_index);
5767 if sync_symbols.contains(&symbol) {
5768 if next_index == error_index {
5769 return None;
5770 }
5771 break;
5772 }
5773 if symbol == TOKEN_EOF {
5774 break;
5775 }
5776 let after = self.consume_index(next_index, symbol);
5777 if after == next_index {
5778 break;
5779 }
5780 next_index = after;
5781 }
5782 let mut diagnostics = FastDiagnostics::new();
5783 diagnostics.insert(0, diagnostic_for_token(token.as_ref(), message));
5784 let mut nodes = NodeList::new();
5785 if self.fast_token_nodes_enabled {
5786 nodes.prepend(Rc::new(FastRecognizedNode::ErrorToken {
5787 index: error_index,
5788 }));
5789 }
5790 Some(FastRecognizeOutcome {
5791 index: next_index,
5792 consumed_eof: false,
5793 diagnostics,
5794 nodes,
5795 })
5796 }
5797
5798 fn fast_child_rule_failure_recovery_outcomes(
5801 &mut self,
5802 request: FastChildRuleFailureRecoveryRequest<'_>,
5803 ) -> Vec<FastRecognizeOutcome> {
5804 let FastChildRuleFailureRecoveryRequest {
5805 atn,
5806 rule_index,
5807 start_index,
5808 follow_state,
5809 stop_state,
5810 expected,
5811 } = request;
5812 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
5813 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
5814 .into_iter()
5815 .collect()
5816 }
5817
5818 #[allow(clippy::too_many_lines)]
5821 fn recognize_state_fast(
5822 &mut self,
5823 atn: &Atn,
5824 request: FastRecognizeRequest,
5825 visiting: &mut FxHashSet<FastRecognizeKey>,
5826 memo: &mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
5827 expected: &mut ExpectedTokens,
5828 ) -> Vec<FastRecognizeOutcome> {
5829 #[cfg(feature = "perf-counters")]
5830 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
5831 let FastRecognizeRequest {
5832 mut state_number,
5833 stop_state,
5834 mut index,
5835 rule_start_index,
5836 decision_start_index,
5837 precedence,
5838 mut depth,
5839 recovery_symbols,
5840 recovery_state,
5841 } = request;
5842 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
5861 let mut inline_consumed_eof = false;
5862 loop {
5863 if depth > RECOGNITION_DEPTH_LIMIT {
5864 return Vec::new();
5865 }
5866 if state_number == stop_state {
5867 let mut nodes = NodeList::new();
5868 if self.fast_token_nodes_enabled {
5869 for token_index in inline_consumed_tokens.iter().rev() {
5870 nodes.prepend(Rc::new(FastRecognizedNode::Token {
5871 index: *token_index,
5872 }));
5873 }
5874 }
5875 return vec![FastRecognizeOutcome {
5876 index,
5877 consumed_eof: inline_consumed_eof,
5878 diagnostics: FastDiagnostics::new(),
5879 nodes,
5880 }];
5881 }
5882 let Some(state) = atn.state(state_number) else {
5883 return Vec::new();
5884 };
5885 if state.transitions.len() == 1
5886 && !starts_prediction_decision(state)
5887 && !state.precedence_rule_decision
5888 {
5889 match &state.transitions[0] {
5890 Transition::Epsilon { target }
5891 | Transition::Predicate { target, .. }
5892 | Transition::Action { target, .. }
5893 if left_recursive_boundary(atn, state, *target).is_none() =>
5894 {
5895 #[cfg(feature = "perf-counters")]
5896 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
5897 state_number = *target;
5898 depth += 1;
5899 continue;
5900 }
5901 Transition::Precedence {
5902 target,
5903 precedence: transition_precedence,
5904 } if *transition_precedence >= precedence
5905 && left_recursive_boundary(atn, state, *target).is_none() =>
5906 {
5907 #[cfg(feature = "perf-counters")]
5908 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
5909 state_number = *target;
5910 depth += 1;
5911 continue;
5912 }
5913 Transition::Atom { target, .. }
5923 | Transition::Range { target, .. }
5924 | Transition::Set { target, .. }
5925 | Transition::NotSet { target, .. }
5926 | Transition::Wildcard { target, .. }
5927 if !self.fast_recovery_enabled =>
5928 {
5929 let symbol = self.token_type_at(index);
5930 let transition = &state.transitions[0];
5931 if transition.matches(symbol, 1, atn.max_token_type()) {
5932 #[cfg(feature = "perf-counters")]
5933 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
5934 if self.fast_token_nodes_enabled {
5935 inline_consumed_tokens.push(index);
5936 }
5937 inline_consumed_eof |= symbol == TOKEN_EOF;
5938 index = self.consume_index(index, symbol);
5939 state_number = *target;
5940 depth += 1;
5941 continue;
5942 }
5943 }
5946 _ => {}
5947 }
5948 }
5949 break;
5950 }
5951 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
5955 let Some(state) = atn.state(state_number) else {
5956 return Vec::new();
5957 };
5958 let transition_count = state.transitions.len();
5959 let memo_lookup_enabled = self.fast_recovery_enabled || transition_count > 1;
5960 let key = if self.fast_recovery_enabled {
5970 FastRecognizeKey {
5971 state_number,
5972 stop_state,
5973 index,
5974 rule_start_index,
5975 decision_start_index,
5976 precedence,
5977 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
5978 recovery_state,
5979 }
5980 } else {
5981 FastRecognizeKey {
5982 state_number,
5983 stop_state,
5984 index,
5985 rule_start_index: 0,
5986 decision_start_index: None,
5987 precedence,
5988 recovery_symbols_id: 0,
5989 recovery_state: None,
5990 }
5991 };
5992 if memo_lookup_enabled {
5993 if let Some(outcomes) = memo.get(&key) {
5994 #[cfg(feature = "perf-counters")]
5995 {
5996 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
5997 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
5998 }
5999 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
6003 let inline_eof = inline_consumed_eof;
6004 let inline_tokens = &inline_consumed_tokens;
6005 return outcomes
6006 .iter()
6007 .cloned()
6008 .map(|mut outcome| {
6009 if inline_eof {
6010 outcome.consumed_eof = true;
6011 }
6012 if self.fast_token_nodes_enabled {
6013 for token_index in inline_tokens.iter().rev() {
6014 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
6015 index: *token_index,
6016 }));
6017 }
6018 }
6019 outcome
6020 })
6021 .collect();
6022 }
6023 return outcomes.to_vec();
6024 }
6025 #[cfg(feature = "perf-counters")]
6026 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
6027 }
6028
6029 let needs_cycle_guard = if self.fast_recovery_enabled {
6034 state.transitions.iter().any(Transition::is_epsilon)
6035 } else {
6036 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
6037 };
6038 #[cfg(feature = "perf-counters")]
6039 if needs_cycle_guard {
6040 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
6041 } else {
6042 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
6043 match &state.transitions[0] {
6044 Transition::Rule { .. } => {
6045 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
6046 }
6047 Transition::Atom { .. }
6048 | Transition::Range { .. }
6049 | Transition::Set { .. }
6050 | Transition::NotSet { .. }
6051 | Transition::Wildcard { .. } => {
6052 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
6053 }
6054 _ => {
6055 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
6056 }
6057 }
6058 }
6059 let has_inserted_cycle_guard = if needs_cycle_guard {
6060 if !visiting.insert(key.clone()) {
6061 #[cfg(feature = "perf-counters")]
6062 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
6063 return Vec::new();
6064 }
6065 true
6066 } else {
6067 false
6068 };
6069 let next_decision_start_index = if starts_prediction_decision(state) {
6070 Some(index)
6071 } else {
6072 decision_start_index
6073 };
6074 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
6075 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
6076 } else {
6077 (Rc::clone(&recovery_symbols), recovery_state)
6078 };
6079
6080 let transition_count = state.transitions.len();
6099 let lookahead_filter = if transition_count > 1
6100 && self.fast_first_set_prefilter
6101 && !state.precedence_rule_decision
6102 && (!self.fast_recovery_enabled || state.kind != AtnStateKind::RuleStart)
6103 {
6104 state
6105 .rule_index
6106 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())
6107 .map(|rule_stop| {
6108 let symbol = self.token_type_at(index);
6109 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6110 (symbol, entry)
6111 })
6112 } else {
6113 None
6114 };
6115 let ll1_only_alt: Option<usize> = if transition_count > 1
6124 && let Some((symbol, entry)) = lookahead_filter.as_ref()
6125 {
6126 let key = (state.state_number, *symbol);
6127 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
6128 cached
6129 } else {
6130 let result = ll1_unique_alt(entry, *symbol);
6131 self.ll1_decision_cache.insert(key, result);
6132 result
6133 }
6134 } else {
6135 None
6136 };
6137 let lookahead_filter = lookahead_filter.as_ref();
6138 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
6144 for (transition_index, transition) in state.transitions.iter().enumerate() {
6145 if let Some(alt) = ll1_only_alt {
6146 if alt != transition_index {
6148 continue;
6149 }
6150 } else if should_skip_via_lookahead(
6151 transition,
6152 transition_index,
6153 lookahead_filter,
6154 index,
6155 self.fast_recovery_enabled,
6156 expected,
6157 ) {
6158 continue;
6159 }
6160 match transition {
6161 Transition::Epsilon { target }
6162 | Transition::Predicate { target, .. }
6163 | Transition::Action { target, .. } => {
6164 #[cfg(feature = "perf-counters")]
6165 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
6166 let boundary = left_recursive_boundary(atn, state, *target);
6167 outcomes.extend(
6168 self.recognize_state_fast(
6169 atn,
6170 FastRecognizeRequest {
6171 state_number: *target,
6172 stop_state,
6173 index,
6174 rule_start_index,
6175 decision_start_index: next_decision_start_index,
6176 precedence,
6177 depth: depth + 1,
6178 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6179 recovery_state: epsilon_recovery_state,
6180 },
6181 visiting,
6182 memo,
6183 expected,
6184 )
6185 .into_iter()
6186 .map(|mut outcome| {
6187 if let Some(rule_index) = boundary {
6188 outcome.nodes.prepend(Rc::new(
6189 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
6190 ));
6191 }
6192 outcome
6193 }),
6194 );
6195 }
6196 Transition::Precedence {
6197 target,
6198 precedence: transition_precedence,
6199 } => {
6200 if *transition_precedence >= precedence {
6201 let boundary = left_recursive_boundary(atn, state, *target);
6202 outcomes.extend(
6203 self.recognize_state_fast(
6204 atn,
6205 FastRecognizeRequest {
6206 state_number: *target,
6207 stop_state,
6208 index,
6209 rule_start_index,
6210 decision_start_index: next_decision_start_index,
6211 precedence,
6212 depth: depth + 1,
6213 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6214 recovery_state: epsilon_recovery_state,
6215 },
6216 visiting,
6217 memo,
6218 expected,
6219 )
6220 .into_iter()
6221 .map(|mut outcome| {
6222 if let Some(rule_index) = boundary {
6223 outcome.nodes.prepend(Rc::new(
6224 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
6225 ));
6226 }
6227 outcome
6228 }),
6229 );
6230 }
6231 }
6232 Transition::Rule {
6233 target,
6234 rule_index,
6235 follow_state,
6236 precedence: rule_precedence,
6237 ..
6238 } => {
6239 #[cfg(feature = "perf-counters")]
6240 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
6241 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
6242 else {
6243 continue;
6244 };
6245 let symbol = self.token_type_at(index);
6257 if self.fast_first_set_prefilter {
6258 let first = self.cached_rule_first_set(atn, *target, child_stop);
6271 if should_skip_rule_via_first_set(
6272 &first,
6273 symbol,
6274 self.fast_recovery_enabled,
6275 index,
6276 expected,
6277 ) {
6278 continue;
6279 }
6280 }
6281 let expected_before_child =
6282 self.fast_recovery_enabled.then(|| expected.clone());
6283 let mut children = self.recognize_state_fast(
6284 atn,
6285 FastRecognizeRequest {
6286 state_number: *target,
6287 stop_state: child_stop,
6288 index,
6289 rule_start_index: index,
6290 decision_start_index: None,
6291 precedence: *rule_precedence,
6292 depth: depth + 1,
6293 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6294 recovery_state: epsilon_recovery_state,
6295 },
6296 visiting,
6297 memo,
6298 expected,
6299 );
6300 if children.is_empty() && self.fast_recovery_enabled {
6301 children = self.fast_child_rule_failure_recovery_outcomes(
6302 FastChildRuleFailureRecoveryRequest {
6303 atn,
6304 rule_index: *rule_index,
6305 start_index: index,
6306 follow_state: *follow_state,
6307 stop_state,
6308 expected,
6309 },
6310 );
6311 }
6312 if let Some(expected_before_child) = expected_before_child {
6313 if children
6314 .iter()
6315 .any(|child| child.diagnostics.is_empty() && child.index > index)
6316 {
6317 *expected = expected_before_child;
6318 }
6319 }
6320 for child in children {
6321 let child_index = child.index;
6322 let child_consumed_eof = child.consumed_eof;
6323 let child_diagnostics = child.diagnostics;
6324 let empty_recovery = self.empty_recovery_symbols();
6325 let follow_outcomes = self.recognize_state_fast(
6326 atn,
6327 FastRecognizeRequest {
6328 state_number: *follow_state,
6329 stop_state,
6330 index: child_index,
6331 rule_start_index,
6332 decision_start_index: next_decision_start_index,
6333 precedence,
6334 depth: depth + 1,
6335 recovery_symbols: empty_recovery,
6336 recovery_state: None,
6337 },
6338 visiting,
6339 memo,
6340 expected,
6341 );
6342 if follow_outcomes.is_empty() {
6343 continue;
6344 }
6345 let child_node = Rc::new(FastRecognizedNode::Rule {
6346 rule_index: *rule_index,
6347 invoking_state: invoking_state_number(state_number),
6348 start_index: index,
6349 stop_index: self.rule_stop_token_index(child_index, child_consumed_eof),
6350 children: child.nodes,
6351 });
6352 let child_diags_empty = child_diagnostics.is_empty();
6353 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
6354 outcome.consumed_eof |= child_consumed_eof;
6355 if !child_diags_empty {
6358 let mut diagnostics = child_diagnostics.clone();
6359 diagnostics.append(&mut outcome.diagnostics);
6360 outcome.diagnostics = diagnostics;
6361 }
6362 outcome.nodes.prepend(Rc::clone(&child_node));
6363 outcome
6364 }));
6365 }
6366 }
6367 Transition::Atom { target, .. }
6368 | Transition::Range { target, .. }
6369 | Transition::Set { target, .. }
6370 | Transition::NotSet { target, .. }
6371 | Transition::Wildcard { target, .. } => {
6372 #[cfg(feature = "perf-counters")]
6373 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
6374 let symbol = self.token_type_at(index);
6375 if transition.matches(symbol, 1, atn.max_token_type()) {
6376 let next_index = self.consume_index(index, symbol);
6377 let empty_recovery = self.empty_recovery_symbols();
6378 outcomes.extend(
6379 self.recognize_state_fast(
6380 atn,
6381 FastRecognizeRequest {
6382 state_number: *target,
6383 stop_state,
6384 index: next_index,
6385 rule_start_index,
6386 decision_start_index: next_decision_start_index,
6387 precedence,
6388 depth: depth + 1,
6389 recovery_symbols: empty_recovery,
6390 recovery_state: None,
6391 },
6392 visiting,
6393 memo,
6394 expected,
6395 )
6396 .into_iter()
6397 .map(|mut outcome| {
6398 outcome.consumed_eof |= symbol == TOKEN_EOF;
6399 if self.fast_token_nodes_enabled {
6400 outcome
6401 .nodes
6402 .prepend(Rc::new(FastRecognizedNode::Token { index }));
6403 }
6404 outcome
6405 }),
6406 );
6407 } else {
6408 if !self.fast_recovery_enabled {
6409 continue;
6417 }
6418 let expected_symbols = fast_recovery_expected_symbols(
6419 self,
6420 atn,
6421 state.state_number,
6422 &recovery_symbols,
6423 );
6424 if expected_symbols.contains(&symbol) {
6425 continue;
6426 }
6427 {
6428 expected.record_transition(index, transition, atn.max_token_type());
6429 record_no_viable_if_ambiguous(
6430 expected,
6431 next_decision_start_index,
6432 index,
6433 );
6434 outcomes.extend(self.fast_single_token_deletion_recovery(
6435 FastRecoveryRequest {
6436 atn,
6437 transition,
6438 expected_symbols: Rc::clone(&expected_symbols),
6439 target: *target,
6440 request: FastRecognizeRequest {
6441 state_number,
6442 stop_state,
6443 index,
6444 rule_start_index,
6445 decision_start_index,
6446 precedence,
6447 depth,
6448 recovery_symbols: Rc::clone(&recovery_symbols),
6449 recovery_state,
6450 },
6451 visiting,
6452 memo,
6453 expected,
6454 },
6455 ));
6456 if !state_is_left_recursive_rule(atn, state) {
6457 outcomes.extend(self.fast_single_token_insertion_recovery(
6458 FastRecoveryRequest {
6459 atn,
6460 transition,
6461 expected_symbols: Rc::clone(&expected_symbols),
6462 target: *target,
6463 request: FastRecognizeRequest {
6464 state_number,
6465 stop_state,
6466 index,
6467 rule_start_index,
6468 decision_start_index,
6469 precedence,
6470 depth,
6471 recovery_symbols: Rc::clone(&recovery_symbols),
6472 recovery_state,
6473 },
6474 visiting,
6475 memo,
6476 expected,
6477 },
6478 ));
6479 }
6480 outcomes.extend(self.fast_current_token_deletion_recovery(
6481 FastCurrentTokenDeletionRequest {
6482 atn,
6483 expected_symbols,
6484 request: FastRecognizeRequest {
6485 state_number,
6486 stop_state,
6487 index,
6488 rule_start_index,
6489 decision_start_index,
6490 precedence,
6491 depth,
6492 recovery_symbols: Rc::clone(&recovery_symbols),
6493 recovery_state,
6494 },
6495 visiting,
6496 memo,
6497 expected,
6498 },
6499 ));
6500 }
6501 }
6502 }
6503 }
6504 }
6505
6506 if has_inserted_cycle_guard {
6507 visiting.remove(&key);
6508 }
6509 if matches!(
6510 self.prediction_mode,
6511 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
6512 ) && self.fast_recovery_enabled
6513 {
6514 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
6518 }
6519 if self.fast_recovery_enabled {
6520 dedupe_fast_outcomes(&mut outcomes);
6521 } else {
6522 dedupe_clean_fast_outcomes(&mut outcomes);
6523 }
6524 let should_memoize = self.fast_recovery_enabled
6534 || (transition_count > 1
6535 && (outcomes.is_empty()
6536 || outcomes.len() > 1
6537 || (outcomes.len() == 1 && self.should_memoize_single_outcome(&key))));
6538 let apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
6542 if inline_consumed_eof {
6543 outcome.consumed_eof = true;
6544 }
6545 if !inline_consumed_tokens.is_empty() {
6546 for token_index in inline_consumed_tokens.iter().rev() {
6547 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
6548 index: *token_index,
6549 }));
6550 }
6551 }
6552 outcome
6553 };
6554 if should_memoize {
6555 #[cfg(feature = "perf-counters")]
6556 {
6557 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
6558 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
6559 match outcomes.len() {
6560 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
6561 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
6562 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
6563 }
6564 }
6565 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
6570 memo.insert(key, Rc::clone(&stored));
6571 if inline_pending {
6572 return stored.iter().cloned().map(apply_inline_pending).collect();
6573 }
6574 return stored.to_vec();
6575 }
6576 #[cfg(feature = "perf-counters")]
6577 match outcomes.len() {
6578 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
6579 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
6580 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
6581 }
6582 if inline_pending {
6583 return outcomes.into_iter().map(apply_inline_pending).collect();
6584 }
6585 outcomes
6586 }
6587
6588 fn single_token_deletion_recovery(
6591 &mut self,
6592 recovery: RecoveryRequest<'_, '_>,
6593 ) -> Vec<RecognizeOutcome> {
6594 let RecoveryRequest {
6595 atn,
6596 transition,
6597 expected_symbols,
6598 target,
6599 request,
6600 visiting,
6601 memo,
6602 expected,
6603 } = recovery;
6604 let RecognizeRequest {
6605 stop_state,
6606 index,
6607 rule_start_index,
6608 decision_start_index,
6609 init_action_rules,
6610 predicates,
6611 semantics,
6612 rule_args,
6613 member_actions,
6614 return_actions,
6615 local_int_arg,
6616 member_values,
6617 return_values,
6618 rule_alt_number,
6619 track_alt_numbers,
6620 consumed_eof,
6621 precedence,
6622 depth,
6623 ..
6624 } = request;
6625 let Some((diagnostic, next_index, next_symbol)) =
6626 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
6627 else {
6628 return Vec::new();
6629 };
6630 let after_next = self.consume_index(next_index, next_symbol);
6631 self.recognize_state(
6632 atn,
6633 RecognizeRequest {
6634 state_number: target,
6635 stop_state,
6636 index: after_next,
6637 rule_start_index,
6638 decision_start_index,
6639 init_action_rules,
6640 predicates,
6641 semantics,
6642 rule_args,
6643 member_actions,
6644 return_actions,
6645 local_int_arg,
6646 member_values,
6647 return_values,
6648 rule_alt_number,
6649 track_alt_numbers,
6650 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
6651 precedence,
6652 depth: depth + 1,
6653 recovery_symbols: BTreeSet::new(),
6654 recovery_state: None,
6655 },
6656 visiting,
6657 memo,
6658 expected,
6659 )
6660 .into_iter()
6661 .map(|mut outcome| {
6662 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
6663 outcome.diagnostics.insert(0, diagnostic.clone());
6664 outcome
6665 .nodes
6666 .insert(0, RecognizedNode::Token { index: next_index });
6667 outcome
6668 .nodes
6669 .insert(0, RecognizedNode::ErrorToken { index });
6670 outcome
6671 })
6672 .collect()
6673 }
6674
6675 fn current_token_deletion_recovery(
6678 &mut self,
6679 recovery: CurrentTokenDeletionRequest<'_, '_>,
6680 ) -> Vec<RecognizeOutcome> {
6681 let CurrentTokenDeletionRequest {
6682 atn,
6683 expected_symbols,
6684 mut request,
6685 visiting,
6686 memo,
6687 expected,
6688 } = recovery;
6689 let error_index = request.index;
6690 if error_index == request.rule_start_index {
6691 return Vec::new();
6692 }
6693 let Some((diagnostic, next_index, skipped)) =
6694 self.current_token_deletion(error_index, &expected_symbols)
6695 else {
6696 return Vec::new();
6697 };
6698 request.state_number = request.recovery_state.unwrap_or(request.state_number);
6699 request.index = next_index;
6700 request.depth += 1;
6701 request.recovery_state = None;
6702 self.recognize_state(atn, request, visiting, memo, expected)
6703 .into_iter()
6704 .map(|mut outcome| {
6705 outcome.diagnostics.insert(0, diagnostic.clone());
6706 for index in skipped.iter().rev() {
6707 outcome
6708 .nodes
6709 .insert(0, RecognizedNode::ErrorToken { index: *index });
6710 }
6711 outcome
6712 })
6713 .collect()
6714 }
6715
6716 fn consuming_failure_fallback(
6719 &mut self,
6720 fallback: ConsumingFailureFallback<'_>,
6721 visiting: &mut BTreeSet<RecognizeKey>,
6722 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
6723 expected: &mut ExpectedTokens,
6724 ) -> Vec<RecognizeOutcome> {
6725 if fallback.expected_symbols.is_empty() {
6726 return Vec::new();
6727 }
6728 if fallback.symbol == TOKEN_EOF {
6729 return self.eof_consuming_failure_fallback(fallback, expected);
6730 }
6731 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
6732 }
6733
6734 fn non_eof_consuming_failure_fallback(
6737 &mut self,
6738 fallback: ConsumingFailureFallback<'_>,
6739 visiting: &mut BTreeSet<RecognizeKey>,
6740 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
6741 expected: &mut ExpectedTokens,
6742 ) -> Vec<RecognizeOutcome> {
6743 let ConsumingFailureFallback {
6744 atn,
6745 target,
6746 request,
6747 symbol,
6748 expected_symbols,
6749 decision_start_index,
6750 decision,
6751 } = fallback;
6752 let error_index = request.index;
6753 let diagnostic =
6754 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
6755 let next_index = self.consume_index(error_index, symbol);
6756 self.recognize_state(
6757 atn,
6758 RecognizeRequest {
6759 state_number: target,
6760 stop_state: request.stop_state,
6761 index: next_index,
6762 rule_start_index: request.rule_start_index,
6763 decision_start_index,
6764 init_action_rules: request.init_action_rules,
6765 predicates: request.predicates,
6766 semantics: request.semantics,
6767 rule_args: request.rule_args,
6768 member_actions: request.member_actions,
6769 return_actions: request.return_actions,
6770 local_int_arg: request.local_int_arg,
6771 member_values: request.member_values,
6772 return_values: request.return_values,
6773 rule_alt_number: request.rule_alt_number,
6774 track_alt_numbers: request.track_alt_numbers,
6775 consumed_eof: request.consumed_eof,
6776 precedence: request.precedence,
6777 depth: request.depth + 1,
6778 recovery_symbols: BTreeSet::new(),
6779 recovery_state: None,
6780 },
6781 visiting,
6782 memo,
6783 expected,
6784 )
6785 .into_iter()
6786 .map(|mut outcome| {
6787 prepend_decision(&mut outcome, decision);
6788 outcome.diagnostics.insert(0, diagnostic.clone());
6789 outcome
6790 .nodes
6791 .insert(0, RecognizedNode::ErrorToken { index: error_index });
6792 outcome
6793 })
6794 .collect()
6795 }
6796
6797 fn eof_consuming_failure_fallback(
6800 &mut self,
6801 fallback: ConsumingFailureFallback<'_>,
6802 expected: &ExpectedTokens,
6803 ) -> Vec<RecognizeOutcome> {
6804 let request = fallback.request;
6805 if request.index == request.rule_start_index {
6806 return Vec::new();
6807 }
6808 let diagnostic =
6809 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
6810 vec![RecognizeOutcome {
6811 index: request.index,
6812 consumed_eof: request.consumed_eof,
6813 alt_number: request.rule_alt_number,
6814 member_values: request.member_values,
6815 return_values: request.return_values,
6816 diagnostics: vec![diagnostic],
6817 decisions: Vec::new(),
6818 actions: Vec::new(),
6819 nodes: Vec::new(),
6820 }]
6821 }
6822
6823 fn single_token_insertion_recovery(
6826 &mut self,
6827 recovery: RecoveryRequest<'_, '_>,
6828 ) -> Vec<RecognizeOutcome> {
6829 let RecoveryRequest {
6830 atn,
6831 transition,
6832 expected_symbols,
6833 target,
6834 request,
6835 visiting,
6836 memo,
6837 expected,
6838 } = recovery;
6839 let RecognizeRequest {
6840 stop_state,
6841 index,
6842 rule_start_index,
6843 decision_start_index,
6844 init_action_rules,
6845 predicates,
6846 semantics,
6847 rule_args,
6848 member_actions,
6849 return_actions,
6850 local_int_arg,
6851 member_values,
6852 return_values,
6853 rule_alt_number,
6854 track_alt_numbers,
6855 consumed_eof,
6856 precedence,
6857 depth,
6858 ..
6859 } = request;
6860 let follow_symbols = state_expected_symbols(atn, transition.target());
6861 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
6862 transition,
6863 index,
6864 atn.max_token_type(),
6865 &expected_symbols,
6866 &follow_symbols,
6867 ) else {
6868 return Vec::new();
6869 };
6870 self.recognize_state(
6871 atn,
6872 RecognizeRequest {
6873 state_number: target,
6874 stop_state,
6875 index,
6876 rule_start_index,
6877 decision_start_index,
6878 init_action_rules,
6879 predicates,
6880 semantics,
6881 rule_args,
6882 member_actions,
6883 return_actions,
6884 local_int_arg,
6885 member_values,
6886 return_values,
6887 rule_alt_number,
6888 track_alt_numbers,
6889 consumed_eof,
6890 precedence,
6891 depth: depth + 1,
6892 recovery_symbols: BTreeSet::new(),
6893 recovery_state: None,
6894 },
6895 visiting,
6896 memo,
6897 expected,
6898 )
6899 .into_iter()
6900 .map(|mut outcome| {
6901 outcome.diagnostics.insert(0, diagnostic.clone());
6902 outcome.nodes.insert(
6903 0,
6904 RecognizedNode::MissingToken {
6905 token_type,
6906 at_index: index,
6907 text: text.clone(),
6908 },
6909 );
6910 outcome
6911 })
6912 .collect()
6913 }
6914
6915 #[allow(clippy::too_many_lines)]
6918 fn recognize_state(
6919 &mut self,
6920 atn: &Atn,
6921 request: RecognizeRequest<'_>,
6922 visiting: &mut BTreeSet<RecognizeKey>,
6923 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
6924 expected: &mut ExpectedTokens,
6925 ) -> Vec<RecognizeOutcome> {
6926 let request_template = request.clone();
6927 let RecognizeRequest {
6928 state_number,
6929 stop_state,
6930 index,
6931 rule_start_index,
6932 decision_start_index,
6933 init_action_rules,
6934 predicates,
6935 semantics,
6936 rule_args,
6937 member_actions,
6938 return_actions,
6939 local_int_arg,
6940 member_values,
6941 return_values,
6942 rule_alt_number,
6943 track_alt_numbers,
6944 consumed_eof,
6945 precedence,
6946 depth,
6947 recovery_symbols,
6948 recovery_state,
6949 } = request;
6950 if depth > RECOGNITION_DEPTH_LIMIT {
6951 return Vec::new();
6952 }
6953 if state_number == stop_state {
6954 return stop_outcome(
6955 index,
6956 consumed_eof,
6957 rule_alt_number,
6958 member_values,
6959 return_values,
6960 );
6961 }
6962 let key = RecognizeKey {
6963 state_number,
6964 stop_state,
6965 index,
6966 rule_start_index,
6967 decision_start_index,
6968 local_int_arg,
6969 member_values: member_values.clone(),
6970 return_values: return_values.clone(),
6971 rule_alt_number,
6972 track_alt_numbers,
6973 consumed_eof,
6974 precedence,
6975 recovery_symbols: recovery_symbols.clone(),
6976 recovery_state,
6977 };
6978 if let Some(outcomes) = memo.get(&key) {
6979 return outcomes.clone();
6980 }
6981
6982 let visit_key = key.clone();
6983 if !visiting.insert(visit_key.clone()) {
6984 return Vec::new();
6985 }
6986
6987 let Some(state) = atn.state(state_number) else {
6988 visiting.remove(&visit_key);
6989 return Vec::new();
6990 };
6991 let next_decision_start_index = if starts_prediction_decision(state) {
6992 Some(index)
6993 } else {
6994 decision_start_index
6995 };
6996 let (epsilon_recovery_symbols, epsilon_recovery_state) =
6997 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
6998 let mut outcomes = Vec::new();
6999 for (transition_index, transition) in state.transitions.iter().enumerate() {
7000 let decision = transition_decision(atn, state, transition_index, predicates);
7001 let next_alt_number =
7002 next_alt_number(state, transition_index, rule_alt_number, track_alt_numbers);
7003 match transition {
7004 Transition::Epsilon { target } | Transition::Action { target, .. } => {
7005 let action_rule_index = match transition {
7006 Transition::Action { rule_index, .. } => Some(*rule_index),
7007 _ => None,
7008 };
7009 outcomes.extend(self.recognize_epsilon_or_action_step(
7010 atn,
7011 &request_template,
7012 EpsilonActionStep {
7013 source_state: state_number,
7014 target: *target,
7015 action_rule_index,
7016 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
7017 decision,
7018 decision_start_index: next_decision_start_index,
7019 alt_number: next_alt_number,
7020 recovery_symbols: epsilon_recovery_symbols.clone(),
7021 recovery_state: epsilon_recovery_state,
7022 },
7023 RecognizeScratch {
7024 visiting,
7025 memo,
7026 expected,
7027 },
7028 ));
7029 }
7030 Transition::Predicate {
7031 target,
7032 rule_index,
7033 pred_index,
7034 ..
7035 } => {
7036 let predicate = PredicateEval {
7037 index,
7038 rule_index: *rule_index,
7039 pred_index: *pred_index,
7040 predicates,
7041 semantics,
7042 context: None,
7043 local_int_arg,
7044 member_values: &member_values,
7045 };
7046 if self.parser_predicate_matches(predicate) {
7047 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
7048 outcomes.extend(
7049 self.recognize_state(
7050 atn,
7051 RecognizeRequest {
7052 state_number: *target,
7053 stop_state,
7054 index,
7055 rule_start_index,
7056 decision_start_index: next_decision_start_index,
7057 init_action_rules,
7058 predicates,
7059 semantics,
7060 rule_args,
7061 member_actions,
7062 return_actions,
7063 local_int_arg,
7064 member_values: member_values.clone(),
7065 return_values: return_values.clone(),
7066 rule_alt_number: next_alt_number,
7067 track_alt_numbers,
7068 consumed_eof,
7069 precedence,
7070 depth: depth + 1,
7071 recovery_symbols: epsilon_recovery_symbols.clone(),
7072 recovery_state: epsilon_recovery_state,
7073 },
7074 visiting,
7075 memo,
7076 expected,
7077 )
7078 .into_iter()
7079 .map(|mut outcome| {
7080 prepend_decision(&mut outcome, decision);
7081 if let Some(rule_index) = left_recursive_boundary {
7082 outcome.nodes.insert(
7083 0,
7084 RecognizedNode::LeftRecursiveBoundary { rule_index },
7085 );
7086 }
7087 outcome
7088 }),
7089 );
7090 } else if let Some(message) = semantics
7091 .and_then(|semantics| {
7092 self.parser_semantic_ir_predicate_failure_message(
7093 *rule_index,
7094 *pred_index,
7095 semantics,
7096 )
7097 })
7098 .or_else(|| {
7099 self.parser_predicate_failure_message(
7100 *rule_index,
7101 *pred_index,
7102 predicates,
7103 )
7104 })
7105 {
7106 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
7107 rule_index: *rule_index,
7108 index,
7109 message,
7110 member_values: member_values.clone(),
7111 return_values: return_values.clone(),
7112 rule_alt_number,
7113 }));
7114 } else {
7115 record_predicate_no_viable(expected, next_decision_start_index, index);
7116 }
7117 }
7118 Transition::Precedence {
7119 target,
7120 precedence: transition_precedence,
7121 } => {
7122 if *transition_precedence >= precedence {
7123 outcomes.extend(
7124 self.recognize_state(
7125 atn,
7126 RecognizeRequest {
7127 state_number: *target,
7128 stop_state,
7129 index,
7130 rule_start_index,
7131 decision_start_index: next_decision_start_index,
7132 init_action_rules,
7133 predicates,
7134 semantics,
7135 rule_args,
7136 member_actions,
7137 return_actions,
7138 local_int_arg,
7139 member_values: member_values.clone(),
7140 return_values: return_values.clone(),
7141 rule_alt_number: next_alt_number,
7142 track_alt_numbers,
7143 consumed_eof,
7144 precedence,
7145 depth: depth + 1,
7146 recovery_symbols: epsilon_recovery_symbols.clone(),
7147 recovery_state: epsilon_recovery_state,
7148 },
7149 visiting,
7150 memo,
7151 expected,
7152 )
7153 .into_iter()
7154 .map(|mut outcome| {
7155 prepend_decision(&mut outcome, decision);
7156 outcome
7157 }),
7158 );
7159 }
7160 }
7161 Transition::Rule {
7162 target,
7163 rule_index,
7164 follow_state,
7165 precedence: rule_precedence,
7166 ..
7167 } => {
7168 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
7169 else {
7170 continue;
7171 };
7172 let child_local_int_arg =
7173 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
7174 let expected_before_child = expected.clone();
7175 let children = self.recognize_state(
7176 atn,
7177 RecognizeRequest {
7178 state_number: *target,
7179 stop_state: child_stop,
7180 index,
7181 rule_start_index: index,
7182 decision_start_index: None,
7183 init_action_rules,
7184 predicates,
7185 semantics,
7186 rule_args,
7187 member_actions,
7188 return_actions,
7189 local_int_arg: child_local_int_arg,
7190 member_values: member_values.clone(),
7191 return_values: BTreeMap::new(),
7192 rule_alt_number: 0,
7193 track_alt_numbers,
7194 consumed_eof: false,
7195 precedence: *rule_precedence,
7196 depth: depth + 1,
7197 recovery_symbols: epsilon_recovery_symbols.clone(),
7198 recovery_state: epsilon_recovery_state,
7199 },
7200 visiting,
7201 memo,
7202 expected,
7203 );
7204 let children = if children.is_empty() {
7205 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
7206 atn,
7207 rule_index: *rule_index,
7208 start_index: index,
7209 follow_state: *follow_state,
7210 stop_state,
7211 member_values: member_values.clone(),
7212 expected,
7213 })
7214 } else {
7215 children
7216 };
7217 let preserve_child_expected =
7218 self.child_expected_reaches_clean_eof(&children, expected);
7219 restore_expected(
7220 &children,
7221 index,
7222 expected,
7223 expected_before_child,
7224 preserve_child_expected,
7225 );
7226 for child in children {
7227 let child_node = RecognizedNode::Rule {
7228 rule_index: *rule_index,
7229 invoking_state: invoking_state_number(state_number),
7230 alt_number: child.alt_number,
7231 start_index: index,
7232 stop_index: self.rule_stop_token_index(child.index, child.consumed_eof),
7233 return_values: child.return_values.clone(),
7234 children: fold_left_recursive_boundaries(child.nodes.clone()),
7235 };
7236 outcomes.extend(
7237 self.recognize_state(
7238 atn,
7239 RecognizeRequest {
7240 state_number: *follow_state,
7241 stop_state,
7242 index: child.index,
7243 rule_start_index,
7244 decision_start_index: next_decision_start_index,
7245 init_action_rules,
7246 predicates,
7247 semantics,
7248 rule_args,
7249 member_actions,
7250 return_actions,
7251 local_int_arg,
7252 member_values: child.member_values.clone(),
7253 return_values: return_values.clone(),
7254 rule_alt_number,
7255 track_alt_numbers,
7256 consumed_eof: consumed_eof || child.consumed_eof,
7257 precedence,
7258 depth: depth + 1,
7259 recovery_symbols: BTreeSet::new(),
7260 recovery_state: None,
7261 },
7262 visiting,
7263 memo,
7264 expected,
7265 )
7266 .into_iter()
7267 .map(|mut outcome| {
7268 outcome.consumed_eof |= child.consumed_eof;
7269 let mut diagnostics = child.diagnostics.clone();
7270 diagnostics.append(&mut outcome.diagnostics);
7271 outcome.diagnostics = diagnostics;
7272 let mut decisions = child.decisions.clone();
7273 decisions.append(&mut outcome.decisions);
7274 outcome.decisions = decisions;
7275 prepend_decision(&mut outcome, decision);
7276 let mut actions = child.actions.clone();
7277 if init_action_rules.contains(rule_index) {
7278 actions.insert(
7279 0,
7280 ParserAction::new_rule_init(
7281 *rule_index,
7282 index,
7283 Some(*follow_state),
7284 ),
7285 );
7286 }
7287 actions.append(&mut outcome.actions);
7288 outcome.actions = actions;
7289 outcome.nodes.insert(0, child_node.clone());
7290 outcome
7291 }),
7292 );
7293 }
7294 }
7295 Transition::Atom { target, .. }
7296 | Transition::Range { target, .. }
7297 | Transition::Set { target, .. }
7298 | Transition::NotSet { target, .. }
7299 | Transition::Wildcard { target, .. } => {
7300 let symbol = self.token_type_at(index);
7301 if transition.matches(symbol, 1, atn.max_token_type()) {
7302 let next_index = self.consume_index(index, symbol);
7303 outcomes.extend(
7304 self.recognize_state(
7305 atn,
7306 RecognizeRequest {
7307 state_number: *target,
7308 stop_state,
7309 index: next_index,
7310 rule_start_index,
7311 decision_start_index: next_decision_start_index,
7312 init_action_rules,
7313 predicates,
7314 semantics,
7315 rule_args,
7316 member_actions,
7317 return_actions,
7318 local_int_arg,
7319 member_values: member_values.clone(),
7320 return_values: return_values.clone(),
7321 rule_alt_number: next_alt_number,
7322 track_alt_numbers,
7323 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
7324 precedence,
7325 depth: depth + 1,
7326 recovery_symbols: BTreeSet::new(),
7327 recovery_state: None,
7328 },
7329 visiting,
7330 memo,
7331 expected,
7332 )
7333 .into_iter()
7334 .map(|mut outcome| {
7335 prepend_decision(&mut outcome, decision);
7336 outcome.consumed_eof |= symbol == TOKEN_EOF;
7337 outcome.nodes.insert(0, RecognizedNode::Token { index });
7338 outcome
7339 }),
7340 );
7341 } else {
7342 let expected_symbols =
7343 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
7344 if expected_symbols.contains(&symbol) {
7345 continue;
7346 }
7347 expected.record_transition(index, transition, atn.max_token_type());
7348 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
7349 let before_recovery = outcomes.len();
7350 let recovery_request = request_template.clone();
7351 outcomes.extend(
7352 self.single_token_deletion_recovery(RecoveryRequest {
7353 atn,
7354 transition,
7355 expected_symbols: expected_symbols.clone(),
7356 target: *target,
7357 request: recovery_request.clone(),
7358 visiting,
7359 memo,
7360 expected,
7361 })
7362 .into_iter()
7363 .map(|mut outcome| {
7364 prepend_decision(&mut outcome, decision);
7365 outcome
7366 }),
7367 );
7368 if !state_is_left_recursive_rule(atn, state) {
7369 outcomes.extend(
7370 self.single_token_insertion_recovery(RecoveryRequest {
7371 atn,
7372 transition,
7373 expected_symbols: expected_symbols.clone(),
7374 target: *target,
7375 request: recovery_request.clone(),
7376 visiting,
7377 memo,
7378 expected,
7379 })
7380 .into_iter()
7381 .map(|mut outcome| {
7382 prepend_decision(&mut outcome, decision);
7383 outcome
7384 }),
7385 );
7386 }
7387 outcomes.extend(self.current_token_deletion_recovery(
7388 CurrentTokenDeletionRequest {
7389 atn,
7390 expected_symbols: expected_symbols.clone(),
7391 request: recovery_request.clone(),
7392 visiting,
7393 memo,
7394 expected,
7395 },
7396 ));
7397 if outcomes.len() == before_recovery {
7398 outcomes.extend(self.consuming_failure_fallback(
7399 ConsumingFailureFallback {
7400 atn,
7401 target: *target,
7402 request: recovery_request,
7403 symbol,
7404 expected_symbols,
7405 decision_start_index: next_decision_start_index,
7406 decision,
7407 },
7408 visiting,
7409 memo,
7410 expected,
7411 ));
7412 }
7413 }
7414 }
7415 }
7416 }
7417
7418 visiting.remove(&visit_key);
7419 self.record_prediction_diagnostics(atn, state, index, &outcomes);
7420 if matches!(
7421 self.prediction_mode,
7422 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
7423 ) {
7424 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes);
7425 }
7426 dedupe_outcomes(&mut outcomes);
7427 memo.insert(key, outcomes.clone());
7428 outcomes
7429 }
7430
7431 fn recognize_epsilon_or_action_step(
7434 &mut self,
7435 atn: &Atn,
7436 request: &RecognizeRequest<'_>,
7437 step: EpsilonActionStep,
7438 scratch: RecognizeScratch<'_>,
7439 ) -> Vec<RecognizeOutcome> {
7440 let RecognizeScratch {
7441 visiting,
7442 memo,
7443 expected,
7444 } = scratch;
7445 let action = step.action_rule_index.map(|rule_index| {
7446 ParserAction::new(
7447 step.source_state,
7448 rule_index,
7449 request.rule_start_index,
7450 self.rule_stop_token_index(request.index, request.consumed_eof),
7451 )
7452 });
7453 let next_member_values = if action.is_some() {
7454 member_values_after_action(
7455 step.source_state,
7456 request.member_actions,
7457 request.semantics,
7458 &request.member_values,
7459 )
7460 } else {
7461 request.member_values.clone()
7462 };
7463 let next_return_values = action.map_or_else(
7464 || request.return_values.clone(),
7465 |action| {
7466 return_values_after_action(
7467 step.source_state,
7468 action.rule_index(),
7469 request.return_actions,
7470 request.semantics,
7471 &request.return_values,
7472 )
7473 },
7474 );
7475
7476 self.recognize_state(
7477 atn,
7478 RecognizeRequest {
7479 state_number: step.target,
7480 stop_state: request.stop_state,
7481 index: request.index,
7482 rule_start_index: request.rule_start_index,
7483 decision_start_index: step.decision_start_index,
7484 init_action_rules: request.init_action_rules,
7485 predicates: request.predicates,
7486 semantics: request.semantics,
7487 rule_args: request.rule_args,
7488 member_actions: request.member_actions,
7489 return_actions: request.return_actions,
7490 local_int_arg: request.local_int_arg,
7491 member_values: next_member_values,
7492 return_values: next_return_values,
7493 rule_alt_number: step.alt_number,
7494 track_alt_numbers: request.track_alt_numbers,
7495 consumed_eof: request.consumed_eof,
7496 precedence: request.precedence,
7497 depth: request.depth + 1,
7498 recovery_symbols: step.recovery_symbols,
7499 recovery_state: step.recovery_state,
7500 },
7501 visiting,
7502 memo,
7503 expected,
7504 )
7505 .into_iter()
7506 .map(|mut outcome| {
7507 prepend_decision(&mut outcome, step.decision);
7508 if let Some(rule_index) = step.left_recursive_boundary {
7509 outcome
7510 .nodes
7511 .insert(0, RecognizedNode::LeftRecursiveBoundary { rule_index });
7512 }
7513 if let Some(action) = action {
7514 outcome.actions.insert(0, action);
7515 }
7516 outcome
7517 })
7518 .collect()
7519 }
7520
7521 fn token_type_at(&mut self, index: usize) -> i32 {
7526 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
7527 self.input.fill();
7528 }
7529 self.input.token_type_at_index(index)
7530 }
7531
7532 fn cached_state_expected_symbols(
7544 &mut self,
7545 atn: &Atn,
7546 state_number: usize,
7547 ) -> Rc<BTreeSet<i32>> {
7548 if let Some(cached) = self.state_expected_cache.get(&state_number) {
7549 return Rc::clone(cached);
7550 }
7551 let symbols = state_expected_symbols(atn, state_number);
7552 let entry = self.intern_recovery_symbols(symbols);
7553 self.state_expected_cache
7554 .insert(state_number, Rc::clone(&entry));
7555 entry
7556 }
7557
7558 fn cached_state_expected_token_set(
7559 &mut self,
7560 atn: &Atn,
7561 state_number: usize,
7562 ) -> Rc<TokenBitSet> {
7563 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
7564 return Rc::clone(cached);
7565 }
7566 let symbols = with_shared_atn_caches(atn, |cache| {
7570 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
7571 return Rc::clone(cached);
7572 }
7573 let symbols = Rc::new(state_expected_token_set(atn, state_number));
7574 cache
7575 .state_expected_tokens
7576 .insert(state_number, Rc::clone(&symbols));
7577 symbols
7578 });
7579 self.state_expected_token_cache
7580 .insert(state_number, Rc::clone(&symbols));
7581 symbols
7582 }
7583
7584 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
7585 if self.rule_stop_reach_cache.len() <= state_number {
7586 self.rule_stop_reach_cache
7587 .resize_with(atn.states().len().max(state_number + 1), || None);
7588 }
7589 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
7590 return reaches;
7591 }
7592 let reaches = with_shared_atn_caches(atn, |cache| {
7593 *cache
7594 .rule_stop_reach
7595 .entry(state_number)
7596 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
7597 });
7598 self.rule_stop_reach_cache[state_number] = Some(reaches);
7599 reaches
7600 }
7601
7602 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
7605 Rc::clone(&self.empty_recovery_symbols)
7606 }
7607
7608 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
7617 if set.is_empty() {
7618 return Rc::clone(&self.empty_recovery_symbols);
7619 }
7620 let candidate = Rc::new(set);
7621 match self.recovery_symbols_intern.get(&candidate) {
7622 Some(existing) => Rc::clone(existing),
7623 None => {
7624 self.recovery_symbols_intern
7625 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
7626 candidate
7627 }
7628 }
7629 }
7630
7631 fn cached_decision_lookahead(
7636 &mut self,
7637 atn: &Atn,
7638 state: &AtnState,
7639 rule_stop_state: usize,
7640 ) -> Rc<DecisionLookahead> {
7641 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number) {
7648 return Rc::clone(cached);
7649 }
7650 let entry = with_shared_atn_caches(atn, |cache| {
7651 if let Some(cached) = cache.decision_lookahead.get(&state.state_number) {
7652 return Rc::clone(cached);
7653 }
7654 let mut entry = DecisionLookahead {
7655 transitions: Vec::with_capacity(state.transitions.len()),
7656 };
7657 for transition in &state.transitions {
7658 entry.transitions.push(transition_first_set(
7659 atn,
7660 transition,
7661 rule_stop_state,
7662 &mut cache.first_set,
7663 ));
7664 }
7665 let entry = Rc::new(entry);
7666 cache
7667 .decision_lookahead
7668 .insert(state.state_number, Rc::clone(&entry));
7669 entry
7670 });
7671 self.decision_lookahead_cache
7672 .insert(state.state_number, Rc::clone(&entry));
7673 entry
7674 }
7675
7676 fn cached_rule_first_set(
7677 &mut self,
7678 atn: &Atn,
7679 target: usize,
7680 child_stop: usize,
7681 ) -> Rc<FirstSet> {
7682 if self.rule_first_set_cache.len() <= target {
7683 self.rule_first_set_cache
7684 .resize_with(atn.states().len().max(target + 1), || None);
7685 }
7686 if let Some(cached) = self
7687 .rule_first_set_cache
7688 .get(target)
7689 .and_then(Option::as_ref)
7690 {
7691 return Rc::clone(cached);
7692 }
7693 let first = with_shared_first_set_cache(atn, |cache| {
7694 rule_first_set(atn, target, child_stop, cache)
7695 });
7696 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
7697 first
7698 }
7699
7700 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
7701 if self.empty_cycle_cache.len() <= state_number {
7702 self.empty_cycle_cache
7703 .resize_with(atn.states().len().max(state_number + 1), || None);
7704 }
7705 if let Some(cached) = self.empty_cycle_cache[state_number] {
7706 return cached;
7707 }
7708 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
7709 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
7710 self.empty_cycle_cache[state_number] = Some(result);
7711 result
7712 }
7713
7714 fn empty_path_reaches_state(
7715 &mut self,
7716 atn: &Atn,
7717 state_number: usize,
7718 target_state: usize,
7719 visited: &mut FxHashSet<usize>,
7720 ) -> bool {
7721 if !visited.insert(state_number) {
7722 return false;
7723 }
7724 let Some(state) = atn.state(state_number) else {
7725 return false;
7726 };
7727 for transition in &state.transitions {
7728 match transition {
7729 Transition::Atom { .. }
7730 | Transition::Range { .. }
7731 | Transition::Set { .. }
7732 | Transition::NotSet { .. }
7733 | Transition::Wildcard { .. } => {}
7734 Transition::Rule {
7735 target,
7736 rule_index,
7737 follow_state,
7738 ..
7739 } => {
7740 if *target == target_state
7741 || self.empty_path_reaches_state(atn, *target, target_state, visited)
7742 {
7743 return true;
7744 }
7745 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
7746 else {
7747 continue;
7748 };
7749 if self
7750 .cached_rule_first_set(atn, *target, child_stop)
7751 .nullable
7752 && (*follow_state == target_state
7753 || self.empty_path_reaches_state(
7754 atn,
7755 *follow_state,
7756 target_state,
7757 visited,
7758 ))
7759 {
7760 return true;
7761 }
7762 }
7763 Transition::Epsilon { target }
7764 | Transition::Predicate { target, .. }
7765 | Transition::Action { target, .. }
7766 | Transition::Precedence { target, .. } => {
7767 if *target == target_state
7768 || self.empty_path_reaches_state(atn, *target, target_state, visited)
7769 {
7770 return true;
7771 }
7772 }
7773 }
7774 }
7775 false
7776 }
7777
7778 fn should_memoize_single_outcome(&mut self, key: &FastRecognizeKey) -> bool {
7781 match self.single_outcome_memo_mode {
7782 SingleOutcomeMemoMode::Promote => true,
7783 SingleOutcomeMemoMode::Sparse => false,
7784 SingleOutcomeMemoMode::Probe => {
7785 self.single_outcome_probe_samples += 1;
7786 if !self.single_outcome_probe_seen.insert(key.clone()) {
7787 self.single_outcome_probe_repeats += 1;
7788 }
7789 if self.single_outcome_probe_repeats >= CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
7790 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Promote;
7791 self.single_outcome_probe_seen.clear();
7792 return true;
7793 }
7794 if self.single_outcome_probe_samples >= CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT {
7795 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Sparse;
7796 self.single_outcome_probe_seen.clear();
7797 return false;
7798 }
7799 true
7800 }
7801 }
7802 }
7803
7804 fn token_at(&mut self, index: usize) -> Option<CommonToken> {
7806 self.input.get(index).cloned()
7807 }
7808
7809 fn token_ref_at(&mut self, index: usize) -> Option<TokenRef> {
7811 self.input.get_ref(index)
7812 }
7813
7814 fn current_visible_index(&mut self) -> usize {
7817 let index = self.input.index();
7818 self.input.seek(index);
7819 self.input.index()
7820 }
7821
7822 fn child_expected_reaches_clean_eof(
7825 &mut self,
7826 children: &[RecognizeOutcome],
7827 expected: &ExpectedTokens,
7828 ) -> bool {
7829 let Some(index) = expected.index else {
7830 return false;
7831 };
7832 self.token_type_at(index) == TOKEN_EOF
7833 && children
7834 .iter()
7835 .any(|child| child.diagnostics.is_empty() && child.index == index)
7836 }
7837
7838 fn previous_token_index(&mut self, index: usize) -> Option<usize> {
7845 self.input.previous_visible_token_index(index)
7846 }
7847
7848 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
7853 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
7854 Some(index)
7855 } else {
7856 self.previous_token_index(index)
7857 }
7858 }
7859
7860 #[must_use]
7877 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
7878 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
7879 self.rule_stop_token_index(current_index, consumed_eof)
7880 }
7881
7882 #[must_use]
7891 pub fn after_action_stop_index_for_tree(
7892 &mut self,
7893 tree: &ParseTree,
7894 current_index: usize,
7895 ) -> Option<usize> {
7896 if let ParseTree::Rule(rule) = tree {
7897 if let Some(stop) = rule.context().stop() {
7898 let token_index = stop.token_index();
7899 if token_index >= 0 {
7900 return Some(token_index.unsigned_abs());
7901 }
7902 }
7903 }
7904 self.after_action_stop_index(current_index)
7905 }
7906
7907 #[must_use]
7917 pub fn after_action_start_index_for_tree(
7918 &self,
7919 tree: &ParseTree,
7920 fallback_index: usize,
7921 ) -> usize {
7922 if let ParseTree::Rule(rule) = tree {
7923 if let Some(start) = rule.context().start() {
7924 let token_index = start.token_index();
7925 if token_index >= 0 {
7926 return token_index.unsigned_abs();
7927 }
7928 }
7929 }
7930 fallback_index
7931 }
7932
7933 fn rule_stop_token_ref(&mut self, index: usize, consumed_eof: bool) -> Option<TokenRef> {
7938 self.rule_stop_token_index(index, consumed_eof)
7939 .and_then(|token_index| self.token_ref_at(token_index))
7940 }
7941
7942 fn predicate_failure_recovery(
7949 &mut self,
7950 request: PredicateFailureRecovery<'_>,
7951 ) -> RecognizeOutcome {
7952 let PredicateFailureRecovery {
7953 rule_index,
7954 index,
7955 message,
7956 member_values,
7957 return_values,
7958 rule_alt_number,
7959 } = request;
7960 let rule_name = self
7961 .rule_names()
7962 .get(rule_index)
7963 .map_or_else(|| rule_index.to_string(), Clone::clone);
7964 let diagnostic = diagnostic_for_token(
7965 self.token_at(index).as_ref(),
7966 format!("rule {rule_name} {message}"),
7967 );
7968 let mut nodes = Vec::new();
7969 let mut next_index = index;
7970 loop {
7971 let symbol = self.token_type_at(next_index);
7972 if symbol == TOKEN_EOF {
7973 break;
7974 }
7975 nodes.push(RecognizedNode::ErrorToken { index: next_index });
7976 let after = self.consume_index(next_index, symbol);
7977 if after == next_index {
7978 break;
7979 }
7980 next_index = after;
7981 }
7982 RecognizeOutcome {
7983 index: next_index,
7984 consumed_eof: false,
7985 alt_number: rule_alt_number,
7986 member_values,
7987 return_values,
7988 diagnostics: vec![diagnostic],
7989 decisions: Vec::new(),
7990 actions: Vec::new(),
7991 nodes,
7992 }
7993 }
7994
7995 fn parser_semantic_hook_result(
7998 &mut self,
7999 request: ParserSemanticHookRequest<'_>,
8000 ) -> Option<bool> {
8001 let ParserSemanticHookRequest {
8002 index,
8003 rule_index,
8004 pred_index,
8005 context,
8006 local_int_arg,
8007 member_values,
8008 } = request;
8009 let rule_name = self.rule_names().get(rule_index).cloned();
8010 self.input.seek(index);
8011 let input = &mut self.input;
8012 let semantic_hooks = &mut self.semantic_hooks;
8013 let mut ctx = ParserSemCtx {
8014 input,
8015 rule_index,
8016 coordinate_index: pred_index,
8017 rule_name,
8018 context,
8019 tree: None,
8020 local_int_arg,
8021 member_values,
8022 action: None,
8023 };
8024 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
8025 }
8026
8027 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
8032 if prior.is_empty() {
8033 return;
8034 }
8035 let mut merged = prior;
8036 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
8037 if !merged.contains(&coordinate) {
8038 merged.push(coordinate);
8039 }
8040 }
8041 self.unknown_predicate_hits = merged;
8042 }
8043
8044 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
8053 apply_unknown_predicate_policy(
8054 self.unknown_predicate_policy,
8055 rule_index,
8056 pred_index,
8057 &mut self.unknown_predicate_hits,
8058 )
8059 }
8060
8061 fn unknown_semantic_error(&self) -> Option<AntlrError> {
8064 use std::fmt::Write as _;
8065 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
8066 return None;
8067 }
8068 let mut message = String::new();
8069 for (rule_index, pred_index) in &self.unknown_predicate_hits {
8070 if !message.is_empty() {
8071 message.push_str("; ");
8072 }
8073 let _ = match self.rule_names().get(*rule_index) {
8074 Some(rule_name) => write!(
8075 message,
8076 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
8077 ),
8078 None => write!(
8079 message,
8080 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
8081 ),
8082 };
8083 }
8084 for (rule_index, source_state) in &self.unhandled_action_hits {
8085 if !message.is_empty() {
8086 message.push_str("; ");
8087 }
8088 let _ = match self.rule_names().get(*rule_index) {
8089 Some(rule_name) => write!(
8090 message,
8091 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
8092 ),
8093 None => write!(
8094 message,
8095 "unhandled semantic action: rule_index={rule_index} state={source_state}"
8096 ),
8097 };
8098 }
8099 Some(AntlrError::Unsupported(message))
8100 }
8101
8102 fn parser_semir_predicate_matches(
8110 &mut self,
8111 semantics: &ParserSemantics,
8112 predicate: &ParserSemanticPredicate,
8113 request: ParserSemanticHookRequest<'_>,
8114 ) -> bool {
8115 self.input.seek(request.index);
8116 let rule_name = self
8117 .data
8118 .rule_names()
8119 .get(request.rule_index)
8120 .map(String::as_str);
8121 let unknown_predicate_policy = self.unknown_predicate_policy;
8122 let mut ctx = ParserSemIrCtx {
8123 input: &mut self.input,
8124 semantic_hooks: &mut self.semantic_hooks,
8125 rule_index: request.rule_index,
8126 coordinate_index: request.pred_index,
8127 rule_name,
8128 context: request.context,
8129 local_int_arg: request.local_int_arg,
8130 member_values: request.member_values,
8131 invoked_predicates: &mut self.invoked_predicates,
8132 unknown_predicate_policy,
8133 unknown_predicate_hits: &mut self.unknown_predicate_hits,
8134 };
8135 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
8136 }
8137
8138 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
8139 let PredicateEval {
8140 index,
8141 rule_index,
8142 pred_index,
8143 predicates,
8144 semantics,
8145 context,
8146 local_int_arg,
8147 member_values,
8148 } = eval;
8149 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
8150 semantics
8151 .predicates
8152 .iter()
8153 .find(|predicate| {
8154 predicate.rule_index == rule_index && predicate.pred_index == pred_index
8155 })
8156 .map(|predicate| (semantics, predicate))
8157 }) {
8158 return self.parser_semir_predicate_matches(
8159 semantics,
8160 predicate,
8161 ParserSemanticHookRequest {
8162 index,
8163 rule_index,
8164 pred_index,
8165 context,
8166 local_int_arg,
8167 member_values,
8168 },
8169 );
8170 }
8171 let Some((_, _, predicate)) = predicates
8172 .iter()
8173 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
8174 else {
8175 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
8176 index,
8177 rule_index,
8178 pred_index,
8179 context,
8180 local_int_arg,
8181 member_values,
8182 }) {
8183 return result;
8184 }
8185 return self.unknown_predicate_result(rule_index, pred_index);
8186 };
8187 self.input.seek(index);
8188 match predicate {
8189 ParserPredicate::True => true,
8190 ParserPredicate::False => false,
8191 ParserPredicate::FalseWithMessage { .. } => false,
8192 ParserPredicate::Invoke { value } => {
8193 let key = (rule_index, pred_index);
8194 if !self.invoked_predicates.contains(&key) {
8195 self.invoked_predicates.push(key);
8196 use std::io::Write as _;
8197 let mut stdout = std::io::stdout().lock();
8198 let _ = writeln!(stdout, "eval={value}");
8199 }
8200 *value
8201 }
8202 ParserPredicate::LookaheadTextEquals { offset, text } => {
8203 self.input.lt(*offset).and_then(Token::text) == Some(*text)
8204 }
8205 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
8206 self.la(*offset) != *token_type
8207 }
8208 ParserPredicate::TokenPairAdjacent => {
8209 let Some(first) = self.input.lt(-2).map(Token::token_index) else {
8210 return false;
8211 };
8212 let Some(second) = self.input.lt(-1).map(Token::token_index) else {
8213 return false;
8214 };
8215 first + 1 == second
8216 }
8217 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
8218 .and_then(|context| {
8219 context.children().iter().find_map(|child| match child {
8220 ParseTree::Rule(rule) if rule.context().rule_index() == *rule_index => {
8221 Some(child.text())
8222 }
8223 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
8224 })
8225 })
8226 .is_none_or(|actual| actual != *text),
8227 ParserPredicate::LocalIntEquals { value } => {
8228 local_int_arg.is_none_or(|(_, actual)| actual == *value)
8229 }
8230 ParserPredicate::LocalIntLessOrEqual { value } => {
8231 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
8232 }
8233 ParserPredicate::MemberModuloEquals {
8234 member,
8235 modulus,
8236 value,
8237 equals,
8238 } => {
8239 if *modulus == 0 {
8240 return false;
8241 }
8242 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
8243 (actual == *value) == *equals
8244 }
8245 ParserPredicate::MemberEquals {
8246 member,
8247 value,
8248 equals,
8249 } => {
8250 let actual = member_values.get(member).copied().unwrap_or_default();
8251 (actual == *value) == *equals
8252 }
8253 }
8254 }
8255
8256 fn parser_predicate_failure_message(
8258 &self,
8259 rule_index: usize,
8260 pred_index: usize,
8261 predicates: &[(usize, usize, ParserPredicate)],
8262 ) -> Option<&'static str> {
8263 predicates
8264 .iter()
8265 .find_map(|(rule, pred, predicate)| match predicate {
8266 ParserPredicate::FalseWithMessage { message }
8267 if *rule == rule_index && *pred == pred_index =>
8268 {
8269 Some(*message)
8270 }
8271 _ => None,
8272 })
8273 }
8274
8275 pub fn parser_semantic_ir_predicate_failure_message(
8278 &self,
8279 rule_index: usize,
8280 pred_index: usize,
8281 semantics: &ParserSemantics,
8282 ) -> Option<&'static str> {
8283 semantics
8284 .predicates
8285 .iter()
8286 .find(|predicate| {
8287 predicate.rule_index == rule_index && predicate.pred_index == pred_index
8288 })
8289 .and_then(|predicate| predicate.failure_message)
8290 }
8291
8292 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
8301 if symbol == TOKEN_EOF {
8302 return index;
8303 }
8304 self.input.next_visible_after(index)
8305 }
8306
8307 fn no_viable_alternative(
8310 &mut self,
8311 start_index: usize,
8312 error_index: usize,
8313 ) -> ParserDiagnostic {
8314 let text = display_input_text(&self.input.text(start_index, error_index));
8315 diagnostic_for_token(
8316 self.token_at(error_index).as_ref(),
8317 format!("no viable alternative at input '{text}'"),
8318 )
8319 }
8320
8321 fn recovery_failure_diagnostic(
8324 &mut self,
8325 index: usize,
8326 decision_start_index: Option<usize>,
8327 expected_symbols: &BTreeSet<i32>,
8328 ) -> ParserDiagnostic {
8329 if expected_symbols.len() > 1 {
8330 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
8331 return self.no_viable_alternative(decision_start, index);
8332 }
8333 }
8334 diagnostic_for_token(
8335 self.token_at(index).as_ref(),
8336 format!(
8337 "mismatched input {} expecting {}",
8338 self.token_at(index)
8339 .as_ref()
8340 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8341 self.expected_symbols_display(expected_symbols)
8342 ),
8343 )
8344 }
8345
8346 fn eof_rule_recovery_diagnostic(
8349 &mut self,
8350 index: usize,
8351 expected_symbols: &BTreeSet<i32>,
8352 expected: &ExpectedTokens,
8353 ) -> ParserDiagnostic {
8354 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
8355 &expected.symbols
8356 } else {
8357 expected_symbols
8358 };
8359 diagnostic_for_token(
8360 self.token_at(index).as_ref(),
8361 format!(
8362 "mismatched input {} expecting {}",
8363 self.token_at(index)
8364 .as_ref()
8365 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8366 self.expected_symbols_display(symbols)
8367 ),
8368 )
8369 }
8370
8371 pub fn text_interval(&mut self, start: usize, stop: Option<usize>) -> String {
8377 let Some(stop) = stop else {
8378 return String::new();
8379 };
8380 let stop = if self
8381 .token_at(stop)
8382 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8383 {
8384 let Some(previous) = self.previous_token_index(stop) else {
8385 return String::new();
8386 };
8387 previous
8388 } else {
8389 stop
8390 };
8391 self.input.text(start, stop)
8392 }
8393
8394 fn clear_prediction_diagnostics(&mut self) {
8397 self.prediction_diagnostics.clear();
8398 self.reported_prediction_diagnostics.clear();
8399 }
8400
8401 fn reset_per_parse_caches(&mut self) {
8423 self.rule_first_set_cache.clear();
8424 self.decision_lookahead_cache.clear();
8425 self.ll1_decision_cache.clear();
8426 self.empty_cycle_cache.clear();
8427 self.rule_stop_reach_cache.clear();
8428 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Probe;
8429 self.single_outcome_probe_seen.clear();
8430 self.single_outcome_probe_samples = 0;
8431 self.single_outcome_probe_repeats = 0;
8432 self.recovery_symbols_intern.clear();
8433 self.state_expected_cache.clear();
8434 self.state_expected_token_cache.clear();
8435 }
8436
8437 fn record_prediction_diagnostics(
8440 &mut self,
8441 atn: &Atn,
8442 state: &AtnState,
8443 start_index: usize,
8444 outcomes: &[RecognizeOutcome],
8445 ) {
8446 if !self.report_diagnostic_errors || state.transitions.len() < 2 {
8447 return;
8448 }
8449 let Some(decision) = atn
8450 .decision_to_state()
8451 .iter()
8452 .position(|state_number| *state_number == state.state_number)
8453 else {
8454 return;
8455 };
8456 let Some(rule_index) = state.rule_index else {
8457 return;
8458 };
8459 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
8460 for outcome in outcomes
8461 .iter()
8462 .filter(|outcome| outcome.diagnostics.is_empty())
8463 {
8464 let Some(alt) = outcome.decisions.first() else {
8465 continue;
8466 };
8467 alts_by_end
8468 .entry(outcome.index)
8469 .or_default()
8470 .insert(alt + 1);
8471 }
8472 let Some((&end_index, ambig_alts)) = alts_by_end
8473 .iter()
8474 .filter(|(_, alts)| alts.len() > 1)
8475 .max_by_key(|(end, _)| *end)
8476 else {
8477 return;
8478 };
8479 let rule_name = self
8480 .rule_names()
8481 .get(rule_index)
8482 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
8483 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
8484 let input = display_input_text(&self.input.text(start_index, stop_index));
8485 let alts = ambig_alts
8486 .iter()
8487 .map(usize::to_string)
8488 .collect::<Vec<_>>()
8489 .join(", ");
8490 let key = (decision, start_index, format!("{alts}:{input}"));
8491 if !self.reported_prediction_diagnostics.insert(key) {
8492 return;
8493 }
8494 let start_token = self.token_at(start_index);
8495 let stop_token = self.token_at(stop_index);
8496 self.prediction_diagnostics.push(diagnostic_for_token(
8497 start_token.as_ref(),
8498 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
8499 ));
8500 self.prediction_diagnostics.push(diagnostic_for_token(
8501 stop_token.as_ref(),
8502 format!(
8503 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
8504 ),
8505 ));
8506 }
8507
8508 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
8510 expected_symbols_display(
8511 &state_expected_symbols(atn, state_number),
8512 self.vocabulary(),
8513 )
8514 }
8515
8516 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
8521 let state = usize::try_from(self.data().state()).unwrap_or(0);
8522 ExpectedTokenSet {
8523 symbols: state_expected_symbols(atn, state),
8524 }
8525 }
8526
8527 pub const fn set_bail_on_error(&mut self, bail: bool) {
8530 self.bail_on_error = bail;
8531 }
8532
8533 #[must_use]
8535 pub const fn bail_on_error(&self) -> bool {
8536 self.bail_on_error
8537 }
8538
8539 pub fn rule_invocation_stack(&self) -> Vec<String> {
8542 self.rule_context_stack
8543 .iter()
8544 .rev()
8545 .map(|frame| {
8546 self.data()
8547 .rule_names()
8548 .get(frame.rule_index)
8549 .cloned()
8550 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
8551 })
8552 .collect()
8553 }
8554
8555 pub fn token_display_at(&mut self, index: usize) -> Option<String> {
8557 self.token_at(index).map(|token| format!("{token}"))
8558 }
8559
8560 fn recognized_node_tree(
8562 &mut self,
8563 node: &RecognizedNode,
8564 track_alt_numbers: bool,
8565 ) -> Result<ParseTree, AntlrError> {
8566 match node {
8567 RecognizedNode::Token { index } => {
8568 let token = self
8569 .input
8570 .get_ref(*index)
8571 .ok_or_else(|| AntlrError::ParserError {
8572 line: 0,
8573 column: 0,
8574 message: format!("missing token at index {index}"),
8575 })?;
8576 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
8577 }
8578 RecognizedNode::ErrorToken { index } => {
8579 let token = self
8580 .input
8581 .get_ref(*index)
8582 .ok_or_else(|| AntlrError::ParserError {
8583 line: 0,
8584 column: 0,
8585 message: format!("missing error token at index {index}"),
8586 })?;
8587 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
8588 }
8589 RecognizedNode::MissingToken {
8590 token_type,
8591 at_index,
8592 text,
8593 } => {
8594 let current = self.token_at(*at_index);
8595 let token = CommonToken::new(*token_type)
8596 .with_text(text.as_str())
8597 .with_span(usize::MAX, usize::MAX)
8598 .with_position(
8599 current.as_ref().map(Token::line).unwrap_or_default(),
8600 current.as_ref().map(Token::column).unwrap_or_default(),
8601 );
8602 Ok(ParseTree::Error(ErrorNode::new(token)))
8603 }
8604 RecognizedNode::Rule {
8605 rule_index,
8606 invoking_state,
8607 alt_number,
8608 start_index,
8609 stop_index,
8610 return_values,
8611 children,
8612 } => {
8613 let mut context = ParserRuleContext::new(*rule_index, *invoking_state);
8614 if track_alt_numbers {
8615 context.set_alt_number(*alt_number);
8616 }
8617 for (name, value) in return_values {
8618 context.set_int_return(name.clone(), *value);
8619 }
8620 if let Some(token) = self.token_ref_at(*start_index) {
8621 context.set_start_ref(token);
8622 }
8623 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
8624 context.set_stop_ref(token);
8625 }
8626 for child in children {
8627 context.add_child(self.recognized_node_tree(child, track_alt_numbers)?);
8628 }
8629 Ok(self.rule_node(context))
8630 }
8631 RecognizedNode::LeftRecursiveBoundary { rule_index } => Err(AntlrError::Unsupported(
8632 format!("unfolded left-recursive boundary for rule {rule_index}"),
8633 )),
8634 }
8635 }
8636}
8637
8638impl<S, H> DirectAdaptiveParser<'_, '_, S, H>
8639where
8640 S: TokenSource,
8641 H: SemanticHooks,
8642{
8643 fn parse_rule(
8644 &mut self,
8645 rule_index: usize,
8646 invoking_state: isize,
8647 precedence: i32,
8648 ) -> DirectAdaptiveParseResult<ParseTree> {
8649 let start_state = *self.atn.rule_to_start_state().get(rule_index).ok_or(
8650 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
8651 )?;
8652 let stop_state = *self
8653 .atn
8654 .rule_to_stop_state()
8655 .get(rule_index)
8656 .filter(|state| **state != usize::MAX)
8657 .ok_or(DirectAdaptiveParseControl::Fallback(
8658 DirectAdaptiveFallback::MissingAtn,
8659 ))?;
8660 let start_index = self.parser.current_visible_index();
8661 let mut children = Vec::new();
8662 let mut state_number = start_state;
8663 let mut consumed_eof = false;
8664 while state_number != stop_state {
8665 self.step()?;
8666 let (transition, boundary) = self.next_transition(state_number, precedence)?;
8667 if boundary.is_some() {
8668 return Err(DirectAdaptiveParseControl::Fallback(
8669 DirectAdaptiveFallback::LeftRecursiveBoundary,
8670 ));
8671 }
8672 match transition {
8673 Transition::Epsilon { target } => {
8674 state_number = target;
8675 }
8676 Transition::Precedence {
8677 target,
8678 precedence: transition_precedence,
8679 } => {
8680 if transition_precedence < precedence {
8681 return Err(DirectAdaptiveParseControl::Fallback(
8682 DirectAdaptiveFallback::Precedence,
8683 ));
8684 }
8685 state_number = target;
8686 }
8687 Transition::Rule {
8688 rule_index,
8689 follow_state,
8690 precedence: rule_precedence,
8691 ..
8692 } => {
8693 let child = self.parse_rule(
8694 rule_index,
8695 invoking_state_number(state_number),
8696 rule_precedence,
8697 )?;
8698 if self.parser.build_parse_trees {
8699 children.push(child);
8700 }
8701 state_number = follow_state;
8702 }
8703 Transition::Atom { .. }
8704 | Transition::Range { .. }
8705 | Transition::Set { .. }
8706 | Transition::NotSet { .. }
8707 | Transition::Wildcard { .. } => {
8708 let (matched_eof, child) = self.consume_transition(&transition)?;
8709 consumed_eof |= matched_eof;
8710 if let Some(child) = child {
8711 children.push(child);
8712 }
8713 state_number = transition.target();
8714 }
8715 Transition::Predicate { .. } => {
8716 return Err(DirectAdaptiveParseControl::Fallback(
8717 DirectAdaptiveFallback::Predicate,
8718 ));
8719 }
8720 Transition::Action { .. } => {
8721 return Err(DirectAdaptiveParseControl::Fallback(
8722 DirectAdaptiveFallback::Action,
8723 ));
8724 }
8725 }
8726 }
8727
8728 let mut context = ParserRuleContext::with_child_capacity(
8729 rule_index,
8730 invoking_state,
8731 if self.parser.build_parse_trees {
8732 children.len()
8733 } else {
8734 0
8735 },
8736 );
8737 if let Some(token) = self.parser.token_ref_at(start_index) {
8738 context.set_start_ref(token);
8739 }
8740 let stop_index = self
8741 .parser
8742 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
8743 if let Some(token) = stop_index.and_then(|index| self.parser.token_ref_at(index)) {
8744 context.set_stop_ref(token);
8745 }
8746 if self.parser.build_parse_trees {
8747 for child in children {
8748 context.add_child(child);
8749 }
8750 }
8751 Ok(self.parser.rule_node(context))
8752 }
8753
8754 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
8755 self.steps += 1;
8756 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
8757 return Err(DirectAdaptiveParseControl::Fallback(
8758 DirectAdaptiveFallback::StepLimit,
8759 ));
8760 }
8761 Ok(())
8762 }
8763
8764 fn next_transition(
8765 &mut self,
8766 state_number: usize,
8767 precedence: i32,
8768 ) -> DirectAdaptiveParseResult<(Transition, Option<usize>)> {
8769 let state = self
8770 .atn
8771 .state(state_number)
8772 .ok_or(DirectAdaptiveParseControl::Fallback(
8773 DirectAdaptiveFallback::MissingAtn,
8774 ))?;
8775 if state.is_rule_stop() {
8776 return Err(DirectAdaptiveParseControl::Fallback(
8777 DirectAdaptiveFallback::RuleStop,
8778 ));
8779 }
8780 let transition_index =
8781 self.transition_index(state_number, state.transitions.len(), precedence)?;
8782 let transition = state.transitions.get(transition_index).cloned().ok_or(
8783 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
8784 )?;
8785 let boundary = match &transition {
8786 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
8787 left_recursive_boundary(self.atn, state, *target)
8788 }
8789 _ => None,
8790 };
8791 Ok((transition, boundary))
8792 }
8793
8794 fn transition_index(
8795 &mut self,
8796 state_number: usize,
8797 transition_count: usize,
8798 precedence: i32,
8799 ) -> DirectAdaptiveParseResult<usize> {
8800 match transition_count {
8801 0 => Err(DirectAdaptiveParseControl::Fallback(
8802 DirectAdaptiveFallback::NoTransition,
8803 )),
8804 1 => Ok(0),
8805 _ => {
8806 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
8807 return Ok(alt);
8808 }
8809 let decision = self
8810 .decision_by_state
8811 .get(state_number)
8812 .and_then(|decision| *decision)
8813 .ok_or(DirectAdaptiveParseControl::Fallback(
8814 DirectAdaptiveFallback::UnknownDecision,
8815 ))?;
8816 let prediction = self
8817 .simulator
8818 .adaptive_predict_stream_info_with_precedence(
8819 decision,
8820 direct_precedence(precedence),
8821 &mut self.parser.input,
8822 )
8823 .map_err(|_| {
8824 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
8825 })?;
8826 if prediction.has_semantic_context {
8827 return Err(DirectAdaptiveParseControl::Fallback(
8828 DirectAdaptiveFallback::SemanticContext,
8829 ));
8830 }
8831 prediction
8832 .alt
8833 .checked_sub(1)
8834 .filter(|index| *index < transition_count)
8835 .ok_or(DirectAdaptiveParseControl::Fallback(
8836 DirectAdaptiveFallback::InvalidAlt,
8837 ))
8838 }
8839 }
8840 }
8841
8842 fn ll1_transition_index(
8843 &mut self,
8844 state_number: usize,
8845 transition_count: usize,
8846 ) -> DirectAdaptiveParseResult<Option<usize>> {
8847 let state = self
8848 .atn
8849 .state(state_number)
8850 .ok_or(DirectAdaptiveParseControl::Fallback(
8851 DirectAdaptiveFallback::MissingAtn,
8852 ))?;
8853 if state.precedence_rule_decision {
8854 return Ok(None);
8855 }
8856 let Some(rule_stop) = state
8857 .rule_index
8858 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index).copied())
8859 else {
8860 return Ok(None);
8861 };
8862 let symbol = self.parser.input.la_token(1);
8863 let entry = self
8864 .parser
8865 .cached_decision_lookahead(self.atn, state, rule_stop);
8866 Ok(ll1_greedy_alt(&entry, symbol, state.non_greedy).filter(|alt| *alt < transition_count))
8867 }
8868
8869 fn consume_transition(
8870 &mut self,
8871 transition: &Transition,
8872 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
8873 let symbol = self.parser.input.la_token(1);
8874 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
8875 return Err(DirectAdaptiveParseControl::Fallback(
8876 DirectAdaptiveFallback::TokenMismatch,
8877 ));
8878 }
8879 let token = self
8880 .parser
8881 .input
8882 .lt_ref(1)
8883 .ok_or(DirectAdaptiveParseControl::Fallback(
8884 DirectAdaptiveFallback::TokenMismatch,
8885 ))?;
8886 let matched_eof = symbol == TOKEN_EOF;
8887 if !matched_eof {
8888 self.parser.consume();
8889 }
8890 let child = self
8891 .parser
8892 .build_parse_trees
8893 .then(|| ParseTree::Terminal(TerminalNode::from_ref(token)));
8894 Ok((matched_eof, child))
8895 }
8896}
8897
8898fn left_recursive_boundary(atn: &Atn, state: &AtnState, target: usize) -> Option<usize> {
8901 if !state.precedence_rule_decision {
8902 return None;
8903 }
8904 let target_state = atn.state(target)?;
8905 if target_state.kind == AtnStateKind::LoopEnd {
8906 return None;
8907 }
8908 state.rule_index
8909}
8910
8911const fn next_alt_number(
8918 state: &AtnState,
8919 transition_index: usize,
8920 current_alt_number: usize,
8921 track_alt_numbers: bool,
8922) -> usize {
8923 if !track_alt_numbers || current_alt_number != 0 || state.transitions.len() <= 1 {
8924 return current_alt_number;
8925 }
8926 if matches!(
8927 state.kind,
8928 AtnStateKind::Basic
8929 | AtnStateKind::BlockStart
8930 | AtnStateKind::PlusBlockStart
8931 | AtnStateKind::StarBlockStart
8932 | AtnStateKind::StarLoopEntry
8933 ) && !state.precedence_rule_decision
8934 {
8935 return transition_index + 1;
8936 }
8937 current_alt_number
8938}
8939
8940fn fold_left_recursive_boundaries(nodes: Vec<RecognizedNode>) -> Vec<RecognizedNode> {
8943 let mut folded = Vec::new();
8944 for node in nodes {
8945 match node {
8946 RecognizedNode::LeftRecursiveBoundary { rule_index } => {
8947 if !folded.is_empty() {
8948 let children = std::mem::take(&mut folded);
8949 let start_index = recognized_nodes_start_index(&children).unwrap_or_default();
8950 let stop_index = recognized_nodes_stop_index(&children);
8951 folded.push(RecognizedNode::Rule {
8952 rule_index,
8953 invoking_state: -1,
8954 alt_number: 0,
8955 start_index,
8956 stop_index,
8957 return_values: BTreeMap::new(),
8958 children,
8959 });
8960 }
8961 }
8962 node => folded.push(node),
8963 }
8964 }
8965 folded
8966}
8967
8968fn fold_fast_left_recursive_boundaries(
8970 nodes: Vec<Rc<FastRecognizedNode>>,
8971) -> Vec<Rc<FastRecognizedNode>> {
8972 if !nodes.iter().any(|node| {
8977 matches!(
8978 node.as_ref(),
8979 FastRecognizedNode::LeftRecursiveBoundary { .. }
8980 )
8981 }) {
8982 return nodes;
8983 }
8984 let mut folded: Vec<Rc<FastRecognizedNode>> = Vec::with_capacity(nodes.len());
8985 for node in nodes {
8986 match node.as_ref() {
8987 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
8988 if !folded.is_empty() {
8989 let children = std::mem::take(&mut folded);
8990 let start_index =
8991 fast_recognized_nodes_start_index(&children).unwrap_or_default();
8992 let stop_index = fast_recognized_nodes_stop_index(&children);
8993 folded.push(Rc::new(FastRecognizedNode::Rule {
8994 rule_index: *rule_index,
8995 invoking_state: -1,
8996 start_index,
8997 stop_index,
8998 children: NodeList::from_vec(children),
8999 }));
9000 }
9001 }
9002 _ => folded.push(node),
9003 }
9004 }
9005 folded
9006}
9007
9008fn fast_node_has_left_recursive_boundary(node: &FastRecognizedNode) -> bool {
9009 match node {
9010 FastRecognizedNode::LeftRecursiveBoundary { .. } => true,
9011 FastRecognizedNode::Rule { children, .. } => children.has_left_recursive_boundary(),
9012 FastRecognizedNode::Token { .. }
9013 | FastRecognizedNode::ErrorToken { .. }
9014 | FastRecognizedNode::MissingToken { .. } => false,
9015 }
9016}
9017
9018fn fast_recognized_nodes_start_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
9019 nodes
9020 .iter()
9021 .find_map(|node| fast_recognized_node_start_index(node.as_ref()))
9022}
9023
9024const fn fast_recognized_node_start_index(node: &FastRecognizedNode) -> Option<usize> {
9025 match node {
9026 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
9027 Some(*index)
9028 }
9029 FastRecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
9030 FastRecognizedNode::Rule { start_index, .. } => Some(*start_index),
9031 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
9032 }
9033}
9034
9035const fn fast_recognized_node_span(node: &FastRecognizedNode) -> Option<(usize, Option<usize>)> {
9036 match node {
9037 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
9038 Some((*index, Some(*index)))
9039 }
9040 FastRecognizedNode::MissingToken { at_index, .. } => Some((*at_index, None)),
9041 FastRecognizedNode::Rule {
9042 start_index,
9043 stop_index,
9044 ..
9045 } => Some((*start_index, *stop_index)),
9046 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
9047 }
9048}
9049
9050fn fast_recognized_nodes_stop_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
9051 nodes
9052 .iter()
9053 .rev()
9054 .find_map(|node| fast_recognized_node_stop_index(node.as_ref()))
9055}
9056
9057const fn fast_recognized_node_stop_index(node: &FastRecognizedNode) -> Option<usize> {
9058 match node {
9059 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
9060 Some(*index)
9061 }
9062 FastRecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
9063 FastRecognizedNode::Rule { stop_index, .. } => *stop_index,
9064 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
9065 }
9066}
9067
9068fn recognized_nodes_start_index(nodes: &[RecognizedNode]) -> Option<usize> {
9069 nodes.iter().find_map(recognized_node_start_index)
9070}
9071
9072const fn recognized_node_start_index(node: &RecognizedNode) -> Option<usize> {
9073 match node {
9074 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
9075 RecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
9076 RecognizedNode::Rule { start_index, .. } => Some(*start_index),
9077 RecognizedNode::LeftRecursiveBoundary { .. } => None,
9078 }
9079}
9080
9081fn recognized_nodes_stop_index(nodes: &[RecognizedNode]) -> Option<usize> {
9082 nodes.iter().rev().find_map(recognized_node_stop_index)
9083}
9084
9085fn invoking_state_number(state_number: usize) -> isize {
9088 isize::try_from(state_number).unwrap_or(isize::MAX)
9089}
9090
9091fn direct_precedence(precedence: i32) -> usize {
9092 usize::try_from(precedence.max(0)).unwrap_or_default()
9093}
9094
9095const fn recognized_node_stop_index(node: &RecognizedNode) -> Option<usize> {
9096 match node {
9097 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
9098 RecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
9099 RecognizedNode::Rule { stop_index, .. } => *stop_index,
9100 RecognizedNode::LeftRecursiveBoundary { .. } => None,
9101 }
9102}
9103
9104fn token_input_display(token: &impl Token) -> String {
9105 format!("'{}'", token.text().unwrap_or("<EOF>"))
9106}
9107
9108fn display_input_text(text: &str) -> String {
9109 let mut out = String::new();
9110 for ch in text.chars() {
9111 match ch {
9112 '\n' => out.push_str("\\n"),
9113 '\r' => out.push_str("\\r"),
9114 '\t' => out.push_str("\\t"),
9115 other => out.push(other),
9116 }
9117 }
9118 out
9119}
9120
9121fn diagnostic_for_token(token: Option<&impl Token>, message: String) -> ParserDiagnostic {
9122 ParserDiagnostic {
9123 line: token.map(Token::line).unwrap_or_default(),
9124 column: token.map(Token::column).unwrap_or_default(),
9125 message,
9126 }
9127}
9128
9129#[allow(clippy::print_stderr)]
9131fn report_parser_diagnostics(diagnostics: &[ParserDiagnostic]) {
9132 for diagnostic in diagnostics {
9133 eprintln!(
9134 "line {}:{} {}",
9135 diagnostic.line, diagnostic.column, diagnostic.message
9136 );
9137 }
9138}
9139
9140#[allow(clippy::print_stderr)]
9143fn report_generated_diagnostics(
9144 parser_diagnostics: &[ParserDiagnostic],
9145 token_errors: &[TokenSourceError],
9146) {
9147 let mut token_iter = token_errors.iter().peekable();
9154 for diagnostic in parser_diagnostics {
9155 while let Some(error) = token_iter.peek() {
9156 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
9157 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9158 token_iter.next();
9159 } else {
9160 break;
9161 }
9162 }
9163 eprintln!(
9164 "line {}:{} {}",
9165 diagnostic.line, diagnostic.column, diagnostic.message
9166 );
9167 }
9168 for error in token_iter {
9169 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9170 }
9171}
9172
9173#[allow(clippy::print_stderr)]
9176fn report_token_source_errors(errors: &[TokenSourceError]) {
9177 for error in errors {
9178 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9179 }
9180}
9181
9182fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
9183 let items = symbols
9184 .iter()
9185 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
9186 .collect::<Vec<_>>();
9187 if let [single] = items.as_slice() {
9188 return single.clone();
9189 }
9190 format!("{{{}}}", items.join(", "))
9191}
9192
9193fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
9194 if symbol == TOKEN_EOF {
9195 return "<EOF>".to_owned();
9196 }
9197 vocabulary.display_name(symbol)
9198}
9199
9200fn is_caller_follow_boundary_text(text: &str) -> bool {
9201 text.chars().any(|ch| ch == ';' || ch == '\n')
9202 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
9203}
9204
9205fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
9206 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
9207}
9208
9209fn state_is_left_recursive_rule(atn: &Atn, state: &AtnState) -> bool {
9213 let Some(rule_index) = state.rule_index else {
9214 return false;
9215 };
9216 atn.rule_to_start_state()
9217 .get(rule_index)
9218 .and_then(|state_number| atn.state(*state_number))
9219 .is_some_and(|rule_start| rule_start.left_recursive_rule)
9220}
9221
9222fn select_better_top_outcome(
9229 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
9230 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
9231) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
9232 match (first, second) {
9233 (Ok(first), Ok(second)) => {
9234 if first.0.diagnostics.is_empty() {
9235 Ok(first)
9236 } else {
9237 Ok(second)
9238 }
9239 }
9240 (Ok(first), Err(_)) => Ok(first),
9241 (Err(_), Ok(second)) => Ok(second),
9242 (Err(_), Err(second_expected)) => Err(second_expected),
9243 }
9244}
9245
9246fn select_best_fast_outcome(
9252 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
9253 prediction_mode: PredictionMode,
9254 caller_follow: Option<&TokenBitSet>,
9255 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
9256) -> Option<FastRecognizeOutcome> {
9257 let mut best = None;
9258 let mut best_caller_follow = None;
9259 for outcome in outcomes {
9260 if matches!(
9261 prediction_mode,
9262 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9263 ) && outcome.diagnostics.is_empty()
9264 && let Some(follow) = caller_follow
9265 {
9266 let (token_type, is_boundary, _) = token_info_at(outcome.index);
9267 if is_boundary && follow.contains(token_type) {
9268 let replace =
9269 best_caller_follow
9270 .as_ref()
9271 .is_none_or(|existing: &FastRecognizeOutcome| {
9272 (outcome.index, outcome.consumed_eof)
9273 < (existing.index, existing.consumed_eof)
9274 });
9275 if replace {
9276 best_caller_follow = Some(outcome.clone());
9277 }
9278 }
9279 }
9280 let Some(existing) = best else {
9281 best = Some(outcome);
9282 continue;
9283 };
9284 let outcome_position = (outcome.index, outcome.consumed_eof);
9285 let best_position = (existing.index, existing.consumed_eof);
9286 let better = match prediction_mode {
9287 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
9288 outcome_position,
9289 &outcome.diagnostics,
9290 best_position,
9291 &existing.diagnostics,
9292 ),
9293 PredictionMode::Sll => outcome.index > existing.index,
9294 };
9295 best = Some(if better { outcome } else { existing });
9296 }
9297 let should_use_caller_follow =
9298 best_caller_follow
9299 .as_ref()
9300 .zip(best.as_ref())
9301 .is_some_and(|(candidate, selected)| {
9302 if !selected.diagnostics.is_empty() {
9303 return true;
9304 }
9305 candidate.index < selected.index
9306 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
9307 });
9308 if should_use_caller_follow {
9309 best_caller_follow
9310 } else {
9311 best
9312 }
9313}
9314
9315fn select_best_outcome(
9316 outcomes: impl Iterator<Item = RecognizeOutcome>,
9317 prediction_mode: PredictionMode,
9318) -> Option<RecognizeOutcome> {
9319 let outcomes = outcomes.collect::<Vec<_>>();
9320 let prefer_first_tie = outcomes
9321 .iter()
9322 .any(|outcome| nodes_need_stable_tie(&outcome.nodes));
9323 outcomes.into_iter().reduce(|best, outcome| {
9324 let outcome_position = (outcome.index, outcome.consumed_eof);
9325 let best_position = (best.index, best.consumed_eof);
9326 let better = match prediction_mode {
9327 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
9328 outcome_is_better(
9329 outcome_position,
9330 &outcome.diagnostics,
9331 best_position,
9332 &best.diagnostics,
9333 ) || (!prefer_first_tie
9334 && outcome_position == best_position
9335 && outcome.diagnostics.len() == best.diagnostics.len()
9336 && diagnostic_recovery_rank(&outcome.diagnostics)
9337 == diagnostic_recovery_rank(&best.diagnostics)
9338 && (outcome.decisions < best.decisions
9339 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
9340 }
9341 PredictionMode::Sll => {
9342 outcome_position > best_position
9343 || (outcome_position == best_position
9344 && !prefer_first_tie
9345 && (outcome.decisions < best.decisions
9346 || (outcome.decisions == best.decisions
9347 && outcome_is_better(
9348 outcome_position,
9349 &outcome.diagnostics,
9350 best_position,
9351 &best.diagnostics,
9352 ))))
9353 }
9354 };
9355 if better {
9356 return outcome;
9357 }
9358 best
9359 })
9360}
9361
9362fn transition_decision(
9369 atn: &Atn,
9370 state: &AtnState,
9371 transition_index: usize,
9372 predicates: &[(usize, usize, ParserPredicate)],
9373) -> Option<usize> {
9374 if state.transitions.len() <= 1
9375 || state.precedence_rule_decision
9376 || decision_reaches_unsupported_predicate(atn, state, predicates)
9377 {
9378 return None;
9379 }
9380 Some(transition_index)
9381}
9382
9383const fn starts_prediction_decision(state: &AtnState) -> bool {
9389 state.transitions.len() > 1
9390 && !matches!(
9391 state.kind,
9392 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
9393 )
9394}
9395
9396fn record_no_viable_if_ambiguous(
9399 expected: &mut ExpectedTokens,
9400 decision_start_index: Option<usize>,
9401 index: usize,
9402) {
9403 if expected.index == Some(index) && expected.symbols.len() > 1 {
9404 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
9405 expected.record_no_viable(decision_start, index);
9406 }
9407 }
9408}
9409
9410const fn record_predicate_no_viable(
9413 expected: &mut ExpectedTokens,
9414 decision_start_index: Option<usize>,
9415 index: usize,
9416) {
9417 if let Some(decision_start) = decision_start_index {
9418 expected.record_no_viable(decision_start, index);
9419 }
9420}
9421
9422const fn no_viable_decision_start(
9424 decision_start_index: Option<usize>,
9425 index: usize,
9426) -> Option<usize> {
9427 match decision_start_index {
9428 Some(start) if index > start => Some(start),
9429 _ => None,
9430 }
9431}
9432
9433fn restore_expected(
9437 children: &[RecognizeOutcome],
9438 child_start_index: usize,
9439 expected: &mut ExpectedTokens,
9440 snapshot: ExpectedTokens,
9441 preserve_child_expected: bool,
9442) {
9443 if preserve_child_expected {
9444 return;
9445 }
9446 if children
9447 .iter()
9448 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
9449 {
9450 *expected = snapshot;
9451 }
9452}
9453
9454fn decision_reaches_unsupported_predicate(
9457 atn: &Atn,
9458 state: &AtnState,
9459 predicates: &[(usize, usize, ParserPredicate)],
9460) -> bool {
9461 state.transitions.iter().any(|transition| {
9462 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
9463 })
9464}
9465
9466fn transition_reaches_unsupported_predicate(
9468 atn: &Atn,
9469 transition: &Transition,
9470 predicates: &[(usize, usize, ParserPredicate)],
9471 visited: &mut BTreeSet<usize>,
9472) -> bool {
9473 match transition {
9474 Transition::Predicate {
9475 rule_index,
9476 pred_index,
9477 ..
9478 } => !predicates
9479 .iter()
9480 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
9481 Transition::Epsilon { target }
9482 | Transition::Action { target, .. }
9483 | Transition::Rule { target, .. } => {
9484 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
9485 }
9486 Transition::Precedence { .. }
9487 | Transition::Atom { .. }
9488 | Transition::Range { .. }
9489 | Transition::Set { .. }
9490 | Transition::NotSet { .. }
9491 | Transition::Wildcard { .. } => false,
9492 }
9493}
9494
9495fn state_reaches_unsupported_predicate(
9497 atn: &Atn,
9498 state_number: usize,
9499 predicates: &[(usize, usize, ParserPredicate)],
9500 visited: &mut BTreeSet<usize>,
9501) -> bool {
9502 if !visited.insert(state_number) {
9503 return false;
9504 }
9505 let Some(state) = atn.state(state_number) else {
9506 return false;
9507 };
9508 state.transitions.iter().any(|transition| {
9509 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
9510 })
9511}
9512
9513fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
9515 if let Some(decision) = decision {
9516 outcome.decisions.insert(0, decision);
9517 }
9518}
9519
9520fn outcome_is_better(
9521 outcome_position: (usize, bool),
9522 outcome_diagnostics: &[ParserDiagnostic],
9523 best_position: (usize, bool),
9524 best_diagnostics: &[ParserDiagnostic],
9525) -> bool {
9526 outcome_position > best_position
9527 || (outcome_position == best_position
9528 && (outcome_diagnostics.len() < best_diagnostics.len()
9529 || (outcome_diagnostics.len() == best_diagnostics.len()
9530 && diagnostic_recovery_rank(outcome_diagnostics)
9531 < diagnostic_recovery_rank(best_diagnostics))))
9532}
9533
9534fn diagnostic_recovery_rank(diagnostics: &[ParserDiagnostic]) -> usize {
9537 diagnostics
9538 .iter()
9539 .filter(|diagnostic| {
9540 diagnostic.message.starts_with("mismatched input ")
9541 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
9542 })
9543 .count()
9544}
9545
9546fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
9547 if outcomes
9548 .iter()
9549 .any(|outcome| outcome.diagnostics.is_empty())
9550 {
9551 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
9552 }
9553}
9554
9555fn discard_recovered_outcomes_if_clean_path_exists(outcomes: &mut Vec<RecognizeOutcome>) {
9556 if outcomes.iter().any(outcome_has_rule_failure_diagnostic) {
9557 return;
9558 }
9559 if outcomes
9560 .iter()
9561 .any(|outcome| outcome.diagnostics.is_empty())
9562 {
9563 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
9564 }
9565}
9566
9567fn outcome_has_rule_failure_diagnostic(outcome: &RecognizeOutcome) -> bool {
9570 outcome
9571 .diagnostics
9572 .iter()
9573 .any(|diagnostic| diagnostic.message.starts_with("rule "))
9574}
9575
9576fn nodes_need_stable_tie(nodes: &[RecognizedNode]) -> bool {
9579 nodes.iter().any(node_needs_stable_tie)
9580}
9581
9582fn node_needs_stable_tie(node: &RecognizedNode) -> bool {
9583 match node {
9584 RecognizedNode::Token { .. }
9585 | RecognizedNode::ErrorToken { .. }
9586 | RecognizedNode::MissingToken { .. } => false,
9587 RecognizedNode::LeftRecursiveBoundary { .. } => true,
9588 RecognizedNode::Rule {
9589 rule_index,
9590 children,
9591 ..
9592 } => children.iter().any(|child| {
9593 matches!(
9594 child,
9595 RecognizedNode::Rule {
9596 rule_index: child_rule,
9597 ..
9598 } if child_rule == rule_index
9599 ) || node_needs_stable_tie(child)
9600 }),
9601 }
9602}
9603
9604fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
9618 if outcomes.len() < 2 {
9619 return;
9620 }
9621 let mut keep = Vec::with_capacity(outcomes.len());
9622 let mut seen: BTreeMap<(usize, bool), Vec<usize>> = BTreeMap::new();
9623 'outcomes: for (index, outcome) in outcomes.iter().enumerate() {
9624 let bucket = seen
9625 .entry((outcome.index, outcome.consumed_eof))
9626 .or_default();
9627 for &previous in bucket.iter() {
9628 if outcomes[previous].diagnostics == outcome.diagnostics {
9629 continue 'outcomes;
9630 }
9631 }
9632 bucket.push(index);
9633 keep.push(index);
9634 }
9635 if keep.len() == outcomes.len() {
9636 return;
9637 }
9638 let mut iter = keep.into_iter();
9639 let mut next_keep = iter.next();
9640 let mut current = 0_usize;
9641 outcomes.retain(|_| {
9642 let result = next_keep == Some(current);
9643 if result {
9644 next_keep = iter.next();
9645 }
9646 current += 1;
9647 result
9648 });
9649}
9650
9651fn dedupe_clean_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
9652 if outcomes.len() < 2 {
9653 return;
9654 }
9655 let mut inline_keys: [(usize, bool); 8] = [(0, false); 8];
9665 let mut inline_len = 0_usize;
9666 let mut overflow: Vec<(usize, bool)> = Vec::new();
9667 outcomes.retain(|outcome| {
9668 let key = (outcome.index, outcome.consumed_eof);
9669 for &existing in &inline_keys[..inline_len] {
9670 if existing == key {
9671 return false;
9672 }
9673 }
9674 if !overflow.is_empty() {
9675 for &existing in &overflow {
9676 if existing == key {
9677 return false;
9678 }
9679 }
9680 }
9681 if inline_len < inline_keys.len() {
9682 inline_keys[inline_len] = key;
9683 inline_len += 1;
9684 } else {
9685 overflow.push(key);
9686 }
9687 true
9688 });
9689}
9690
9691fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>) {
9693 outcomes.sort_unstable();
9694 outcomes.dedup();
9695}
9696
9697impl<S, H> Recognizer for BaseParser<S, H>
9698where
9699 S: TokenSource,
9700 H: SemanticHooks,
9701{
9702 fn data(&self) -> &RecognizerData {
9703 &self.data
9704 }
9705
9706 fn data_mut(&mut self) -> &mut RecognizerData {
9707 &mut self.data
9708 }
9709}
9710
9711impl<S, H> Parser for BaseParser<S, H>
9712where
9713 S: TokenSource,
9714 H: SemanticHooks,
9715{
9716 fn build_parse_trees(&self) -> bool {
9717 self.build_parse_trees
9718 }
9719
9720 fn set_build_parse_trees(&mut self, build: bool) {
9721 self.build_parse_trees = build;
9722 }
9723
9724 fn number_of_syntax_errors(&self) -> usize {
9725 Self::number_of_syntax_errors(self)
9726 }
9727
9728 fn report_diagnostic_errors(&self) -> bool {
9729 self.report_diagnostic_errors
9730 }
9731
9732 fn set_report_diagnostic_errors(&mut self, report: bool) {
9733 self.report_diagnostic_errors = report;
9734 }
9735
9736 fn prediction_mode(&self) -> PredictionMode {
9737 self.prediction_mode
9738 }
9739
9740 fn set_prediction_mode(&mut self, mode: PredictionMode) {
9741 self.prediction_mode = mode;
9742 }
9743}
9744
9745#[cfg(test)]
9746mod tests {
9747 use super::*;
9748 use crate::atn::AtnType;
9749 use crate::atn::IntervalSet;
9750 use crate::atn::parser::{
9751 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
9752 };
9753 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
9754 use crate::token::{CommonToken, HIDDEN_CHANNEL, Token};
9755 use crate::token_stream::CommonTokenStream;
9756 use crate::vocabulary::Vocabulary;
9757
9758 #[test]
9759 fn fx_hasher_write_matches_typed_methods_for_full_words() {
9760 let value: u64 = 0x0102_0304_0506_0708;
9767 let mut typed = FxHasher::default();
9768 typed.write_u64(value);
9769 let mut bytewise = FxHasher::default();
9770 bytewise.write(&value.to_le_bytes());
9771 assert_eq!(typed.finish(), bytewise.finish());
9772 }
9773
9774 #[derive(Debug)]
9775 struct Source {
9776 tokens: Vec<CommonToken>,
9777 index: usize,
9778 }
9779
9780 impl TokenSource for Source {
9781 fn next_token(&mut self) -> CommonToken {
9782 let token = self
9783 .tokens
9784 .get(self.index)
9785 .cloned()
9786 .unwrap_or_else(|| CommonToken::eof("parser-test", self.index, 1, self.index));
9787 self.index += 1;
9788 token
9789 }
9790
9791 fn line(&self) -> usize {
9792 1
9793 }
9794
9795 fn column(&self) -> usize {
9796 self.index
9797 }
9798
9799 fn source_name(&self) -> &'static str {
9800 "parser-test"
9801 }
9802 }
9803
9804 fn mini_parser_data() -> RecognizerData {
9805 RecognizerData::new(
9806 "Mini.g4",
9807 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
9808 )
9809 .with_rule_names(["s"])
9810 }
9811
9812 fn mini_parser(tokens: Vec<CommonToken>) -> BaseParser<Source> {
9813 let data = mini_parser_data();
9814 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
9815 }
9816
9817 fn mini_parser_with_hooks<H>(tokens: Vec<CommonToken>, hooks: H) -> BaseParser<Source, H>
9818 where
9819 H: SemanticHooks,
9820 {
9821 BaseParser::with_semantic_hooks(
9822 CommonTokenStream::new(Source { tokens, index: 0 }),
9823 mini_parser_data(),
9824 hooks,
9825 )
9826 }
9827
9828 fn token_then_eof_atn() -> Atn {
9829 AtnDeserializer::new(&SerializedAtn::from_i32(&[
9830 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, ]))
9846 .deserialize()
9847 .expect("artificial parser ATN should deserialize")
9848 }
9849
9850 fn eof_then_action_atn() -> Atn {
9851 AtnDeserializer::new(&SerializedAtn::from_i32(&[
9852 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, ]))
9868 .deserialize()
9869 .expect("artificial parser ATN should deserialize")
9870 }
9871
9872 fn noop_action_then_token_then_eof_atn() -> Atn {
9873 AtnDeserializer::new(&SerializedAtn::from_i32(&[
9874 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, ]))
9892 .deserialize()
9893 .expect("artificial no-op action ATN should deserialize")
9894 }
9895
9896 fn two_alt_decision_atn() -> Atn {
9897 let mut atn = Atn::new(AtnType::Parser, 2);
9898 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9899 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
9900 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
9901 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
9902 atn.add_state(AtnState::new(4, AtnStateKind::BlockEnd).with_rule_index(0));
9903 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
9904 atn.set_rule_to_start_state(vec![0]);
9905 atn.set_rule_to_stop_state(vec![5]);
9906 atn.add_decision_state(1);
9907 atn.state_mut(0)
9908 .expect("state 0")
9909 .add_transition(Transition::Epsilon { target: 1 });
9910 atn.state_mut(1)
9911 .expect("state 1")
9912 .add_transition(Transition::Atom {
9913 target: 2,
9914 label: 1,
9915 });
9916 atn.state_mut(1)
9917 .expect("state 1")
9918 .add_transition(Transition::Atom {
9919 target: 3,
9920 label: 2,
9921 });
9922 atn.state_mut(2)
9923 .expect("state 2")
9924 .add_transition(Transition::Epsilon { target: 4 });
9925 atn.state_mut(3)
9926 .expect("state 3")
9927 .add_transition(Transition::Epsilon { target: 4 });
9928 atn.state_mut(4)
9929 .expect("state 4")
9930 .add_transition(Transition::Epsilon { target: 5 });
9931 atn
9932 }
9933
9934 fn optional_then_b_eof_atn() -> Atn {
9937 let mut atn = Atn::new(AtnType::Parser, 3);
9938 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9939 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
9940 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
9941 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
9942 atn.add_state(AtnState::new(4, AtnStateKind::Basic).with_rule_index(0));
9943 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
9944 atn.set_rule_to_start_state(vec![0]);
9945 atn.set_rule_to_stop_state(vec![5]);
9946 atn.add_decision_state(1);
9947 atn.state_mut(0)
9948 .expect("state 0")
9949 .add_transition(Transition::Epsilon { target: 1 });
9950 atn.state_mut(1)
9952 .expect("state 1")
9953 .add_transition(Transition::Atom {
9954 target: 3,
9955 label: 1,
9956 });
9957 atn.state_mut(1)
9958 .expect("state 1")
9959 .add_transition(Transition::Epsilon { target: 3 });
9960 atn.state_mut(3)
9962 .expect("state 3")
9963 .add_transition(Transition::Atom {
9964 target: 4,
9965 label: 2,
9966 });
9967 atn.state_mut(4)
9968 .expect("state 4")
9969 .add_transition(Transition::Atom {
9970 target: 5,
9971 label: TOKEN_EOF,
9972 });
9973 atn
9974 }
9975
9976 #[test]
9977 fn sync_decision_deletes_only_a_single_token() {
9978 let atn = optional_then_b_eof_atn();
9986
9987 let mut single = mini_parser(vec![
9988 CommonToken::new(3).with_text("c"),
9989 CommonToken::new(2).with_text("b"),
9990 CommonToken::eof("parser-test", 1, 2, 2),
9991 ]);
9992 single.rule_context_stack = vec![RuleContextFrame {
9993 rule_index: 0,
9994 invoking_state: 0,
9995 }];
9996 let children = single
9997 .sync_decision(&atn, 1, true, false)
9998 .expect("single extraneous token recovers");
9999 assert_eq!(children.len(), 1);
10000 assert!(matches!(children[0], ParseTree::Error(_)));
10001 assert_eq!(single.number_of_syntax_errors(), 1);
10002 assert_eq!(single.la(1), 2);
10004
10005 let mut double = mini_parser(vec![
10006 CommonToken::new(3).with_text("c"),
10007 CommonToken::new(3).with_text("c"),
10008 CommonToken::new(2).with_text("b"),
10009 CommonToken::eof("parser-test", 1, 3, 3),
10010 ]);
10011 double.rule_context_stack = vec![RuleContextFrame {
10012 rule_index: 0,
10013 invoking_state: 0,
10014 }];
10015 let result = double.sync_decision(&atn, 1, true, false);
10016 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
10021 match error {
10022 AntlrError::ParserError { message, .. } => {
10023 assert!(message.starts_with("mismatched input"), "got: {message}");
10024 }
10025 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
10026 }
10027 assert_eq!(double.la(1), 3);
10028 }
10029
10030 fn star_loop_then_eof_atn() -> Atn {
10034 AtnDeserializer::new(&SerializedAtn::from_i32(&[
10035 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,
10036 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,
10037 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,
10038 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
10039 ]))
10040 .deserialize()
10041 .expect("star-loop-then-EOF ATN should deserialize")
10042 }
10043
10044 fn plus_loop_with_recovering_body_atn() -> Atn {
10050 let mut atn = Atn::new(AtnType::Parser, 2);
10051 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10052 let mut loop_start = AtnState::new(1, AtnStateKind::PlusBlockStart).with_rule_index(0);
10053 loop_start.end_state = Some(3);
10054 atn.add_state(loop_start);
10055 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10056 atn.add_state(AtnState::new(3, AtnStateKind::BlockEnd).with_rule_index(0));
10057 atn.add_state(AtnState::new(4, AtnStateKind::PlusLoopBack).with_rule_index(0));
10058 let mut loop_end = AtnState::new(5, AtnStateKind::LoopEnd).with_rule_index(0);
10059 loop_end.loop_back_state = Some(4);
10060 atn.add_state(loop_end);
10061 atn.add_state(AtnState::new(6, AtnStateKind::RuleStop).with_rule_index(0));
10062 atn.add_state(AtnState::new(7, AtnStateKind::RuleStart).with_rule_index(1));
10063 atn.add_state(AtnState::new(8, AtnStateKind::Basic).with_rule_index(1));
10064 atn.add_state(AtnState::new(9, AtnStateKind::RuleStop).with_rule_index(1));
10065 atn.set_rule_to_start_state(vec![0, 7]);
10066 atn.set_rule_to_stop_state(vec![6, 9]);
10067 atn.state_mut(0)
10068 .expect("state 0")
10069 .add_transition(Transition::Epsilon { target: 1 });
10070 atn.state_mut(1)
10071 .expect("state 1")
10072 .add_transition(Transition::Epsilon { target: 2 });
10073 atn.state_mut(2)
10074 .expect("state 2")
10075 .add_transition(Transition::Rule {
10076 target: 7,
10077 rule_index: 1,
10078 follow_state: 3,
10079 precedence: 0,
10080 });
10081 atn.state_mut(3)
10082 .expect("state 3")
10083 .add_transition(Transition::Epsilon { target: 4 });
10084 atn.state_mut(4)
10085 .expect("state 4")
10086 .add_transition(Transition::Epsilon { target: 1 });
10087 atn.state_mut(4)
10088 .expect("state 4")
10089 .add_transition(Transition::Epsilon { target: 5 });
10090 atn.state_mut(5)
10091 .expect("state 5")
10092 .add_transition(Transition::Atom {
10093 target: 6,
10094 label: 2,
10095 });
10096 atn.state_mut(7)
10097 .expect("state 7")
10098 .add_transition(Transition::Atom {
10099 target: 8,
10100 label: 1,
10101 });
10102 atn.state_mut(8)
10103 .expect("state 8")
10104 .add_transition(Transition::Epsilon { target: 9 });
10105 atn
10106 }
10107
10108 #[test]
10109 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
10110 let atn = plus_loop_with_recovering_body_atn();
10111 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10112
10113 let error = parser
10114 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
10115 .expect_err("EOF recovery should report a bounded mismatch");
10116
10117 let AntlrError::ParserError { message, .. } = error else {
10118 panic!("expected ParserError, got {error:?}");
10119 };
10120 assert_eq!(message, "mismatched input '<EOF>' expecting {'x', 2}");
10121 assert_eq!(parser.number_of_syntax_errors(), 1);
10122 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
10123 }
10124
10125 #[test]
10126 fn sync_decision_deletes_token_before_eof_at_loop_back() {
10127 let atn = star_loop_then_eof_atn();
10133 let mut parser = mini_parser(vec![
10134 CommonToken::new(2).with_text("c"),
10135 CommonToken::eof("parser-test", 1, 1, 1),
10136 ]);
10137 parser.rule_context_stack = vec![RuleContextFrame {
10138 rule_index: 0,
10139 invoking_state: 0,
10140 }];
10141 let children = parser
10142 .sync_decision(&atn, 5, true, false)
10143 .expect("single token before EOF recovers");
10144 assert_eq!(children.len(), 1);
10145 assert!(matches!(children[0], ParseTree::Error(_)));
10146 assert_eq!(parser.number_of_syntax_errors(), 1);
10147 assert_eq!(
10148 parser.la(1),
10149 TOKEN_EOF,
10150 "EOF is left for the rule's EOF match"
10151 );
10152 }
10153
10154 #[test]
10155 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
10156 let atn = star_loop_then_eof_atn();
10161 let mut parser = mini_parser(vec![
10162 CommonToken::new(2).with_text("c"),
10163 CommonToken::new(2).with_text("c"),
10164 CommonToken::eof("parser-test", 1, 2, 2),
10165 ]);
10166 parser.rule_context_stack = vec![RuleContextFrame {
10167 rule_index: 0,
10168 invoking_state: 0,
10169 }];
10170 let error = parser
10171 .sync_decision(&atn, 5, true, false)
10172 .expect_err("two tokens at the loop entry must not be deleted");
10173 match error {
10174 AntlrError::ParserError { message, .. } => {
10175 assert!(message.starts_with("mismatched input"), "got: {message}");
10176 }
10177 other => panic!("expected mismatched-input ParserError, got {other:?}"),
10178 }
10179 assert_eq!(
10180 parser.la(1),
10181 2,
10182 "nothing consumed; cursor still on first `c`"
10183 );
10184 }
10185
10186 #[test]
10187 fn sync_decision_consumes_until_eof_at_loop_back() {
10188 let atn = star_loop_then_eof_atn();
10194 let mut parser = mini_parser(vec![
10195 CommonToken::new(2).with_text("c"),
10196 CommonToken::new(2).with_text("c"),
10197 CommonToken::eof("parser-test", 1, 2, 2),
10198 ]);
10199 parser.rule_context_stack = vec![RuleContextFrame {
10200 rule_index: 0,
10201 invoking_state: 0,
10202 }];
10203 let children = parser
10204 .sync_decision(&atn, 5, false, true)
10205 .expect("loop-back multi-token deletion recovers onto EOF");
10206 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
10207 assert!(children.iter().all(|c| matches!(c, ParseTree::Error(_))));
10208 assert_eq!(parser.number_of_syntax_errors(), 1);
10209 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
10210 }
10211
10212 fn predicate_after_token_atn() -> Atn {
10213 let mut atn = Atn::new(AtnType::Parser, 2);
10214 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10215 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
10216 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10217 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
10218 atn.add_state(AtnState::new(4, AtnStateKind::RuleStop).with_rule_index(0));
10219 atn.set_rule_to_start_state(vec![0]);
10220 atn.set_rule_to_stop_state(vec![4]);
10221 atn.state_mut(0)
10222 .expect("state 0")
10223 .add_transition(Transition::Atom {
10224 target: 1,
10225 label: 1,
10226 });
10227 atn.state_mut(1)
10228 .expect("state 1")
10229 .add_transition(Transition::Predicate {
10230 target: 2,
10231 rule_index: 0,
10232 pred_index: 0,
10233 context_dependent: false,
10234 });
10235 atn.state_mut(2)
10236 .expect("state 2")
10237 .add_transition(Transition::Atom {
10238 target: 3,
10239 label: 2,
10240 });
10241 atn.state_mut(3)
10242 .expect("state 3")
10243 .add_transition(Transition::Epsilon { target: 4 });
10244 atn
10245 }
10246
10247 fn nested_nullable_context_atn() -> Atn {
10248 let mut atn = Atn::new(AtnType::Parser, 1);
10249 for state_number in 0..=20 {
10250 let kind = match state_number {
10251 0 | 10 | 16 => AtnStateKind::RuleStart,
10252 9 | 15 | 20 => AtnStateKind::RuleStop,
10253 _ => AtnStateKind::Basic,
10254 };
10255 let rule_index = match state_number {
10256 0..=9 => 0,
10257 10..=15 => 1,
10258 _ => 2,
10259 };
10260 atn.add_state(AtnState::new(state_number, kind).with_rule_index(rule_index));
10261 }
10262 atn.set_rule_to_start_state(vec![0, 10, 16]);
10263 atn.set_rule_to_stop_state(vec![9, 15, 20]);
10264 atn.state_mut(1)
10265 .expect("state 1")
10266 .add_transition(Transition::Rule {
10267 target: 10,
10268 rule_index: 1,
10269 follow_state: 8,
10270 precedence: 0,
10271 });
10272 atn.state_mut(8)
10273 .expect("state 8")
10274 .add_transition(Transition::Atom {
10275 target: 9,
10276 label: 1,
10277 });
10278 atn.state_mut(8)
10279 .expect("state 8")
10280 .add_transition(Transition::Epsilon { target: 9 });
10281 atn.state_mut(2)
10282 .expect("state 2")
10283 .add_transition(Transition::Rule {
10284 target: 16,
10285 rule_index: 2,
10286 follow_state: 14,
10287 precedence: 0,
10288 });
10289 atn.state_mut(14)
10290 .expect("state 14")
10291 .add_transition(Transition::Epsilon { target: 15 });
10292 atn
10293 }
10294
10295 fn generated_match_recovery_atn() -> Atn {
10296 let mut atn = Atn::new(AtnType::Parser, 2);
10297 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10298 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
10299 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10300 atn.add_state(AtnState::new(3, AtnStateKind::RuleStop).with_rule_index(0));
10301 atn.add_state(AtnState::new(4, AtnStateKind::RuleStart).with_rule_index(1));
10302 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(1));
10303 atn.set_rule_to_start_state(vec![0, 4]);
10304 atn.set_rule_to_stop_state(vec![3, 5]);
10305 atn.state_mut(1)
10306 .expect("state 1")
10307 .add_transition(Transition::Rule {
10308 target: 4,
10309 rule_index: 1,
10310 follow_state: 2,
10311 precedence: 0,
10312 });
10313 atn.state_mut(2)
10314 .expect("state 2")
10315 .add_transition(Transition::Atom {
10316 target: 3,
10317 label: TOKEN_EOF,
10318 });
10319 atn
10320 }
10321
10322 fn complement_set_atn() -> Atn {
10323 let mut atn = Atn::new(AtnType::Parser, 1);
10324 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10325 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
10326 atn.set_rule_to_start_state(vec![0]);
10327 atn.set_rule_to_stop_state(vec![1]);
10328 let mut excluded = IntervalSet::new();
10329 excluded.add(1);
10330 atn.state_mut(0)
10331 .expect("state 0")
10332 .add_transition(Transition::NotSet {
10333 target: 1,
10334 set: excluded,
10335 });
10336 atn
10337 }
10338
10339 fn wildcard_then_eof_atn() -> Atn {
10342 let mut atn = Atn::new(AtnType::Parser, 1);
10343 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10344 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
10345 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10346 atn.set_rule_to_start_state(vec![0]);
10347 atn.set_rule_to_stop_state(vec![1]);
10348 atn.state_mut(0)
10349 .expect("state 0")
10350 .add_transition(Transition::Wildcard { target: 2 });
10351 atn.state_mut(2)
10352 .expect("state 2")
10353 .add_transition(Transition::Atom {
10354 target: 1,
10355 label: TOKEN_EOF,
10356 });
10357 atn
10358 }
10359
10360 #[test]
10361 fn parser_matches_token_and_reports_mismatch() {
10362 let source = Source {
10363 tokens: vec![
10364 CommonToken::new(1).with_text("x"),
10365 CommonToken::eof("parser-test", 1, 1, 1),
10366 ],
10367 index: 0,
10368 };
10369 let data = RecognizerData::new(
10370 "Mini.g4",
10371 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10372 );
10373 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
10374 assert_eq!(
10375 parser.match_token(1).expect("token 1 should match").text(),
10376 "x"
10377 );
10378 assert!(parser.match_token(1).is_err());
10379 }
10380
10381 #[test]
10382 fn parser_matches_token_sets() {
10383 let mut parser = mini_parser(vec![
10384 CommonToken::new(1).with_text("x"),
10385 CommonToken::eof("parser-test", 1, 1, 1),
10386 ]);
10387
10388 assert_eq!(
10389 parser
10390 .match_set(&[(1, 1), (3, 4)])
10391 .expect("token set should match")
10392 .text(),
10393 "x"
10394 );
10395 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
10396 }
10397
10398 #[test]
10399 fn generated_rule_api_tracks_state_and_precedence() {
10400 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10401
10402 let context = parser.enter_rule(7, 2);
10403 assert_eq!(context.rule_index(), 2);
10404 assert_eq!(parser.state(), 7);
10405 assert_eq!(
10406 parser.rule_context_stack,
10407 vec![RuleContextFrame {
10408 rule_index: 2,
10409 invoking_state: 7
10410 }]
10411 );
10412
10413 let recursive = parser.enter_recursion_rule(11, 3, 4);
10414 assert_eq!(recursive.rule_index(), 3);
10415 assert!(parser.precpred(4));
10416 assert!(parser.precpred(5));
10417 assert!(!parser.precpred(3));
10418
10419 let next = parser.push_new_recursion_context(13, 3);
10420 assert_eq!(next.invoking_state(), 13);
10421 parser.unroll_recursion_context();
10422 assert_eq!(parser.precedence_stack, vec![0]);
10423 assert_eq!(
10424 parser.rule_context_stack,
10425 vec![RuleContextFrame {
10426 rule_index: 2,
10427 invoking_state: 7
10428 }]
10429 );
10430
10431 parser.exit_rule();
10432 assert!(parser.rule_context_stack.is_empty());
10433 }
10434
10435 #[test]
10436 fn parser_predicates_support_token_adjacency() {
10437 let mut parser = mini_parser(vec![
10438 CommonToken::new(1).with_text("=").with_span(0, 0),
10439 CommonToken::new(1).with_text(">").with_span(1, 1),
10440 CommonToken::eof("parser-test", 2, 1, 2),
10441 ]);
10442 parser.consume();
10443 parser.consume();
10444
10445 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
10446
10447 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
10448
10449 let mut parser = mini_parser(vec![
10450 CommonToken::new(1).with_text("=").with_span(0, 0),
10451 CommonToken::new(1)
10452 .with_text(" ")
10453 .with_channel(HIDDEN_CHANNEL)
10454 .with_span(1, 1),
10455 CommonToken::new(1).with_text(">").with_span(2, 2),
10456 CommonToken::eof("parser-test", 3, 1, 3),
10457 ]);
10458 parser.consume();
10459 parser.consume();
10460
10461 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
10462 }
10463
10464 #[test]
10465 fn parser_predicates_support_context_child_text_checks() {
10466 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10467 let mut context = ParserRuleContext::new(1, 0);
10468 let mut child_context = ParserRuleContext::new(2, 0);
10469 child_context.add_child(ParseTree::Terminal(TerminalNode::new(
10470 CommonToken::new(1).with_text("var"),
10471 )));
10472 context.add_child(ParseTree::Rule(RuleNode::new(child_context)));
10473 let predicates = [(
10474 1,
10475 0,
10476 ParserPredicate::ContextChildRuleTextNotEquals {
10477 rule_index: 2,
10478 text: "var",
10479 },
10480 )];
10481
10482 assert!(
10483 !parser.parser_semantic_predicate_matches_with_context_and_local(
10484 &predicates,
10485 1,
10486 0,
10487 &context,
10488 0,
10489 )
10490 );
10491 }
10492
10493 #[test]
10494 fn context_expected_symbols_walks_nullable_parent_contexts() {
10495 let atn = nested_nullable_context_atn();
10496 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10497 parser.rule_context_stack = vec![
10498 RuleContextFrame {
10499 rule_index: 0,
10500 invoking_state: 0,
10501 },
10502 RuleContextFrame {
10503 rule_index: 1,
10504 invoking_state: 1,
10505 },
10506 RuleContextFrame {
10507 rule_index: 2,
10508 invoking_state: 2,
10509 },
10510 ];
10511
10512 let expected = parser.context_expected_symbols(&atn);
10513
10514 assert!(expected.contains(&1));
10515 assert!(expected.contains(&TOKEN_EOF));
10516 }
10517
10518 #[test]
10519 fn prediction_context_reuses_cached_stack_until_rule_stack_changes() {
10520 let atn = nested_nullable_context_atn();
10521 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10522 parser.rule_context_stack = vec![
10523 RuleContextFrame {
10524 rule_index: 0,
10525 invoking_state: 0,
10526 },
10527 RuleContextFrame {
10528 rule_index: 1,
10529 invoking_state: 1,
10530 },
10531 RuleContextFrame {
10532 rule_index: 2,
10533 invoking_state: 2,
10534 },
10535 ];
10536
10537 let first = parser.prediction_context(&atn);
10538 let second = parser.prediction_context(&atn);
10539 assert!(Rc::ptr_eq(&first, &second));
10540
10541 parser.exit_rule();
10542 let after_pop = parser.prediction_context(&atn);
10543 assert!(!Rc::ptr_eq(&first, &after_pop));
10544 }
10545
10546 #[test]
10547 fn generated_match_token_recovers_missing_token_from_context_follow() {
10548 let atn = generated_match_recovery_atn();
10549 let data = RecognizerData::new(
10550 "Mini.g4",
10551 Vocabulary::new(
10552 [None, Some("'X'"), Some("'Y'")],
10553 [None, Some("X"), Some("Y")],
10554 [None::<&str>, None, None],
10555 ),
10556 );
10557 let mut parser = BaseParser::new(
10558 CommonTokenStream::new(Source {
10559 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
10560 index: 0,
10561 }),
10562 data,
10563 );
10564 parser.rule_context_stack = vec![
10565 RuleContextFrame {
10566 rule_index: 0,
10567 invoking_state: 0,
10568 },
10569 RuleContextFrame {
10570 rule_index: 1,
10571 invoking_state: 1,
10572 },
10573 ];
10574 assert_eq!(parser.number_of_syntax_errors(), 0);
10575
10576 let node = parser
10577 .match_token_recovering(2, 5, &atn)
10578 .expect("generated match should insert missing token");
10579
10580 assert_eq!(node.children().len(), 1);
10581 assert_eq!(node.children()[0].text(), "<missing 'Y'>");
10582 assert!(!node.consumed_eof());
10585 assert_eq!(parser.la(1), TOKEN_EOF);
10586 assert_eq!(parser.number_of_syntax_errors(), 1);
10587 assert_eq!(
10588 parser.generated_parser_diagnostics,
10589 [ParserDiagnostic {
10590 line: 1,
10591 column: 3,
10592 message: "missing 'Y' at '<EOF>'".to_owned(),
10593 }]
10594 );
10595 }
10596
10597 #[test]
10598 fn generated_match_token_counts_single_token_deletion_recovery() {
10599 let atn = generated_match_recovery_atn();
10600 let data = RecognizerData::new(
10601 "Mini.g4",
10602 Vocabulary::new(
10603 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
10604 [None, Some("X"), Some("Y"), Some("Z")],
10605 [None::<&str>, None, None, None],
10606 ),
10607 );
10608 let mut parser = BaseParser::new(
10609 CommonTokenStream::new(Source {
10610 tokens: vec![
10611 CommonToken::new(3).with_text("z"),
10612 CommonToken::new(2).with_text("y"),
10613 CommonToken::eof("parser-test", 3, 1, 3),
10614 ],
10615 index: 0,
10616 }),
10617 data,
10618 );
10619
10620 let node = parser
10621 .match_token_recovering(2, 5, &atn)
10622 .expect("generated match should delete the extraneous token");
10623
10624 assert_eq!(node.children().len(), 2);
10625 assert!(matches!(node.children()[0], ParseTree::Error(_)));
10626 assert_eq!(node.children()[0].text(), "z");
10627 assert_eq!(node.children()[1].text(), "y");
10628 assert_eq!(parser.number_of_syntax_errors(), 1);
10629 }
10630
10631 #[test]
10632 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
10633 let atn = generated_match_recovery_atn();
10634 let data = RecognizerData::new(
10635 "Mini.g4",
10636 Vocabulary::new(
10637 [None, Some("'X'"), Some("'Y'")],
10638 [None, Some("X"), Some("Y")],
10639 [None::<&str>, None, None],
10640 ),
10641 );
10642 let mut parser = BaseParser::new(
10643 CommonTokenStream::new(Source {
10644 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
10645 index: 0,
10646 }),
10647 data,
10648 );
10649 parser.rule_context_stack = vec![
10650 RuleContextFrame {
10651 rule_index: 0,
10652 invoking_state: 0,
10653 },
10654 RuleContextFrame {
10655 rule_index: 1,
10656 invoking_state: 1,
10657 },
10658 ];
10659 let marker = parser.generated_diagnostics_checkpoint();
10660
10661 let _ = parser
10662 .match_token_recovering(2, 5, &atn)
10663 .expect("generated match should insert missing token");
10664 assert_eq!(parser.number_of_syntax_errors(), 1);
10665
10666 parser.restore_generated_diagnostics(marker);
10667
10668 assert_eq!(parser.number_of_syntax_errors(), 0);
10669 assert!(parser.generated_parser_diagnostics.is_empty());
10670 }
10671
10672 #[test]
10673 fn generated_prediction_diagnostics_use_adaptive_context() {
10674 let atn = two_alt_decision_atn();
10675 let data = RecognizerData::new(
10676 "Mini.g4",
10677 Vocabulary::new(
10678 [None, Some("'x'"), Some("'y'")],
10679 [None, Some("X"), Some("Y")],
10680 [None::<&str>, None, None],
10681 ),
10682 )
10683 .with_rule_names(["s"]);
10684 let mut parser = BaseParser::new(
10685 CommonTokenStream::new(Source {
10686 tokens: vec![
10687 CommonToken::new(1)
10688 .with_text("x")
10689 .with_position(1, 0)
10690 .with_span(0, 0),
10691 CommonToken::new(2)
10692 .with_text("y")
10693 .with_position(1, 2)
10694 .with_span(1, 1),
10695 CommonToken::eof("parser-test", 2, 1, 3),
10696 ],
10697 index: 0,
10698 }),
10699 data,
10700 );
10701 parser.set_report_diagnostic_errors(true);
10702
10703 parser.record_generated_prediction_diagnostic(
10704 &atn,
10705 1,
10706 &ParserAtnPrediction {
10707 alt: 1,
10708 requires_full_context: true,
10709 has_semantic_context: false,
10710 diagnostic: Some(ParserAtnPredictionDiagnostic {
10711 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
10712 start_index: 0,
10713 sll_stop_index: 1,
10714 ll_stop_index: 0,
10715 conflicting_alts: vec![1, 2],
10716 exact: false,
10717 }),
10718 },
10719 );
10720 parser.record_generated_prediction_diagnostic(
10725 &atn,
10726 1,
10727 &ParserAtnPrediction {
10728 alt: 1,
10729 requires_full_context: true,
10730 has_semantic_context: false,
10731 diagnostic: Some(ParserAtnPredictionDiagnostic {
10732 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
10733 start_index: 0,
10734 sll_stop_index: 1,
10735 ll_stop_index: 1,
10736 conflicting_alts: vec![1, 2],
10737 exact: false,
10738 }),
10739 },
10740 );
10741
10742 assert_eq!(
10743 parser.generated_parser_diagnostics,
10744 [
10745 ParserDiagnostic {
10746 line: 1,
10747 column: 2,
10748 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
10749 },
10750 ParserDiagnostic {
10751 line: 1,
10752 column: 0,
10753 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
10754 },
10755 ParserDiagnostic {
10756 line: 1,
10757 column: 2,
10758 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
10759 },
10760 ]
10761 );
10762 }
10763
10764 #[test]
10765 fn generated_match_not_set_recovers_empty_complement_at_eof() {
10766 let atn = complement_set_atn();
10767 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10768 parser.rule_context_stack = vec![RuleContextFrame {
10769 rule_index: 0,
10770 invoking_state: 0,
10771 }];
10772
10773 let node = parser
10774 .match_not_set_recovering(&[(1, 1)], 1, 1, 1, &atn)
10775 .expect("empty complement should recover at EOF");
10776
10777 assert_eq!(node.children().len(), 1);
10778 assert!(!node.consumed_eof());
10781 assert_eq!(parser.la(1), TOKEN_EOF);
10782 assert_eq!(
10783 parser.generated_parser_diagnostics,
10784 [ParserDiagnostic {
10785 line: 1,
10786 column: 1,
10787 message: "missing {} at '<EOF>'".to_owned(),
10788 }]
10789 );
10790 }
10791
10792 #[test]
10793 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
10794 let atn = wildcard_then_eof_atn();
10800 let data = RecognizerData::new(
10801 "Mini.g4",
10802 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10803 );
10804 let mut parser = BaseParser::new(
10805 CommonTokenStream::new(Source {
10806 tokens: vec![CommonToken::eof("parser-test", 1, 1, 1)],
10807 index: 0,
10808 }),
10809 data,
10810 );
10811 parser.rule_context_stack = vec![RuleContextFrame {
10812 rule_index: 0,
10813 invoking_state: 0,
10814 }];
10815
10816 let node = parser
10817 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
10818 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
10819
10820 assert_eq!(node.children().len(), 1);
10822 assert!(!node.consumed_eof());
10823 assert!(node.children()[0].text().starts_with("<missing"));
10824 assert_eq!(parser.la(1), TOKEN_EOF);
10825 assert_eq!(
10826 parser.generated_parser_diagnostics,
10827 [ParserDiagnostic {
10828 line: 1,
10829 column: 1,
10830 message: "missing 'x' at '<EOF>'".to_owned(),
10831 }]
10832 );
10833 }
10834
10835 #[test]
10836 fn generated_rule_recovery_consumes_to_parent_follow() {
10837 let atn = generated_match_recovery_atn();
10838 let data = RecognizerData::new(
10839 "Mini.g4",
10840 Vocabulary::new(
10841 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
10842 [None, Some("X"), Some("Y"), Some("Z")],
10843 [None::<&str>, None, None, None],
10844 ),
10845 );
10846 let mut parser = BaseParser::new(
10847 CommonTokenStream::new(Source {
10848 tokens: vec![
10849 CommonToken::new(3).with_text("z"),
10850 CommonToken::eof("parser-test", 1, 1, 1),
10851 ],
10852 index: 0,
10853 }),
10854 data,
10855 );
10856 let _parent = parser.enter_rule(0, 0);
10857 let marker = parser.push_invoking_state(1);
10858 let mut child = parser.enter_rule(4, 1);
10859 parser.discard_invoking_state(marker);
10860
10861 parser.recover_generated_rule(
10862 &mut child,
10863 &atn,
10864 AntlrError::ParserError {
10865 line: 1,
10866 column: 0,
10867 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
10868 },
10869 );
10870 let tree = parser.finish_rule(child, false);
10871
10872 assert_eq!(parser.la(1), TOKEN_EOF);
10873 assert_eq!(tree.to_string_tree_with_names(&["s", "a"]), "(a z)");
10874 assert_eq!(parser.number_of_syntax_errors(), 1);
10875 assert_eq!(
10876 parser.generated_parser_diagnostics,
10877 [ParserDiagnostic {
10878 line: 1,
10879 column: 0,
10880 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
10881 }]
10882 );
10883 parser.exit_rule();
10884 }
10885
10886 #[test]
10887 fn greedy_ll1_alt_handles_nullable_loop_exit() {
10888 let mut body_symbols = TokenBitSet::default();
10889 body_symbols.insert(1);
10890 let entry = DecisionLookahead {
10891 transitions: vec![
10892 TransitionLookSet {
10893 symbols: body_symbols,
10894 nullable: false,
10895 },
10896 TransitionLookSet {
10897 symbols: TokenBitSet::default(),
10898 nullable: true,
10899 },
10900 ],
10901 };
10902
10903 assert_eq!(ll1_unique_alt(&entry, 2), None);
10904 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
10905 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
10906 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
10907 }
10908
10909 #[test]
10910 fn single_outcome_memo_probe_selects_sparse_or_promote_mode() {
10911 let key = |state_number| FastRecognizeKey {
10912 state_number,
10913 stop_state: 10,
10914 index: state_number,
10915 rule_start_index: 0,
10916 decision_start_index: None,
10917 precedence: 0,
10918 recovery_symbols_id: 0,
10919 recovery_state: None,
10920 };
10921
10922 let mut sparse = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10923 for state_number in 0..(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT - 1) {
10924 assert!(sparse.should_memoize_single_outcome(&key(state_number)));
10925 }
10926 assert!(!sparse.should_memoize_single_outcome(&key(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT)));
10927 assert_eq!(
10928 sparse.single_outcome_memo_mode,
10929 SingleOutcomeMemoMode::Sparse
10930 );
10931
10932 let mut promote = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10933 let repeated = key(1);
10934 for _ in 0..=CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
10935 assert!(promote.should_memoize_single_outcome(&repeated));
10936 }
10937 assert_eq!(
10938 promote.single_outcome_memo_mode,
10939 SingleOutcomeMemoMode::Promote
10940 );
10941 }
10942
10943 #[test]
10944 fn clean_empty_multi_alt_outcomes_are_memoized() {
10945 let mut atn = Atn::new(AtnType::Parser, 2);
10946 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10947 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
10948 atn.add_state(AtnState::new(2, AtnStateKind::RuleStop).with_rule_index(0));
10949 atn.set_rule_to_start_state(vec![0]);
10950 atn.set_rule_to_stop_state(vec![2]);
10951 atn.state_mut(0)
10952 .expect("state 0")
10953 .add_transition(Transition::Epsilon { target: 1 });
10954 atn.state_mut(1)
10955 .expect("state 1")
10956 .add_transition(Transition::Atom {
10957 target: 2,
10958 label: 1,
10959 });
10960 atn.state_mut(1)
10961 .expect("state 1")
10962 .add_transition(Transition::Atom {
10963 target: 2,
10964 label: 2,
10965 });
10966
10967 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
10968 parser.fast_recovery_enabled = false;
10969 let mut visiting = FxHashSet::default();
10970 let mut memo = FxHashMap::default();
10971 let mut expected = ExpectedTokens::default();
10972 let outcomes = parser.recognize_state_fast(
10973 &atn,
10974 FastRecognizeRequest {
10975 state_number: 1,
10976 stop_state: 2,
10977 index: 0,
10978 rule_start_index: 0,
10979 decision_start_index: None,
10980 precedence: 0,
10981 depth: 0,
10982 recovery_symbols: parser.empty_recovery_symbols(),
10983 recovery_state: None,
10984 },
10985 &mut visiting,
10986 &mut memo,
10987 &mut expected,
10988 );
10989
10990 assert!(outcomes.is_empty());
10991 assert_eq!(memo.len(), 1);
10992 assert!(memo.values().next().expect("memo entry").is_empty());
10993 }
10994
10995 #[test]
10996 fn wildcard_matches_non_eof_only() {
10997 let mut parser = mini_parser(vec![
10998 CommonToken::new(1).with_text("x"),
10999 CommonToken::eof("parser-test", 1, 1, 1),
11000 ]);
11001 assert_eq!(parser.match_wildcard().expect("wildcard").text(), "x");
11002 assert!(parser.match_wildcard().is_err());
11003 }
11004
11005 #[test]
11006 fn add_parse_child_records_match_even_without_tree_building() {
11007 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11012 let token = CommonToken::new(1).with_text("x");
11013
11014 parser.set_build_parse_trees(false);
11015 let mut ctx = ParserRuleContext::new(0, 0);
11016 assert!(!ctx.has_matched_child());
11017 parser.add_parse_child(
11018 &mut ctx,
11019 ParseTree::Terminal(TerminalNode::new(token.clone())),
11020 );
11021 assert!(ctx.children().is_empty());
11023 assert!(ctx.has_matched_child());
11025
11026 parser.set_build_parse_trees(true);
11028 let mut ctx = ParserRuleContext::new(0, 0);
11029 parser.add_parse_child(&mut ctx, ParseTree::Terminal(TerminalNode::new(token)));
11030 assert_eq!(ctx.children().len(), 1);
11031 assert!(ctx.has_matched_child());
11032 }
11033
11034 #[test]
11035 fn parser_interprets_simple_atn_rule() {
11036 let atn = token_then_eof_atn();
11037 let mut parser = mini_parser(vec![
11038 CommonToken::new(1).with_text("x"),
11039 CommonToken::eof("parser-test", 1, 1, 1),
11040 ]);
11041
11042 let tree = parser
11043 .parse_atn_rule(&atn, 0)
11044 .expect("artificial parser rule should parse");
11045 assert_eq!(tree.text(), "x<EOF>");
11046 assert_eq!(parser.number_of_syntax_errors(), 0);
11047 assert_eq!(
11048 tree.first_rule_stop(0)
11049 .expect("rule should stop at EOF")
11050 .token_type(),
11051 TOKEN_EOF
11052 );
11053
11054 let mut parser = mini_parser(vec![
11055 CommonToken::new(1).with_text("x"),
11056 CommonToken::eof("parser-test", 1, 1, 1),
11057 ]);
11058 let (tree, actions) = parser
11059 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11060 .expect("runtime-option parser rule should parse");
11061 assert!(actions.is_empty());
11062 assert_eq!(
11063 tree.first_rule_stop(0)
11064 .expect("rule should stop at EOF")
11065 .token_type(),
11066 TOKEN_EOF
11067 );
11068 }
11069
11070 #[test]
11071 fn runtime_options_default_ignores_noop_action_transitions() {
11072 let atn = noop_action_then_token_then_eof_atn();
11073 let mut parser = mini_parser(vec![
11074 CommonToken::new(1).with_text("x"),
11075 CommonToken::eof("parser-test", 1, 1, 1),
11076 ]);
11077
11078 let (tree, actions) = parser
11079 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11080 .expect("no-op parser action should not force action replay");
11081
11082 assert_eq!(tree.text(), "x<EOF>");
11083 assert!(
11084 actions.is_empty(),
11085 "action_index=None transitions are ANTLR metadata, not replay actions"
11086 );
11087 assert_eq!(parser.number_of_syntax_errors(), 0);
11088 }
11089
11090 #[test]
11091 fn parser_exposes_buffered_token_stream_after_parse() {
11092 let atn = token_then_eof_atn();
11093 let mut parser = mini_parser(vec![
11094 CommonToken::new(1).with_text("x"),
11095 CommonToken::eof("parser-test", 1, 1, 1),
11096 ]);
11097
11098 let tree = parser
11099 .parse_atn_rule(&atn, 0)
11100 .expect("artificial parser rule should parse");
11101 assert_eq!(tree.text(), "x<EOF>");
11102
11103 let stream = parser.token_stream();
11104 let source_index_after_parse = stream.token_source().index;
11105 let buffered = stream.tokens();
11106 assert_eq!(buffered.len(), 2);
11107 assert_eq!(buffered[0].text(), "x");
11108 assert_eq!(buffered[0].token_index(), 0);
11109 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
11110 assert_eq!(stream.token_source().index, source_index_after_parse);
11111
11112 let stream = parser.into_token_stream();
11113 assert_eq!(stream.token_source().index, source_index_after_parse);
11114 assert_eq!(stream.tokens()[0].text(), "x");
11115 assert_eq!(stream.tokens()[1].token_type(), TOKEN_EOF);
11116 }
11117
11118 #[test]
11119 fn parser_syntax_error_count_tracks_interpreted_recovery() {
11120 let atn = token_then_eof_atn();
11121 let mut parser = mini_parser(vec![
11122 CommonToken::new(1).with_text("x"),
11123 CommonToken::new(2).with_text("y"),
11124 CommonToken::eof("parser-test", 2, 1, 2),
11125 ]);
11126
11127 let tree = parser
11128 .parse_atn_rule(&atn, 0)
11129 .expect("invalid token should recover into an error node");
11130
11131 assert_eq!(parser.number_of_syntax_errors(), 1);
11132 assert_eq!(
11133 tree.first_error_token()
11134 .expect("recovery should embed an error token")
11135 .text(),
11136 "y"
11137 );
11138 }
11139
11140 #[test]
11141 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
11142 let atn = token_then_eof_atn();
11143 let mut parser = mini_parser(vec![
11144 CommonToken::new(2).with_text("y"),
11145 CommonToken::eof("parser-test", 1, 1, 1),
11146 ]);
11147
11148 let error = parser
11149 .parse_atn_rule(&atn, 0)
11150 .expect_err("start-rule mismatch should remain a parser error");
11151
11152 assert_eq!(parser.number_of_syntax_errors(), 1);
11153 assert!(matches!(error, AntlrError::ParserError { .. }));
11154 }
11155
11156 #[test]
11157 fn adaptive_direct_rule_uses_simulator_decision() {
11158 let atn = two_alt_decision_atn();
11159 let mut simulator = ParserAtnSimulator::new(&atn);
11160 let mut parser = mini_parser(vec![
11161 CommonToken::new(2).with_text("y"),
11162 CommonToken::eof("parser-test", 1, 1, 1),
11163 ]);
11164
11165 let tree = parser
11166 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
11167 .expect("direct adaptive rule should parse");
11168
11169 assert_eq!(tree.text(), "y");
11170 assert_eq!(parser.input.index(), 1);
11171 }
11172
11173 #[test]
11174 fn adaptive_direct_rule_restores_input_on_fallback() {
11175 let atn = predicate_after_token_atn();
11176 let mut simulator = ParserAtnSimulator::new(&atn);
11177 let mut parser = mini_parser(vec![
11178 CommonToken::new(1).with_text("x"),
11179 CommonToken::new(2).with_text("y"),
11180 CommonToken::eof("parser-test", 2, 1, 2),
11181 ]);
11182
11183 let tree = parser
11184 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
11185 .expect("fallback recognizer should parse");
11186
11187 assert_eq!(tree.text(), "xy");
11188 assert_eq!(parser.input.index(), 2);
11189 }
11190
11191 #[test]
11192 fn unknown_predicate_policy_defaults_to_assume_true() {
11193 let atn = predicate_after_token_atn();
11194 let mut parser = mini_parser(vec![
11195 CommonToken::new(1).with_text("x"),
11196 CommonToken::new(2).with_text("y"),
11197 CommonToken::eof("parser-test", 2, 1, 2),
11198 ]);
11199
11200 let (tree, _) = parser
11201 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11202 .expect("unknown predicate should pass under the default policy");
11203
11204 assert_eq!(tree.text(), "xy");
11205 assert_eq!(parser.number_of_syntax_errors(), 0);
11206 }
11207
11208 #[test]
11209 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
11210 let atn = token_then_eof_atn();
11214 let mut parser = mini_parser(vec![
11215 CommonToken::new(1).with_text("x"),
11216 CommonToken::eof("parser-test", 1, 1, 1),
11217 ]);
11218
11219 parser.unknown_predicate_hits.push((7, 3));
11221
11222 parser
11224 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11225 .expect("child rule parses");
11226
11227 let error = parser
11229 .take_unknown_semantic_error()
11230 .expect("parent's recorded coordinate must survive the nested interpreted parse");
11231 let AntlrError::Unsupported(message) = error else {
11232 panic!("expected AntlrError::Unsupported, got {error:?}");
11233 };
11234 assert!(message.contains("pred_index=3"), "message: {message}");
11235 }
11236
11237 #[test]
11238 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
11239 let atn = predicate_after_token_atn();
11240 let mut parser = mini_parser(vec![
11241 CommonToken::new(1).with_text("x"),
11242 CommonToken::new(2).with_text("y"),
11243 CommonToken::eof("parser-test", 2, 1, 2),
11244 ]);
11245
11246 let result = parser.parse_atn_rule_with_runtime_options(
11247 &atn,
11248 0,
11249 ParserRuntimeOptions {
11250 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
11251 ..ParserRuntimeOptions::default()
11252 },
11253 );
11254
11255 assert!(
11256 result.is_err(),
11257 "the only path is predicate-guarded, so assume-false must fail the parse"
11258 );
11259 }
11260
11261 #[test]
11262 fn unknown_predicate_policy_error_names_the_coordinate() {
11263 let atn = predicate_after_token_atn();
11264 let mut parser = mini_parser(vec![
11265 CommonToken::new(1).with_text("x"),
11266 CommonToken::new(2).with_text("y"),
11267 CommonToken::eof("parser-test", 2, 1, 2),
11268 ]);
11269
11270 let error = parser
11271 .parse_atn_rule_with_runtime_options(
11272 &atn,
11273 0,
11274 ParserRuntimeOptions {
11275 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11276 ..ParserRuntimeOptions::default()
11277 },
11278 )
11279 .expect_err("evaluating an unknown predicate under Error policy must fail");
11280
11281 let AntlrError::Unsupported(message) = error else {
11282 panic!("expected AntlrError::Unsupported, got {error:?}");
11283 };
11284 assert!(
11285 message.contains("unsupported semantic predicate"),
11286 "message should name the failure class: {message}"
11287 );
11288 assert!(
11289 message.contains("pred_index=0"),
11290 "message should carry the coordinate: {message}"
11291 );
11292 }
11293
11294 #[test]
11295 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
11296 let atn = predicate_after_token_atn();
11302 let mut parser = mini_parser(vec![
11303 CommonToken::new(1).with_text("x"),
11304 CommonToken::new(2).with_text("y"),
11305 CommonToken::eof("parser-test", 2, 1, 2),
11306 ]);
11307
11308 parser
11309 .parse_atn_rule_with_runtime_options(
11310 &atn,
11311 0,
11312 ParserRuntimeOptions {
11313 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11314 ..ParserRuntimeOptions::default()
11315 },
11316 )
11317 .expect_err("first parse fails loud under the Error policy");
11318
11319 parser.reset_unknown_semantic_hits();
11324 assert!(
11325 parser.take_unknown_semantic_error().is_none(),
11326 "reset must drop stale unknown-predicate coordinates before a reused parse"
11327 );
11328 }
11329
11330 #[derive(Debug, Default)]
11331 struct RecordingHooks {
11332 predicates: Vec<(usize, usize, usize, Option<String>)>,
11333 actions: Vec<(usize, String, Option<String>)>,
11334 }
11335
11336 impl SemanticHooks for RecordingHooks {
11337 fn sempred<S>(
11338 &mut self,
11339 ctx: &mut ParserSemCtx<'_, S>,
11340 rule_index: usize,
11341 pred_index: usize,
11342 ) -> Option<bool>
11343 where
11344 S: TokenSource,
11345 {
11346 self.predicates.push((
11347 ctx.input_index(),
11348 rule_index,
11349 pred_index,
11350 ctx.token_text(1).map(str::to_owned),
11351 ));
11352 Some(true)
11353 }
11354
11355 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
11356 where
11357 S: TokenSource,
11358 {
11359 self.actions.push((
11360 action.source_state(),
11361 ctx.action_text(),
11362 ctx.rule_name().map(str::to_owned),
11363 ));
11364 true
11365 }
11366 }
11367
11368 #[derive(Debug, Default)]
11369 struct RejectingPredicateHooks {
11370 predicates: Vec<(usize, usize, usize, Option<String>)>,
11371 }
11372
11373 impl SemanticHooks for RejectingPredicateHooks {
11374 fn sempred<S>(
11375 &mut self,
11376 ctx: &mut ParserSemCtx<'_, S>,
11377 rule_index: usize,
11378 pred_index: usize,
11379 ) -> Option<bool>
11380 where
11381 S: TokenSource,
11382 {
11383 self.predicates.push((
11384 ctx.input_index(),
11385 rule_index,
11386 pred_index,
11387 ctx.token_text(1).map(str::to_owned),
11388 ));
11389 Some(false)
11390 }
11391 }
11392
11393 #[test]
11394 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
11395 let atn = predicate_after_token_atn();
11396 let mut parser = mini_parser_with_hooks(
11397 vec![
11398 CommonToken::new(1).with_text("x"),
11399 CommonToken::new(2).with_text("y"),
11400 CommonToken::eof("parser-test", 2, 1, 2),
11401 ],
11402 RecordingHooks::default(),
11403 );
11404
11405 let (tree, _) = parser
11406 .parse_atn_rule_with_runtime_options(
11407 &atn,
11408 0,
11409 ParserRuntimeOptions {
11410 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11411 ..ParserRuntimeOptions::default()
11412 },
11413 )
11414 .expect("hook supplies the missing predicate result");
11415
11416 assert_eq!(tree.text(), "xy");
11417 assert_eq!(
11418 parser.semantic_hooks.predicates,
11419 vec![(1, 0, 0, Some("y".to_owned()))]
11420 );
11421 }
11422
11423 #[test]
11424 fn runtime_options_default_preserves_semantic_hook_predicates() {
11425 let atn = predicate_after_token_atn();
11426 let mut parser = mini_parser_with_hooks(
11427 vec![
11428 CommonToken::new(1).with_text("x"),
11429 CommonToken::new(2).with_text("y"),
11430 CommonToken::eof("parser-test", 2, 1, 2),
11431 ],
11432 RejectingPredicateHooks::default(),
11433 );
11434
11435 let result =
11436 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
11437
11438 assert!(
11439 result.is_err(),
11440 "default runtime options must not bypass semantic hooks for predicate ATNs"
11441 );
11442 assert_eq!(
11443 parser.semantic_hooks.predicates,
11444 vec![(1, 0, 0, Some("y".to_owned()))]
11445 );
11446 }
11447
11448 #[test]
11449 fn semantic_hook_handles_committed_parser_action() {
11450 let atn = token_then_eof_atn();
11451 let mut parser = mini_parser_with_hooks(
11452 vec![
11453 CommonToken::new(1).with_text("x"),
11454 CommonToken::eof("parser-test", 1, 1, 1),
11455 ],
11456 RecordingHooks::default(),
11457 );
11458 let (tree, _) = parser
11459 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11460 .expect("rule parses before action hook is tested");
11461
11462 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
11463 assert_eq!(
11464 parser.semantic_hooks.actions,
11465 vec![(42, "x".to_owned(), Some("s".to_owned()))]
11466 );
11467 }
11468
11469 #[test]
11470 fn unhandled_committed_action_fails_loud_under_error_policy() {
11471 let mut parser =
11475 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11476 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
11477 let tree = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, -1)));
11478
11479 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
11481
11482 let error = parser
11483 .take_unknown_semantic_error()
11484 .expect("an unhandled committed action under Error policy must fail loud");
11485 let AntlrError::Unsupported(message) = error else {
11486 panic!("expected AntlrError::Unsupported, got {error:?}");
11487 };
11488 assert!(
11489 message.contains("unhandled semantic action") && message.contains("state=42"),
11490 "message should name the dropped action coordinate: {message}"
11491 );
11492
11493 let mut lenient =
11495 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11496 let tree = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, -1)));
11497 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
11498 assert!(lenient.take_unknown_semantic_error().is_none());
11499 }
11500
11501 #[test]
11502 fn translated_predicate_is_unaffected_by_error_policy() {
11503 let atn = predicate_after_token_atn();
11504 let mut parser = mini_parser(vec![
11505 CommonToken::new(1).with_text("x"),
11506 CommonToken::new(2).with_text("y"),
11507 CommonToken::eof("parser-test", 2, 1, 2),
11508 ]);
11509
11510 let (tree, _) = parser
11511 .parse_atn_rule_with_runtime_options(
11512 &atn,
11513 0,
11514 ParserRuntimeOptions {
11515 predicates: &[(0, 0, ParserPredicate::True)],
11516 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11517 ..ParserRuntimeOptions::default()
11518 },
11519 )
11520 .expect("a predicate covered by the table is not an unknown coordinate");
11521
11522 assert_eq!(tree.text(), "xy");
11523 }
11524
11525 fn hook_predicate_semantics() -> ParserSemantics {
11530 let mut ir = SemIr::new();
11531 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
11532 ParserSemantics {
11533 ir,
11534 predicates: vec![ParserSemanticPredicate {
11535 rule_index: 0,
11536 pred_index: 0,
11537 expr,
11538 failure_message: None,
11539 }],
11540 actions: Vec::new(),
11541 }
11542 }
11543
11544 #[derive(Debug, Default)]
11545 struct DecliningHooks;
11546
11547 impl SemanticHooks for DecliningHooks {}
11548
11549 #[test]
11550 fn semir_hook_none_falls_through_to_assume_true() {
11551 let atn = predicate_after_token_atn();
11552 let semantics = hook_predicate_semantics();
11553 let mut parser = mini_parser_with_hooks(
11554 vec![
11555 CommonToken::new(1).with_text("x"),
11556 CommonToken::new(2).with_text("y"),
11557 CommonToken::eof("parser-test", 2, 1, 2),
11558 ],
11559 DecliningHooks,
11560 );
11561
11562 let (tree, _) = parser
11563 .parse_atn_rule_with_runtime_options(
11564 &atn,
11565 0,
11566 ParserRuntimeOptions {
11567 semantics: Some(&semantics),
11568 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
11569 ..ParserRuntimeOptions::default()
11570 },
11571 )
11572 .expect("a declined SemIR hook must pass under assume-true");
11573
11574 assert_eq!(tree.text(), "xy");
11575 }
11576
11577 #[test]
11578 fn semir_hook_none_falls_through_to_assume_false() {
11579 let atn = predicate_after_token_atn();
11580 let semantics = hook_predicate_semantics();
11581 let mut parser = mini_parser_with_hooks(
11582 vec![
11583 CommonToken::new(1).with_text("x"),
11584 CommonToken::new(2).with_text("y"),
11585 CommonToken::eof("parser-test", 2, 1, 2),
11586 ],
11587 DecliningHooks,
11588 );
11589
11590 let result = parser.parse_atn_rule_with_runtime_options(
11591 &atn,
11592 0,
11593 ParserRuntimeOptions {
11594 semantics: Some(&semantics),
11595 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
11596 ..ParserRuntimeOptions::default()
11597 },
11598 );
11599
11600 assert!(
11601 result.is_err(),
11602 "a declined SemIR hook must fail the only guarded path under assume-false"
11603 );
11604 }
11605
11606 #[test]
11607 fn semir_hook_none_records_coordinate_under_error_policy() {
11608 let atn = predicate_after_token_atn();
11609 let semantics = hook_predicate_semantics();
11610 let mut parser = mini_parser_with_hooks(
11611 vec![
11612 CommonToken::new(1).with_text("x"),
11613 CommonToken::new(2).with_text("y"),
11614 CommonToken::eof("parser-test", 2, 1, 2),
11615 ],
11616 DecliningHooks,
11617 );
11618
11619 let error = parser
11620 .parse_atn_rule_with_runtime_options(
11621 &atn,
11622 0,
11623 ParserRuntimeOptions {
11624 semantics: Some(&semantics),
11625 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11626 ..ParserRuntimeOptions::default()
11627 },
11628 )
11629 .expect_err("a declined SemIR hook under Error policy must fail the parse");
11630
11631 let AntlrError::Unsupported(message) = error else {
11632 panic!("expected AntlrError::Unsupported, got {error:?}");
11633 };
11634 assert!(
11635 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
11636 "message should name the unresolved coordinate: {message}"
11637 );
11638 }
11639
11640 #[test]
11641 fn generated_direct_predicate_honors_installed_policy() {
11642 let semantics = hook_predicate_semantics();
11648 let context = ParserRuleContext::new(0, -1);
11649
11650 let mut assume_true =
11651 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11652 assert!(
11653 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
11654 &semantics, 0, 0, &context, 0
11655 ),
11656 "default AssumeTrue accepts a declined hook"
11657 );
11658 assert!(assume_true.take_unknown_semantic_error().is_none());
11659
11660 let mut error_policy =
11661 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11662 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
11663 assert!(
11664 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
11665 &semantics, 0, 0, &context, 0
11666 ),
11667 "Error policy rejects a declined hook on the generated-direct path"
11668 );
11669 let error = error_policy
11670 .take_unknown_semantic_error()
11671 .expect("Error policy records the unresolved coordinate for the generated path");
11672 let AntlrError::Unsupported(message) = error else {
11673 panic!("expected AntlrError::Unsupported, got {error:?}");
11674 };
11675 assert!(message.contains("pred_index=0"), "message: {message}");
11676 }
11677
11678 #[test]
11679 fn parser_rule_start_skips_leading_hidden_tokens() {
11680 let atn = token_then_eof_atn();
11681 let mut parser = mini_parser(vec![
11682 CommonToken::new(99)
11683 .with_text(" ")
11684 .with_channel(HIDDEN_CHANNEL),
11685 CommonToken::new(1).with_text("x"),
11686 CommonToken::eof("parser-test", 2, 1, 2),
11687 ]);
11688
11689 let tree = parser
11690 .parse_atn_rule(&atn, 0)
11691 .expect("artificial parser rule should parse");
11692 let Some(ParseTree::Rule(rule)) = tree.first_rule(0) else {
11693 panic!("rule node should be present");
11694 };
11695 assert_eq!(
11696 rule.context()
11697 .start()
11698 .expect("rule should have a start token")
11699 .token_type(),
11700 1
11701 );
11702 }
11703
11704 #[test]
11705 fn parser_action_after_eof_stops_at_eof_token() {
11706 let atn = eof_then_action_atn();
11707 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
11708
11709 let (_, actions) = parser
11710 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11711 .expect("EOF action rule should parse");
11712
11713 assert_eq!(actions.len(), 1);
11714 assert_eq!(actions[0].stop_index(), Some(0));
11715 assert_eq!(
11716 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
11717 ""
11718 );
11719 }
11720
11721 #[test]
11722 fn after_action_stop_uses_rule_context_stop_not_cursor() {
11723 let mut id = CommonToken::new(1).with_text("x");
11728 id.set_token_index(0);
11729 let mut eof = CommonToken::eof("parser-test", 1, 1, 1);
11730 eof.set_token_index(1);
11731 let mut parser = mini_parser(vec![id.clone(), eof]);
11732 parser.consume();
11734 assert_eq!(parser.la(1), TOKEN_EOF);
11735
11736 let mut ctx = ParserRuleContext::new(0, 0);
11739 ctx.set_stop(id);
11740 let tree = ParseTree::Rule(RuleNode::new(ctx));
11741
11742 let current_index = parser.input.index();
11743 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
11745 assert_eq!(
11747 parser.after_action_stop_index_for_tree(&tree, current_index),
11748 Some(0)
11749 );
11750 }
11751
11752 #[test]
11753 fn after_action_start_uses_rule_context_start_not_cursor() {
11754 let parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11759 let mut id = CommonToken::new(1).with_text("x");
11760 id.set_token_index(2);
11762
11763 let mut ctx = ParserRuleContext::new(0, 0);
11764 ctx.set_start(id);
11765 let tree = ParseTree::Rule(RuleNode::new(ctx));
11766
11767 assert_eq!(parser.after_action_start_index_for_tree(&tree, 0), 2);
11770
11771 let empty = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, 0)));
11773 assert_eq!(parser.after_action_start_index_for_tree(&empty, 7), 7);
11774 }
11775
11776 #[test]
11777 fn fast_outcome_selection_respects_sll_tie_order() {
11778 let first = FastRecognizeOutcome {
11779 index: 1,
11780 consumed_eof: false,
11781 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
11782 line: 1,
11783 column: 0,
11784 message: "mismatched input 'x'".to_owned(),
11785 }]),
11786 nodes: NodeList::new(),
11787 };
11788 let second = FastRecognizeOutcome {
11789 index: first.index,
11790 consumed_eof: first.consumed_eof,
11791 diagnostics: FastDiagnostics::new(),
11792 nodes: NodeList::new(),
11793 };
11794
11795 let selected = select_best_fast_outcome(
11796 [first.clone(), second.clone()].into_iter(),
11797 PredictionMode::Sll,
11798 None,
11799 |_| panic!("caller-follow token probe should not run"),
11800 )
11801 .expect("one outcome should be selected");
11802 assert_eq!(selected.diagnostics.len(), 1);
11803 let eof_second = FastRecognizeOutcome {
11804 index: second.index,
11805 consumed_eof: true,
11806 diagnostics: FastDiagnostics::new(),
11807 nodes: NodeList::new(),
11808 };
11809 let selected = select_best_fast_outcome(
11810 [first.clone(), eof_second].into_iter(),
11811 PredictionMode::Sll,
11812 None,
11813 |_| panic!("caller-follow token probe should not run"),
11814 )
11815 .expect("one outcome should be selected");
11816 assert!(!selected.consumed_eof);
11817 let selected = select_best_fast_outcome(
11818 [first, second].into_iter(),
11819 PredictionMode::Ll,
11820 None,
11821 |_| panic!("caller-follow token probe should not run"),
11822 )
11823 .expect("one outcome should be selected");
11824 assert!(selected.diagnostics.is_empty());
11825 }
11826
11827 #[test]
11828 fn fast_outcome_selection_prefers_generated_caller_follow() {
11829 let earlier = FastRecognizeOutcome {
11830 index: 7,
11831 consumed_eof: false,
11832 diagnostics: FastDiagnostics::new(),
11833 nodes: NodeList::new(),
11834 };
11835 let later = FastRecognizeOutcome {
11836 index: 8,
11837 consumed_eof: false,
11838 diagnostics: FastDiagnostics::new(),
11839 nodes: NodeList::new(),
11840 };
11841 let mut follow = TokenBitSet::default();
11842 follow.insert(5);
11843
11844 let selected = select_best_fast_outcome(
11845 [later.clone(), earlier.clone()].into_iter(),
11846 PredictionMode::Ll,
11847 Some(&follow),
11848 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
11849 )
11850 .expect("one outcome should be selected");
11851 assert_eq!(selected.index, 7);
11852
11853 let selected = select_best_fast_outcome(
11854 [later.clone(), earlier.clone()].into_iter(),
11855 PredictionMode::Ll,
11856 Some(&follow),
11857 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
11858 )
11859 .expect("one outcome should be selected");
11860 assert_eq!(selected.index, 8);
11861
11862 let indented_next_statement = FastRecognizeOutcome {
11863 index: 9,
11864 consumed_eof: false,
11865 diagnostics: FastDiagnostics::new(),
11866 nodes: NodeList::new(),
11867 };
11868 let selected = select_best_fast_outcome(
11869 [indented_next_statement, earlier.clone()].into_iter(),
11870 PredictionMode::Ll,
11871 Some(&follow),
11872 |index| {
11873 let is_boundary = index == 7;
11874 let is_boundary_gap = matches!(index, 7 | 8);
11875 (
11876 if index == 7 { 5 } else { TOKEN_EOF },
11877 is_boundary,
11878 is_boundary_gap,
11879 )
11880 },
11881 )
11882 .expect("one outcome should be selected");
11883 assert_eq!(selected.index, 7);
11884
11885 let continuation = FastRecognizeOutcome {
11886 index: 10,
11887 consumed_eof: false,
11888 diagnostics: FastDiagnostics::new(),
11889 nodes: NodeList::new(),
11890 };
11891 let selected = select_best_fast_outcome(
11892 [continuation, earlier.clone()].into_iter(),
11893 PredictionMode::Ll,
11894 Some(&follow),
11895 |index| {
11896 let is_boundary = matches!(index, 7 | 9);
11897 (
11898 if index == 7 { 5 } else { TOKEN_EOF },
11899 is_boundary,
11900 is_boundary,
11901 )
11902 },
11903 )
11904 .expect("one outcome should be selected");
11905 assert_eq!(selected.index, 10);
11906
11907 let selected = select_best_fast_outcome(
11908 [earlier, later].into_iter(),
11909 PredictionMode::Sll,
11910 Some(&follow),
11911 |_| panic!("caller-follow token probe should not run in SLL mode"),
11912 )
11913 .expect("one outcome should be selected");
11914 assert_eq!(selected.index, 8);
11915 }
11916
11917 #[test]
11918 fn caller_follow_boundary_text_requires_separator_shape() {
11919 assert!(is_caller_follow_boundary_text(";"));
11920 assert!(is_caller_follow_boundary_text("\n"));
11921 assert!(is_caller_follow_boundary_text("\r\n "));
11922 assert!(is_caller_follow_boundary_text(";\n"));
11923 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
11924 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
11925 assert!(!is_caller_follow_boundary_text("identifier"));
11926 assert!(is_caller_follow_boundary_gap_text(" \t "));
11927 assert!(is_caller_follow_boundary_gap_text("\n "));
11928 assert!(is_caller_follow_boundary_gap_text(";\t"));
11929 assert!(!is_caller_follow_boundary_gap_text(
11930 "\"\"\"line1\nline2\"\"\""
11931 ));
11932 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
11933 }
11934
11935 #[test]
11936 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
11937 let mut parser = mini_parser(vec![
11938 CommonToken::new(5).with_text("\n"),
11939 CommonToken::new(6)
11940 .with_text("// comment\n")
11941 .with_channel(HIDDEN_CHANNEL),
11942 CommonToken::new(1).with_text("x"),
11943 CommonToken::eof("parser-test", 1, 2, 0),
11944 ]);
11945
11946 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
11947 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
11948 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
11949 }
11950
11951 #[test]
11952 fn caller_follow_token_info_uses_stream_visible_channel() {
11953 let source = Source {
11954 tokens: vec![
11955 CommonToken::new(5).with_text("\n").with_channel(2),
11956 CommonToken::new(1).with_text("x").with_channel(2),
11957 CommonToken::new(6)
11958 .with_text("// comment\n")
11959 .with_channel(HIDDEN_CHANNEL),
11960 CommonToken::eof("parser-test", 1, 2, 0),
11961 ],
11962 index: 0,
11963 };
11964 let data = RecognizerData::new(
11965 "Mini.g4",
11966 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
11967 );
11968 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
11969
11970 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
11971 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
11972 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
11973 }
11974
11975 #[test]
11976 fn reset_per_parse_caches_clears_state_expected_token_cache() {
11977 let atn = token_then_eof_atn();
11978 let mut parser = mini_parser(Vec::new());
11979
11980 let _ = parser.cached_state_expected_token_set(&atn, 0);
11981 assert!(!parser.state_expected_token_cache.is_empty());
11982
11983 parser.reset_per_parse_caches();
11984 assert!(parser.state_expected_token_cache.is_empty());
11985 }
11986
11987 #[test]
11988 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
11989 let source = Source {
11990 tokens: vec![
11991 CommonToken::new(1).with_text("x"),
11992 CommonToken::eof("parser-test", 1, 1, 1),
11993 ],
11994 index: 0,
11995 };
11996 let data = RecognizerData::new(
11997 "Mini.g4",
11998 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
11999 );
12000 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
12001 let expected = ExpectedTokens {
12002 index: Some(0),
12003 symbols: BTreeSet::new(),
12004 no_viable: None,
12005 };
12006
12007 let (_, message) = parser.expected_error_message(0, 0, &expected);
12008
12009 assert_eq!(message, "mismatched input 'x'");
12010 }
12011
12012 #[test]
12013 fn eof_rule_stop_index_points_at_eof_token() {
12014 let source = Source {
12015 tokens: vec![
12016 CommonToken::new(1).with_text("x"),
12017 CommonToken::eof("parser-test", 1, 1, 1),
12018 ],
12019 index: 0,
12020 };
12021 let data = RecognizerData::new(
12022 "Mini.g4",
12023 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12024 );
12025 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
12026
12027 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
12028 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
12029 }
12030
12031 #[test]
12032 fn generated_parser_action_uses_current_rule_stop_boundary() {
12033 let mut parser = mini_parser(vec![
12034 CommonToken::new(1).with_text("x"),
12035 CommonToken::eof("parser-test", 1, 1, 1),
12036 ]);
12037
12038 parser.match_token(1).expect("token should match");
12039 let action = parser.parser_action_at_current(7, 0, 0, false);
12040 assert_eq!(action.source_state(), 7);
12041 assert_eq!(action.rule_index(), 0);
12042 assert_eq!(action.start_index(), 0);
12043 assert_eq!(action.stop_index(), Some(0));
12044
12045 parser.match_eof().expect("EOF should match");
12046 let action = parser.parser_action_at_current(8, 0, 0, true);
12047 assert_eq!(action.stop_index(), Some(1));
12048 }
12049
12050 #[test]
12051 fn folds_left_recursive_boundary_into_rule_node() {
12052 let nodes = fold_left_recursive_boundaries(vec![
12053 RecognizedNode::Token { index: 0 },
12054 RecognizedNode::LeftRecursiveBoundary { rule_index: 1 },
12055 RecognizedNode::Token { index: 1 },
12056 ]);
12057
12058 assert_eq!(
12059 nodes,
12060 vec![
12061 RecognizedNode::Rule {
12062 rule_index: 1,
12063 invoking_state: -1,
12064 alt_number: 0,
12065 start_index: 0,
12066 stop_index: Some(0),
12067 return_values: BTreeMap::new(),
12068 children: vec![RecognizedNode::Token { index: 0 }],
12069 },
12070 RecognizedNode::Token { index: 1 },
12071 ]
12072 );
12073 }
12074
12075 #[test]
12076 fn outcome_ties_keep_later_non_recursive_alternative() {
12077 let first = RecognizeOutcome {
12078 index: 1,
12079 consumed_eof: false,
12080 alt_number: 0,
12081 member_values: BTreeMap::new(),
12082 return_values: BTreeMap::new(),
12083 diagnostics: Vec::new(),
12084 decisions: Vec::new(),
12085 actions: vec![ParserAction::new(1, 0, 0, None)],
12086 nodes: vec![RecognizedNode::Token { index: 0 }],
12087 };
12088 let second = RecognizeOutcome {
12089 actions: vec![ParserAction::new(2, 0, 0, None)],
12090 ..first.clone()
12091 };
12092
12093 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
12094 .expect("one outcome should be selected");
12095 assert_eq!(selected.actions[0].source_state(), 2);
12096 }
12097
12098 #[test]
12099 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
12100 let first = RecognizeOutcome {
12101 index: 1,
12102 consumed_eof: false,
12103 alt_number: 0,
12104 member_values: BTreeMap::new(),
12105 return_values: BTreeMap::new(),
12106 diagnostics: Vec::new(),
12107 decisions: Vec::new(),
12108 actions: vec![ParserAction::new(1, 0, 0, None)],
12109 nodes: vec![RecognizedNode::Token { index: 0 }],
12110 };
12111 let second = RecognizeOutcome {
12112 actions: vec![
12113 ParserAction::new(2, 0, 0, None),
12114 ParserAction::new(3, 0, 0, None),
12115 ],
12116 ..first.clone()
12117 };
12118
12119 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll)
12120 .expect("one outcome should be selected");
12121 assert_eq!(selected.actions.len(), 2);
12122 }
12123
12124 #[test]
12125 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
12126 let first = RecognizeOutcome {
12127 index: 7,
12128 consumed_eof: false,
12129 alt_number: 0,
12130 member_values: BTreeMap::new(),
12131 return_values: BTreeMap::new(),
12132 diagnostics: Vec::new(),
12133 decisions: vec![1, 0],
12134 actions: vec![
12135 ParserAction::new(23, 2, 2, Some(4)),
12136 ParserAction::new(23, 2, 0, Some(6)),
12137 ],
12138 nodes: vec![RecognizedNode::Token { index: 0 }],
12139 };
12140 let second = RecognizeOutcome {
12141 decisions: vec![0, 1],
12142 actions: vec![
12143 ParserAction::new(23, 2, 2, Some(6)),
12144 ParserAction::new(23, 2, 0, Some(6)),
12145 ],
12146 ..first.clone()
12147 };
12148
12149 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
12150 .expect("one outcome should be selected");
12151 assert_eq!(selected.actions[0].stop_index(), Some(6));
12152 }
12153
12154 #[test]
12155 fn outcome_ties_keep_first_recursive_tree_shape() {
12156 let recursive_nodes = vec![RecognizedNode::Rule {
12157 rule_index: 1,
12158 invoking_state: -1,
12159 alt_number: 0,
12160 start_index: 0,
12161 stop_index: Some(0),
12162 return_values: BTreeMap::new(),
12163 children: vec![RecognizedNode::Rule {
12164 rule_index: 1,
12165 invoking_state: -1,
12166 alt_number: 0,
12167 start_index: 0,
12168 stop_index: Some(0),
12169 return_values: BTreeMap::new(),
12170 children: vec![RecognizedNode::Token { index: 0 }],
12171 }],
12172 }];
12173 let first = RecognizeOutcome {
12174 index: 1,
12175 consumed_eof: false,
12176 alt_number: 0,
12177 member_values: BTreeMap::new(),
12178 return_values: BTreeMap::new(),
12179 diagnostics: Vec::new(),
12180 decisions: Vec::new(),
12181 actions: vec![ParserAction::new(1, 0, 0, None)],
12182 nodes: recursive_nodes.clone(),
12183 };
12184 let second = RecognizeOutcome {
12185 index: 1,
12186 consumed_eof: false,
12187 alt_number: 0,
12188 member_values: BTreeMap::new(),
12189 return_values: BTreeMap::new(),
12190 diagnostics: Vec::new(),
12191 decisions: Vec::new(),
12192 actions: vec![ParserAction::new(2, 0, 0, None)],
12193 nodes: recursive_nodes,
12194 };
12195
12196 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
12197 .expect("one outcome should be selected");
12198 assert_eq!(selected.actions[0].source_state(), 1);
12199 }
12200
12201 #[test]
12202 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
12203 let first_alt = RecognizeOutcome {
12204 index: 2,
12205 consumed_eof: true,
12206 alt_number: 0,
12207 member_values: BTreeMap::new(),
12208 return_values: BTreeMap::new(),
12209 diagnostics: vec![ParserDiagnostic {
12210 line: 1,
12211 column: 3,
12212 message: "missing 'Y' at '<EOF>'".to_owned(),
12213 }],
12214 decisions: vec![0],
12215 actions: vec![ParserAction::new(1, 0, 0, None)],
12216 nodes: vec![RecognizedNode::Token { index: 0 }],
12217 };
12218 let second_alt = RecognizeOutcome {
12219 diagnostics: Vec::new(),
12220 decisions: vec![1],
12221 actions: vec![ParserAction::new(2, 0, 0, None)],
12222 ..first_alt.clone()
12223 };
12224
12225 let selected =
12226 select_best_outcome([second_alt, first_alt].into_iter(), PredictionMode::Sll)
12227 .expect("one outcome should be selected");
12228 assert_eq!(selected.diagnostics.len(), 1);
12229 assert_eq!(selected.decisions, [0]);
12230 }
12231}