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 #[must_use]
398 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
399 self.context
400 }
401
402 #[must_use]
405 pub const fn tree(&self) -> Option<&'a ParseTree> {
406 self.tree
407 }
408
409 #[must_use]
411 pub fn local_int_arg(&self) -> Option<i64> {
412 self.local_int_arg.map(|(_, value)| value)
413 }
414
415 #[must_use]
417 pub fn member_int(&self, member: usize) -> Option<i64> {
418 self.member_values.get(&member).copied()
419 }
420
421 #[must_use]
424 pub const fn action(&self) -> Option<ParserAction> {
425 self.action
426 }
427
428 pub fn action_text(&mut self) -> String {
436 let Some(action) = self.action else {
437 return String::new();
438 };
439 let Some(stop) = action.stop_index() else {
440 return String::new();
441 };
442 let stop = if self
443 .input
444 .get(stop)
445 .is_some_and(|token| token.token_type() == TOKEN_EOF)
446 {
447 let Some(previous) = self.input.previous_visible_token_index(stop) else {
448 return String::new();
449 };
450 previous
451 } else {
452 stop
453 };
454 self.input.text(action.start_index(), stop)
455 }
456}
457
458pub trait SemanticHooks {
465 fn sempred<S>(
466 &mut self,
467 ctx: &mut ParserSemCtx<'_, S>,
468 rule_index: usize,
469 pred_index: usize,
470 ) -> Option<bool>
471 where
472 S: TokenSource,
473 {
474 let _ = (ctx, rule_index, pred_index);
475 None
476 }
477
478 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
479 where
480 S: TokenSource,
481 {
482 let _ = (ctx, action);
483 false
484 }
485
486 fn lexer_sempred<I, F>(
487 &mut self,
488 ctx: &mut LexerSemCtx<'_, I, F>,
489 rule_index: usize,
490 pred_index: usize,
491 ) -> Option<bool>
492 where
493 I: CharStream,
494 F: TokenFactory,
495 {
496 let _ = (ctx, rule_index, pred_index);
497 None
498 }
499
500 fn lexer_action<I, F>(
510 &mut self,
511 ctx: &mut LexerSemCtx<'_, I, F>,
512 action: LexerCustomAction,
513 ) -> bool
514 where
515 I: CharStream,
516 F: TokenFactory,
517 {
518 let _ = (ctx, action);
519 false
520 }
521}
522
523#[derive(Clone, Copy, Debug, Default)]
526pub struct NoSemanticHooks;
527
528impl SemanticHooks for NoSemanticHooks {}
529
530#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
537pub enum ParserPredicate {
538 True,
539 False,
540 FalseWithMessage {
542 message: &'static str,
543 },
544 Invoke {
547 value: bool,
548 },
549 LookaheadTextEquals {
550 offset: isize,
551 text: &'static str,
552 },
553 LookaheadNotEquals {
554 offset: isize,
555 token_type: i32,
556 },
557 TokenPairAdjacent,
560 ContextChildRuleTextNotEquals {
565 rule_index: usize,
566 text: &'static str,
567 },
568 LocalIntEquals {
571 value: i64,
572 },
573 LocalIntLessOrEqual {
576 value: i64,
577 },
578 MemberModuloEquals {
580 member: usize,
581 modulus: i64,
582 value: i64,
583 equals: bool,
584 },
585 MemberEquals {
587 member: usize,
588 value: i64,
589 equals: bool,
590 },
591}
592
593impl ParserPredicate {
594 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
600 match self {
601 Self::True => ir.expr(PExpr::Bool(true)),
602 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
603 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
604 Self::LookaheadTextEquals { offset, text } => {
605 let token = ir.expr(PExpr::TokenText(offset));
606 let text = ir.intern(text);
607 let text = ir.expr(PExpr::Str(text));
608 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
609 }
610 Self::LookaheadNotEquals { offset, token_type } => {
611 let actual = ir.expr(PExpr::La(offset));
612 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
613 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
614 }
615 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
616 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
617 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
618 let expected = ir.intern(text);
619 let expected = ir.expr(PExpr::Str(expected));
620 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
621 }
622 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
623 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
624 Self::MemberModuloEquals {
625 member,
626 modulus,
627 value,
628 equals,
629 } => {
630 if modulus == 0 {
631 return ir.expr(PExpr::Bool(false));
632 }
633 let member = ir.expr(PExpr::Member(member));
634 let modulus = ir.expr(PExpr::Int(modulus));
635 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
636 let expected = ir.expr(PExpr::Int(value));
637 ir.expr(PExpr::Cmp(
638 if equals { CmpOp::Eq } else { CmpOp::Ne },
639 actual,
640 expected,
641 ))
642 }
643 Self::MemberEquals {
644 member,
645 value,
646 equals,
647 } => {
648 let actual = ir.expr(PExpr::Member(member));
649 let expected = ir.expr(PExpr::Int(value));
650 ir.expr(PExpr::Cmp(
651 if equals { CmpOp::Eq } else { CmpOp::Ne },
652 actual,
653 expected,
654 ))
655 }
656 }
657 }
658
659 #[must_use]
660 pub const fn failure_message(self) -> Option<&'static str> {
661 match self {
662 Self::FalseWithMessage { message } => Some(message),
663 Self::True
664 | Self::False
665 | Self::Invoke { .. }
666 | Self::LookaheadTextEquals { .. }
667 | Self::LookaheadNotEquals { .. }
668 | Self::TokenPairAdjacent
669 | Self::ContextChildRuleTextNotEquals { .. }
670 | Self::LocalIntEquals { .. }
671 | Self::LocalIntLessOrEqual { .. }
672 | Self::MemberModuloEquals { .. }
673 | Self::MemberEquals { .. } => None,
674 }
675 }
676}
677
678fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
679 let local = ir.expr(PExpr::LocalArg);
680 let absent = ir.expr(PExpr::IsNull(local));
681 let expected = ir.expr(PExpr::Int(value));
682 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
683 ir.expr(PExpr::Or([absent, comparison].into()))
684}
685
686#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
699pub enum UnknownSemanticPolicy {
700 #[default]
702 AssumeTrue,
703 AssumeFalse,
705 Error,
708}
709
710fn apply_unknown_predicate_policy(
719 policy: UnknownSemanticPolicy,
720 rule_index: usize,
721 pred_index: usize,
722 hits: &mut Vec<(usize, usize)>,
723) -> bool {
724 match policy {
725 UnknownSemanticPolicy::AssumeTrue => true,
726 UnknownSemanticPolicy::AssumeFalse => false,
727 UnknownSemanticPolicy::Error => {
728 let coordinate = (rule_index, pred_index);
729 if !hits.contains(&coordinate) {
730 hits.push(coordinate);
731 }
732 false
733 }
734 }
735}
736
737#[derive(Clone, Debug, Eq, PartialEq)]
741pub struct ExpectedTokenSet {
742 symbols: BTreeSet<i32>,
743}
744
745impl ExpectedTokenSet {
746 #[must_use]
748 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
749 expected_symbols_display(&self.symbols, vocabulary)
750 }
751}
752
753#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
758pub struct BailErrorStrategy;
759
760impl BailErrorStrategy {
761 #[must_use]
762 pub const fn new() -> Self {
763 Self
764 }
765}
766
767#[derive(Clone, Copy, Debug, Eq, PartialEq)]
769pub enum PredictionMode {
770 Ll,
773 Sll,
776 LlExactAmbigDetection,
778}
779
780#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
786pub struct ParserRuleArg {
787 pub source_state: usize,
789 pub rule_index: usize,
791 pub value: i64,
793 pub inherit_local: bool,
795}
796
797#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
799pub struct ParserMemberAction {
800 pub source_state: usize,
802 pub member: usize,
804 pub delta: i64,
806}
807
808#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
815pub struct ParserReturnAction {
816 pub source_state: usize,
818 pub rule_index: usize,
820 pub name: &'static str,
822 pub value: i64,
824}
825
826impl ParserMemberAction {
827 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
829 let delta = ir.expr(PExpr::Int(self.delta));
830 ParserSemanticAction {
831 source_state: self.source_state,
832 rule_index: usize::MAX,
833 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
834 speculative: true,
835 }
836 }
837}
838
839impl ParserReturnAction {
840 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
842 let name = ir.intern(self.name);
843 let value = ir.expr(PExpr::Int(self.value));
844 ParserSemanticAction {
845 source_state: self.source_state,
846 rule_index: self.rule_index,
847 stmt: ir.stmt(AStmt::SetReturn(name, value)),
848 speculative: false,
849 }
850 }
851}
852
853#[derive(Clone, Copy, Debug, Eq, PartialEq)]
855pub struct ParserSemanticPredicate {
856 pub rule_index: usize,
858 pub pred_index: usize,
860 pub expr: ExprId,
862 pub failure_message: Option<&'static str>,
864}
865
866#[derive(Clone, Copy, Debug, Eq, PartialEq)]
868pub struct ParserSemanticAction {
869 pub source_state: usize,
871 pub rule_index: usize,
873 pub stmt: StmtId,
875 pub speculative: bool,
877}
878
879#[derive(Clone, Debug, Default, Eq, PartialEq)]
886pub struct ParserSemantics {
887 pub ir: SemIr,
888 pub predicates: Vec<ParserSemanticPredicate>,
889 pub actions: Vec<ParserSemanticAction>,
890}
891
892#[derive(Clone, Copy, Debug, Default)]
894pub struct ParserRuntimeOptions<'a> {
895 pub init_action_rules: &'a [usize],
897 pub track_alt_numbers: bool,
899 pub predicates: &'a [(usize, usize, ParserPredicate)],
901 pub semantics: Option<&'a ParserSemantics>,
903 pub rule_args: &'a [ParserRuleArg],
905 pub member_actions: &'a [ParserMemberAction],
907 pub return_actions: &'a [ParserReturnAction],
909 pub unknown_predicate_policy: UnknownSemanticPolicy,
912}
913
914pub trait Parser: Recognizer {
915 fn build_parse_trees(&self) -> bool;
918
919 fn set_build_parse_trees(&mut self, build: bool);
921
922 fn number_of_syntax_errors(&self) -> usize {
925 0
926 }
927
928 fn report_diagnostic_errors(&self) -> bool {
931 false
932 }
933
934 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
937
938 fn prediction_mode(&self) -> PredictionMode {
940 PredictionMode::Ll
941 }
942
943 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
945}
946
947#[derive(Debug)]
948struct CachedPredictionContext {
949 version: usize,
950 atn_key: usize,
951 context: Rc<PredictionContext>,
952}
953
954#[derive(Debug)]
955pub struct BaseParser<S, H = NoSemanticHooks> {
956 input: CommonTokenStream<S>,
957 data: RecognizerData,
958 semantic_hooks: H,
959 build_parse_trees: bool,
960 syntax_errors: usize,
961 report_diagnostic_errors: bool,
962 prediction_mode: PredictionMode,
963 prediction_diagnostics: Vec<ParserDiagnostic>,
964 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
965 generated_parser_diagnostics: Vec<ParserDiagnostic>,
966 generated_sync_expected: Option<TokenBitSet>,
967 int_members: BTreeMap<usize, i64>,
968 rule_context_stack: Vec<RuleContextFrame>,
969 rule_context_version: usize,
970 prediction_context_cache: Option<CachedPredictionContext>,
971 pending_invoking_states: Vec<isize>,
972 precedence_stack: Vec<i32>,
973 invoked_predicates: Vec<(usize, usize)>,
977 bail_on_error: bool,
981 unknown_predicate_policy: UnknownSemanticPolicy,
984 unknown_predicate_hits: Vec<(usize, usize)>,
987 unhandled_action_hits: Vec<(usize, usize)>,
992 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
997 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1003 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1008 rule_stop_reach_cache: Vec<Option<bool>>,
1013 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1018 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1024 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1030 empty_cycle_cache: Vec<Option<bool>>,
1034 single_outcome_memo_mode: SingleOutcomeMemoMode,
1037 single_outcome_probe_seen: FxHashSet<FastRecognizeKey>,
1038 single_outcome_probe_samples: usize,
1039 single_outcome_probe_repeats: usize,
1040 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1043 fast_first_set_prefilter: bool,
1051 fast_recovery_enabled: bool,
1055 fast_token_nodes_enabled: bool,
1060}
1061
1062#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1064pub struct GeneratedDiagnosticsCheckpoint {
1065 diagnostics_len: usize,
1066 syntax_errors: usize,
1067}
1068
1069#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1070struct RuleContextFrame {
1071 rule_index: usize,
1072 invoking_state: isize,
1073}
1074
1075#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1076struct RecognizeOutcome {
1077 index: usize,
1078 consumed_eof: bool,
1079 alt_number: usize,
1080 member_values: BTreeMap<usize, i64>,
1081 return_values: BTreeMap<String, i64>,
1082 diagnostics: Vec<ParserDiagnostic>,
1083 decisions: Vec<usize>,
1084 actions: Vec<ParserAction>,
1085 nodes: Vec<RecognizedNode>,
1086}
1087
1088#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1089enum RecognizedNode {
1090 Token {
1091 index: usize,
1092 },
1093 ErrorToken {
1094 index: usize,
1095 },
1096 MissingToken {
1097 token_type: i32,
1098 at_index: usize,
1099 text: String,
1100 },
1101 Rule {
1102 rule_index: usize,
1103 invoking_state: isize,
1104 alt_number: usize,
1105 start_index: usize,
1106 stop_index: Option<usize>,
1107 return_values: BTreeMap<String, i64>,
1108 children: Vec<Self>,
1109 },
1110 LeftRecursiveBoundary {
1111 rule_index: usize,
1112 },
1113}
1114
1115#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1116struct FastRecognizeOutcome {
1117 index: usize,
1118 consumed_eof: bool,
1119 diagnostics: FastDiagnostics,
1120 nodes: NodeList,
1129}
1130
1131#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
1132#[allow(clippy::box_collection)]
1133struct FastDiagnostics(Option<Box<Vec<ParserDiagnostic>>>);
1134
1135impl FastDiagnostics {
1136 const fn new() -> Self {
1137 Self(None)
1138 }
1139
1140 #[cfg(test)]
1141 fn from_vec(diagnostics: Vec<ParserDiagnostic>) -> Self {
1142 if diagnostics.is_empty() {
1143 Self::new()
1144 } else {
1145 Self(Some(Box::new(diagnostics)))
1146 }
1147 }
1148
1149 fn is_empty(&self) -> bool {
1150 self.0
1151 .as_ref()
1152 .is_none_or(|diagnostics| diagnostics.is_empty())
1153 }
1154
1155 fn as_slice(&self) -> &[ParserDiagnostic] {
1156 self.0.as_deref().map_or(&[], Vec::as_slice)
1157 }
1158
1159 fn insert(&mut self, index: usize, diagnostic: ParserDiagnostic) {
1160 self.0
1161 .get_or_insert_with(Box::default)
1162 .insert(index, diagnostic);
1163 }
1164
1165 fn append(&mut self, other: &mut Self) {
1166 if other.is_empty() {
1167 return;
1168 }
1169 self.0
1170 .get_or_insert_with(Box::default)
1171 .append(other.0.get_or_insert_with(Box::default));
1172 if other.is_empty() {
1173 other.0 = None;
1174 }
1175 }
1176}
1177
1178impl std::ops::Deref for FastDiagnostics {
1179 type Target = [ParserDiagnostic];
1180
1181 fn deref(&self) -> &Self::Target {
1182 self.as_slice()
1183 }
1184}
1185
1186#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
1195enum NodeList {
1196 #[default]
1197 Empty,
1198 One(Rc<FastRecognizedNode>),
1199 Cons {
1200 head: Rc<FastRecognizedNode>,
1201 tail: Rc<Self>,
1202 },
1203}
1204
1205impl NodeList {
1206 const fn new() -> Self {
1208 Self::Empty
1209 }
1210
1211 fn cons(self, node: Rc<FastRecognizedNode>) -> Self {
1214 match self {
1215 Self::Empty => Self::One(node),
1216 existing @ (Self::One(_) | Self::Cons { .. }) => Self::Cons {
1217 head: node,
1218 tail: Rc::new(existing),
1219 },
1220 }
1221 }
1222
1223 fn prepend(&mut self, node: Rc<FastRecognizedNode>) {
1226 let owned = std::mem::take(self);
1227 *self = owned.cons(node);
1228 }
1229
1230 fn to_vec(&self) -> Vec<Rc<FastRecognizedNode>> {
1235 let mut out = Vec::new();
1236 let mut cursor = self;
1237 loop {
1238 match cursor {
1239 Self::Empty => break,
1240 Self::One(node) => {
1241 out.push(Rc::clone(node));
1242 break;
1243 }
1244 Self::Cons { head, tail } => {
1245 out.push(Rc::clone(head));
1246 cursor = tail.as_ref();
1247 }
1248 }
1249 }
1250 out
1251 }
1252
1253 const fn iter(&self) -> NodeListIter<'_> {
1254 NodeListIter { cursor: self }
1255 }
1256
1257 fn len(&self) -> usize {
1258 self.iter().count()
1259 }
1260
1261 fn has_left_recursive_boundary(&self) -> bool {
1262 self.iter()
1263 .any(|node| fast_node_has_left_recursive_boundary(node.as_ref()))
1264 }
1265
1266 fn has_explicit_token_node(&self) -> bool {
1267 self.iter().any(|node| {
1268 matches!(
1269 node.as_ref(),
1270 FastRecognizedNode::Token { .. }
1271 | FastRecognizedNode::ErrorToken { .. }
1272 | FastRecognizedNode::MissingToken { .. }
1273 )
1274 })
1275 }
1276
1277 fn from_vec(nodes: Vec<Rc<FastRecognizedNode>>) -> Self {
1279 let mut list = Self::new();
1280 for node in nodes.into_iter().rev() {
1281 list.prepend(node);
1282 }
1283 list
1284 }
1285}
1286
1287struct NodeListIter<'a> {
1288 cursor: &'a NodeList,
1289}
1290
1291impl<'a> Iterator for NodeListIter<'a> {
1292 type Item = &'a Rc<FastRecognizedNode>;
1293
1294 fn next(&mut self) -> Option<Self::Item> {
1295 match self.cursor {
1296 NodeList::Empty => None,
1297 NodeList::One(node) => {
1298 self.cursor = &NodeList::Empty;
1299 Some(node)
1300 }
1301 NodeList::Cons { head, tail } => {
1302 self.cursor = tail.as_ref();
1303 Some(head)
1304 }
1305 }
1306 }
1307}
1308
1309#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1313enum FastRecognizedNode {
1314 Token {
1315 index: usize,
1316 },
1317 ErrorToken {
1318 index: usize,
1319 },
1320 MissingToken {
1321 token_type: i32,
1322 at_index: usize,
1323 text: String,
1324 },
1325 Rule {
1326 rule_index: usize,
1327 invoking_state: isize,
1328 start_index: usize,
1329 stop_index: Option<usize>,
1330 children: NodeList,
1331 },
1332 LeftRecursiveBoundary {
1336 rule_index: usize,
1337 },
1338}
1339
1340#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1341struct ParserDiagnostic {
1342 line: usize,
1343 column: usize,
1344 message: String,
1345}
1346
1347#[derive(Clone, Debug, Default, Eq, PartialEq)]
1348struct ExpectedTokens {
1349 index: Option<usize>,
1350 symbols: BTreeSet<i32>,
1351 no_viable: Option<NoViableAlternative>,
1352}
1353
1354#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1355struct NoViableAlternative {
1356 start_index: usize,
1357 error_index: usize,
1358}
1359
1360impl ExpectedTokens {
1361 fn record_transition(&mut self, index: usize, transition: &Transition, max_token_type: i32) {
1364 let symbols = transition_expected_symbols(transition, max_token_type);
1365 match self.index {
1366 Some(current) if index < current => {}
1367 Some(current) if index == current => self.symbols.extend(symbols),
1368 _ => {
1369 self.index = Some(index);
1370 self.symbols = symbols;
1371 }
1372 }
1373 }
1374
1375 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
1378 match self.no_viable {
1379 Some(current) if error_index < current.error_index => {}
1380 _ => {
1381 self.no_viable = Some(NoViableAlternative {
1382 start_index,
1383 error_index,
1384 });
1385 }
1386 }
1387 }
1388}
1389
1390#[derive(Clone, Debug, Default, Eq, PartialEq)]
1397struct TokenBitSet {
1398 words: Vec<u64>,
1399}
1400
1401impl TokenBitSet {
1402 fn insert(&mut self, symbol: i32) {
1403 let Some(slot) = token_bit_slot(symbol) else {
1404 return;
1405 };
1406 let word = slot / u64::BITS as usize;
1407 if word >= self.words.len() {
1408 self.words.resize(word + 1, 0);
1409 }
1410 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
1411 }
1412
1413 fn extend_range(&mut self, start: i32, stop: i32) {
1414 let (start, stop) = if start <= stop {
1415 (start, stop)
1416 } else {
1417 (stop, start)
1418 };
1419 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
1420 self.insert(TOKEN_EOF);
1421 }
1422 let positive_start = start.max(1);
1423 if positive_start > stop {
1424 return;
1425 }
1426 let Some(start_slot) = token_bit_slot(positive_start) else {
1427 return;
1428 };
1429 let Some(stop_slot) = token_bit_slot(stop) else {
1430 return;
1431 };
1432 self.extend_slot_range(start_slot, stop_slot);
1433 }
1434
1435 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
1436 if start_slot > stop_slot {
1437 return;
1438 }
1439 let start_word = start_slot / u64::BITS as usize;
1440 let stop_word = stop_slot / u64::BITS as usize;
1441 if stop_word >= self.words.len() {
1442 self.words.resize(stop_word + 1, 0);
1443 }
1444 let start_offset = start_slot % u64::BITS as usize;
1445 let stop_offset = stop_slot % u64::BITS as usize;
1446 if start_word == stop_word {
1447 self.words[start_word] |=
1448 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
1449 return;
1450 }
1451 self.words[start_word] |= !0_u64 << start_offset;
1452 for word in &mut self.words[(start_word + 1)..stop_word] {
1453 *word = !0_u64;
1454 }
1455 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
1456 }
1457
1458 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
1459 for symbol in symbols {
1460 self.insert(symbol);
1461 }
1462 }
1463
1464 fn extend_from(&mut self, other: &Self) {
1465 if other.words.len() > self.words.len() {
1466 self.words.resize(other.words.len(), 0);
1467 }
1468 for (left, right) in self.words.iter_mut().zip(&other.words) {
1469 *left |= *right;
1470 }
1471 }
1472
1473 fn contains(&self, symbol: i32) -> bool {
1474 let Some(slot) = token_bit_slot(symbol) else {
1475 return false;
1476 };
1477 let word = slot / u64::BITS as usize;
1478 self.words
1479 .get(word)
1480 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
1481 }
1482
1483 fn is_empty(&self) -> bool {
1484 self.words.iter().all(|word| *word == 0)
1485 }
1486
1487 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
1488 for (word_index, word) in self.words.iter().copied().enumerate() {
1489 let mut bits = word;
1490 while bits != 0 {
1491 let bit = bits.trailing_zeros() as usize;
1492 if let Some(symbol) = token_bit_symbol(word_index * u64::BITS as usize + bit) {
1493 target.insert(symbol);
1494 }
1495 bits &= bits - 1;
1496 }
1497 }
1498 }
1499
1500 fn to_btree_set(&self) -> BTreeSet<i32> {
1501 let mut out = BTreeSet::new();
1502 self.extend_btree_set(&mut out);
1503 out
1504 }
1505}
1506
1507fn token_bit_slot(symbol: i32) -> Option<usize> {
1508 if symbol == TOKEN_EOF {
1509 Some(0)
1510 } else if symbol > 0 {
1511 usize::try_from(symbol).ok()
1512 } else {
1513 None
1514 }
1515}
1516
1517fn token_bit_symbol(slot: usize) -> Option<i32> {
1518 if slot == 0 {
1519 Some(TOKEN_EOF)
1520 } else {
1521 i32::try_from(slot).ok()
1522 }
1523}
1524
1525fn transition_expected_symbols(transition: &Transition, max_token_type: i32) -> BTreeSet<i32> {
1528 let mut symbols = BTreeSet::new();
1529 match transition {
1530 Transition::Atom { label, .. } => {
1531 symbols.insert(*label);
1532 }
1533 Transition::Range { start, stop, .. } => {
1534 symbols.extend(*start..=*stop);
1535 }
1536 Transition::Set { set, .. } => {
1537 for (start, stop) in set.ranges() {
1538 symbols.extend(*start..=*stop);
1539 }
1540 }
1541 Transition::NotSet { set, .. } => {
1542 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
1543 }
1544 Transition::Wildcard { .. } => {
1545 symbols.extend(1..=max_token_type);
1546 }
1547 Transition::Epsilon { .. }
1548 | Transition::Rule { .. }
1549 | Transition::Predicate { .. }
1550 | Transition::Action { .. }
1551 | Transition::Precedence { .. } => {}
1552 }
1553 symbols
1554}
1555
1556fn transition_expected_token_set(transition: &Transition, max_token_type: i32) -> TokenBitSet {
1557 let mut symbols = TokenBitSet::default();
1558 match transition {
1559 Transition::Atom { label, .. } => {
1560 symbols.insert(*label);
1561 }
1562 Transition::Range { start, stop, .. } => {
1563 symbols.extend_range(*start, *stop);
1564 }
1565 Transition::Set { set, .. } => {
1566 for (start, stop) in set.ranges() {
1567 symbols.extend_range(*start, *stop);
1568 }
1569 }
1570 Transition::NotSet { set, .. } => {
1571 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
1572 }
1573 Transition::Wildcard { .. } => {
1574 symbols.extend_range(1, max_token_type);
1575 }
1576 Transition::Epsilon { .. }
1577 | Transition::Rule { .. }
1578 | Transition::Predicate { .. }
1579 | Transition::Action { .. }
1580 | Transition::Precedence { .. } => {}
1581 }
1582 symbols
1583}
1584
1585fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
1589 let mut symbols = BTreeSet::new();
1590 let mut stack = vec![state_number];
1591 let mut visited = BTreeSet::new();
1592 while let Some(current) = stack.pop() {
1593 if !visited.insert(current) {
1594 continue;
1595 }
1596 let Some(state) = atn.state(current) else {
1597 continue;
1598 };
1599 for transition in &state.transitions {
1600 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1601 if transition_symbols.is_empty() {
1602 if transition.is_epsilon() {
1603 stack.push(transition.target());
1604 }
1605 } else {
1606 symbols.extend(transition_symbols);
1607 }
1608 }
1609 }
1610 symbols
1611}
1612
1613fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
1614 let mut symbols = TokenBitSet::default();
1615 let mut stack = vec![state_number];
1616 let mut visited = BTreeSet::new();
1617 while let Some(current) = stack.pop() {
1618 if !visited.insert(current) {
1619 continue;
1620 }
1621 let Some(state) = atn.state(current) else {
1622 continue;
1623 };
1624 for transition in &state.transitions {
1625 let transition_symbols =
1626 transition_expected_token_set(transition, atn.max_token_type());
1627 if transition_symbols.is_empty() {
1628 if transition.is_epsilon() {
1629 stack.push(transition.target());
1630 }
1631 } else {
1632 symbols.extend_from(&transition_symbols);
1633 }
1634 }
1635 }
1636 symbols
1637}
1638
1639fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
1640 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
1641 return false;
1642 };
1643 let Some(&stop_state) = atn.rule_to_stop_state().get(rule_index) else {
1644 return false;
1645 };
1646 epsilon_reaches_state(atn, state_number, stop_state)
1647}
1648
1649fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
1650 let mut stack = vec![start];
1651 let mut visited = BTreeSet::new();
1652 while let Some(current) = stack.pop() {
1653 if current == target {
1654 return true;
1655 }
1656 if !visited.insert(current) {
1657 continue;
1658 }
1659 let Some(state) = atn.state(current) else {
1660 continue;
1661 };
1662 stack.extend(
1663 state
1664 .transitions
1665 .iter()
1666 .filter(|transition| transition.is_epsilon())
1667 .map(Transition::target),
1668 );
1669 }
1670 false
1671}
1672
1673#[derive(Clone, Debug, Default, Eq, PartialEq)]
1680struct FirstSet {
1681 symbols: TokenBitSet,
1682 nullable: bool,
1683}
1684
1685type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
1692
1693type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
1700
1701#[derive(Default)]
1702struct SharedAtnCache {
1703 first_set: FirstSetCache,
1704 decision_lookahead: DecisionLookaheadCache,
1705 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
1706 rule_stop_reach: FxHashMap<usize, bool>,
1707}
1708
1709thread_local! {
1710 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
1711 RefCell::new(FxHashMap::default());
1712}
1713
1714#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1725struct SharedAtnCacheKey {
1726 atn: usize,
1727 states: usize,
1728 state_count: usize,
1729 max_token_type: i32,
1730}
1731
1732impl SharedAtnCacheKey {
1733 fn for_atn(atn: &Atn) -> Self {
1734 Self {
1735 atn: std::ptr::from_ref::<Atn>(atn) as usize,
1736 states: atn.states().as_ptr() as usize,
1737 state_count: atn.states().len(),
1738 max_token_type: atn.max_token_type(),
1739 }
1740 }
1741}
1742
1743fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
1744 SHARED_ATN_CACHES.with(|cell| {
1745 let key = SharedAtnCacheKey::for_atn(atn);
1746 let mut map = cell.borrow_mut();
1747 let cache = map.entry(key).or_default();
1748 f(&mut cache.first_set)
1749 })
1750}
1751
1752fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
1753 SHARED_ATN_CACHES.with(|cell| {
1754 let key = SharedAtnCacheKey::for_atn(atn);
1755 let mut map = cell.borrow_mut();
1756 let cache = map.entry(key).or_default();
1757 f(cache)
1758 })
1759}
1760
1761#[derive(Debug, Default)]
1770struct DecisionLookahead {
1771 transitions: Vec<TransitionLookSet>,
1772}
1773
1774#[derive(Clone, Debug, Default)]
1781struct TransitionLookSet {
1782 symbols: TokenBitSet,
1783 nullable: bool,
1784}
1785
1786struct FirstSetCtx<'a> {
1790 cache: &'a mut FirstSetCache,
1791 in_progress: BTreeSet<(usize, usize)>,
1792 hit_cycle: bool,
1793}
1794
1795fn rule_first_set(
1804 atn: &Atn,
1805 target: usize,
1806 rule_stop_state: usize,
1807 cache: &mut FirstSetCache,
1808) -> Rc<FirstSet> {
1809 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
1810 return Rc::clone(cached);
1811 }
1812 let mut ctx = FirstSetCtx {
1813 cache,
1814 in_progress: BTreeSet::new(),
1815 hit_cycle: false,
1816 };
1817 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
1818}
1819
1820fn rule_first_set_cached(
1821 atn: &Atn,
1822 target: usize,
1823 rule_stop_state: usize,
1824 ctx: &mut FirstSetCtx<'_>,
1825) -> Rc<FirstSet> {
1826 let key = (target, rule_stop_state);
1827 if let Some(cached) = ctx.cache.get(&key) {
1828 return Rc::clone(cached);
1829 }
1830 if !ctx.in_progress.insert(key) {
1831 return Rc::new(FirstSet::default());
1835 }
1836 let saved_hit_cycle = ctx.hit_cycle;
1837 ctx.hit_cycle = false;
1838 let mut first = FirstSet::default();
1839 let mut visited = BTreeSet::new();
1840 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
1841 ctx.in_progress.remove(&key);
1842 let entry = Rc::new(first);
1843 if !ctx.hit_cycle {
1844 ctx.cache.insert(key, Rc::clone(&entry));
1845 }
1846 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
1847 entry
1848}
1849
1850fn transition_first_set(
1854 atn: &Atn,
1855 transition: &Transition,
1856 rule_stop_state: usize,
1857 cache: &mut FirstSetCache,
1858) -> TransitionLookSet {
1859 match transition {
1860 Transition::Atom { label, .. } => {
1861 let mut symbols = TokenBitSet::default();
1862 symbols.insert(*label);
1863 TransitionLookSet {
1864 symbols,
1865 nullable: false,
1866 }
1867 }
1868 Transition::Range { start, stop, .. } => {
1869 let mut symbols = TokenBitSet::default();
1870 symbols.extend_range(*start, *stop);
1871 TransitionLookSet {
1872 symbols,
1873 nullable: false,
1874 }
1875 }
1876 Transition::Set { set, .. } => {
1877 let mut symbols = TokenBitSet::default();
1878 for (start, stop) in set.ranges() {
1879 symbols.extend_range(*start, *stop);
1880 }
1881 TransitionLookSet {
1882 symbols,
1883 nullable: false,
1884 }
1885 }
1886 Transition::NotSet { set, .. } => {
1887 let max = atn.max_token_type();
1888 let mut symbols = TokenBitSet::default();
1889 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
1890 TransitionLookSet {
1891 symbols,
1892 nullable: false,
1893 }
1894 }
1895 Transition::Wildcard { .. } => {
1896 let mut symbols = TokenBitSet::default();
1897 symbols.extend_range(1, atn.max_token_type());
1898 TransitionLookSet {
1899 symbols,
1900 nullable: false,
1901 }
1902 }
1903 Transition::Epsilon { target }
1904 | Transition::Action { target, .. }
1905 | Transition::Predicate { target, .. }
1906 | Transition::Precedence { target, .. } => {
1907 let first = rule_first_set(atn, *target, rule_stop_state, cache);
1910 TransitionLookSet {
1911 symbols: first.symbols.clone(),
1912 nullable: first.nullable,
1913 }
1914 }
1915 Transition::Rule {
1916 target,
1917 rule_index,
1918 follow_state,
1919 ..
1920 } => {
1921 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
1922 return TransitionLookSet::default();
1923 };
1924 let child = rule_first_set(atn, *target, child_stop, cache);
1925 let mut symbols = child.symbols.clone();
1926 let nullable = if child.nullable {
1927 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
1928 symbols.extend_from(&follow.symbols);
1929 follow.nullable
1930 } else {
1931 false
1932 };
1933 TransitionLookSet { symbols, nullable }
1934 }
1935 }
1936}
1937
1938fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
1959 let mut chosen: Option<usize> = None;
1960 for (index, transition) in entry.transitions.iter().enumerate() {
1961 if transition.nullable {
1962 return None;
1963 }
1964 if transition.symbols.contains(symbol) {
1965 if chosen.is_some() {
1966 return None;
1967 }
1968 chosen = Some(index);
1969 }
1970 }
1971 chosen
1972}
1973
1974fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
1983 let mut matching_non_nullable_alt = None;
1984 let mut nullable_alt = None;
1985 for (index, transition) in entry.transitions.iter().enumerate() {
1986 if transition.nullable {
1987 if nullable_alt.is_some() {
1988 return None;
1989 }
1990 nullable_alt = Some(index);
1991 }
1992 if transition.symbols.contains(symbol) {
1993 if transition.nullable {
1994 continue;
1995 }
1996 if matching_non_nullable_alt.is_some() {
1997 return None;
1998 }
1999 matching_non_nullable_alt = Some(index);
2000 }
2001 }
2002 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2003 return None;
2004 }
2005 if non_greedy {
2006 nullable_alt.or(matching_non_nullable_alt)
2007 } else {
2008 matching_non_nullable_alt.or(nullable_alt)
2009 }
2010}
2011
2012fn should_skip_via_lookahead(
2013 transition: &Transition,
2014 transition_index: usize,
2015 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2016 index: usize,
2017 record_expected: bool,
2018 expected: &mut ExpectedTokens,
2019) -> bool {
2020 let prune_non_consuming = matches!(
2021 transition,
2022 Transition::Epsilon { .. }
2023 | Transition::Action { .. }
2024 | Transition::Predicate { .. }
2025 | Transition::Rule { .. }
2026 | Transition::Precedence { .. }
2027 );
2028 if !prune_non_consuming {
2029 return false;
2030 }
2031 let Some((symbol, entry)) = lookahead_filter else {
2032 return false;
2033 };
2034 let Some(set) = entry.transitions.get(transition_index) else {
2035 return false;
2036 };
2037 if set.symbols.contains(*symbol) || set.nullable {
2038 return false;
2039 }
2040 if record_expected && !set.symbols.is_empty() {
2041 record_pruned_transition_expected(set, index, expected);
2042 }
2043 true
2044}
2045
2046fn should_skip_rule_via_first_set(
2047 first: &FirstSet,
2048 symbol: i32,
2049 record_expected: bool,
2050 index: usize,
2051 expected: &mut ExpectedTokens,
2052) -> bool {
2053 if first.nullable || first.symbols.contains(symbol) {
2054 return false;
2055 }
2056 if record_expected && !first.symbols.is_empty() {
2057 record_token_bit_expected(&first.symbols, index, expected);
2058 }
2059 true
2060}
2061
2062fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2063 match expected.index {
2064 Some(current) if index < current => {}
2065 Some(current) if index == current => {
2066 symbols.extend_btree_set(&mut expected.symbols);
2067 }
2068 _ => {
2069 expected.index = Some(index);
2070 expected.symbols = symbols.to_btree_set();
2071 }
2072 }
2073}
2074
2075fn record_pruned_transition_expected(
2077 set: &TransitionLookSet,
2078 index: usize,
2079 expected: &mut ExpectedTokens,
2080) {
2081 match expected.index {
2082 Some(current) if index < current => {}
2083 Some(current) if index == current => {
2084 set.symbols.extend_btree_set(&mut expected.symbols);
2085 }
2086 _ => {
2087 expected.index = Some(index);
2088 expected.symbols = set.symbols.to_btree_set();
2089 }
2090 }
2091}
2092
2093fn rule_first_set_inner(
2094 atn: &Atn,
2095 state_number: usize,
2096 rule_stop_state: usize,
2097 ctx: &mut FirstSetCtx<'_>,
2098 visited: &mut BTreeSet<usize>,
2099 first: &mut FirstSet,
2100) {
2101 if !visited.insert(state_number) {
2102 return;
2103 }
2104 if state_number == rule_stop_state {
2105 first.nullable = true;
2106 return;
2107 }
2108 let Some(state) = atn.state(state_number) else {
2109 return;
2110 };
2111 for transition in &state.transitions {
2112 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2113 if !transition_symbols.is_empty() {
2114 first.symbols.extend_iter(transition_symbols);
2115 continue;
2116 }
2117 match transition {
2118 Transition::Epsilon { target }
2119 | Transition::Action { target, .. }
2120 | Transition::Predicate { target, .. }
2121 | Transition::Precedence { target, .. } => {
2122 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2123 }
2124 Transition::Rule {
2125 target,
2126 rule_index,
2127 follow_state,
2128 ..
2129 } => {
2130 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
2131 continue;
2132 };
2133 let child_key = (*target, child_stop);
2134 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2135 ctx.hit_cycle = true;
2136 }
2137 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2138 first.symbols.extend_from(&child.symbols);
2139 if child.nullable {
2140 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2141 }
2142 }
2143 Transition::Atom { .. }
2144 | Transition::Range { .. }
2145 | Transition::Set { .. }
2146 | Transition::NotSet { .. }
2147 | Transition::Wildcard { .. } => {}
2148 }
2149 }
2150}
2151
2152fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2155 let mut symbols = BTreeSet::new();
2156 state_sync_symbols_inner(
2157 atn,
2158 state_number,
2159 stop_state,
2160 &mut BTreeSet::new(),
2161 &mut symbols,
2162 );
2163 symbols
2164}
2165
2166fn state_sync_symbols_inner(
2169 atn: &Atn,
2170 state_number: usize,
2171 stop_state: usize,
2172 visited: &mut BTreeSet<usize>,
2173 symbols: &mut BTreeSet<i32>,
2174) {
2175 if !visited.insert(state_number) {
2176 return;
2177 }
2178 if state_number == stop_state {
2179 symbols.insert(TOKEN_EOF);
2180 return;
2181 }
2182 let Some(state) = atn.state(state_number) else {
2183 return;
2184 };
2185 for transition in &state.transitions {
2186 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2187 if transition_symbols.is_empty() {
2188 match transition {
2189 Transition::Rule { target, .. }
2190 | Transition::Epsilon { target }
2191 | Transition::Action { target, .. }
2192 | Transition::Predicate { target, .. }
2193 | Transition::Precedence { target, .. } => {
2194 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
2195 }
2196 Transition::Atom { .. }
2197 | Transition::Range { .. }
2198 | Transition::Set { .. }
2199 | Transition::NotSet { .. }
2200 | Transition::Wildcard { .. } => {}
2201 }
2202 } else {
2203 symbols.extend(transition_symbols);
2204 }
2205 }
2206}
2207
2208fn state_can_reach_symbol_with_precedence(
2209 atn: &Atn,
2210 state_number: usize,
2211 symbol: i32,
2212 precedence: i32,
2213 visited: &mut BTreeSet<usize>,
2214) -> bool {
2215 if !visited.insert(state_number) {
2216 return false;
2217 }
2218 let Some(state) = atn.state(state_number) else {
2219 return false;
2220 };
2221 state.transitions.iter().any(|transition| {
2222 if transition.matches(symbol, 1, atn.max_token_type()) {
2223 return true;
2224 }
2225 if !transition.is_epsilon() {
2226 return false;
2227 }
2228 if matches!(
2229 transition,
2230 Transition::Precedence {
2231 precedence: transition_precedence,
2232 ..
2233 } if *transition_precedence < precedence
2234 ) {
2235 return false;
2236 }
2237 state_can_reach_symbol_with_precedence(
2238 atn,
2239 transition.target(),
2240 symbol,
2241 precedence,
2242 visited,
2243 )
2244 })
2245}
2246
2247fn context_can_match_symbol_before_state(
2248 atn: &Atn,
2249 context: &PredictionContext,
2250 stop_state_number: usize,
2251 symbol: i32,
2252) -> bool {
2253 (0..context.len()).any(|index| {
2254 context.return_state(index).is_some_and(|return_state| {
2255 let parent = context
2256 .parent(index)
2257 .unwrap_or_else(PredictionContext::empty);
2258 state_or_parent_can_match_symbol_before_state(
2259 atn,
2260 return_state,
2261 &parent,
2262 stop_state_number,
2263 symbol,
2264 &mut BTreeSet::new(),
2265 )
2266 })
2267 })
2268}
2269
2270fn state_or_parent_can_match_symbol_before_state(
2271 atn: &Atn,
2272 state_number: usize,
2273 parent: &Rc<PredictionContext>,
2274 stop_state_number: usize,
2275 symbol: i32,
2276 visited: &mut BTreeSet<usize>,
2277) -> bool {
2278 if state_number == EMPTY_RETURN_STATE {
2279 return false;
2280 }
2281 if state_number == stop_state_number {
2282 return context_can_match_symbol_before_state(atn, parent, stop_state_number, symbol);
2283 }
2284 if !visited.insert(state_number) {
2285 return false;
2286 }
2287 let Some(state) = atn.state(state_number) else {
2288 return false;
2289 };
2290 state.transitions.iter().any(|transition| {
2291 if transition.matches(symbol, 1, atn.max_token_type()) {
2292 return true;
2293 }
2294 transition.is_epsilon()
2295 && state_or_parent_can_match_symbol_before_state(
2296 atn,
2297 transition.target(),
2298 parent,
2299 stop_state_number,
2300 symbol,
2301 visited,
2302 )
2303 })
2304}
2305
2306fn next_recovery_context(
2310 atn: &Atn,
2311 state: &AtnState,
2312 inherited: &BTreeSet<i32>,
2313 inherited_state: Option<usize>,
2314) -> (BTreeSet<i32>, Option<usize>) {
2315 let state_symbols = state_expected_symbols(atn, state.state_number);
2316 if state.transitions.len() > 1 && !state_symbols.is_empty() {
2317 let mut symbols = state_symbols;
2318 symbols.extend(inherited.iter().copied());
2319 return (symbols, Some(state.state_number));
2320 }
2321 (inherited.clone(), inherited_state)
2322}
2323
2324fn recovery_expected_symbols(
2325 atn: &Atn,
2326 state_number: usize,
2327 inherited: &BTreeSet<i32>,
2328) -> BTreeSet<i32> {
2329 let mut symbols = state_expected_symbols(atn, state_number);
2330 symbols.extend(inherited.iter().copied());
2331 symbols
2332}
2333
2334fn fast_next_recovery_context<S, H>(
2338 parser: &mut BaseParser<S, H>,
2339 atn: &Atn,
2340 state: &AtnState,
2341 inherited: &Rc<BTreeSet<i32>>,
2342 inherited_state: Option<usize>,
2343) -> (Rc<BTreeSet<i32>>, Option<usize>)
2344where
2345 S: TokenSource,
2346 H: SemanticHooks,
2347{
2348 if state.transitions.len() <= 1 {
2349 return (Rc::clone(inherited), inherited_state);
2350 }
2351 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number);
2352 if state_symbols.is_empty() {
2353 return (Rc::clone(inherited), inherited_state);
2354 }
2355 if inherited.is_empty() {
2356 return (state_symbols, Some(state.state_number));
2357 }
2358 if Rc::ptr_eq(&state_symbols, inherited) {
2359 return (state_symbols, Some(state.state_number));
2360 }
2361 let mut combined = (*state_symbols).clone();
2362 combined.extend(inherited.iter().copied());
2363 (
2364 parser.intern_recovery_symbols(combined),
2365 Some(state.state_number),
2366 )
2367}
2368
2369fn fast_recovery_expected_symbols<S, H>(
2373 parser: &mut BaseParser<S, H>,
2374 atn: &Atn,
2375 state_number: usize,
2376 inherited: &Rc<BTreeSet<i32>>,
2377) -> Rc<BTreeSet<i32>>
2378where
2379 S: TokenSource,
2380 H: SemanticHooks,
2381{
2382 let cached = parser.cached_state_expected_symbols(atn, state_number);
2383 if inherited.is_empty() {
2384 return cached;
2385 }
2386 if cached.is_empty() {
2387 return Rc::clone(inherited);
2388 }
2389 if Rc::ptr_eq(&cached, inherited) {
2390 return cached;
2391 }
2392 let mut combined = (*cached).clone();
2393 combined.extend(inherited.iter().copied());
2394 parser.intern_recovery_symbols(combined)
2395}
2396
2397struct ParserTableSemCtx<'a> {
2398 member_values: &'a mut BTreeMap<usize, i64>,
2399 return_values: &'a mut BTreeMap<String, i64>,
2400}
2401
2402impl semir::PredContext for ParserTableSemCtx<'_> {
2403 fn la(&mut self, _offset: isize) -> i64 {
2404 i64::from(TOKEN_EOF)
2405 }
2406
2407 fn token_text(&mut self, _offset: isize) -> Option<&str> {
2408 None
2409 }
2410
2411 fn token_index_adjacent(&mut self) -> bool {
2412 false
2413 }
2414
2415 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
2416 None
2417 }
2418
2419 fn member(&self, member: usize) -> Option<i64> {
2420 Some(self.member_values.get(&member).copied().unwrap_or_default())
2421 }
2422
2423 fn local_arg(&self) -> Option<i64> {
2424 None
2425 }
2426
2427 fn column(&self) -> Option<i64> {
2428 None
2429 }
2430
2431 fn token_start_column(&self) -> Option<i64> {
2432 None
2433 }
2434
2435 fn token_text_so_far(&self) -> Option<String> {
2436 None
2437 }
2438
2439 fn hook(&mut self, _hook: HookId) -> bool {
2440 false
2441 }
2442}
2443
2444impl semir::ActContext for ParserTableSemCtx<'_> {
2445 fn set_member(&mut self, member: usize, value: i64) {
2446 self.member_values.insert(member, value);
2447 }
2448
2449 fn set_return(&mut self, name: &str, value: i64) {
2450 self.return_values.insert(name.to_owned(), value);
2451 }
2452
2453 fn action_hook(&mut self, _hook: HookId) {}
2454}
2455
2456fn apply_member_actions(
2458 source_state: usize,
2459 actions: &[ParserMemberAction],
2460 semantics: Option<&ParserSemantics>,
2461 values: &mut BTreeMap<usize, i64>,
2462) {
2463 for action in actions
2464 .iter()
2465 .filter(|action| action.source_state == source_state)
2466 {
2467 *values.entry(action.member).or_default() += action.delta;
2468 }
2469 let Some(semantics) = semantics else {
2470 return;
2471 };
2472 let mut return_values = BTreeMap::new();
2473 let mut ctx = ParserTableSemCtx {
2474 member_values: values,
2475 return_values: &mut return_values,
2476 };
2477 for action in semantics
2478 .actions
2479 .iter()
2480 .filter(|action| action.source_state == source_state && action.speculative)
2481 {
2482 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
2483 }
2484}
2485
2486fn member_values_after_action(
2488 source_state: usize,
2489 actions: &[ParserMemberAction],
2490 semantics: Option<&ParserSemantics>,
2491 values: &BTreeMap<usize, i64>,
2492) -> BTreeMap<usize, i64> {
2493 let mut values = values.clone();
2494 apply_member_actions(source_state, actions, semantics, &mut values);
2495 values
2496}
2497
2498fn return_values_after_action(
2500 source_state: usize,
2501 rule_index: usize,
2502 actions: &[ParserReturnAction],
2503 semantics: Option<&ParserSemantics>,
2504 values: &BTreeMap<String, i64>,
2505) -> BTreeMap<String, i64> {
2506 let mut values = values.clone();
2507 for action in actions
2508 .iter()
2509 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
2510 {
2511 values.insert(action.name.to_owned(), action.value);
2512 }
2513 if let Some(semantics) = semantics {
2514 let mut member_values = BTreeMap::new();
2515 let mut ctx = ParserTableSemCtx {
2516 member_values: &mut member_values,
2517 return_values: &mut values,
2518 };
2519 for action in semantics.actions.iter().filter(|action| {
2520 action.source_state == source_state
2521 && action.rule_index == rule_index
2522 && !action.speculative
2523 }) {
2524 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
2525 }
2526 }
2527 values
2528}
2529
2530fn rule_local_int_arg(
2532 rule_args: &[ParserRuleArg],
2533 source_state: usize,
2534 rule_index: usize,
2535 local_int_arg: Option<(usize, i64)>,
2536) -> Option<(usize, i64)> {
2537 rule_args
2538 .iter()
2539 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
2540 .map(|arg| {
2541 let value = if arg.inherit_local {
2542 local_int_arg.map_or(arg.value, |(_, value)| value)
2543 } else {
2544 arg.value
2545 };
2546 (rule_index, value)
2547 })
2548}
2549
2550fn stop_outcome(
2553 index: usize,
2554 consumed_eof: bool,
2555 rule_alt_number: usize,
2556 member_values: BTreeMap<usize, i64>,
2557 return_values: BTreeMap<String, i64>,
2558) -> Vec<RecognizeOutcome> {
2559 vec![RecognizeOutcome {
2560 index,
2561 consumed_eof,
2562 alt_number: rule_alt_number,
2563 member_values,
2564 return_values,
2565 diagnostics: Vec::new(),
2566 decisions: Vec::new(),
2567 actions: Vec::new(),
2568 nodes: Vec::new(),
2569 }]
2570}
2571
2572#[derive(Clone, Debug, Eq, PartialEq)]
2573struct RecognizeRequest<'a> {
2574 state_number: usize,
2575 stop_state: usize,
2576 index: usize,
2577 rule_start_index: usize,
2578 decision_start_index: Option<usize>,
2579 init_action_rules: &'a BTreeSet<usize>,
2580 predicates: &'a [(usize, usize, ParserPredicate)],
2581 semantics: Option<&'a ParserSemantics>,
2582 rule_args: &'a [ParserRuleArg],
2583 member_actions: &'a [ParserMemberAction],
2584 return_actions: &'a [ParserReturnAction],
2585 local_int_arg: Option<(usize, i64)>,
2586 member_values: BTreeMap<usize, i64>,
2587 return_values: BTreeMap<String, i64>,
2588 rule_alt_number: usize,
2589 track_alt_numbers: bool,
2590 consumed_eof: bool,
2591 precedence: i32,
2594 depth: usize,
2595 recovery_symbols: BTreeSet<i32>,
2596 recovery_state: Option<usize>,
2597}
2598
2599#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2600struct RecognizeKey {
2601 state_number: usize,
2602 stop_state: usize,
2603 index: usize,
2604 rule_start_index: usize,
2605 decision_start_index: Option<usize>,
2606 local_int_arg: Option<(usize, i64)>,
2607 member_values: BTreeMap<usize, i64>,
2608 return_values: BTreeMap<String, i64>,
2609 rule_alt_number: usize,
2610 track_alt_numbers: bool,
2611 consumed_eof: bool,
2612 precedence: i32,
2613 recovery_symbols: BTreeSet<i32>,
2614 recovery_state: Option<usize>,
2615}
2616
2617#[derive(Clone, Debug, Eq, PartialEq)]
2618struct EpsilonActionStep {
2619 source_state: usize,
2620 target: usize,
2621 action_rule_index: Option<usize>,
2622 left_recursive_boundary: Option<usize>,
2623 decision: Option<usize>,
2624 decision_start_index: Option<usize>,
2625 alt_number: usize,
2626 recovery_symbols: BTreeSet<i32>,
2627 recovery_state: Option<usize>,
2628}
2629
2630struct RecognizeScratch<'a> {
2631 visiting: &'a mut BTreeSet<RecognizeKey>,
2632 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2633 expected: &'a mut ExpectedTokens,
2634}
2635
2636#[derive(Clone, Debug, Eq, PartialEq)]
2637struct FastRecognizeRequest {
2638 state_number: usize,
2639 stop_state: usize,
2640 index: usize,
2641 rule_start_index: usize,
2642 decision_start_index: Option<usize>,
2643 precedence: i32,
2644 depth: usize,
2645 recovery_symbols: Rc<BTreeSet<i32>>,
2646 recovery_state: Option<usize>,
2647}
2648
2649#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2650struct FastRecognizeTopRequest {
2651 start_state: usize,
2652 stop_state: usize,
2653 start_index: usize,
2654 precedence: i32,
2655 caller_follow_state: Option<usize>,
2656}
2657
2658#[derive(Clone, Debug)]
2665struct FastRecognizeKey {
2666 state_number: usize,
2667 stop_state: usize,
2668 index: usize,
2669 rule_start_index: usize,
2670 decision_start_index: Option<usize>,
2671 precedence: i32,
2672 recovery_symbols_id: usize,
2673 recovery_state: Option<usize>,
2674}
2675
2676impl PartialEq for FastRecognizeKey {
2677 fn eq(&self, other: &Self) -> bool {
2678 if self.state_number != other.state_number
2679 || self.stop_state != other.stop_state
2680 || self.index != other.index
2681 || self.rule_start_index != other.rule_start_index
2682 || self.decision_start_index != other.decision_start_index
2683 || self.precedence != other.precedence
2684 || self.recovery_state != other.recovery_state
2685 || self.recovery_symbols_id != other.recovery_symbols_id
2686 {
2687 return false;
2688 }
2689 true
2690 }
2691}
2692
2693impl Eq for FastRecognizeKey {}
2694
2695impl Hash for FastRecognizeKey {
2696 fn hash<H: Hasher>(&self, hasher: &mut H) {
2697 self.state_number.hash(hasher);
2698 self.stop_state.hash(hasher);
2699 self.index.hash(hasher);
2700 self.rule_start_index.hash(hasher);
2701 self.decision_start_index.hash(hasher);
2702 self.precedence.hash(hasher);
2703 self.recovery_state.hash(hasher);
2704 self.recovery_symbols_id.hash(hasher);
2705 }
2706}
2707
2708struct FastRecoveryRequest<'a, 'b> {
2709 atn: &'a Atn,
2710 transition: &'a Transition,
2711 expected_symbols: Rc<BTreeSet<i32>>,
2712 target: usize,
2713 request: FastRecognizeRequest,
2714 visiting: &'b mut FxHashSet<(usize, usize)>,
2715 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
2716 expected: &'b mut ExpectedTokens,
2717}
2718
2719struct FastCurrentTokenDeletionRequest<'a, 'b> {
2720 atn: &'a Atn,
2721 expected_symbols: Rc<BTreeSet<i32>>,
2722 request: FastRecognizeRequest,
2723 visiting: &'b mut FxHashSet<(usize, usize)>,
2724 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
2725 expected: &'b mut ExpectedTokens,
2726}
2727
2728#[derive(Clone, Copy)]
2729struct FastChildRuleFailureRecoveryRequest<'a> {
2730 atn: &'a Atn,
2731 rule_index: usize,
2732 start_index: usize,
2733 follow_state: usize,
2734 stop_state: usize,
2735 expected: &'a ExpectedTokens,
2736}
2737
2738struct RecoveryRequest<'a, 'b> {
2739 atn: &'a Atn,
2740 transition: &'a Transition,
2741 expected_symbols: BTreeSet<i32>,
2742 target: usize,
2743 request: RecognizeRequest<'a>,
2744 visiting: &'b mut BTreeSet<RecognizeKey>,
2745 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2746 expected: &'b mut ExpectedTokens,
2747}
2748
2749struct CurrentTokenDeletionRequest<'a, 'b> {
2750 atn: &'a Atn,
2751 expected_symbols: BTreeSet<i32>,
2752 request: RecognizeRequest<'a>,
2753 visiting: &'b mut BTreeSet<RecognizeKey>,
2754 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2755 expected: &'b mut ExpectedTokens,
2756}
2757
2758struct ConsumingFailureFallback<'a> {
2761 atn: &'a Atn,
2762 target: usize,
2763 request: RecognizeRequest<'a>,
2764 symbol: i32,
2765 expected_symbols: BTreeSet<i32>,
2766 decision_start_index: Option<usize>,
2767 decision: Option<usize>,
2768}
2769
2770struct ChildRuleFailureRecovery<'a> {
2773 atn: &'a Atn,
2774 rule_index: usize,
2775 start_index: usize,
2776 follow_state: usize,
2777 stop_state: usize,
2778 member_values: BTreeMap<usize, i64>,
2779 expected: &'a ExpectedTokens,
2780}
2781
2782#[derive(Clone, Copy, Debug)]
2784struct PredicateEval<'a> {
2785 index: usize,
2786 rule_index: usize,
2787 pred_index: usize,
2788 predicates: &'a [(usize, usize, ParserPredicate)],
2789 semantics: Option<&'a ParserSemantics>,
2790 context: Option<&'a ParserRuleContext>,
2791 local_int_arg: Option<(usize, i64)>,
2792 member_values: &'a BTreeMap<usize, i64>,
2793}
2794
2795#[derive(Clone, Copy, Debug)]
2796struct ParserSemanticHookRequest<'a> {
2797 index: usize,
2798 rule_index: usize,
2799 pred_index: usize,
2800 context: Option<&'a ParserRuleContext>,
2801 local_int_arg: Option<(usize, i64)>,
2802 member_values: &'a BTreeMap<usize, i64>,
2803}
2804
2805struct ParserSemIrCtx<'a, S, H>
2814where
2815 S: TokenSource,
2816 H: SemanticHooks,
2817{
2818 input: &'a mut CommonTokenStream<S>,
2819 semantic_hooks: &'a mut H,
2820 rule_index: usize,
2821 coordinate_index: usize,
2822 rule_name: Option<&'a str>,
2823 context: Option<&'a ParserRuleContext>,
2824 local_int_arg: Option<(usize, i64)>,
2825 member_values: &'a BTreeMap<usize, i64>,
2826 invoked_predicates: &'a mut Vec<(usize, usize)>,
2827 unknown_predicate_policy: UnknownSemanticPolicy,
2831 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
2832}
2833
2834impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
2835where
2836 S: TokenSource,
2837 H: SemanticHooks,
2838{
2839 fn la(&mut self, offset: isize) -> i64 {
2840 i64::from(self.input.la(offset))
2841 }
2842
2843 fn token_text(&mut self, offset: isize) -> Option<&str> {
2844 self.input.lt(offset).and_then(Token::text)
2845 }
2846
2847 fn token_index_adjacent(&mut self) -> bool {
2848 let Some(first) = self.input.lt(-2).map(Token::token_index) else {
2849 return false;
2850 };
2851 let Some(second) = self.input.lt(-1).map(Token::token_index) else {
2852 return false;
2853 };
2854 first + 1 == second
2855 }
2856
2857 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
2858 self.context.and_then(|context| {
2859 context.children().iter().find_map(|child| match child {
2860 ParseTree::Rule(rule) if rule.context().rule_index() == rule_index => {
2861 Some(child.text())
2862 }
2863 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
2864 })
2865 })
2866 }
2867
2868 fn member(&self, member: usize) -> Option<i64> {
2869 Some(self.member_values.get(&member).copied().unwrap_or_default())
2870 }
2871
2872 fn local_arg(&self) -> Option<i64> {
2873 self.local_int_arg.map(|(_, value)| value)
2874 }
2875
2876 fn column(&self) -> Option<i64> {
2877 None
2878 }
2879
2880 fn token_start_column(&self) -> Option<i64> {
2881 None
2882 }
2883
2884 fn token_text_so_far(&self) -> Option<String> {
2885 None
2886 }
2887
2888 fn hook(&mut self, _hook: HookId) -> bool {
2889 let mut ctx = ParserSemCtx {
2890 input: &mut *self.input,
2891 rule_index: self.rule_index,
2892 coordinate_index: self.coordinate_index,
2893 rule_name: self.rule_name.map(str::to_owned),
2894 context: self.context,
2895 tree: None,
2896 local_int_arg: self.local_int_arg,
2897 member_values: self.member_values,
2898 action: None,
2899 };
2900 match self
2901 .semantic_hooks
2902 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
2903 {
2904 Some(result) => result,
2905 None => apply_unknown_predicate_policy(
2909 self.unknown_predicate_policy,
2910 self.rule_index,
2911 self.coordinate_index,
2912 self.unknown_predicate_hits,
2913 ),
2914 }
2915 }
2916
2917 fn trace_bool(&mut self, value: bool) -> bool {
2918 let key = (self.rule_index, self.coordinate_index);
2919 if !self.invoked_predicates.contains(&key) {
2920 self.invoked_predicates.push(key);
2921 use std::io::Write as _;
2922 let mut stdout = std::io::stdout().lock();
2923 let _ = writeln!(stdout, "eval={value}");
2924 }
2925 value
2926 }
2927}
2928
2929struct PredicateFailureRecovery<'a> {
2931 rule_index: usize,
2932 index: usize,
2933 message: &'a str,
2934 member_values: BTreeMap<usize, i64>,
2935 return_values: BTreeMap<String, i64>,
2936 rule_alt_number: usize,
2937}
2938
2939#[derive(Debug)]
2940enum DirectAdaptiveParseControl {
2941 Fallback(DirectAdaptiveFallback),
2942}
2943
2944#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2945enum DirectAdaptiveFallback {
2946 Action,
2947 InvalidAlt,
2948 LeftRecursiveBoundary,
2949 MissingAtn,
2950 NoTransition,
2951 Predicate,
2952 Prediction,
2953 Precedence,
2954 RuleStop,
2955 SemanticContext,
2956 StepLimit,
2957 TokenMismatch,
2958 UnknownDecision,
2959}
2960
2961type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
2962
2963struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
2964where
2965 S: TokenSource,
2966 H: SemanticHooks,
2967{
2968 parser: &'sim mut BaseParser<S, H>,
2969 atn: &'atn Atn,
2970 simulator: &'sim mut ParserAtnSimulator<'atn>,
2971 decision_by_state: Vec<Option<usize>>,
2972 steps: usize,
2973}
2974
2975#[derive(Clone, Debug, Eq, PartialEq)]
2985pub struct GeneratedMatch {
2986 children: Vec<ParseTree>,
2987 consumed_eof: bool,
2988}
2989
2990impl GeneratedMatch {
2991 #[must_use]
2995 pub fn children(&self) -> &[ParseTree] {
2996 &self.children
2997 }
2998
2999 #[must_use]
3002 pub fn into_children(self) -> Vec<ParseTree> {
3003 self.children
3004 }
3005
3006 #[must_use]
3008 pub const fn consumed_eof(&self) -> bool {
3009 self.consumed_eof
3010 }
3011}
3012
3013impl<S> BaseParser<S, NoSemanticHooks>
3014where
3015 S: TokenSource,
3016{
3017 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
3020 Self::with_semantic_hooks(input, data, NoSemanticHooks)
3021 }
3022}
3023
3024impl<S, H> BaseParser<S, H>
3025where
3026 S: TokenSource,
3027 H: SemanticHooks,
3028{
3029 pub fn with_semantic_hooks(
3031 input: CommonTokenStream<S>,
3032 data: RecognizerData,
3033 semantic_hooks: H,
3034 ) -> Self {
3035 Self {
3036 input,
3037 data,
3038 semantic_hooks,
3039 build_parse_trees: true,
3040 syntax_errors: 0,
3041 report_diagnostic_errors: false,
3042 prediction_mode: PredictionMode::Ll,
3043 prediction_diagnostics: Vec::new(),
3044 reported_prediction_diagnostics: BTreeSet::new(),
3045 generated_parser_diagnostics: Vec::new(),
3046 generated_sync_expected: None,
3047 int_members: BTreeMap::new(),
3048 rule_context_stack: Vec::new(),
3049 rule_context_version: 0,
3050 prediction_context_cache: None,
3051 pending_invoking_states: Vec::new(),
3052 precedence_stack: vec![0],
3053 invoked_predicates: Vec::new(),
3054 bail_on_error: false,
3055 unknown_predicate_policy: UnknownSemanticPolicy::default(),
3056 unknown_predicate_hits: Vec::new(),
3057 unhandled_action_hits: Vec::new(),
3058 rule_first_set_cache: Vec::new(),
3059 state_expected_cache: FxHashMap::default(),
3060 state_expected_token_cache: FxHashMap::default(),
3061 rule_stop_reach_cache: Vec::new(),
3062 recovery_symbols_intern: FxHashMap::default(),
3063 decision_lookahead_cache: FxHashMap::default(),
3064 ll1_decision_cache: FxHashMap::default(),
3065 empty_cycle_cache: Vec::new(),
3066 single_outcome_memo_mode: SingleOutcomeMemoMode::Probe,
3067 single_outcome_probe_seen: FxHashSet::default(),
3068 single_outcome_probe_samples: 0,
3069 single_outcome_probe_repeats: 0,
3070 empty_recovery_symbols: Rc::new(BTreeSet::new()),
3071 fast_first_set_prefilter: true,
3072 fast_recovery_enabled: true,
3073 fast_token_nodes_enabled: true,
3074 }
3075 }
3076
3077 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
3078 &mut self.input
3079 }
3080
3081 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
3092 self.unknown_predicate_policy = policy;
3093 }
3094
3095 #[must_use]
3101 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
3102 let error = self.unknown_semantic_error();
3103 self.unknown_predicate_hits.clear();
3104 self.unhandled_action_hits.clear();
3105 error
3106 }
3107
3108 pub fn reset_unknown_semantic_hits(&mut self) {
3115 self.unknown_predicate_hits.clear();
3116 self.unhandled_action_hits.clear();
3117 }
3118
3119 #[must_use]
3121 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
3122 &self.input
3123 }
3124
3125 #[must_use]
3127 pub fn into_token_stream(self) -> CommonTokenStream<S> {
3128 self.input
3129 }
3130
3131 pub const fn number_of_syntax_errors(&self) -> usize {
3134 self.syntax_errors
3135 }
3136
3137 pub const fn record_generated_syntax_error(&mut self) {
3140 self.record_syntax_errors(1);
3141 }
3142
3143 const fn record_syntax_errors(&mut self, count: usize) {
3144 self.syntax_errors = self.syntax_errors.saturating_add(count);
3145 }
3146
3147 pub fn report_token_source_errors(&mut self) {
3150 report_token_source_errors(&self.input.drain_source_errors());
3151 }
3152
3153 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
3156 GeneratedDiagnosticsCheckpoint {
3157 diagnostics_len: self.generated_parser_diagnostics.len(),
3158 syntax_errors: self.syntax_errors,
3159 }
3160 }
3161
3162 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
3164 self.generated_parser_diagnostics
3165 .truncate(marker.diagnostics_len);
3166 self.syntax_errors = marker.syntax_errors;
3167 self.generated_sync_expected = None;
3168 }
3169
3170 pub fn report_generated_parser_diagnostics(&mut self) {
3172 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
3173 let token_errors = self.input.drain_source_errors();
3174 report_generated_diagnostics(&parser_diagnostics, &token_errors);
3175 }
3176
3177 pub fn record_generated_ambiguity_diagnostic(
3180 &mut self,
3181 atn: &Atn,
3182 state_number: usize,
3183 start_index: usize,
3184 stop_index: usize,
3185 alts: &[usize],
3186 ) {
3187 if !self.report_diagnostic_errors || alts.len() < 2 {
3188 return;
3189 }
3190 let Some(decision) = atn
3191 .decision_to_state()
3192 .iter()
3193 .position(|candidate| *candidate == state_number)
3194 else {
3195 return;
3196 };
3197 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
3198 return;
3199 };
3200 let rule_name = self
3201 .rule_names()
3202 .get(rule_index)
3203 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
3204 let input = display_input_text(&self.input.text(start_index, stop_index));
3205 let alts = alts
3206 .iter()
3207 .map(usize::to_string)
3208 .collect::<Vec<_>>()
3209 .join(", ");
3210 let key = (decision, start_index, format!("{alts}:{input}"));
3211 if !self.reported_prediction_diagnostics.insert(key) {
3212 return;
3213 }
3214 let start_token = self.token_at(start_index);
3215 let stop_token = self.token_at(stop_index);
3216 self.generated_parser_diagnostics.push(diagnostic_for_token(
3217 start_token.as_ref(),
3218 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
3219 ));
3220 self.generated_parser_diagnostics.push(diagnostic_for_token(
3221 stop_token.as_ref(),
3222 format!(
3223 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
3224 ),
3225 ));
3226 }
3227
3228 pub fn record_generated_prediction_diagnostic(
3231 &mut self,
3232 atn: &Atn,
3233 state_number: usize,
3234 prediction: &ParserAtnPrediction,
3235 ) {
3236 let Some(diagnostic) = &prediction.diagnostic else {
3237 return;
3238 };
3239 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
3240 return;
3241 }
3242 let Some(decision) = atn
3243 .decision_to_state()
3244 .iter()
3245 .position(|candidate| *candidate == state_number)
3246 else {
3247 return;
3248 };
3249 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
3250 return;
3251 };
3252 let rule_name = self
3253 .rule_names()
3254 .get(rule_index)
3255 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
3256 let attempt_input = display_input_text(
3257 &self
3258 .input
3259 .text(diagnostic.start_index, diagnostic.sll_stop_index),
3260 );
3261 let result_input = display_input_text(
3262 &self
3263 .input
3264 .text(diagnostic.start_index, diagnostic.ll_stop_index),
3265 );
3266 let alts = diagnostic
3267 .conflicting_alts
3268 .iter()
3269 .map(usize::to_string)
3270 .collect::<Vec<_>>()
3271 .join(", ");
3272 let key = (
3273 decision,
3274 diagnostic.start_index,
3275 format!(
3276 "{:?}:{alts}:{attempt_input}:{result_input}",
3277 diagnostic.kind
3278 ),
3279 );
3280 if !self.reported_prediction_diagnostics.insert(key) {
3281 return;
3282 }
3283 let attempt_token = self.token_at(diagnostic.sll_stop_index);
3284 self.generated_parser_diagnostics.push(diagnostic_for_token(
3285 attempt_token.as_ref(),
3286 format!(
3287 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
3288 ),
3289 ));
3290 let result_token = self.token_at(diagnostic.ll_stop_index);
3291 let message = match diagnostic.kind {
3292 ParserAtnPredictionDiagnosticKind::Ambiguity => {
3293 if !diagnostic.exact {
3298 return;
3299 }
3300 format!(
3301 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
3302 )
3303 }
3304 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
3305 format!(
3306 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
3307 )
3308 }
3309 };
3310 self.generated_parser_diagnostics
3311 .push(diagnostic_for_token(result_token.as_ref(), message));
3312 }
3313
3314 pub fn la(&mut self, offset: isize) -> i32 {
3315 self.input.la_token(offset)
3316 }
3317
3318 pub fn consume(&mut self) {
3319 IntStream::consume(&mut self.input);
3320 }
3321
3322 pub fn set_int_member(&mut self, member: usize, value: i64) {
3324 self.int_members.insert(member, value);
3325 }
3326
3327 pub fn int_member(&self, member: usize) -> Option<i64> {
3329 self.int_members.get(&member).copied()
3330 }
3331
3332 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
3335 self.int_members.clone()
3336 }
3337
3338 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
3340 self.int_members = members;
3341 }
3342
3343 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
3345 let value = self.int_members.entry(member).or_default();
3346 *value += delta;
3347 *value
3348 }
3349
3350 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
3357 let current = self
3358 .input
3359 .lt_ref(1)
3360 .ok_or_else(|| AntlrError::ParserError {
3361 line: 0,
3362 column: 0,
3363 message: "missing current token".to_owned(),
3364 })?;
3365 if current.token_type() == token_type {
3366 self.consume();
3367 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
3368 } else {
3369 Err(AntlrError::MismatchedInput {
3370 expected: self.vocabulary().display_name(token_type),
3371 found: self.vocabulary().display_name(current.token_type()),
3372 })
3373 }
3374 }
3375
3376 pub fn match_token_recovering(
3380 &mut self,
3381 token_type: i32,
3382 follow_state: usize,
3383 atn: &Atn,
3384 ) -> Result<GeneratedMatch, AntlrError> {
3385 let current = self
3386 .input
3387 .lt_ref(1)
3388 .ok_or_else(|| AntlrError::ParserError {
3389 line: 0,
3390 column: 0,
3391 message: "missing current token".to_owned(),
3392 })?;
3393 if current.token_type() == token_type {
3394 self.generated_sync_expected = None;
3395 let consumed_eof = current.token_type() == TOKEN_EOF;
3396 self.consume();
3397 return Ok(GeneratedMatch {
3398 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
3399 consumed_eof,
3400 });
3401 }
3402 let mut expected_symbols = BTreeSet::new();
3403 expected_symbols.insert(token_type);
3404 self.recover_generated_match(
3405 current.as_ref().clone(),
3406 &expected_symbols,
3407 follow_state,
3408 atn,
3409 |symbol| symbol == token_type,
3410 )
3411 }
3412
3413 pub fn match_set_recovering(
3414 &mut self,
3415 intervals: &[(i32, i32)],
3416 follow_state: usize,
3417 atn: &Atn,
3418 ) -> Result<GeneratedMatch, AntlrError> {
3419 let current = self
3420 .input
3421 .lt_ref(1)
3422 .ok_or_else(|| AntlrError::ParserError {
3423 line: 0,
3424 column: 0,
3425 message: "missing current token".to_owned(),
3426 })?;
3427 if interval_set_contains(intervals, current.token_type()) {
3428 self.generated_sync_expected = None;
3429 let consumed_eof = current.token_type() == TOKEN_EOF;
3430 self.consume();
3431 return Ok(GeneratedMatch {
3432 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
3433 consumed_eof,
3434 });
3435 }
3436 let expected_symbols = interval_symbols(intervals);
3437 self.recover_generated_match(
3438 current.as_ref().clone(),
3439 &expected_symbols,
3440 follow_state,
3441 atn,
3442 |symbol| interval_set_contains(intervals, symbol),
3443 )
3444 }
3445
3446 pub fn match_not_set_recovering(
3447 &mut self,
3448 intervals: &[(i32, i32)],
3449 min_vocabulary: i32,
3450 max_vocabulary: i32,
3451 follow_state: usize,
3452 atn: &Atn,
3453 ) -> Result<GeneratedMatch, AntlrError> {
3454 let current = self
3455 .input
3456 .lt_ref(1)
3457 .ok_or_else(|| AntlrError::ParserError {
3458 line: 0,
3459 column: 0,
3460 message: "missing current token".to_owned(),
3461 })?;
3462 if (min_vocabulary..=max_vocabulary).contains(¤t.token_type())
3463 && !interval_set_contains(intervals, current.token_type())
3464 {
3465 self.generated_sync_expected = None;
3466 let consumed_eof = current.token_type() == TOKEN_EOF;
3467 self.consume();
3468 return Ok(GeneratedMatch {
3469 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
3470 consumed_eof,
3471 });
3472 }
3473 let expected_symbols =
3474 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
3475 self.recover_generated_match(
3476 current.as_ref().clone(),
3477 &expected_symbols,
3478 follow_state,
3479 atn,
3480 |symbol| {
3481 (min_vocabulary..=max_vocabulary).contains(&symbol)
3482 && !interval_set_contains(intervals, symbol)
3483 },
3484 )
3485 }
3486
3487 fn recover_generated_match(
3488 &mut self,
3489 current: CommonToken,
3490 expected_symbols: &BTreeSet<i32>,
3491 follow_state: usize,
3492 atn: &Atn,
3493 matches: impl Fn(i32) -> bool,
3494 ) -> Result<GeneratedMatch, AntlrError> {
3495 let expected_display = self.expected_symbols_display(expected_symbols);
3496 if self.bail_on_error {
3497 return Err(AntlrError::ParserError {
3498 line: current.line(),
3499 column: current.column(),
3500 message: format!(
3501 "mismatched input {} expecting {expected_display}",
3502 token_input_display(¤t)
3503 ),
3504 });
3505 }
3506 if current.token_type() != TOKEN_EOF
3507 && let Some(next) = self.input.lt(2).cloned()
3508 && matches(next.token_type())
3509 {
3510 let message = format!(
3511 "extraneous input {} expecting {expected_display}",
3512 token_input_display(¤t)
3513 );
3514 self.push_generated_parser_diagnostic(diagnostic_for_token(Some(¤t), message));
3515 self.record_syntax_errors(1);
3516 self.generated_sync_expected = None;
3517 let consumed_eof = next.token_type() == TOKEN_EOF;
3520 self.consume();
3521 self.consume();
3522 return Ok(GeneratedMatch {
3523 children: vec![
3524 ParseTree::Error(ErrorNode::new(current)),
3525 ParseTree::Terminal(TerminalNode::new(next)),
3526 ],
3527 consumed_eof,
3528 });
3529 }
3530 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
3531 let follow_explicitly_expects_eof = current.token_type() == TOKEN_EOF
3540 && self
3541 .cached_state_expected_symbols(atn, follow_state)
3542 .contains(&TOKEN_EOF);
3543 if follow_symbols.contains(¤t.token_type())
3544 && (current.token_type() != TOKEN_EOF
3545 || self.rule_context_stack.len() > 1
3546 || expected_symbols.is_empty()
3547 || follow_explicitly_expects_eof)
3548 {
3549 let message = format!(
3550 "missing {expected_display} at {}",
3551 token_input_display(¤t)
3552 );
3553 self.push_generated_parser_diagnostic(diagnostic_for_token(Some(¤t), message));
3554 self.record_syntax_errors(1);
3555 self.generated_sync_expected = None;
3556 let token_type = expected_symbols.iter().next().copied().unwrap_or(TOKEN_EOF);
3557 let mut missing_symbol = BTreeSet::new();
3558 missing_symbol.insert(token_type);
3559 let missing_display = self.expected_symbols_display(&missing_symbol);
3560 let token = CommonToken::new(token_type)
3561 .with_text(format!("<missing {missing_display}>"))
3562 .with_span(usize::MAX, usize::MAX)
3563 .with_position(current.line(), current.column());
3564 return Ok(GeneratedMatch {
3569 children: vec![ParseTree::Error(ErrorNode::new(token))],
3570 consumed_eof: false,
3571 });
3572 }
3573 let mismatch_expected = self.generated_sync_expected.take().map_or_else(
3574 || expected_symbols.clone(),
3575 |symbols| symbols.to_btree_set(),
3576 );
3577 let mismatch_expected_display = self.expected_symbols_display(&mismatch_expected);
3578 Err(AntlrError::ParserError {
3579 line: current.line(),
3580 column: current.column(),
3581 message: format!(
3582 "mismatched input {} expecting {mismatch_expected_display}",
3583 token_input_display(¤t)
3584 ),
3585 })
3586 }
3587
3588 fn generated_recovery_follow_symbols(
3589 &mut self,
3590 atn: &Atn,
3591 follow_state: usize,
3592 ) -> BTreeSet<i32> {
3593 let mut follow = self
3594 .cached_state_expected_symbols(atn, follow_state)
3595 .as_ref()
3596 .clone();
3597 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
3598 follow.extend(self.context_expected_symbols(atn));
3599 }
3600 follow
3601 }
3602
3603 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
3604 self.match_token(TOKEN_EOF)
3605 }
3606
3607 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
3608 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
3609 }
3610
3611 pub fn match_not_set(
3612 &mut self,
3613 intervals: &[(i32, i32)],
3614 min_vocabulary: i32,
3615 max_vocabulary: i32,
3616 ) -> Result<ParseTree, AntlrError> {
3617 self.match_interval_condition(intervals, |symbol| {
3618 (min_vocabulary..=max_vocabulary).contains(&symbol)
3619 && !interval_set_contains(intervals, symbol)
3620 })
3621 }
3622
3623 fn match_interval_condition(
3624 &mut self,
3625 intervals: &[(i32, i32)],
3626 matches: impl FnOnce(i32) -> bool,
3627 ) -> Result<ParseTree, AntlrError> {
3628 let current = self
3629 .input
3630 .lt_ref(1)
3631 .ok_or_else(|| AntlrError::ParserError {
3632 line: 0,
3633 column: 0,
3634 message: "missing current token".to_owned(),
3635 })?;
3636 if matches(current.token_type()) {
3637 self.consume();
3638 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
3639 } else {
3640 Err(AntlrError::MismatchedInput {
3641 expected: self.interval_display(intervals),
3642 found: self.vocabulary().display_name(current.token_type()),
3643 })
3644 }
3645 }
3646
3647 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
3648 let values = intervals
3649 .iter()
3650 .map(|(start, stop)| {
3651 if start == stop {
3652 self.vocabulary().display_name(*start)
3653 } else {
3654 format!(
3655 "{}..{}",
3656 self.vocabulary().display_name(*start),
3657 self.vocabulary().display_name(*stop)
3658 )
3659 }
3660 })
3661 .collect::<Vec<_>>()
3662 .join(", ");
3663 format!("{{{values}}}")
3664 }
3665
3666 pub const fn rule_node(&self, context: ParserRuleContext) -> ParseTree {
3667 ParseTree::Rule(RuleNode::new(context))
3668 }
3669
3670 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
3673 self.set_state(state);
3674 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
3675 self.rule_context_stack.push(RuleContextFrame {
3676 rule_index,
3677 invoking_state,
3678 });
3679 self.invalidate_prediction_context_cache();
3680 let start_index = self.current_visible_index();
3681 let mut context = ParserRuleContext::new(rule_index, invoking_state);
3682 if let Some(token) = self.token_ref_at(start_index) {
3683 context.set_start_ref(token);
3684 }
3685 context
3686 }
3687
3688 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
3695 let marker = self.pending_invoking_states.len();
3696 self.pending_invoking_states.push(invoking_state);
3697 marker
3698 }
3699
3700 pub fn discard_invoking_state(&mut self, marker: usize) {
3702 self.pending_invoking_states.truncate(marker);
3703 }
3704
3705 pub fn exit_rule(&mut self) {
3707 self.rule_context_stack.pop();
3708 self.invalidate_prediction_context_cache();
3709 }
3710
3711 pub fn prediction_context(&mut self, atn: &Atn) -> Rc<PredictionContext> {
3714 let atn_ptr: *const Atn = atn;
3715 let atn_key = atn_ptr as usize;
3716 if let Some(cached) = &self.prediction_context_cache
3717 && cached.version == self.rule_context_version
3718 && cached.atn_key == atn_key
3719 {
3720 return Rc::clone(&cached.context);
3721 }
3722 let mut context = PredictionContext::empty();
3723 for frame in self.rule_context_stack.iter().skip(1) {
3724 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
3725 continue;
3726 };
3727 let Some(Transition::Rule { follow_state, .. }) = atn
3728 .state(state_number)
3729 .and_then(|state| state.transitions.first())
3730 else {
3731 continue;
3732 };
3733 context = PredictionContext::singleton(context, *follow_state);
3734 }
3735 self.prediction_context_cache = Some(CachedPredictionContext {
3736 version: self.rule_context_version,
3737 atn_key,
3738 context: Rc::clone(&context),
3739 });
3740 context
3741 }
3742
3743 fn invalidate_prediction_context_cache(&mut self) {
3744 self.rule_context_version = self.rule_context_version.wrapping_add(1);
3745 self.prediction_context_cache = None;
3746 }
3747
3748 pub fn add_parse_child(&self, context: &mut ParserRuleContext, child: ParseTree) {
3753 if self.build_parse_trees {
3754 context.add_child(child);
3755 } else {
3756 context.note_matched_child();
3757 }
3758 }
3759
3760 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
3762 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
3763 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
3764 context.set_stop_ref(token);
3765 }
3766 self.exit_rule();
3767 self.rule_node(context)
3768 }
3769
3770 pub fn recover_generated_rule(
3777 &mut self,
3778 context: &mut ParserRuleContext,
3779 atn: &Atn,
3780 error: AntlrError,
3781 ) {
3782 let diagnostic = self.generated_rule_error_diagnostic(error);
3783 self.push_generated_parser_diagnostic(diagnostic);
3784 self.generated_sync_expected = None;
3785 let recovery_symbols = self.context_expected_symbols(atn);
3786 loop {
3787 let symbol = self.la(1);
3788 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
3789 break;
3790 }
3791 let Some(token) = self.input.lt(1).cloned() else {
3792 break;
3793 };
3794 self.consume();
3795 self.add_parse_child(context, ParseTree::Error(ErrorNode::new(token)));
3796 }
3797 self.record_syntax_errors(1);
3798 }
3799
3800 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
3801 if self
3802 .generated_parser_diagnostics
3803 .iter()
3804 .any(|existing| existing == &diagnostic)
3805 {
3806 return;
3807 }
3808 self.generated_parser_diagnostics.push(diagnostic);
3809 }
3810
3811 fn generated_rule_error_diagnostic(&mut self, error: AntlrError) -> ParserDiagnostic {
3812 match error {
3813 AntlrError::ParserError {
3814 line,
3815 column,
3816 message,
3817 } => ParserDiagnostic {
3818 line,
3819 column,
3820 message,
3821 },
3822 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
3823 self.input.lt(1),
3824 format!("mismatched input {found} expecting {expected}"),
3825 ),
3826 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
3827 self.input.lt(1),
3828 format!("no viable alternative at input {input}"),
3829 ),
3830 AntlrError::LexerError {
3831 line,
3832 column,
3833 message,
3834 } => ParserDiagnostic {
3835 line,
3836 column,
3837 message,
3838 },
3839 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
3840 }
3841 }
3842
3843 pub fn finish_recursion_rule(
3845 &mut self,
3846 mut context: ParserRuleContext,
3847 consumed_eof: bool,
3848 ) -> ParseTree {
3849 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
3850 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
3851 context.set_stop_ref(token);
3852 }
3853 self.unroll_recursion_context();
3854 self.rule_node(context)
3855 }
3856
3857 pub fn enter_recursion_rule(
3859 &mut self,
3860 state: isize,
3861 rule_index: usize,
3862 precedence: i32,
3863 ) -> ParserRuleContext {
3864 self.precedence_stack.push(precedence);
3865 self.enter_rule(state, rule_index)
3866 }
3867
3868 pub fn push_new_recursion_context(
3870 &mut self,
3871 state: isize,
3872 rule_index: usize,
3873 ) -> ParserRuleContext {
3874 self.set_state(state);
3875 ParserRuleContext::new(rule_index, state)
3876 }
3877
3878 pub fn push_new_recursion_context_with_previous(
3881 &mut self,
3882 state: isize,
3883 rule_index: usize,
3884 current: &mut ParserRuleContext,
3885 ) {
3886 self.set_state(state);
3887 if let Some(stop) = self
3888 .rule_stop_token_index(self.input.index(), false)
3889 .and_then(|index| self.token_ref_at(index))
3890 {
3891 current.set_stop_ref(stop);
3892 }
3893 let invoking_state = current.invoking_state();
3894 let start = current.start_ref();
3895 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
3896 if let Some(start) = start {
3897 replacement.set_start_ref(start);
3898 }
3899 let previous = std::mem::replace(current, replacement);
3900 if self.build_parse_trees {
3901 current.add_child(self.rule_node(previous));
3902 }
3903 }
3904
3905 pub fn unroll_recursion_context(&mut self) {
3907 if self.precedence_stack.len() > 1 {
3908 self.precedence_stack.pop();
3909 }
3910 self.exit_rule();
3911 }
3912
3913 pub fn left_recursive_loop_enter_matches(
3918 &mut self,
3919 atn: &Atn,
3920 state_number: usize,
3921 precedence: i32,
3922 ) -> bool {
3923 let symbol = self.la(1);
3924 if symbol == TOKEN_EOF {
3925 return false;
3926 }
3927 let Some(state) = atn.state(state_number) else {
3928 return false;
3929 };
3930 let context = self.prediction_context(atn);
3931 if context_can_match_symbol_before_state(atn, &context, state_number, symbol) {
3932 return false;
3933 }
3934 state.transitions.iter().any(|transition| {
3935 let target = transition.target();
3936 if atn
3937 .state(target)
3938 .is_some_and(|state| state.kind == AtnStateKind::LoopEnd)
3939 {
3940 return false;
3941 }
3942 state_can_reach_symbol_with_precedence(
3943 atn,
3944 target,
3945 symbol,
3946 precedence,
3947 &mut BTreeSet::new(),
3948 )
3949 })
3950 }
3951
3952 pub fn precpred(&self, precedence: i32) -> bool {
3954 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
3955 }
3956
3957 pub fn parser_semantic_predicate_matches(
3960 &mut self,
3961 predicates: &[(usize, usize, ParserPredicate)],
3962 rule_index: usize,
3963 pred_index: usize,
3964 ) -> bool {
3965 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
3966 }
3967
3968 pub fn parser_semantic_predicate_matches_with_local(
3971 &mut self,
3972 predicates: &[(usize, usize, ParserPredicate)],
3973 rule_index: usize,
3974 pred_index: usize,
3975 local_int_arg: i32,
3976 ) -> bool {
3977 self.parser_semantic_predicate_matches_inner(
3978 predicates,
3979 rule_index,
3980 pred_index,
3981 Some((rule_index, i64::from(local_int_arg))),
3982 )
3983 }
3984
3985 fn parser_semantic_predicate_matches_inner(
3986 &mut self,
3987 predicates: &[(usize, usize, ParserPredicate)],
3988 rule_index: usize,
3989 pred_index: usize,
3990 local_int_arg: Option<(usize, i64)>,
3991 ) -> bool {
3992 let index = self.input.index();
3993 let member_values = self.int_members.clone();
3994 self.parser_predicate_matches(PredicateEval {
3995 index,
3996 rule_index,
3997 pred_index,
3998 predicates,
3999 semantics: None,
4000 context: None,
4001 local_int_arg,
4002 member_values: &member_values,
4003 })
4004 }
4005
4006 pub fn parser_semantic_predicate_matches_with_context_and_local(
4009 &mut self,
4010 predicates: &[(usize, usize, ParserPredicate)],
4011 rule_index: usize,
4012 pred_index: usize,
4013 context: &ParserRuleContext,
4014 local_int_arg: i32,
4015 ) -> bool {
4016 let index = self.input.index();
4017 let member_values = self.int_members.clone();
4018 self.parser_predicate_matches(PredicateEval {
4019 index,
4020 rule_index,
4021 pred_index,
4022 predicates,
4023 semantics: None,
4024 context: Some(context),
4025 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
4026 member_values: &member_values,
4027 })
4028 }
4029
4030 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
4033 &mut self,
4034 semantics: &ParserSemantics,
4035 rule_index: usize,
4036 pred_index: usize,
4037 context: &ParserRuleContext,
4038 local_int_arg: i32,
4039 ) -> bool {
4040 let index = self.input.index();
4041 let member_values = self.int_members.clone();
4042 self.parser_predicate_matches(PredicateEval {
4043 index,
4044 rule_index,
4045 pred_index,
4046 predicates: &[],
4047 semantics: Some(semantics),
4048 context: Some(context),
4049 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
4050 member_values: &member_values,
4051 })
4052 }
4053
4054 pub fn parser_semantic_predicate_failure_message(
4057 &self,
4058 rule_index: usize,
4059 pred_index: usize,
4060 predicates: &[(usize, usize, ParserPredicate)],
4061 ) -> Option<&'static str> {
4062 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
4063 }
4064
4065 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
4067 let current = self
4068 .input
4069 .lt_ref(1)
4070 .ok_or_else(|| AntlrError::ParserError {
4071 line: 0,
4072 column: 0,
4073 message: "missing current token".to_owned(),
4074 })?;
4075 if current.token_type() == TOKEN_EOF {
4076 return Err(AntlrError::MismatchedInput {
4077 expected: "wildcard".to_owned(),
4078 found: self.vocabulary().display_name(TOKEN_EOF),
4079 });
4080 }
4081 self.consume();
4082 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
4083 }
4084
4085 #[allow(clippy::unnecessary_wraps)]
4089 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
4090 self.set_state(state);
4091 Ok(())
4092 }
4093
4094 pub fn sync_decision(
4102 &mut self,
4103 atn: &Atn,
4104 state_number: usize,
4105 current_context_empty: bool,
4106 loop_back: bool,
4107 ) -> Result<Vec<ParseTree>, AntlrError> {
4108 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
4109 self.generated_sync_expected = None;
4110 let Some(state) = atn.state(state_number) else {
4111 return Ok(Vec::new());
4112 };
4113 let Some(rule_index) = state.rule_index else {
4114 return Ok(Vec::new());
4115 };
4116 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index).copied() else {
4117 return Ok(Vec::new());
4118 };
4119 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
4120 let symbol = self.la(1);
4121 let mut has_expected_symbols = false;
4122 let mut nullable = false;
4123 let mut explicit_eof_expected = false;
4131 for transition in &entry.transitions {
4132 if transition.symbols.contains(symbol) {
4133 return Ok(Vec::new());
4134 }
4135 has_expected_symbols |= !transition.symbols.is_empty();
4136 nullable |= transition.nullable;
4137 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
4138 }
4139 if nullable && self.context_expected_contains(atn, symbol) {
4144 return Ok(Vec::new());
4145 }
4146 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
4147 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
4148 return Ok(Vec::new());
4149 }
4150 let mut expected = TokenBitSet::default();
4151 for transition in &entry.transitions {
4152 expected.extend_from(&transition.symbols);
4153 }
4154 if let Some(context_expected) = context_expected {
4155 expected.extend_from(&context_expected);
4156 }
4157 let can_delete_in_place =
4158 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
4159 let loop_sync = loop_back;
4176 if symbol != TOKEN_EOF && can_delete_in_place {
4177 let mut cursor = self.input.index();
4178 let mut skipped = Vec::new();
4179 loop {
4180 let current = self.token_type_at(cursor);
4181 if current == TOKEN_EOF {
4182 break;
4183 }
4184 skipped.push(cursor);
4185 let next = self.consume_index(cursor, current);
4186 if next == cursor {
4187 break;
4188 }
4189 let next_symbol = self.token_type_at(next);
4190 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
4198 explicit_eof_expected
4199 } else {
4200 expected.contains(next_symbol)
4201 };
4202 if next_is_expected_stop {
4203 let current_token = self.input.lt(1).cloned();
4204 let expected_symbols = expected.to_btree_set();
4205 let message = format!(
4206 "extraneous input {} expecting {}",
4207 current_token
4208 .as_ref()
4209 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4210 self.expected_symbols_display(&expected_symbols)
4211 );
4212 self.push_generated_parser_diagnostic(diagnostic_for_token(
4213 current_token.as_ref(),
4214 message,
4215 ));
4216 self.record_syntax_errors(1);
4217 let mut children = Vec::with_capacity(skipped.len());
4218 for index in skipped {
4219 if let Some(token) = self.token_at(index) {
4220 self.consume();
4221 children.push(ParseTree::Error(ErrorNode::new(token)));
4222 }
4223 }
4224 return Ok(children);
4225 }
4226 if !loop_sync {
4230 break;
4231 }
4232 cursor = next;
4233 }
4234 }
4235 if nullable {
4236 self.generated_sync_expected = Some(expected);
4237 return Ok(Vec::new());
4238 }
4239 let current = self.input.lt(1).cloned();
4240 let expected_symbols = expected.to_btree_set();
4241 Err(AntlrError::ParserError {
4242 line: current.as_ref().map(Token::line).unwrap_or_default(),
4243 column: current.as_ref().map(Token::column).unwrap_or_default(),
4244 message: format!(
4245 "mismatched input {} expecting {}",
4246 current
4247 .as_ref()
4248 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4249 self.expected_symbols_display(&expected_symbols)
4250 ),
4251 })
4252 }
4253
4254 pub fn ll1_decision_prediction(
4261 &mut self,
4262 atn: &Atn,
4263 state_number: usize,
4264 ) -> Option<ParserAtnPrediction> {
4265 let state = atn.state(state_number)?;
4266 if state.precedence_rule_decision {
4267 return None;
4268 }
4269 let rule_stop = state
4270 .rule_index
4271 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())?;
4272 let symbol = self.la(1);
4273 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
4274 ll1_greedy_alt(&entry, symbol, state.non_greedy).map(|alt| ParserAtnPrediction {
4275 alt: alt + 1,
4276 requires_full_context: false,
4277 has_semantic_context: false,
4278 diagnostic: None,
4279 })
4280 }
4281
4282 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
4283 let context = self.prediction_context(atn);
4284 let mut expected = BTreeSet::new();
4285 self.collect_context_expected_symbols(atn, &context, &mut expected);
4286 expected
4287 }
4288
4289 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
4290 let context = self.prediction_context(atn);
4291 let mut expected = TokenBitSet::default();
4292 self.collect_context_expected_token_set(atn, &context, &mut expected);
4293 expected
4294 }
4295
4296 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
4307 for index in (1..self.rule_context_stack.len()).rev() {
4308 let invoking_state = self.rule_context_stack[index].invoking_state;
4309 let Ok(state_number) = usize::try_from(invoking_state) else {
4310 continue;
4311 };
4312 let Some(Transition::Rule { follow_state, .. }) = atn
4313 .state(state_number)
4314 .and_then(|state| state.transitions.first())
4315 else {
4316 continue;
4317 };
4318 let follow_state = *follow_state;
4319 if self
4320 .cached_state_expected_token_set(atn, follow_state)
4321 .contains(symbol)
4322 {
4323 return true;
4324 }
4325 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
4326 return false;
4327 }
4328 }
4329 symbol == TOKEN_EOF
4330 }
4331
4332 fn collect_context_expected_symbols(
4333 &mut self,
4334 atn: &Atn,
4335 context: &Rc<PredictionContext>,
4336 expected: &mut BTreeSet<i32>,
4337 ) {
4338 if context.is_empty() {
4339 expected.insert(TOKEN_EOF);
4340 return;
4341 }
4342 for index in 0..context.len() {
4343 let Some(return_state) = context.return_state(index) else {
4344 continue;
4345 };
4346 if return_state == EMPTY_RETURN_STATE {
4347 expected.insert(TOKEN_EOF);
4348 continue;
4349 }
4350 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
4351 if self.cached_state_can_reach_rule_stop(atn, return_state)
4352 && let Some(parent) = context.parent(index)
4353 {
4354 self.collect_context_expected_symbols(atn, &parent, expected);
4355 }
4356 }
4357 }
4358
4359 fn collect_context_expected_token_set(
4360 &mut self,
4361 atn: &Atn,
4362 context: &Rc<PredictionContext>,
4363 expected: &mut TokenBitSet,
4364 ) {
4365 if context.is_empty() {
4366 expected.insert(TOKEN_EOF);
4367 return;
4368 }
4369 for index in 0..context.len() {
4370 let Some(return_state) = context.return_state(index) else {
4371 continue;
4372 };
4373 if return_state == EMPTY_RETURN_STATE {
4374 expected.insert(TOKEN_EOF);
4375 continue;
4376 }
4377 let state_expected = self.cached_state_expected_token_set(atn, return_state);
4378 expected.extend_from(&state_expected);
4379 if self.cached_state_can_reach_rule_stop(atn, return_state)
4380 && let Some(parent) = context.parent(index)
4381 {
4382 self.collect_context_expected_token_set(atn, &parent, expected);
4383 }
4384 }
4385 }
4386
4387 pub fn no_viable_alternative_error(&mut self, start_index: usize) -> AntlrError {
4389 let error_index = self.input.index();
4390 self.no_viable_alternative_error_at(start_index, error_index)
4391 }
4392
4393 pub fn no_viable_alternative_error_at(
4398 &mut self,
4399 start_index: usize,
4400 error_index: usize,
4401 ) -> AntlrError {
4402 let diagnostic = self.no_viable_alternative(start_index, error_index);
4403 AntlrError::ParserError {
4404 line: diagnostic.line,
4405 column: diagnostic.column,
4406 message: diagnostic.message,
4407 }
4408 }
4409
4410 pub fn failed_predicate_error(&mut self, message: impl Into<String>) -> AntlrError {
4412 let current = self.input.lt(1).cloned();
4413 AntlrError::ParserError {
4414 line: current.as_ref().map(Token::line).unwrap_or_default(),
4415 column: current.as_ref().map(Token::column).unwrap_or_default(),
4416 message: format!("rule failed predicate: {}", message.into()),
4417 }
4418 }
4419
4420 pub fn failed_predicate_option_error(
4423 &mut self,
4424 rule_index: usize,
4425 message: impl Into<String>,
4426 ) -> AntlrError {
4427 let current = self.input.lt(1).cloned();
4428 let rule_name = self
4429 .rule_names()
4430 .get(rule_index)
4431 .map_or_else(|| rule_index.to_string(), Clone::clone);
4432 AntlrError::ParserError {
4433 line: current.as_ref().map(Token::line).unwrap_or_default(),
4434 column: current.as_ref().map(Token::column).unwrap_or_default(),
4435 message: format!("rule {rule_name} {}", message.into()),
4436 }
4437 }
4438
4439 pub fn parser_action_at_current(
4441 &mut self,
4442 source_state: usize,
4443 rule_index: usize,
4444 start_index: usize,
4445 consumed_eof: bool,
4446 ) -> ParserAction {
4447 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
4448 ParserAction::new(source_state, rule_index, start_index, stop_index)
4449 }
4450
4451 pub fn parser_action_hook(&mut self, action: ParserAction, tree: &ParseTree) -> bool {
4456 let rule_index = action.rule_index();
4457 let rule_name = self.rule_names().get(rule_index).cloned();
4458 let context = match tree {
4459 ParseTree::Rule(rule) if rule.context().rule_index() == rule_index => {
4460 Some(rule.context())
4461 }
4462 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
4463 };
4464 let input = &mut self.input;
4465 let semantic_hooks = &mut self.semantic_hooks;
4466 let member_values = &self.int_members;
4467 let mut ctx = ParserSemCtx {
4468 input,
4469 rule_index,
4470 coordinate_index: usize::MAX,
4471 rule_name,
4472 context,
4473 tree: Some(tree),
4474 local_int_arg: None,
4475 member_values,
4476 action: Some(action),
4477 };
4478 let handled = semantic_hooks.action(&mut ctx, action);
4479 if !handled
4485 && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error)
4486 {
4487 let coordinate = (rule_index, action.source_state());
4488 if !self.unhandled_action_hits.contains(&coordinate) {
4489 self.unhandled_action_hits.push(coordinate);
4490 }
4491 }
4492 handled
4493 }
4494
4495 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
4500 &mut self,
4501 atn: &'atn Atn,
4502 simulator: &mut ParserAtnSimulator<'atn>,
4503 rule_index: usize,
4504 ) -> Result<ParseTree, AntlrError> {
4505 let start_index = self.current_visible_index();
4506 self.clear_prediction_diagnostics();
4507 self.reset_per_parse_caches();
4508 let mut decision_by_state = vec![None; atn.states().len()];
4509 for (decision, &state_number) in atn.decision_to_state().iter().enumerate() {
4510 if let Some(slot) = decision_by_state.get_mut(state_number) {
4511 *slot = Some(decision);
4512 }
4513 }
4514
4515 let result = DirectAdaptiveParser {
4516 parser: self,
4517 atn,
4518 simulator,
4519 decision_by_state,
4520 steps: 0,
4521 }
4522 .parse_rule(rule_index, -1, 0);
4523
4524 match result {
4525 Ok(tree) => {
4526 report_token_source_errors(&self.input.drain_source_errors());
4527 Ok(tree)
4528 }
4529 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
4530 let _ = reason;
4531 self.input.seek(start_index);
4532 self.parse_atn_rule(atn, rule_index)
4533 }
4534 }
4535 }
4536
4537 pub fn parse_atn_rule(
4547 &mut self,
4548 atn: &Atn,
4549 rule_index: usize,
4550 ) -> Result<ParseTree, AntlrError> {
4551 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
4552 }
4553
4554 pub fn parse_atn_rule_with_precedence(
4557 &mut self,
4558 atn: &Atn,
4559 rule_index: usize,
4560 precedence: i32,
4561 ) -> Result<ParseTree, AntlrError> {
4562 let start_state = atn
4563 .rule_to_start_state()
4564 .get(rule_index)
4565 .copied()
4566 .ok_or_else(|| {
4567 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
4568 })?;
4569 let stop_state = atn
4570 .rule_to_stop_state()
4571 .get(rule_index)
4572 .copied()
4573 .filter(|state| *state != usize::MAX)
4574 .ok_or_else(|| {
4575 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
4576 })?;
4577
4578 let start_index = self.current_visible_index();
4579 self.clear_prediction_diagnostics();
4580 self.reset_per_parse_caches();
4581 let caller_follow_state = self.pending_invoking_follow_state(atn);
4582 self.fast_recovery_enabled = false;
4583 self.fast_token_nodes_enabled = false;
4584 let top_request = FastRecognizeTopRequest {
4585 start_state,
4586 stop_state,
4587 start_index,
4588 precedence,
4589 caller_follow_state,
4590 };
4591 let first_pass = self.fast_recognize_top(atn, top_request);
4592 self.fast_token_nodes_enabled = true;
4593 self.fast_recovery_enabled = true;
4594 let needs_tree_retry = matches!(
4595 &first_pass,
4596 Ok((outcome, _)) if self.build_parse_trees && outcome.nodes.has_left_recursive_boundary()
4597 );
4598 let needs_retry = match &first_pass {
4599 Err(_) => true,
4612 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
4613 };
4614 let (outcome, _expected) = if needs_retry {
4615 self.fast_first_set_prefilter = false;
4616 let retry = self.fast_recognize_top(atn, top_request);
4617 self.fast_first_set_prefilter = true;
4618 let selected = if needs_tree_retry {
4619 match retry {
4620 ok @ Ok(_) => ok,
4621 Err(_) => first_pass,
4622 }
4623 } else {
4624 select_better_top_outcome(first_pass, retry)
4625 };
4626 selected.map_err(|expected| {
4627 let error = self.recognition_error(rule_index, start_index, &expected);
4628 self.record_syntax_errors(1);
4629 report_token_source_errors(&self.input.drain_source_errors());
4630 error
4631 })?
4632 } else {
4633 first_pass.expect("first_pass is Ok in the no-retry branch")
4634 };
4635 self.record_syntax_errors(outcome.diagnostics.len());
4636 report_parser_diagnostics(&self.prediction_diagnostics);
4637 report_parser_diagnostics(&outcome.diagnostics);
4638 report_token_source_errors(&self.input.drain_source_errors());
4639 let mut context = ParserRuleContext::with_child_capacity(
4640 rule_index,
4641 self.state(),
4642 if self.build_parse_trees {
4643 outcome.nodes.len()
4644 } else {
4645 0
4646 },
4647 );
4648 if let Some(token) = self.token_ref_at(start_index) {
4649 context.set_start_ref(token);
4650 }
4651 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
4652 if let Some(token) = stop_index.and_then(|token_index| self.token_ref_at(token_index)) {
4653 context.set_stop_ref(token);
4654 }
4655 if self.build_parse_trees {
4656 if outcome.nodes.has_left_recursive_boundary() {
4657 let folded = fold_fast_left_recursive_boundaries(outcome.nodes.to_vec());
4658 if folded.iter().any(|node| {
4659 matches!(
4660 node.as_ref(),
4661 FastRecognizedNode::Token { .. }
4662 | FastRecognizedNode::ErrorToken { .. }
4663 | FastRecognizedNode::MissingToken { .. }
4664 )
4665 }) {
4666 for node in &folded {
4667 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
4668 }
4669 } else {
4670 self.add_fast_implicit_token_children(
4671 &mut context,
4672 start_index,
4673 stop_index,
4674 &folded,
4675 )?;
4676 }
4677 } else if outcome.nodes.has_explicit_token_node() {
4678 for node in outcome.nodes.iter() {
4679 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
4680 }
4681 } else {
4682 self.add_fast_implicit_token_children_iter(
4683 &mut context,
4684 start_index,
4685 stop_index,
4686 outcome.nodes.iter(),
4687 )?;
4688 }
4689 }
4690 self.input.seek(outcome.index);
4691
4692 Ok(self.rule_node(context))
4693 }
4694
4695 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
4696 let invoking_state = self.pending_invoking_states.last().copied()?;
4697 let state_number = usize::try_from(invoking_state).ok()?;
4698 match atn.state(state_number)?.transitions.first()? {
4699 Transition::Rule { follow_state, .. } => Some(*follow_state),
4700 _ => None,
4701 }
4702 }
4703
4704 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
4705 let token_type = self.token_type_at(index);
4708 let visible_channel = self.input.channel();
4709 let token = self.token_at(index);
4710 let is_boundary = token
4711 .as_ref()
4712 .and_then(Token::text)
4713 .is_some_and(is_caller_follow_boundary_text);
4714 let is_boundary_gap = token.as_ref().is_some_and(|token| {
4715 token.channel() != visible_channel
4716 || is_caller_follow_boundary_gap_text(token.text())
4717 });
4718 (token_type, is_boundary, is_boundary_gap)
4719 }
4720
4721 fn fast_recognize_top(
4726 &mut self,
4727 atn: &Atn,
4728 request: FastRecognizeTopRequest,
4729 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
4730 let FastRecognizeTopRequest {
4731 start_state,
4732 stop_state,
4733 start_index,
4734 precedence,
4735 caller_follow_state,
4736 } = request;
4737 let memo_capacity = self.input.size().saturating_mul(8).clamp(65_536, 524_288);
4746 let mut visiting = FxHashSet::with_capacity_and_hasher(256, FxBuildHasher::default());
4747 let mut memo = FxHashMap::with_capacity_and_hasher(memo_capacity, FxBuildHasher::default());
4748 let mut expected = ExpectedTokens::default();
4749 let empty_recovery = self.empty_recovery_symbols();
4750 let outcomes = self.recognize_state_fast(
4751 atn,
4752 FastRecognizeRequest {
4753 state_number: start_state,
4754 stop_state,
4755 index: start_index,
4756 rule_start_index: start_index,
4757 decision_start_index: None,
4758 precedence,
4759 depth: 0,
4760 recovery_symbols: empty_recovery,
4761 recovery_state: None,
4762 },
4763 &mut visiting,
4764 &mut memo,
4765 &mut expected,
4766 );
4767 #[cfg(feature = "perf-counters")]
4768 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
4769 perf_counters::dump();
4770 perf_counters::reset();
4771 }
4772 let caller_follow =
4773 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
4774 match select_best_fast_outcome(
4775 outcomes.into_iter(),
4776 self.prediction_mode,
4777 caller_follow.as_deref(),
4778 |index| self.caller_follow_token_info(index),
4779 ) {
4780 Some(outcome) => Ok((outcome, expected)),
4781 None => Err(expected),
4782 }
4783 }
4784
4785 fn fast_recognized_node_tree(
4788 &mut self,
4789 node: &FastRecognizedNode,
4790 ) -> Result<ParseTree, AntlrError> {
4791 match node {
4792 FastRecognizedNode::Token { index } => {
4793 let token = self
4794 .input
4795 .get_ref(*index)
4796 .ok_or_else(|| AntlrError::ParserError {
4797 line: 0,
4798 column: 0,
4799 message: format!("missing token at index {index}"),
4800 })?;
4801 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
4802 }
4803 FastRecognizedNode::ErrorToken { index } => {
4804 let token = self
4805 .input
4806 .get_ref(*index)
4807 .ok_or_else(|| AntlrError::ParserError {
4808 line: 0,
4809 column: 0,
4810 message: format!("missing error token at index {index}"),
4811 })?;
4812 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
4813 }
4814 FastRecognizedNode::MissingToken {
4815 token_type,
4816 at_index,
4817 text,
4818 } => {
4819 let current = self.token_at(*at_index);
4820 let token = CommonToken::new(*token_type)
4821 .with_text(text.as_str())
4822 .with_span(usize::MAX, usize::MAX)
4823 .with_position(
4824 current.as_ref().map(Token::line).unwrap_or_default(),
4825 current.as_ref().map(Token::column).unwrap_or_default(),
4826 );
4827 Ok(ParseTree::Error(ErrorNode::new(token)))
4828 }
4829 FastRecognizedNode::Rule {
4830 rule_index,
4831 invoking_state,
4832 start_index,
4833 stop_index,
4834 children,
4835 } => {
4836 let mut context = ParserRuleContext::with_child_capacity(
4837 *rule_index,
4838 *invoking_state,
4839 children.len(),
4840 );
4841 if let Some(token) = self.token_ref_at(*start_index) {
4842 context.set_start_ref(token);
4843 }
4844 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
4845 context.set_stop_ref(token);
4846 }
4847 if children.has_left_recursive_boundary() {
4848 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
4849 for child in &folded {
4850 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
4851 }
4852 } else {
4853 for child in children.iter() {
4854 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
4855 }
4856 }
4857 Ok(self.rule_node(context))
4858 }
4859 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
4860 Err(AntlrError::Unsupported(format!(
4861 "unfolded left-recursive boundary for rule {rule_index}"
4862 )))
4863 }
4864 }
4865 }
4866
4867 fn fast_recognized_node_tree_with_implicit_tokens(
4868 &mut self,
4869 node: &FastRecognizedNode,
4870 ) -> Result<ParseTree, AntlrError> {
4871 match node {
4872 FastRecognizedNode::Rule {
4873 rule_index,
4874 invoking_state,
4875 start_index,
4876 stop_index,
4877 children,
4878 } => {
4879 let mut context = ParserRuleContext::with_child_capacity(
4880 *rule_index,
4881 *invoking_state,
4882 children.len(),
4883 );
4884 if let Some(token) = self.token_ref_at(*start_index) {
4885 context.set_start_ref(token);
4886 }
4887 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
4888 context.set_stop_ref(token);
4889 }
4890 if children.has_left_recursive_boundary() {
4891 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
4892 self.add_fast_implicit_token_children(
4893 &mut context,
4894 *start_index,
4895 *stop_index,
4896 &folded,
4897 )?;
4898 } else {
4899 self.add_fast_implicit_token_children_iter(
4900 &mut context,
4901 *start_index,
4902 *stop_index,
4903 children.iter(),
4904 )?;
4905 }
4906 Ok(self.rule_node(context))
4907 }
4908 _ => self.fast_recognized_node_tree(node),
4909 }
4910 }
4911
4912 fn add_fast_implicit_token_children(
4913 &mut self,
4914 context: &mut ParserRuleContext,
4915 start_index: usize,
4916 stop_index: Option<usize>,
4917 children: &[Rc<FastRecognizedNode>],
4918 ) -> Result<(), AntlrError> {
4919 self.add_fast_implicit_token_children_iter(
4920 context,
4921 start_index,
4922 stop_index,
4923 children.iter(),
4924 )
4925 }
4926
4927 fn add_fast_implicit_token_children_iter<'a>(
4928 &mut self,
4929 context: &mut ParserRuleContext,
4930 start_index: usize,
4931 stop_index: Option<usize>,
4932 children: impl IntoIterator<Item = &'a Rc<FastRecognizedNode>>,
4933 ) -> Result<(), AntlrError> {
4934 let mut cursor = Some(start_index);
4935 for child in children {
4936 if let Some((child_start, child_stop)) = fast_recognized_node_span(child.as_ref()) {
4937 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
4938 context.add_child(
4939 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
4940 );
4941 if let Some(child_stop) = child_stop {
4942 cursor = self.next_visible_after_token(child_stop);
4943 }
4944 } else {
4945 context.add_child(
4946 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
4947 );
4948 }
4949 }
4950 if let Some(stop) = stop_index {
4951 self.add_visible_terminals_through(context, cursor, stop)?;
4952 }
4953 Ok(())
4954 }
4955
4956 fn add_visible_terminals_before(
4957 &mut self,
4958 context: &mut ParserRuleContext,
4959 cursor: &mut Option<usize>,
4960 before: usize,
4961 ) -> Result<(), AntlrError> {
4962 let Some(stop) = before.checked_sub(1) else {
4963 return Ok(());
4964 };
4965 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
4966 *cursor = next;
4967 Ok(())
4968 }
4969
4970 fn add_visible_terminals_through(
4971 &mut self,
4972 context: &mut ParserRuleContext,
4973 mut cursor: Option<usize>,
4974 stop: usize,
4975 ) -> Result<Option<usize>, AntlrError> {
4976 while let Some(index) = cursor {
4977 if index > stop {
4978 return Ok(Some(index));
4979 }
4980 let token = self
4981 .input
4982 .get_ref(index)
4983 .ok_or_else(|| AntlrError::ParserError {
4984 line: 0,
4985 column: 0,
4986 message: format!("missing token at index {index}"),
4987 })?;
4988 let is_eof = token.token_type() == TOKEN_EOF;
4989 context.add_child(ParseTree::Terminal(TerminalNode::from_ref(token)));
4990 if is_eof {
4991 return Ok(None);
4992 }
4993 cursor = self.next_visible_after_token(index);
4994 }
4995 Ok(None)
4996 }
4997
4998 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
4999 let next = self.input.next_visible_after(index);
5000 (next != index).then_some(next)
5001 }
5002
5003 pub fn parse_atn_rule_with_actions(
5010 &mut self,
5011 atn: &Atn,
5012 rule_index: usize,
5013 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5014 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
5015 }
5016
5017 pub fn parse_atn_rule_with_action_inits(
5025 &mut self,
5026 atn: &Atn,
5027 rule_index: usize,
5028 init_action_rules: &[usize],
5029 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5030 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
5031 }
5032
5033 pub fn parse_atn_rule_with_action_options(
5039 &mut self,
5040 atn: &Atn,
5041 rule_index: usize,
5042 init_action_rules: &[usize],
5043 track_alt_numbers: bool,
5044 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5045 self.parse_atn_rule_with_runtime_options(
5046 atn,
5047 rule_index,
5048 ParserRuntimeOptions {
5049 init_action_rules,
5050 track_alt_numbers,
5051 ..ParserRuntimeOptions::default()
5052 },
5053 )
5054 }
5055
5056 pub fn parse_atn_rule_with_runtime_options(
5063 &mut self,
5064 atn: &Atn,
5065 rule_index: usize,
5066 options: ParserRuntimeOptions<'_>,
5067 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5068 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
5069 }
5070
5071 pub fn parse_atn_rule_with_runtime_options_and_precedence(
5074 &mut self,
5075 atn: &Atn,
5076 rule_index: usize,
5077 precedence: i32,
5078 options: ParserRuntimeOptions<'_>,
5079 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
5080 let ParserRuntimeOptions {
5081 init_action_rules,
5082 track_alt_numbers,
5083 predicates,
5084 semantics,
5085 rule_args,
5086 member_actions,
5087 return_actions,
5088 unknown_predicate_policy,
5089 } = options;
5090 self.unknown_predicate_policy = unknown_predicate_policy;
5091 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
5098 let start_state = atn
5099 .rule_to_start_state()
5100 .get(rule_index)
5101 .copied()
5102 .ok_or_else(|| {
5103 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
5104 })?;
5105 let stop_state = atn
5106 .rule_to_stop_state()
5107 .get(rule_index)
5108 .copied()
5109 .filter(|state| *state != usize::MAX)
5110 .ok_or_else(|| {
5111 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
5112 })?;
5113
5114 let start_index = self.current_visible_index();
5115 self.clear_prediction_diagnostics();
5116 self.reset_per_parse_caches();
5117 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
5118 let invoking_state = self.pending_invoking_states.pop();
5119 let local_int_arg = invoking_state
5120 .and_then(|state| usize::try_from(state).ok())
5121 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
5122 let mut visiting = BTreeSet::new();
5123 let mut memo = BTreeMap::new();
5124 let mut expected = ExpectedTokens::default();
5125 let member_values = self.int_members.clone();
5126 let return_values = BTreeMap::new();
5127 let outcomes = self.recognize_state(
5128 atn,
5129 RecognizeRequest {
5130 state_number: start_state,
5131 stop_state,
5132 index: start_index,
5133 rule_start_index: start_index,
5134 decision_start_index: None,
5135 init_action_rules: &init_action_rules,
5136 predicates,
5137 semantics,
5138 rule_args,
5139 member_actions,
5140 return_actions,
5141 local_int_arg,
5142 member_values,
5143 return_values,
5144 rule_alt_number: 0,
5145 track_alt_numbers,
5146 consumed_eof: false,
5147 precedence,
5148 depth: 0,
5149 recovery_symbols: BTreeSet::new(),
5150 recovery_state: None,
5151 },
5152 &mut visiting,
5153 &mut memo,
5154 &mut expected,
5155 );
5156 if let Some(error) = self.unknown_semantic_error() {
5157 report_token_source_errors(&self.input.drain_source_errors());
5158 return Err(error);
5165 }
5166 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
5169 let Some(outcome) = select_best_outcome(outcomes.into_iter(), self.prediction_mode) else {
5170 let error = self.recognition_error(rule_index, start_index, &expected);
5171 self.record_syntax_errors(1);
5172 report_token_source_errors(&self.input.drain_source_errors());
5173 return Err(error);
5174 };
5175
5176 self.record_syntax_errors(outcome.diagnostics.len());
5177 report_parser_diagnostics(&self.prediction_diagnostics);
5178 report_parser_diagnostics(&outcome.diagnostics);
5179 report_token_source_errors(&self.input.drain_source_errors());
5180 let mut actions = outcome.actions;
5181 if init_action_rules.contains(&rule_index) {
5182 actions.insert(
5183 0,
5184 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
5185 );
5186 }
5187 let mut context =
5188 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
5189 if track_alt_numbers {
5190 context.set_alt_number(outcome.alt_number);
5191 }
5192 for (name, value) in outcome.return_values {
5193 context.set_int_return(name, value);
5194 }
5195 if let Some(token) = self.token_ref_at(start_index) {
5196 context.set_start_ref(token);
5197 }
5198 if let Some(token) = self.rule_stop_token_ref(outcome.index, outcome.consumed_eof) {
5199 context.set_stop_ref(token);
5200 }
5201 if self.build_parse_trees {
5202 let nodes = fold_left_recursive_boundaries(outcome.nodes);
5203 for node in &nodes {
5204 context.add_child(self.recognized_node_tree(node, track_alt_numbers)?);
5205 }
5206 }
5207 self.input.seek(outcome.index);
5208
5209 Ok((self.rule_node(context), actions))
5210 }
5211
5212 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
5219 let mut context = ParserRuleContext::new(rule_index, self.state());
5220 while self.la(1) != TOKEN_EOF {
5221 let token_type = self.la(1);
5222 let child = self.match_token(token_type)?;
5223 if self.build_parse_trees {
5224 context.add_child(child);
5225 }
5226 }
5227 if self.build_parse_trees {
5228 context.add_child(self.match_eof()?);
5229 }
5230 Ok(self.rule_node(context))
5231 }
5232
5233 fn recognition_error(
5236 &mut self,
5237 rule_index: usize,
5238 start_index: usize,
5239 expected: &ExpectedTokens,
5240 ) -> AntlrError {
5241 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
5242 self.input.seek(index);
5243 let current = self.input.lt(1).cloned();
5244 let line = current.as_ref().map(Token::line).unwrap_or_default();
5245 let column = current.as_ref().map(Token::column).unwrap_or_default();
5246 AntlrError::ParserError {
5247 line,
5248 column,
5249 message,
5250 }
5251 }
5252
5253 fn expected_error_message(
5255 &mut self,
5256 rule_index: usize,
5257 start_index: usize,
5258 expected: &ExpectedTokens,
5259 ) -> (usize, String) {
5260 let index = expected
5261 .index
5262 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
5263 .unwrap_or_else(|| self.input.index());
5264 self.input.seek(index);
5265 let current = self.input.lt(1).cloned();
5266 let message = if expected
5267 .no_viable
5268 .as_ref()
5269 .is_some_and(|no_viable| no_viable.error_index == index)
5270 {
5271 let start = expected
5272 .no_viable
5273 .as_ref()
5274 .map_or(start_index, |no_viable| no_viable.start_index);
5275 let text = display_input_text(&self.input.text(start, index));
5276 format!("no viable alternative at input '{text}'")
5277 } else if expected.symbols.is_empty() {
5278 if expected.index.is_some() {
5279 let found = current
5280 .as_ref()
5281 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
5282 if current
5283 .as_ref()
5284 .is_some_and(|token| token.token_type() == TOKEN_EOF)
5285 {
5286 format!(
5287 "missing {} at {found}",
5288 self.expected_symbols_display(&expected.symbols)
5289 )
5290 } else {
5291 format!("mismatched input {found}")
5292 }
5293 } else {
5294 format!("no viable alternative while parsing rule {rule_index}")
5295 }
5296 } else {
5297 format!(
5298 "mismatched input {} expecting {}",
5299 current
5300 .as_ref()
5301 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5302 self.expected_symbols_display(&expected.symbols)
5303 )
5304 };
5305 (index, message)
5306 }
5307
5308 fn child_rule_failure_recovery(
5311 &mut self,
5312 rule_index: usize,
5313 start_index: usize,
5314 sync_symbols: &BTreeSet<i32>,
5315 member_values: BTreeMap<usize, i64>,
5316 expected: &ExpectedTokens,
5317 ) -> Option<RecognizeOutcome> {
5318 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
5319 let token = self.token_at(error_index);
5320 let mut next_index = error_index;
5321 loop {
5322 let symbol = self.token_type_at(next_index);
5323 if sync_symbols.contains(&symbol) {
5324 if next_index == error_index {
5325 return None;
5326 }
5327 break;
5328 }
5329 if symbol == TOKEN_EOF {
5330 break;
5331 }
5332 let after = self.consume_index(next_index, symbol);
5333 if after == next_index {
5334 break;
5335 }
5336 next_index = after;
5337 }
5338 Some(RecognizeOutcome {
5339 index: next_index,
5340 consumed_eof: false,
5341 alt_number: 0,
5342 member_values,
5343 return_values: BTreeMap::new(),
5344 diagnostics: vec![diagnostic_for_token(token.as_ref(), message)],
5345 decisions: Vec::new(),
5346 actions: Vec::new(),
5347 nodes: vec![RecognizedNode::ErrorToken { index: error_index }],
5348 })
5349 }
5350
5351 fn child_rule_failure_recovery_outcomes(
5354 &mut self,
5355 request: ChildRuleFailureRecovery<'_>,
5356 ) -> Vec<RecognizeOutcome> {
5357 let sync_symbols =
5358 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
5359 self.child_rule_failure_recovery(
5360 request.rule_index,
5361 request.start_index,
5362 &sync_symbols,
5363 request.member_values,
5364 request.expected,
5365 )
5366 .into_iter()
5367 .collect()
5368 }
5369
5370 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
5372 expected_symbols_display(symbols, self.vocabulary())
5373 }
5374
5375 fn single_token_deletion(
5378 &mut self,
5379 transition: &Transition,
5380 index: usize,
5381 max_token_type: i32,
5382 expected_symbols: &BTreeSet<i32>,
5383 ) -> Option<(ParserDiagnostic, usize, i32)> {
5384 let current_symbol = self.token_type_at(index);
5385 if current_symbol == TOKEN_EOF {
5386 return None;
5387 }
5388 let next_index = self.consume_index(index, current_symbol);
5389 if next_index == index {
5390 return None;
5391 }
5392 let next_symbol = self.token_type_at(next_index);
5393 if !transition.matches(next_symbol, 1, max_token_type) {
5394 return None;
5395 }
5396 let transition_expected = transition_expected_symbols(transition, max_token_type);
5397 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
5398 &transition_expected
5399 } else {
5400 expected_symbols
5401 });
5402 let current = self.token_at(index);
5403 let message = format!(
5404 "extraneous input {} expecting {expected_display}",
5405 current
5406 .as_ref()
5407 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
5408 );
5409 Some((
5410 diagnostic_for_token(current.as_ref(), message),
5411 next_index,
5412 next_symbol,
5413 ))
5414 }
5415
5416 fn current_token_deletion(
5419 &mut self,
5420 index: usize,
5421 expected_symbols: &BTreeSet<i32>,
5422 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
5423 if expected_symbols.is_empty() {
5424 return None;
5425 }
5426 let current_symbol = self.token_type_at(index);
5427 if current_symbol == TOKEN_EOF {
5428 return None;
5429 }
5430 let current = self.token_at(index);
5431 let message = format!(
5432 "extraneous input {} expecting {}",
5433 current
5434 .as_ref()
5435 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5436 self.expected_symbols_display(expected_symbols)
5437 );
5438 let diagnostic = diagnostic_for_token(current.as_ref(), message);
5439 let mut skipped = Vec::new();
5440 let mut cursor = index;
5441 loop {
5442 let symbol = self.token_type_at(cursor);
5443 if symbol == TOKEN_EOF {
5444 return None;
5445 }
5446 skipped.push(cursor);
5447 let next_index = self.consume_index(cursor, symbol);
5448 if next_index == cursor {
5449 return None;
5450 }
5451 let next_symbol = self.token_type_at(next_index);
5452 if expected_symbols.contains(&next_symbol) {
5453 return Some((diagnostic, next_index, skipped));
5454 }
5455 cursor = next_index;
5456 }
5457 }
5458
5459 fn single_token_insertion(
5463 &mut self,
5464 transition: &Transition,
5465 index: usize,
5466 max_token_type: i32,
5467 expected_symbols: &BTreeSet<i32>,
5468 follow_symbols: &BTreeSet<i32>,
5469 ) -> Option<(ParserDiagnostic, i32, String)> {
5470 let current_symbol = self.token_type_at(index);
5471 if !follow_symbols.contains(¤t_symbol) {
5472 return None;
5473 }
5474 let transition_expected = transition_expected_symbols(transition, max_token_type);
5475 let token_type = transition_expected.iter().next().copied()?;
5476 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
5477 &transition_expected
5478 } else {
5479 expected_symbols
5480 });
5481 let mut token_symbols = BTreeSet::new();
5482 token_symbols.insert(token_type);
5483 let missing_token_display = self.expected_symbols_display(&token_symbols);
5484 let current = self.token_at(index);
5485 let message = format!(
5486 "missing {expected_display} at {}",
5487 current
5488 .as_ref()
5489 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
5490 );
5491 let text = format!("<missing {missing_token_display}>");
5492 Some((
5493 diagnostic_for_token(current.as_ref(), message),
5494 token_type,
5495 text,
5496 ))
5497 }
5498
5499 fn fast_single_token_deletion_recovery(
5503 &mut self,
5504 recovery: FastRecoveryRequest<'_, '_>,
5505 ) -> Vec<FastRecognizeOutcome> {
5506 let FastRecoveryRequest {
5507 atn,
5508 transition,
5509 expected_symbols,
5510 target,
5511 request,
5512 visiting,
5513 memo,
5514 expected,
5515 } = recovery;
5516 let FastRecognizeRequest {
5517 stop_state,
5518 index,
5519 rule_start_index,
5520 decision_start_index,
5521 precedence,
5522 depth,
5523 ..
5524 } = request;
5525 let Some((diagnostic, next_index, next_symbol)) =
5526 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
5527 else {
5528 return Vec::new();
5529 };
5530 let after_next = self.consume_index(next_index, next_symbol);
5531 let empty_recovery = self.empty_recovery_symbols();
5532 self.recognize_state_fast(
5533 atn,
5534 FastRecognizeRequest {
5535 state_number: target,
5536 stop_state,
5537 index: after_next,
5538 rule_start_index,
5539 decision_start_index,
5540 precedence,
5541 depth: depth + 1,
5542 recovery_symbols: empty_recovery,
5543 recovery_state: None,
5544 },
5545 visiting,
5546 memo,
5547 expected,
5548 )
5549 .into_iter()
5550 .map(|mut outcome| {
5551 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
5552 outcome.diagnostics.insert(0, diagnostic.clone());
5553 if self.fast_token_nodes_enabled {
5554 outcome
5555 .nodes
5556 .prepend(Rc::new(FastRecognizedNode::Token { index: next_index }));
5557 outcome
5558 .nodes
5559 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index }));
5560 }
5561 outcome
5562 })
5563 .collect()
5564 }
5565
5566 fn fast_single_token_insertion_recovery(
5570 &mut self,
5571 recovery: FastRecoveryRequest<'_, '_>,
5572 ) -> Vec<FastRecognizeOutcome> {
5573 let FastRecoveryRequest {
5574 atn,
5575 transition,
5576 expected_symbols,
5577 target,
5578 request,
5579 visiting,
5580 memo,
5581 expected,
5582 } = recovery;
5583 let FastRecognizeRequest {
5584 stop_state,
5585 index,
5586 rule_start_index,
5587 decision_start_index,
5588 precedence,
5589 depth,
5590 ..
5591 } = request;
5592 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
5593 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
5594 transition,
5595 index,
5596 atn.max_token_type(),
5597 &expected_symbols,
5598 &follow_symbols,
5599 ) else {
5600 return Vec::new();
5601 };
5602 let empty_recovery = self.empty_recovery_symbols();
5603 self.recognize_state_fast(
5604 atn,
5605 FastRecognizeRequest {
5606 state_number: target,
5607 stop_state,
5608 index,
5609 rule_start_index,
5610 decision_start_index,
5611 precedence,
5612 depth: depth + 1,
5613 recovery_symbols: empty_recovery,
5614 recovery_state: None,
5615 },
5616 visiting,
5617 memo,
5618 expected,
5619 )
5620 .into_iter()
5621 .map(|mut outcome| {
5622 outcome.diagnostics.insert(0, diagnostic.clone());
5623 outcome
5624 .nodes
5625 .prepend(Rc::new(FastRecognizedNode::MissingToken {
5626 token_type,
5627 at_index: index,
5628 text: text.clone(),
5629 }));
5630 outcome
5631 })
5632 .collect()
5633 }
5634
5635 fn fast_current_token_deletion_recovery(
5638 &mut self,
5639 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
5640 ) -> Vec<FastRecognizeOutcome> {
5641 let FastCurrentTokenDeletionRequest {
5642 atn,
5643 expected_symbols,
5644 mut request,
5645 visiting,
5646 memo,
5647 expected,
5648 } = recovery;
5649 if request.index == request.rule_start_index {
5650 return Vec::new();
5651 }
5652 let Some((diagnostic, next_index, skipped)) =
5653 self.current_token_deletion(request.index, &expected_symbols)
5654 else {
5655 return Vec::new();
5656 };
5657 request.state_number = request.recovery_state.unwrap_or(request.state_number);
5658 request.index = next_index;
5659 request.depth += 1;
5660 request.recovery_state = None;
5661 self.recognize_state_fast(atn, request, visiting, memo, expected)
5662 .into_iter()
5663 .map(|mut outcome| {
5664 outcome.diagnostics.insert(0, diagnostic.clone());
5665 for index in skipped.iter().rev() {
5666 outcome
5667 .nodes
5668 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index: *index }));
5669 }
5670 outcome
5671 })
5672 .collect()
5673 }
5674
5675 fn fast_child_rule_failure_recovery(
5678 &mut self,
5679 rule_index: usize,
5680 start_index: usize,
5681 sync_symbols: &BTreeSet<i32>,
5682 expected: &ExpectedTokens,
5683 ) -> Option<FastRecognizeOutcome> {
5684 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
5685 let token = self.token_at(error_index);
5686 let mut next_index = error_index;
5687 loop {
5688 let symbol = self.token_type_at(next_index);
5689 if sync_symbols.contains(&symbol) {
5690 if next_index == error_index {
5691 return None;
5692 }
5693 break;
5694 }
5695 if symbol == TOKEN_EOF {
5696 break;
5697 }
5698 let after = self.consume_index(next_index, symbol);
5699 if after == next_index {
5700 break;
5701 }
5702 next_index = after;
5703 }
5704 let mut diagnostics = FastDiagnostics::new();
5705 diagnostics.insert(0, diagnostic_for_token(token.as_ref(), message));
5706 let mut nodes = NodeList::new();
5707 if self.fast_token_nodes_enabled {
5708 nodes.prepend(Rc::new(FastRecognizedNode::ErrorToken {
5709 index: error_index,
5710 }));
5711 }
5712 Some(FastRecognizeOutcome {
5713 index: next_index,
5714 consumed_eof: false,
5715 diagnostics,
5716 nodes,
5717 })
5718 }
5719
5720 fn fast_child_rule_failure_recovery_outcomes(
5723 &mut self,
5724 request: FastChildRuleFailureRecoveryRequest<'_>,
5725 ) -> Vec<FastRecognizeOutcome> {
5726 let FastChildRuleFailureRecoveryRequest {
5727 atn,
5728 rule_index,
5729 start_index,
5730 follow_state,
5731 stop_state,
5732 expected,
5733 } = request;
5734 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
5735 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
5736 .into_iter()
5737 .collect()
5738 }
5739
5740 #[allow(clippy::too_many_lines)]
5743 fn recognize_state_fast(
5744 &mut self,
5745 atn: &Atn,
5746 request: FastRecognizeRequest,
5747 visiting: &mut FxHashSet<(usize, usize)>,
5748 memo: &mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
5749 expected: &mut ExpectedTokens,
5750 ) -> Vec<FastRecognizeOutcome> {
5751 #[cfg(feature = "perf-counters")]
5752 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
5753 let FastRecognizeRequest {
5754 mut state_number,
5755 stop_state,
5756 mut index,
5757 rule_start_index,
5758 decision_start_index,
5759 precedence,
5760 mut depth,
5761 recovery_symbols,
5762 recovery_state,
5763 } = request;
5764 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
5783 let mut inline_consumed_eof = false;
5784 loop {
5785 if depth > RECOGNITION_DEPTH_LIMIT {
5786 return Vec::new();
5787 }
5788 if state_number == stop_state {
5789 let mut nodes = NodeList::new();
5790 if self.fast_token_nodes_enabled {
5791 for token_index in inline_consumed_tokens.iter().rev() {
5792 nodes.prepend(Rc::new(FastRecognizedNode::Token {
5793 index: *token_index,
5794 }));
5795 }
5796 }
5797 return vec![FastRecognizeOutcome {
5798 index,
5799 consumed_eof: inline_consumed_eof,
5800 diagnostics: FastDiagnostics::new(),
5801 nodes,
5802 }];
5803 }
5804 let Some(state) = atn.state(state_number) else {
5805 return Vec::new();
5806 };
5807 if state.transitions.len() == 1
5808 && !starts_prediction_decision(state)
5809 && !state.precedence_rule_decision
5810 {
5811 match &state.transitions[0] {
5812 Transition::Epsilon { target }
5813 | Transition::Predicate { target, .. }
5814 | Transition::Action { target, .. }
5815 if left_recursive_boundary(atn, state, *target).is_none() =>
5816 {
5817 #[cfg(feature = "perf-counters")]
5818 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
5819 state_number = *target;
5820 depth += 1;
5821 continue;
5822 }
5823 Transition::Precedence {
5824 target,
5825 precedence: transition_precedence,
5826 } if *transition_precedence >= precedence
5827 && left_recursive_boundary(atn, state, *target).is_none() =>
5828 {
5829 #[cfg(feature = "perf-counters")]
5830 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
5831 state_number = *target;
5832 depth += 1;
5833 continue;
5834 }
5835 Transition::Atom { target, .. }
5845 | Transition::Range { target, .. }
5846 | Transition::Set { target, .. }
5847 | Transition::NotSet { target, .. }
5848 | Transition::Wildcard { target, .. }
5849 if !self.fast_recovery_enabled =>
5850 {
5851 let symbol = self.token_type_at(index);
5852 let transition = &state.transitions[0];
5853 if transition.matches(symbol, 1, atn.max_token_type()) {
5854 #[cfg(feature = "perf-counters")]
5855 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
5856 if self.fast_token_nodes_enabled {
5857 inline_consumed_tokens.push(index);
5858 }
5859 inline_consumed_eof |= symbol == TOKEN_EOF;
5860 index = self.consume_index(index, symbol);
5861 state_number = *target;
5862 depth += 1;
5863 continue;
5864 }
5865 }
5868 _ => {}
5869 }
5870 }
5871 break;
5872 }
5873 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
5877 let Some(state) = atn.state(state_number) else {
5878 return Vec::new();
5879 };
5880 let transition_count = state.transitions.len();
5881 let memo_lookup_enabled = self.fast_recovery_enabled || transition_count > 1;
5882 let key = if self.fast_recovery_enabled {
5892 FastRecognizeKey {
5893 state_number,
5894 stop_state,
5895 index,
5896 rule_start_index,
5897 decision_start_index,
5898 precedence,
5899 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
5900 recovery_state,
5901 }
5902 } else {
5903 FastRecognizeKey {
5904 state_number,
5905 stop_state,
5906 index,
5907 rule_start_index: 0,
5908 decision_start_index: None,
5909 precedence,
5910 recovery_symbols_id: 0,
5911 recovery_state: None,
5912 }
5913 };
5914 if memo_lookup_enabled {
5915 if let Some(outcomes) = memo.get(&key) {
5916 #[cfg(feature = "perf-counters")]
5917 {
5918 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
5919 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
5920 }
5921 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
5925 let inline_eof = inline_consumed_eof;
5926 let inline_tokens = &inline_consumed_tokens;
5927 return outcomes
5928 .iter()
5929 .cloned()
5930 .map(|mut outcome| {
5931 if inline_eof {
5932 outcome.consumed_eof = true;
5933 }
5934 if self.fast_token_nodes_enabled {
5935 for token_index in inline_tokens.iter().rev() {
5936 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
5937 index: *token_index,
5938 }));
5939 }
5940 }
5941 outcome
5942 })
5943 .collect();
5944 }
5945 return outcomes.to_vec();
5946 }
5947 #[cfg(feature = "perf-counters")]
5948 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
5949 }
5950
5951 let needs_cycle_guard =
5959 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number);
5960 #[cfg(feature = "perf-counters")]
5961 if needs_cycle_guard {
5962 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
5963 } else {
5964 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
5965 match &state.transitions[0] {
5966 Transition::Rule { .. } => {
5967 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
5968 }
5969 Transition::Atom { .. }
5970 | Transition::Range { .. }
5971 | Transition::Set { .. }
5972 | Transition::NotSet { .. }
5973 | Transition::Wildcard { .. } => {
5974 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
5975 }
5976 _ => {
5977 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
5978 }
5979 }
5980 }
5981 let visit_id = (state_number, index);
5982 if needs_cycle_guard && !visiting.insert(visit_id) {
5983 #[cfg(feature = "perf-counters")]
5984 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
5985 return Vec::new();
5986 }
5987 let next_decision_start_index = if starts_prediction_decision(state) {
5988 Some(index)
5989 } else {
5990 decision_start_index
5991 };
5992 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
5993 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
5994 } else {
5995 (Rc::clone(&recovery_symbols), recovery_state)
5996 };
5997
5998 let transition_count = state.transitions.len();
6017 let lookahead_filter = if transition_count > 1
6018 && self.fast_first_set_prefilter
6019 && !state.precedence_rule_decision
6020 && (!self.fast_recovery_enabled || state.kind != AtnStateKind::RuleStart)
6021 {
6022 state
6023 .rule_index
6024 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())
6025 .map(|rule_stop| {
6026 let symbol = self.token_type_at(index);
6027 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6028 (symbol, entry)
6029 })
6030 } else {
6031 None
6032 };
6033 let ll1_only_alt: Option<usize> = if transition_count > 1
6042 && let Some((symbol, entry)) = lookahead_filter.as_ref()
6043 {
6044 let key = (state.state_number, *symbol);
6045 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
6046 cached
6047 } else {
6048 let result = ll1_unique_alt(entry, *symbol);
6049 self.ll1_decision_cache.insert(key, result);
6050 result
6051 }
6052 } else {
6053 None
6054 };
6055 let lookahead_filter = lookahead_filter.as_ref();
6056 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
6062 for (transition_index, transition) in state.transitions.iter().enumerate() {
6063 if let Some(alt) = ll1_only_alt {
6064 if alt != transition_index {
6066 continue;
6067 }
6068 } else if should_skip_via_lookahead(
6069 transition,
6070 transition_index,
6071 lookahead_filter,
6072 index,
6073 self.fast_recovery_enabled,
6074 expected,
6075 ) {
6076 continue;
6077 }
6078 match transition {
6079 Transition::Epsilon { target }
6080 | Transition::Predicate { target, .. }
6081 | Transition::Action { target, .. } => {
6082 #[cfg(feature = "perf-counters")]
6083 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
6084 let boundary = left_recursive_boundary(atn, state, *target);
6085 outcomes.extend(
6086 self.recognize_state_fast(
6087 atn,
6088 FastRecognizeRequest {
6089 state_number: *target,
6090 stop_state,
6091 index,
6092 rule_start_index,
6093 decision_start_index: next_decision_start_index,
6094 precedence,
6095 depth: depth + 1,
6096 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6097 recovery_state: epsilon_recovery_state,
6098 },
6099 visiting,
6100 memo,
6101 expected,
6102 )
6103 .into_iter()
6104 .map(|mut outcome| {
6105 if let Some(rule_index) = boundary {
6106 outcome.nodes.prepend(Rc::new(
6107 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
6108 ));
6109 }
6110 outcome
6111 }),
6112 );
6113 }
6114 Transition::Precedence {
6115 target,
6116 precedence: transition_precedence,
6117 } => {
6118 if *transition_precedence >= precedence {
6119 let boundary = left_recursive_boundary(atn, state, *target);
6120 outcomes.extend(
6121 self.recognize_state_fast(
6122 atn,
6123 FastRecognizeRequest {
6124 state_number: *target,
6125 stop_state,
6126 index,
6127 rule_start_index,
6128 decision_start_index: next_decision_start_index,
6129 precedence,
6130 depth: depth + 1,
6131 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6132 recovery_state: epsilon_recovery_state,
6133 },
6134 visiting,
6135 memo,
6136 expected,
6137 )
6138 .into_iter()
6139 .map(|mut outcome| {
6140 if let Some(rule_index) = boundary {
6141 outcome.nodes.prepend(Rc::new(
6142 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
6143 ));
6144 }
6145 outcome
6146 }),
6147 );
6148 }
6149 }
6150 Transition::Rule {
6151 target,
6152 rule_index,
6153 follow_state,
6154 precedence: rule_precedence,
6155 ..
6156 } => {
6157 #[cfg(feature = "perf-counters")]
6158 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
6159 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
6160 else {
6161 continue;
6162 };
6163 let symbol = self.token_type_at(index);
6175 if self.fast_first_set_prefilter {
6176 let first = self.cached_rule_first_set(atn, *target, child_stop);
6189 if should_skip_rule_via_first_set(
6190 &first,
6191 symbol,
6192 self.fast_recovery_enabled,
6193 index,
6194 expected,
6195 ) {
6196 continue;
6197 }
6198 }
6199 let expected_before_child =
6200 self.fast_recovery_enabled.then(|| expected.clone());
6201 let mut children = self.recognize_state_fast(
6202 atn,
6203 FastRecognizeRequest {
6204 state_number: *target,
6205 stop_state: child_stop,
6206 index,
6207 rule_start_index: index,
6208 decision_start_index: None,
6209 precedence: *rule_precedence,
6210 depth: depth + 1,
6211 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
6212 recovery_state: epsilon_recovery_state,
6213 },
6214 visiting,
6215 memo,
6216 expected,
6217 );
6218 if children.is_empty() && self.fast_recovery_enabled {
6219 children = self.fast_child_rule_failure_recovery_outcomes(
6220 FastChildRuleFailureRecoveryRequest {
6221 atn,
6222 rule_index: *rule_index,
6223 start_index: index,
6224 follow_state: *follow_state,
6225 stop_state,
6226 expected,
6227 },
6228 );
6229 }
6230 if let Some(expected_before_child) = expected_before_child {
6231 if children
6232 .iter()
6233 .any(|child| child.diagnostics.is_empty() && child.index > index)
6234 {
6235 *expected = expected_before_child;
6236 }
6237 }
6238 for child in children {
6239 let child_index = child.index;
6240 let child_consumed_eof = child.consumed_eof;
6241 let child_diagnostics = child.diagnostics;
6242 let empty_recovery = self.empty_recovery_symbols();
6243 let follow_outcomes = self.recognize_state_fast(
6244 atn,
6245 FastRecognizeRequest {
6246 state_number: *follow_state,
6247 stop_state,
6248 index: child_index,
6249 rule_start_index,
6250 decision_start_index: next_decision_start_index,
6251 precedence,
6252 depth: depth + 1,
6253 recovery_symbols: empty_recovery,
6254 recovery_state: None,
6255 },
6256 visiting,
6257 memo,
6258 expected,
6259 );
6260 if follow_outcomes.is_empty() {
6261 continue;
6262 }
6263 let child_node = Rc::new(FastRecognizedNode::Rule {
6264 rule_index: *rule_index,
6265 invoking_state: invoking_state_number(state_number),
6266 start_index: index,
6267 stop_index: self.rule_stop_token_index(child_index, child_consumed_eof),
6268 children: child.nodes,
6269 });
6270 let child_diags_empty = child_diagnostics.is_empty();
6271 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
6272 outcome.consumed_eof |= child_consumed_eof;
6273 if !child_diags_empty {
6276 let mut diagnostics = child_diagnostics.clone();
6277 diagnostics.append(&mut outcome.diagnostics);
6278 outcome.diagnostics = diagnostics;
6279 }
6280 outcome.nodes.prepend(Rc::clone(&child_node));
6281 outcome
6282 }));
6283 }
6284 }
6285 Transition::Atom { target, .. }
6286 | Transition::Range { target, .. }
6287 | Transition::Set { target, .. }
6288 | Transition::NotSet { target, .. }
6289 | Transition::Wildcard { target, .. } => {
6290 #[cfg(feature = "perf-counters")]
6291 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
6292 let symbol = self.token_type_at(index);
6293 if transition.matches(symbol, 1, atn.max_token_type()) {
6294 let next_index = self.consume_index(index, symbol);
6295 let empty_recovery = self.empty_recovery_symbols();
6296 outcomes.extend(
6297 self.recognize_state_fast(
6298 atn,
6299 FastRecognizeRequest {
6300 state_number: *target,
6301 stop_state,
6302 index: next_index,
6303 rule_start_index,
6304 decision_start_index: next_decision_start_index,
6305 precedence,
6306 depth: depth + 1,
6307 recovery_symbols: empty_recovery,
6308 recovery_state: None,
6309 },
6310 visiting,
6311 memo,
6312 expected,
6313 )
6314 .into_iter()
6315 .map(|mut outcome| {
6316 outcome.consumed_eof |= symbol == TOKEN_EOF;
6317 if self.fast_token_nodes_enabled {
6318 outcome
6319 .nodes
6320 .prepend(Rc::new(FastRecognizedNode::Token { index }));
6321 }
6322 outcome
6323 }),
6324 );
6325 } else {
6326 if !self.fast_recovery_enabled {
6327 continue;
6335 }
6336 let expected_symbols = fast_recovery_expected_symbols(
6337 self,
6338 atn,
6339 state.state_number,
6340 &recovery_symbols,
6341 );
6342 if expected_symbols.contains(&symbol) {
6343 continue;
6344 }
6345 {
6346 expected.record_transition(index, transition, atn.max_token_type());
6347 record_no_viable_if_ambiguous(
6348 expected,
6349 next_decision_start_index,
6350 index,
6351 );
6352 outcomes.extend(self.fast_single_token_deletion_recovery(
6353 FastRecoveryRequest {
6354 atn,
6355 transition,
6356 expected_symbols: Rc::clone(&expected_symbols),
6357 target: *target,
6358 request: FastRecognizeRequest {
6359 state_number,
6360 stop_state,
6361 index,
6362 rule_start_index,
6363 decision_start_index,
6364 precedence,
6365 depth,
6366 recovery_symbols: Rc::clone(&recovery_symbols),
6367 recovery_state,
6368 },
6369 visiting,
6370 memo,
6371 expected,
6372 },
6373 ));
6374 if !state_is_left_recursive_rule(atn, state) {
6375 outcomes.extend(self.fast_single_token_insertion_recovery(
6376 FastRecoveryRequest {
6377 atn,
6378 transition,
6379 expected_symbols: Rc::clone(&expected_symbols),
6380 target: *target,
6381 request: FastRecognizeRequest {
6382 state_number,
6383 stop_state,
6384 index,
6385 rule_start_index,
6386 decision_start_index,
6387 precedence,
6388 depth,
6389 recovery_symbols: Rc::clone(&recovery_symbols),
6390 recovery_state,
6391 },
6392 visiting,
6393 memo,
6394 expected,
6395 },
6396 ));
6397 }
6398 outcomes.extend(self.fast_current_token_deletion_recovery(
6399 FastCurrentTokenDeletionRequest {
6400 atn,
6401 expected_symbols,
6402 request: FastRecognizeRequest {
6403 state_number,
6404 stop_state,
6405 index,
6406 rule_start_index,
6407 decision_start_index,
6408 precedence,
6409 depth,
6410 recovery_symbols: Rc::clone(&recovery_symbols),
6411 recovery_state,
6412 },
6413 visiting,
6414 memo,
6415 expected,
6416 },
6417 ));
6418 }
6419 }
6420 }
6421 }
6422 }
6423
6424 if needs_cycle_guard {
6425 visiting.remove(&visit_id);
6426 }
6427 if matches!(
6428 self.prediction_mode,
6429 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
6430 ) && self.fast_recovery_enabled
6431 {
6432 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
6436 }
6437 if self.fast_recovery_enabled {
6438 dedupe_fast_outcomes(&mut outcomes);
6439 } else {
6440 dedupe_clean_fast_outcomes(&mut outcomes);
6441 }
6442 let should_memoize = self.fast_recovery_enabled
6452 || (transition_count > 1
6453 && (outcomes.is_empty()
6454 || outcomes.len() > 1
6455 || (outcomes.len() == 1 && self.should_memoize_single_outcome(&key))));
6456 let apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
6460 if inline_consumed_eof {
6461 outcome.consumed_eof = true;
6462 }
6463 if !inline_consumed_tokens.is_empty() {
6464 for token_index in inline_consumed_tokens.iter().rev() {
6465 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
6466 index: *token_index,
6467 }));
6468 }
6469 }
6470 outcome
6471 };
6472 if should_memoize {
6473 #[cfg(feature = "perf-counters")]
6474 {
6475 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
6476 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
6477 match outcomes.len() {
6478 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
6479 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
6480 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
6481 }
6482 }
6483 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
6488 memo.insert(key, Rc::clone(&stored));
6489 if inline_pending {
6490 return stored.iter().cloned().map(apply_inline_pending).collect();
6491 }
6492 return stored.to_vec();
6493 }
6494 #[cfg(feature = "perf-counters")]
6495 match outcomes.len() {
6496 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
6497 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
6498 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
6499 }
6500 if inline_pending {
6501 return outcomes.into_iter().map(apply_inline_pending).collect();
6502 }
6503 outcomes
6504 }
6505
6506 fn single_token_deletion_recovery(
6509 &mut self,
6510 recovery: RecoveryRequest<'_, '_>,
6511 ) -> Vec<RecognizeOutcome> {
6512 let RecoveryRequest {
6513 atn,
6514 transition,
6515 expected_symbols,
6516 target,
6517 request,
6518 visiting,
6519 memo,
6520 expected,
6521 } = recovery;
6522 let RecognizeRequest {
6523 stop_state,
6524 index,
6525 rule_start_index,
6526 decision_start_index,
6527 init_action_rules,
6528 predicates,
6529 semantics,
6530 rule_args,
6531 member_actions,
6532 return_actions,
6533 local_int_arg,
6534 member_values,
6535 return_values,
6536 rule_alt_number,
6537 track_alt_numbers,
6538 consumed_eof,
6539 precedence,
6540 depth,
6541 ..
6542 } = request;
6543 let Some((diagnostic, next_index, next_symbol)) =
6544 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
6545 else {
6546 return Vec::new();
6547 };
6548 let after_next = self.consume_index(next_index, next_symbol);
6549 self.recognize_state(
6550 atn,
6551 RecognizeRequest {
6552 state_number: target,
6553 stop_state,
6554 index: after_next,
6555 rule_start_index,
6556 decision_start_index,
6557 init_action_rules,
6558 predicates,
6559 semantics,
6560 rule_args,
6561 member_actions,
6562 return_actions,
6563 local_int_arg,
6564 member_values,
6565 return_values,
6566 rule_alt_number,
6567 track_alt_numbers,
6568 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
6569 precedence,
6570 depth: depth + 1,
6571 recovery_symbols: BTreeSet::new(),
6572 recovery_state: None,
6573 },
6574 visiting,
6575 memo,
6576 expected,
6577 )
6578 .into_iter()
6579 .map(|mut outcome| {
6580 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
6581 outcome.diagnostics.insert(0, diagnostic.clone());
6582 outcome
6583 .nodes
6584 .insert(0, RecognizedNode::Token { index: next_index });
6585 outcome
6586 .nodes
6587 .insert(0, RecognizedNode::ErrorToken { index });
6588 outcome
6589 })
6590 .collect()
6591 }
6592
6593 fn current_token_deletion_recovery(
6596 &mut self,
6597 recovery: CurrentTokenDeletionRequest<'_, '_>,
6598 ) -> Vec<RecognizeOutcome> {
6599 let CurrentTokenDeletionRequest {
6600 atn,
6601 expected_symbols,
6602 mut request,
6603 visiting,
6604 memo,
6605 expected,
6606 } = recovery;
6607 let error_index = request.index;
6608 if error_index == request.rule_start_index {
6609 return Vec::new();
6610 }
6611 let Some((diagnostic, next_index, skipped)) =
6612 self.current_token_deletion(error_index, &expected_symbols)
6613 else {
6614 return Vec::new();
6615 };
6616 request.state_number = request.recovery_state.unwrap_or(request.state_number);
6617 request.index = next_index;
6618 request.depth += 1;
6619 request.recovery_state = None;
6620 self.recognize_state(atn, request, visiting, memo, expected)
6621 .into_iter()
6622 .map(|mut outcome| {
6623 outcome.diagnostics.insert(0, diagnostic.clone());
6624 for index in skipped.iter().rev() {
6625 outcome
6626 .nodes
6627 .insert(0, RecognizedNode::ErrorToken { index: *index });
6628 }
6629 outcome
6630 })
6631 .collect()
6632 }
6633
6634 fn consuming_failure_fallback(
6637 &mut self,
6638 fallback: ConsumingFailureFallback<'_>,
6639 visiting: &mut BTreeSet<RecognizeKey>,
6640 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
6641 expected: &mut ExpectedTokens,
6642 ) -> Vec<RecognizeOutcome> {
6643 if fallback.expected_symbols.is_empty() {
6644 return Vec::new();
6645 }
6646 if fallback.symbol == TOKEN_EOF {
6647 return self.eof_consuming_failure_fallback(fallback, expected);
6648 }
6649 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
6650 }
6651
6652 fn non_eof_consuming_failure_fallback(
6655 &mut self,
6656 fallback: ConsumingFailureFallback<'_>,
6657 visiting: &mut BTreeSet<RecognizeKey>,
6658 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
6659 expected: &mut ExpectedTokens,
6660 ) -> Vec<RecognizeOutcome> {
6661 let ConsumingFailureFallback {
6662 atn,
6663 target,
6664 request,
6665 symbol,
6666 expected_symbols,
6667 decision_start_index,
6668 decision,
6669 } = fallback;
6670 let error_index = request.index;
6671 let diagnostic =
6672 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
6673 let next_index = self.consume_index(error_index, symbol);
6674 self.recognize_state(
6675 atn,
6676 RecognizeRequest {
6677 state_number: target,
6678 stop_state: request.stop_state,
6679 index: next_index,
6680 rule_start_index: request.rule_start_index,
6681 decision_start_index,
6682 init_action_rules: request.init_action_rules,
6683 predicates: request.predicates,
6684 semantics: request.semantics,
6685 rule_args: request.rule_args,
6686 member_actions: request.member_actions,
6687 return_actions: request.return_actions,
6688 local_int_arg: request.local_int_arg,
6689 member_values: request.member_values,
6690 return_values: request.return_values,
6691 rule_alt_number: request.rule_alt_number,
6692 track_alt_numbers: request.track_alt_numbers,
6693 consumed_eof: request.consumed_eof,
6694 precedence: request.precedence,
6695 depth: request.depth + 1,
6696 recovery_symbols: BTreeSet::new(),
6697 recovery_state: None,
6698 },
6699 visiting,
6700 memo,
6701 expected,
6702 )
6703 .into_iter()
6704 .map(|mut outcome| {
6705 prepend_decision(&mut outcome, decision);
6706 outcome.diagnostics.insert(0, diagnostic.clone());
6707 outcome
6708 .nodes
6709 .insert(0, RecognizedNode::ErrorToken { index: error_index });
6710 outcome
6711 })
6712 .collect()
6713 }
6714
6715 fn eof_consuming_failure_fallback(
6718 &mut self,
6719 fallback: ConsumingFailureFallback<'_>,
6720 expected: &ExpectedTokens,
6721 ) -> Vec<RecognizeOutcome> {
6722 let request = fallback.request;
6723 if request.index == request.rule_start_index {
6724 return Vec::new();
6725 }
6726 let diagnostic =
6727 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
6728 vec![RecognizeOutcome {
6729 index: request.index,
6730 consumed_eof: request.consumed_eof,
6731 alt_number: request.rule_alt_number,
6732 member_values: request.member_values,
6733 return_values: request.return_values,
6734 diagnostics: vec![diagnostic],
6735 decisions: Vec::new(),
6736 actions: Vec::new(),
6737 nodes: Vec::new(),
6738 }]
6739 }
6740
6741 fn single_token_insertion_recovery(
6744 &mut self,
6745 recovery: RecoveryRequest<'_, '_>,
6746 ) -> Vec<RecognizeOutcome> {
6747 let RecoveryRequest {
6748 atn,
6749 transition,
6750 expected_symbols,
6751 target,
6752 request,
6753 visiting,
6754 memo,
6755 expected,
6756 } = recovery;
6757 let RecognizeRequest {
6758 stop_state,
6759 index,
6760 rule_start_index,
6761 decision_start_index,
6762 init_action_rules,
6763 predicates,
6764 semantics,
6765 rule_args,
6766 member_actions,
6767 return_actions,
6768 local_int_arg,
6769 member_values,
6770 return_values,
6771 rule_alt_number,
6772 track_alt_numbers,
6773 consumed_eof,
6774 precedence,
6775 depth,
6776 ..
6777 } = request;
6778 let follow_symbols = state_expected_symbols(atn, transition.target());
6779 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
6780 transition,
6781 index,
6782 atn.max_token_type(),
6783 &expected_symbols,
6784 &follow_symbols,
6785 ) else {
6786 return Vec::new();
6787 };
6788 self.recognize_state(
6789 atn,
6790 RecognizeRequest {
6791 state_number: target,
6792 stop_state,
6793 index,
6794 rule_start_index,
6795 decision_start_index,
6796 init_action_rules,
6797 predicates,
6798 semantics,
6799 rule_args,
6800 member_actions,
6801 return_actions,
6802 local_int_arg,
6803 member_values,
6804 return_values,
6805 rule_alt_number,
6806 track_alt_numbers,
6807 consumed_eof,
6808 precedence,
6809 depth: depth + 1,
6810 recovery_symbols: BTreeSet::new(),
6811 recovery_state: None,
6812 },
6813 visiting,
6814 memo,
6815 expected,
6816 )
6817 .into_iter()
6818 .map(|mut outcome| {
6819 outcome.diagnostics.insert(0, diagnostic.clone());
6820 outcome.nodes.insert(
6821 0,
6822 RecognizedNode::MissingToken {
6823 token_type,
6824 at_index: index,
6825 text: text.clone(),
6826 },
6827 );
6828 outcome
6829 })
6830 .collect()
6831 }
6832
6833 #[allow(clippy::too_many_lines)]
6836 fn recognize_state(
6837 &mut self,
6838 atn: &Atn,
6839 request: RecognizeRequest<'_>,
6840 visiting: &mut BTreeSet<RecognizeKey>,
6841 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
6842 expected: &mut ExpectedTokens,
6843 ) -> Vec<RecognizeOutcome> {
6844 let request_template = request.clone();
6845 let RecognizeRequest {
6846 state_number,
6847 stop_state,
6848 index,
6849 rule_start_index,
6850 decision_start_index,
6851 init_action_rules,
6852 predicates,
6853 semantics,
6854 rule_args,
6855 member_actions,
6856 return_actions,
6857 local_int_arg,
6858 member_values,
6859 return_values,
6860 rule_alt_number,
6861 track_alt_numbers,
6862 consumed_eof,
6863 precedence,
6864 depth,
6865 recovery_symbols,
6866 recovery_state,
6867 } = request;
6868 if depth > RECOGNITION_DEPTH_LIMIT {
6869 return Vec::new();
6870 }
6871 if state_number == stop_state {
6872 return stop_outcome(
6873 index,
6874 consumed_eof,
6875 rule_alt_number,
6876 member_values,
6877 return_values,
6878 );
6879 }
6880 let key = RecognizeKey {
6881 state_number,
6882 stop_state,
6883 index,
6884 rule_start_index,
6885 decision_start_index,
6886 local_int_arg,
6887 member_values: member_values.clone(),
6888 return_values: return_values.clone(),
6889 rule_alt_number,
6890 track_alt_numbers,
6891 consumed_eof,
6892 precedence,
6893 recovery_symbols: recovery_symbols.clone(),
6894 recovery_state,
6895 };
6896 if let Some(outcomes) = memo.get(&key) {
6897 return outcomes.clone();
6898 }
6899
6900 let visit_key = key.clone();
6901 if !visiting.insert(visit_key.clone()) {
6902 return Vec::new();
6903 }
6904
6905 let Some(state) = atn.state(state_number) else {
6906 visiting.remove(&visit_key);
6907 return Vec::new();
6908 };
6909 let next_decision_start_index = if starts_prediction_decision(state) {
6910 Some(index)
6911 } else {
6912 decision_start_index
6913 };
6914 let (epsilon_recovery_symbols, epsilon_recovery_state) =
6915 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
6916 let mut outcomes = Vec::new();
6917 for (transition_index, transition) in state.transitions.iter().enumerate() {
6918 let decision = transition_decision(atn, state, transition_index, predicates);
6919 let next_alt_number =
6920 next_alt_number(state, transition_index, rule_alt_number, track_alt_numbers);
6921 match transition {
6922 Transition::Epsilon { target } | Transition::Action { target, .. } => {
6923 let action_rule_index = match transition {
6924 Transition::Action { rule_index, .. } => Some(*rule_index),
6925 _ => None,
6926 };
6927 outcomes.extend(self.recognize_epsilon_or_action_step(
6928 atn,
6929 &request_template,
6930 EpsilonActionStep {
6931 source_state: state_number,
6932 target: *target,
6933 action_rule_index,
6934 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
6935 decision,
6936 decision_start_index: next_decision_start_index,
6937 alt_number: next_alt_number,
6938 recovery_symbols: epsilon_recovery_symbols.clone(),
6939 recovery_state: epsilon_recovery_state,
6940 },
6941 RecognizeScratch {
6942 visiting,
6943 memo,
6944 expected,
6945 },
6946 ));
6947 }
6948 Transition::Predicate {
6949 target,
6950 rule_index,
6951 pred_index,
6952 ..
6953 } => {
6954 let predicate = PredicateEval {
6955 index,
6956 rule_index: *rule_index,
6957 pred_index: *pred_index,
6958 predicates,
6959 semantics,
6960 context: None,
6961 local_int_arg,
6962 member_values: &member_values,
6963 };
6964 if self.parser_predicate_matches(predicate) {
6965 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
6966 outcomes.extend(
6967 self.recognize_state(
6968 atn,
6969 RecognizeRequest {
6970 state_number: *target,
6971 stop_state,
6972 index,
6973 rule_start_index,
6974 decision_start_index: next_decision_start_index,
6975 init_action_rules,
6976 predicates,
6977 semantics,
6978 rule_args,
6979 member_actions,
6980 return_actions,
6981 local_int_arg,
6982 member_values: member_values.clone(),
6983 return_values: return_values.clone(),
6984 rule_alt_number: next_alt_number,
6985 track_alt_numbers,
6986 consumed_eof,
6987 precedence,
6988 depth: depth + 1,
6989 recovery_symbols: epsilon_recovery_symbols.clone(),
6990 recovery_state: epsilon_recovery_state,
6991 },
6992 visiting,
6993 memo,
6994 expected,
6995 )
6996 .into_iter()
6997 .map(|mut outcome| {
6998 prepend_decision(&mut outcome, decision);
6999 if let Some(rule_index) = left_recursive_boundary {
7000 outcome.nodes.insert(
7001 0,
7002 RecognizedNode::LeftRecursiveBoundary { rule_index },
7003 );
7004 }
7005 outcome
7006 }),
7007 );
7008 } else if let Some(message) = semantics
7009 .and_then(|semantics| {
7010 self.parser_semantic_ir_predicate_failure_message(
7011 *rule_index,
7012 *pred_index,
7013 semantics,
7014 )
7015 })
7016 .or_else(|| {
7017 self.parser_predicate_failure_message(
7018 *rule_index,
7019 *pred_index,
7020 predicates,
7021 )
7022 })
7023 {
7024 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
7025 rule_index: *rule_index,
7026 index,
7027 message,
7028 member_values: member_values.clone(),
7029 return_values: return_values.clone(),
7030 rule_alt_number,
7031 }));
7032 } else {
7033 record_predicate_no_viable(expected, next_decision_start_index, index);
7034 }
7035 }
7036 Transition::Precedence {
7037 target,
7038 precedence: transition_precedence,
7039 } => {
7040 if *transition_precedence >= precedence {
7041 outcomes.extend(
7042 self.recognize_state(
7043 atn,
7044 RecognizeRequest {
7045 state_number: *target,
7046 stop_state,
7047 index,
7048 rule_start_index,
7049 decision_start_index: next_decision_start_index,
7050 init_action_rules,
7051 predicates,
7052 semantics,
7053 rule_args,
7054 member_actions,
7055 return_actions,
7056 local_int_arg,
7057 member_values: member_values.clone(),
7058 return_values: return_values.clone(),
7059 rule_alt_number: next_alt_number,
7060 track_alt_numbers,
7061 consumed_eof,
7062 precedence,
7063 depth: depth + 1,
7064 recovery_symbols: epsilon_recovery_symbols.clone(),
7065 recovery_state: epsilon_recovery_state,
7066 },
7067 visiting,
7068 memo,
7069 expected,
7070 )
7071 .into_iter()
7072 .map(|mut outcome| {
7073 prepend_decision(&mut outcome, decision);
7074 outcome
7075 }),
7076 );
7077 }
7078 }
7079 Transition::Rule {
7080 target,
7081 rule_index,
7082 follow_state,
7083 precedence: rule_precedence,
7084 ..
7085 } => {
7086 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
7087 else {
7088 continue;
7089 };
7090 let child_local_int_arg =
7091 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
7092 let expected_before_child = expected.clone();
7093 let children = self.recognize_state(
7094 atn,
7095 RecognizeRequest {
7096 state_number: *target,
7097 stop_state: child_stop,
7098 index,
7099 rule_start_index: index,
7100 decision_start_index: None,
7101 init_action_rules,
7102 predicates,
7103 semantics,
7104 rule_args,
7105 member_actions,
7106 return_actions,
7107 local_int_arg: child_local_int_arg,
7108 member_values: member_values.clone(),
7109 return_values: BTreeMap::new(),
7110 rule_alt_number: 0,
7111 track_alt_numbers,
7112 consumed_eof: false,
7113 precedence: *rule_precedence,
7114 depth: depth + 1,
7115 recovery_symbols: epsilon_recovery_symbols.clone(),
7116 recovery_state: epsilon_recovery_state,
7117 },
7118 visiting,
7119 memo,
7120 expected,
7121 );
7122 let children = if children.is_empty() {
7123 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
7124 atn,
7125 rule_index: *rule_index,
7126 start_index: index,
7127 follow_state: *follow_state,
7128 stop_state,
7129 member_values: member_values.clone(),
7130 expected,
7131 })
7132 } else {
7133 children
7134 };
7135 let preserve_child_expected =
7136 self.child_expected_reaches_clean_eof(&children, expected);
7137 restore_expected(
7138 &children,
7139 index,
7140 expected,
7141 expected_before_child,
7142 preserve_child_expected,
7143 );
7144 for child in children {
7145 let child_node = RecognizedNode::Rule {
7146 rule_index: *rule_index,
7147 invoking_state: invoking_state_number(state_number),
7148 alt_number: child.alt_number,
7149 start_index: index,
7150 stop_index: self.rule_stop_token_index(child.index, child.consumed_eof),
7151 return_values: child.return_values.clone(),
7152 children: fold_left_recursive_boundaries(child.nodes.clone()),
7153 };
7154 outcomes.extend(
7155 self.recognize_state(
7156 atn,
7157 RecognizeRequest {
7158 state_number: *follow_state,
7159 stop_state,
7160 index: child.index,
7161 rule_start_index,
7162 decision_start_index: next_decision_start_index,
7163 init_action_rules,
7164 predicates,
7165 semantics,
7166 rule_args,
7167 member_actions,
7168 return_actions,
7169 local_int_arg,
7170 member_values: child.member_values.clone(),
7171 return_values: return_values.clone(),
7172 rule_alt_number,
7173 track_alt_numbers,
7174 consumed_eof: consumed_eof || child.consumed_eof,
7175 precedence,
7176 depth: depth + 1,
7177 recovery_symbols: BTreeSet::new(),
7178 recovery_state: None,
7179 },
7180 visiting,
7181 memo,
7182 expected,
7183 )
7184 .into_iter()
7185 .map(|mut outcome| {
7186 outcome.consumed_eof |= child.consumed_eof;
7187 let mut diagnostics = child.diagnostics.clone();
7188 diagnostics.append(&mut outcome.diagnostics);
7189 outcome.diagnostics = diagnostics;
7190 let mut decisions = child.decisions.clone();
7191 decisions.append(&mut outcome.decisions);
7192 outcome.decisions = decisions;
7193 prepend_decision(&mut outcome, decision);
7194 let mut actions = child.actions.clone();
7195 if init_action_rules.contains(rule_index) {
7196 actions.insert(
7197 0,
7198 ParserAction::new_rule_init(
7199 *rule_index,
7200 index,
7201 Some(*follow_state),
7202 ),
7203 );
7204 }
7205 actions.append(&mut outcome.actions);
7206 outcome.actions = actions;
7207 outcome.nodes.insert(0, child_node.clone());
7208 outcome
7209 }),
7210 );
7211 }
7212 }
7213 Transition::Atom { target, .. }
7214 | Transition::Range { target, .. }
7215 | Transition::Set { target, .. }
7216 | Transition::NotSet { target, .. }
7217 | Transition::Wildcard { target, .. } => {
7218 let symbol = self.token_type_at(index);
7219 if transition.matches(symbol, 1, atn.max_token_type()) {
7220 let next_index = self.consume_index(index, symbol);
7221 outcomes.extend(
7222 self.recognize_state(
7223 atn,
7224 RecognizeRequest {
7225 state_number: *target,
7226 stop_state,
7227 index: next_index,
7228 rule_start_index,
7229 decision_start_index: next_decision_start_index,
7230 init_action_rules,
7231 predicates,
7232 semantics,
7233 rule_args,
7234 member_actions,
7235 return_actions,
7236 local_int_arg,
7237 member_values: member_values.clone(),
7238 return_values: return_values.clone(),
7239 rule_alt_number: next_alt_number,
7240 track_alt_numbers,
7241 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
7242 precedence,
7243 depth: depth + 1,
7244 recovery_symbols: BTreeSet::new(),
7245 recovery_state: None,
7246 },
7247 visiting,
7248 memo,
7249 expected,
7250 )
7251 .into_iter()
7252 .map(|mut outcome| {
7253 prepend_decision(&mut outcome, decision);
7254 outcome.consumed_eof |= symbol == TOKEN_EOF;
7255 outcome.nodes.insert(0, RecognizedNode::Token { index });
7256 outcome
7257 }),
7258 );
7259 } else {
7260 let expected_symbols =
7261 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
7262 if expected_symbols.contains(&symbol) {
7263 continue;
7264 }
7265 expected.record_transition(index, transition, atn.max_token_type());
7266 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
7267 let before_recovery = outcomes.len();
7268 let recovery_request = request_template.clone();
7269 outcomes.extend(
7270 self.single_token_deletion_recovery(RecoveryRequest {
7271 atn,
7272 transition,
7273 expected_symbols: expected_symbols.clone(),
7274 target: *target,
7275 request: recovery_request.clone(),
7276 visiting,
7277 memo,
7278 expected,
7279 })
7280 .into_iter()
7281 .map(|mut outcome| {
7282 prepend_decision(&mut outcome, decision);
7283 outcome
7284 }),
7285 );
7286 if !state_is_left_recursive_rule(atn, state) {
7287 outcomes.extend(
7288 self.single_token_insertion_recovery(RecoveryRequest {
7289 atn,
7290 transition,
7291 expected_symbols: expected_symbols.clone(),
7292 target: *target,
7293 request: recovery_request.clone(),
7294 visiting,
7295 memo,
7296 expected,
7297 })
7298 .into_iter()
7299 .map(|mut outcome| {
7300 prepend_decision(&mut outcome, decision);
7301 outcome
7302 }),
7303 );
7304 }
7305 outcomes.extend(self.current_token_deletion_recovery(
7306 CurrentTokenDeletionRequest {
7307 atn,
7308 expected_symbols: expected_symbols.clone(),
7309 request: recovery_request.clone(),
7310 visiting,
7311 memo,
7312 expected,
7313 },
7314 ));
7315 if outcomes.len() == before_recovery {
7316 outcomes.extend(self.consuming_failure_fallback(
7317 ConsumingFailureFallback {
7318 atn,
7319 target: *target,
7320 request: recovery_request,
7321 symbol,
7322 expected_symbols,
7323 decision_start_index: next_decision_start_index,
7324 decision,
7325 },
7326 visiting,
7327 memo,
7328 expected,
7329 ));
7330 }
7331 }
7332 }
7333 }
7334 }
7335
7336 visiting.remove(&visit_key);
7337 self.record_prediction_diagnostics(atn, state, index, &outcomes);
7338 if matches!(
7339 self.prediction_mode,
7340 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
7341 ) {
7342 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes);
7343 }
7344 dedupe_outcomes(&mut outcomes);
7345 memo.insert(key, outcomes.clone());
7346 outcomes
7347 }
7348
7349 fn recognize_epsilon_or_action_step(
7352 &mut self,
7353 atn: &Atn,
7354 request: &RecognizeRequest<'_>,
7355 step: EpsilonActionStep,
7356 scratch: RecognizeScratch<'_>,
7357 ) -> Vec<RecognizeOutcome> {
7358 let RecognizeScratch {
7359 visiting,
7360 memo,
7361 expected,
7362 } = scratch;
7363 let action = step.action_rule_index.map(|rule_index| {
7364 ParserAction::new(
7365 step.source_state,
7366 rule_index,
7367 request.rule_start_index,
7368 self.rule_stop_token_index(request.index, request.consumed_eof),
7369 )
7370 });
7371 let next_member_values = if action.is_some() {
7372 member_values_after_action(
7373 step.source_state,
7374 request.member_actions,
7375 request.semantics,
7376 &request.member_values,
7377 )
7378 } else {
7379 request.member_values.clone()
7380 };
7381 let next_return_values = action.map_or_else(
7382 || request.return_values.clone(),
7383 |action| {
7384 return_values_after_action(
7385 step.source_state,
7386 action.rule_index(),
7387 request.return_actions,
7388 request.semantics,
7389 &request.return_values,
7390 )
7391 },
7392 );
7393
7394 self.recognize_state(
7395 atn,
7396 RecognizeRequest {
7397 state_number: step.target,
7398 stop_state: request.stop_state,
7399 index: request.index,
7400 rule_start_index: request.rule_start_index,
7401 decision_start_index: step.decision_start_index,
7402 init_action_rules: request.init_action_rules,
7403 predicates: request.predicates,
7404 semantics: request.semantics,
7405 rule_args: request.rule_args,
7406 member_actions: request.member_actions,
7407 return_actions: request.return_actions,
7408 local_int_arg: request.local_int_arg,
7409 member_values: next_member_values,
7410 return_values: next_return_values,
7411 rule_alt_number: step.alt_number,
7412 track_alt_numbers: request.track_alt_numbers,
7413 consumed_eof: request.consumed_eof,
7414 precedence: request.precedence,
7415 depth: request.depth + 1,
7416 recovery_symbols: step.recovery_symbols,
7417 recovery_state: step.recovery_state,
7418 },
7419 visiting,
7420 memo,
7421 expected,
7422 )
7423 .into_iter()
7424 .map(|mut outcome| {
7425 prepend_decision(&mut outcome, step.decision);
7426 if let Some(rule_index) = step.left_recursive_boundary {
7427 outcome
7428 .nodes
7429 .insert(0, RecognizedNode::LeftRecursiveBoundary { rule_index });
7430 }
7431 if let Some(action) = action {
7432 outcome.actions.insert(0, action);
7433 }
7434 outcome
7435 })
7436 .collect()
7437 }
7438
7439 fn token_type_at(&mut self, index: usize) -> i32 {
7444 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
7445 self.input.fill();
7446 }
7447 self.input.token_type_at_index(index)
7448 }
7449
7450 fn cached_state_expected_symbols(
7462 &mut self,
7463 atn: &Atn,
7464 state_number: usize,
7465 ) -> Rc<BTreeSet<i32>> {
7466 if let Some(cached) = self.state_expected_cache.get(&state_number) {
7467 return Rc::clone(cached);
7468 }
7469 let symbols = state_expected_symbols(atn, state_number);
7470 let entry = self.intern_recovery_symbols(symbols);
7471 self.state_expected_cache
7472 .insert(state_number, Rc::clone(&entry));
7473 entry
7474 }
7475
7476 fn cached_state_expected_token_set(
7477 &mut self,
7478 atn: &Atn,
7479 state_number: usize,
7480 ) -> Rc<TokenBitSet> {
7481 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
7482 return Rc::clone(cached);
7483 }
7484 let symbols = with_shared_atn_caches(atn, |cache| {
7488 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
7489 return Rc::clone(cached);
7490 }
7491 let symbols = Rc::new(state_expected_token_set(atn, state_number));
7492 cache
7493 .state_expected_tokens
7494 .insert(state_number, Rc::clone(&symbols));
7495 symbols
7496 });
7497 self.state_expected_token_cache
7498 .insert(state_number, Rc::clone(&symbols));
7499 symbols
7500 }
7501
7502 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
7503 if self.rule_stop_reach_cache.len() <= state_number {
7504 self.rule_stop_reach_cache
7505 .resize_with(atn.states().len().max(state_number + 1), || None);
7506 }
7507 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
7508 return reaches;
7509 }
7510 let reaches = with_shared_atn_caches(atn, |cache| {
7511 *cache
7512 .rule_stop_reach
7513 .entry(state_number)
7514 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
7515 });
7516 self.rule_stop_reach_cache[state_number] = Some(reaches);
7517 reaches
7518 }
7519
7520 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
7523 Rc::clone(&self.empty_recovery_symbols)
7524 }
7525
7526 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
7535 if set.is_empty() {
7536 return Rc::clone(&self.empty_recovery_symbols);
7537 }
7538 let candidate = Rc::new(set);
7539 match self.recovery_symbols_intern.get(&candidate) {
7540 Some(existing) => Rc::clone(existing),
7541 None => {
7542 self.recovery_symbols_intern
7543 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
7544 candidate
7545 }
7546 }
7547 }
7548
7549 fn cached_decision_lookahead(
7554 &mut self,
7555 atn: &Atn,
7556 state: &AtnState,
7557 rule_stop_state: usize,
7558 ) -> Rc<DecisionLookahead> {
7559 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number) {
7566 return Rc::clone(cached);
7567 }
7568 let entry = with_shared_atn_caches(atn, |cache| {
7569 if let Some(cached) = cache.decision_lookahead.get(&state.state_number) {
7570 return Rc::clone(cached);
7571 }
7572 let mut entry = DecisionLookahead {
7573 transitions: Vec::with_capacity(state.transitions.len()),
7574 };
7575 for transition in &state.transitions {
7576 entry.transitions.push(transition_first_set(
7577 atn,
7578 transition,
7579 rule_stop_state,
7580 &mut cache.first_set,
7581 ));
7582 }
7583 let entry = Rc::new(entry);
7584 cache
7585 .decision_lookahead
7586 .insert(state.state_number, Rc::clone(&entry));
7587 entry
7588 });
7589 self.decision_lookahead_cache
7590 .insert(state.state_number, Rc::clone(&entry));
7591 entry
7592 }
7593
7594 fn cached_rule_first_set(
7595 &mut self,
7596 atn: &Atn,
7597 target: usize,
7598 child_stop: usize,
7599 ) -> Rc<FirstSet> {
7600 if self.rule_first_set_cache.len() <= target {
7601 self.rule_first_set_cache
7602 .resize_with(atn.states().len().max(target + 1), || None);
7603 }
7604 if let Some(cached) = self
7605 .rule_first_set_cache
7606 .get(target)
7607 .and_then(Option::as_ref)
7608 {
7609 return Rc::clone(cached);
7610 }
7611 let first = with_shared_first_set_cache(atn, |cache| {
7612 rule_first_set(atn, target, child_stop, cache)
7613 });
7614 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
7615 first
7616 }
7617
7618 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
7619 if self.empty_cycle_cache.len() <= state_number {
7620 self.empty_cycle_cache
7621 .resize_with(atn.states().len().max(state_number + 1), || None);
7622 }
7623 if let Some(cached) = self.empty_cycle_cache[state_number] {
7624 return cached;
7625 }
7626 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
7627 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
7628 self.empty_cycle_cache[state_number] = Some(result);
7629 result
7630 }
7631
7632 fn empty_path_reaches_state(
7633 &mut self,
7634 atn: &Atn,
7635 state_number: usize,
7636 target_state: usize,
7637 visited: &mut FxHashSet<usize>,
7638 ) -> bool {
7639 if !visited.insert(state_number) {
7640 return false;
7641 }
7642 let Some(state) = atn.state(state_number) else {
7643 return false;
7644 };
7645 for transition in &state.transitions {
7646 match transition {
7647 Transition::Atom { .. }
7648 | Transition::Range { .. }
7649 | Transition::Set { .. }
7650 | Transition::NotSet { .. }
7651 | Transition::Wildcard { .. } => {}
7652 Transition::Rule {
7653 target,
7654 rule_index,
7655 follow_state,
7656 ..
7657 } => {
7658 if *target == target_state
7659 || self.empty_path_reaches_state(atn, *target, target_state, visited)
7660 {
7661 return true;
7662 }
7663 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
7664 else {
7665 continue;
7666 };
7667 if self
7668 .cached_rule_first_set(atn, *target, child_stop)
7669 .nullable
7670 && (*follow_state == target_state
7671 || self.empty_path_reaches_state(
7672 atn,
7673 *follow_state,
7674 target_state,
7675 visited,
7676 ))
7677 {
7678 return true;
7679 }
7680 }
7681 Transition::Epsilon { target }
7682 | Transition::Predicate { target, .. }
7683 | Transition::Action { target, .. }
7684 | Transition::Precedence { target, .. } => {
7685 if *target == target_state
7686 || self.empty_path_reaches_state(atn, *target, target_state, visited)
7687 {
7688 return true;
7689 }
7690 }
7691 }
7692 }
7693 false
7694 }
7695
7696 fn should_memoize_single_outcome(&mut self, key: &FastRecognizeKey) -> bool {
7699 match self.single_outcome_memo_mode {
7700 SingleOutcomeMemoMode::Promote => true,
7701 SingleOutcomeMemoMode::Sparse => false,
7702 SingleOutcomeMemoMode::Probe => {
7703 self.single_outcome_probe_samples += 1;
7704 if !self.single_outcome_probe_seen.insert(key.clone()) {
7705 self.single_outcome_probe_repeats += 1;
7706 }
7707 if self.single_outcome_probe_repeats >= CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
7708 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Promote;
7709 self.single_outcome_probe_seen.clear();
7710 return true;
7711 }
7712 if self.single_outcome_probe_samples >= CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT {
7713 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Sparse;
7714 self.single_outcome_probe_seen.clear();
7715 return false;
7716 }
7717 true
7718 }
7719 }
7720 }
7721
7722 fn token_at(&mut self, index: usize) -> Option<CommonToken> {
7724 self.input.get(index).cloned()
7725 }
7726
7727 fn token_ref_at(&mut self, index: usize) -> Option<TokenRef> {
7729 self.input.get_ref(index)
7730 }
7731
7732 fn current_visible_index(&mut self) -> usize {
7735 let index = self.input.index();
7736 self.input.seek(index);
7737 self.input.index()
7738 }
7739
7740 fn child_expected_reaches_clean_eof(
7743 &mut self,
7744 children: &[RecognizeOutcome],
7745 expected: &ExpectedTokens,
7746 ) -> bool {
7747 let Some(index) = expected.index else {
7748 return false;
7749 };
7750 self.token_type_at(index) == TOKEN_EOF
7751 && children
7752 .iter()
7753 .any(|child| child.diagnostics.is_empty() && child.index == index)
7754 }
7755
7756 fn previous_token_index(&mut self, index: usize) -> Option<usize> {
7763 self.input.previous_visible_token_index(index)
7764 }
7765
7766 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
7771 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
7772 Some(index)
7773 } else {
7774 self.previous_token_index(index)
7775 }
7776 }
7777
7778 #[must_use]
7795 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
7796 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
7797 self.rule_stop_token_index(current_index, consumed_eof)
7798 }
7799
7800 #[must_use]
7809 pub fn after_action_stop_index_for_tree(
7810 &mut self,
7811 tree: &ParseTree,
7812 current_index: usize,
7813 ) -> Option<usize> {
7814 if let ParseTree::Rule(rule) = tree {
7815 if let Some(stop) = rule.context().stop() {
7816 let token_index = stop.token_index();
7817 if token_index >= 0 {
7818 return Some(token_index.unsigned_abs());
7819 }
7820 }
7821 }
7822 self.after_action_stop_index(current_index)
7823 }
7824
7825 #[must_use]
7835 pub fn after_action_start_index_for_tree(
7836 &self,
7837 tree: &ParseTree,
7838 fallback_index: usize,
7839 ) -> usize {
7840 if let ParseTree::Rule(rule) = tree {
7841 if let Some(start) = rule.context().start() {
7842 let token_index = start.token_index();
7843 if token_index >= 0 {
7844 return token_index.unsigned_abs();
7845 }
7846 }
7847 }
7848 fallback_index
7849 }
7850
7851 fn rule_stop_token_ref(&mut self, index: usize, consumed_eof: bool) -> Option<TokenRef> {
7856 self.rule_stop_token_index(index, consumed_eof)
7857 .and_then(|token_index| self.token_ref_at(token_index))
7858 }
7859
7860 fn predicate_failure_recovery(
7867 &mut self,
7868 request: PredicateFailureRecovery<'_>,
7869 ) -> RecognizeOutcome {
7870 let PredicateFailureRecovery {
7871 rule_index,
7872 index,
7873 message,
7874 member_values,
7875 return_values,
7876 rule_alt_number,
7877 } = request;
7878 let rule_name = self
7879 .rule_names()
7880 .get(rule_index)
7881 .map_or_else(|| rule_index.to_string(), Clone::clone);
7882 let diagnostic = diagnostic_for_token(
7883 self.token_at(index).as_ref(),
7884 format!("rule {rule_name} {message}"),
7885 );
7886 let mut nodes = Vec::new();
7887 let mut next_index = index;
7888 loop {
7889 let symbol = self.token_type_at(next_index);
7890 if symbol == TOKEN_EOF {
7891 break;
7892 }
7893 nodes.push(RecognizedNode::ErrorToken { index: next_index });
7894 let after = self.consume_index(next_index, symbol);
7895 if after == next_index {
7896 break;
7897 }
7898 next_index = after;
7899 }
7900 RecognizeOutcome {
7901 index: next_index,
7902 consumed_eof: false,
7903 alt_number: rule_alt_number,
7904 member_values,
7905 return_values,
7906 diagnostics: vec![diagnostic],
7907 decisions: Vec::new(),
7908 actions: Vec::new(),
7909 nodes,
7910 }
7911 }
7912
7913 fn parser_semantic_hook_result(
7916 &mut self,
7917 request: ParserSemanticHookRequest<'_>,
7918 ) -> Option<bool> {
7919 let ParserSemanticHookRequest {
7920 index,
7921 rule_index,
7922 pred_index,
7923 context,
7924 local_int_arg,
7925 member_values,
7926 } = request;
7927 let rule_name = self.rule_names().get(rule_index).cloned();
7928 self.input.seek(index);
7929 let input = &mut self.input;
7930 let semantic_hooks = &mut self.semantic_hooks;
7931 let mut ctx = ParserSemCtx {
7932 input,
7933 rule_index,
7934 coordinate_index: pred_index,
7935 rule_name,
7936 context,
7937 tree: None,
7938 local_int_arg,
7939 member_values,
7940 action: None,
7941 };
7942 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
7943 }
7944
7945 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
7950 if prior.is_empty() {
7951 return;
7952 }
7953 let mut merged = prior;
7954 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
7955 if !merged.contains(&coordinate) {
7956 merged.push(coordinate);
7957 }
7958 }
7959 self.unknown_predicate_hits = merged;
7960 }
7961
7962 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
7971 apply_unknown_predicate_policy(
7972 self.unknown_predicate_policy,
7973 rule_index,
7974 pred_index,
7975 &mut self.unknown_predicate_hits,
7976 )
7977 }
7978
7979 fn unknown_semantic_error(&self) -> Option<AntlrError> {
7982 use std::fmt::Write as _;
7983 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
7984 return None;
7985 }
7986 let mut message = String::new();
7987 for (rule_index, pred_index) in &self.unknown_predicate_hits {
7988 if !message.is_empty() {
7989 message.push_str("; ");
7990 }
7991 let _ = match self.rule_names().get(*rule_index) {
7992 Some(rule_name) => write!(
7993 message,
7994 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
7995 ),
7996 None => write!(
7997 message,
7998 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
7999 ),
8000 };
8001 }
8002 for (rule_index, source_state) in &self.unhandled_action_hits {
8003 if !message.is_empty() {
8004 message.push_str("; ");
8005 }
8006 let _ = match self.rule_names().get(*rule_index) {
8007 Some(rule_name) => write!(
8008 message,
8009 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
8010 ),
8011 None => write!(
8012 message,
8013 "unhandled semantic action: rule_index={rule_index} state={source_state}"
8014 ),
8015 };
8016 }
8017 Some(AntlrError::Unsupported(message))
8018 }
8019
8020 fn parser_semir_predicate_matches(
8028 &mut self,
8029 semantics: &ParserSemantics,
8030 predicate: &ParserSemanticPredicate,
8031 request: ParserSemanticHookRequest<'_>,
8032 ) -> bool {
8033 self.input.seek(request.index);
8034 let rule_name = self
8035 .data
8036 .rule_names()
8037 .get(request.rule_index)
8038 .map(String::as_str);
8039 let unknown_predicate_policy = self.unknown_predicate_policy;
8040 let mut ctx = ParserSemIrCtx {
8041 input: &mut self.input,
8042 semantic_hooks: &mut self.semantic_hooks,
8043 rule_index: request.rule_index,
8044 coordinate_index: request.pred_index,
8045 rule_name,
8046 context: request.context,
8047 local_int_arg: request.local_int_arg,
8048 member_values: request.member_values,
8049 invoked_predicates: &mut self.invoked_predicates,
8050 unknown_predicate_policy,
8051 unknown_predicate_hits: &mut self.unknown_predicate_hits,
8052 };
8053 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
8054 }
8055
8056 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
8057 let PredicateEval {
8058 index,
8059 rule_index,
8060 pred_index,
8061 predicates,
8062 semantics,
8063 context,
8064 local_int_arg,
8065 member_values,
8066 } = eval;
8067 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
8068 semantics
8069 .predicates
8070 .iter()
8071 .find(|predicate| {
8072 predicate.rule_index == rule_index && predicate.pred_index == pred_index
8073 })
8074 .map(|predicate| (semantics, predicate))
8075 }) {
8076 return self.parser_semir_predicate_matches(
8077 semantics,
8078 predicate,
8079 ParserSemanticHookRequest {
8080 index,
8081 rule_index,
8082 pred_index,
8083 context,
8084 local_int_arg,
8085 member_values,
8086 },
8087 );
8088 }
8089 let Some((_, _, predicate)) = predicates
8090 .iter()
8091 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
8092 else {
8093 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
8094 index,
8095 rule_index,
8096 pred_index,
8097 context,
8098 local_int_arg,
8099 member_values,
8100 }) {
8101 return result;
8102 }
8103 return self.unknown_predicate_result(rule_index, pred_index);
8104 };
8105 self.input.seek(index);
8106 match predicate {
8107 ParserPredicate::True => true,
8108 ParserPredicate::False => false,
8109 ParserPredicate::FalseWithMessage { .. } => false,
8110 ParserPredicate::Invoke { value } => {
8111 let key = (rule_index, pred_index);
8112 if !self.invoked_predicates.contains(&key) {
8113 self.invoked_predicates.push(key);
8114 use std::io::Write as _;
8115 let mut stdout = std::io::stdout().lock();
8116 let _ = writeln!(stdout, "eval={value}");
8117 }
8118 *value
8119 }
8120 ParserPredicate::LookaheadTextEquals { offset, text } => {
8121 self.input.lt(*offset).and_then(Token::text) == Some(*text)
8122 }
8123 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
8124 self.la(*offset) != *token_type
8125 }
8126 ParserPredicate::TokenPairAdjacent => {
8127 let Some(first) = self.input.lt(-2).map(Token::token_index) else {
8128 return false;
8129 };
8130 let Some(second) = self.input.lt(-1).map(Token::token_index) else {
8131 return false;
8132 };
8133 first + 1 == second
8134 }
8135 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
8136 .and_then(|context| {
8137 context.children().iter().find_map(|child| match child {
8138 ParseTree::Rule(rule) if rule.context().rule_index() == *rule_index => {
8139 Some(child.text())
8140 }
8141 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
8142 })
8143 })
8144 .is_none_or(|actual| actual != *text),
8145 ParserPredicate::LocalIntEquals { value } => {
8146 local_int_arg.is_none_or(|(_, actual)| actual == *value)
8147 }
8148 ParserPredicate::LocalIntLessOrEqual { value } => {
8149 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
8150 }
8151 ParserPredicate::MemberModuloEquals {
8152 member,
8153 modulus,
8154 value,
8155 equals,
8156 } => {
8157 if *modulus == 0 {
8158 return false;
8159 }
8160 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
8161 (actual == *value) == *equals
8162 }
8163 ParserPredicate::MemberEquals {
8164 member,
8165 value,
8166 equals,
8167 } => {
8168 let actual = member_values.get(member).copied().unwrap_or_default();
8169 (actual == *value) == *equals
8170 }
8171 }
8172 }
8173
8174 fn parser_predicate_failure_message(
8176 &self,
8177 rule_index: usize,
8178 pred_index: usize,
8179 predicates: &[(usize, usize, ParserPredicate)],
8180 ) -> Option<&'static str> {
8181 predicates
8182 .iter()
8183 .find_map(|(rule, pred, predicate)| match predicate {
8184 ParserPredicate::FalseWithMessage { message }
8185 if *rule == rule_index && *pred == pred_index =>
8186 {
8187 Some(*message)
8188 }
8189 _ => None,
8190 })
8191 }
8192
8193 pub fn parser_semantic_ir_predicate_failure_message(
8196 &self,
8197 rule_index: usize,
8198 pred_index: usize,
8199 semantics: &ParserSemantics,
8200 ) -> Option<&'static str> {
8201 semantics
8202 .predicates
8203 .iter()
8204 .find(|predicate| {
8205 predicate.rule_index == rule_index && predicate.pred_index == pred_index
8206 })
8207 .and_then(|predicate| predicate.failure_message)
8208 }
8209
8210 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
8219 if symbol == TOKEN_EOF {
8220 return index;
8221 }
8222 self.input.next_visible_after(index)
8223 }
8224
8225 fn no_viable_alternative(
8228 &mut self,
8229 start_index: usize,
8230 error_index: usize,
8231 ) -> ParserDiagnostic {
8232 let text = display_input_text(&self.input.text(start_index, error_index));
8233 diagnostic_for_token(
8234 self.token_at(error_index).as_ref(),
8235 format!("no viable alternative at input '{text}'"),
8236 )
8237 }
8238
8239 fn recovery_failure_diagnostic(
8242 &mut self,
8243 index: usize,
8244 decision_start_index: Option<usize>,
8245 expected_symbols: &BTreeSet<i32>,
8246 ) -> ParserDiagnostic {
8247 if expected_symbols.len() > 1 {
8248 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
8249 return self.no_viable_alternative(decision_start, index);
8250 }
8251 }
8252 diagnostic_for_token(
8253 self.token_at(index).as_ref(),
8254 format!(
8255 "mismatched input {} expecting {}",
8256 self.token_at(index)
8257 .as_ref()
8258 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8259 self.expected_symbols_display(expected_symbols)
8260 ),
8261 )
8262 }
8263
8264 fn eof_rule_recovery_diagnostic(
8267 &mut self,
8268 index: usize,
8269 expected_symbols: &BTreeSet<i32>,
8270 expected: &ExpectedTokens,
8271 ) -> ParserDiagnostic {
8272 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
8273 &expected.symbols
8274 } else {
8275 expected_symbols
8276 };
8277 diagnostic_for_token(
8278 self.token_at(index).as_ref(),
8279 format!(
8280 "mismatched input {} expecting {}",
8281 self.token_at(index)
8282 .as_ref()
8283 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8284 self.expected_symbols_display(symbols)
8285 ),
8286 )
8287 }
8288
8289 pub fn text_interval(&mut self, start: usize, stop: Option<usize>) -> String {
8295 let Some(stop) = stop else {
8296 return String::new();
8297 };
8298 let stop = if self
8299 .token_at(stop)
8300 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8301 {
8302 let Some(previous) = self.previous_token_index(stop) else {
8303 return String::new();
8304 };
8305 previous
8306 } else {
8307 stop
8308 };
8309 self.input.text(start, stop)
8310 }
8311
8312 fn clear_prediction_diagnostics(&mut self) {
8315 self.prediction_diagnostics.clear();
8316 self.reported_prediction_diagnostics.clear();
8317 }
8318
8319 fn reset_per_parse_caches(&mut self) {
8341 self.rule_first_set_cache.clear();
8342 self.decision_lookahead_cache.clear();
8343 self.ll1_decision_cache.clear();
8344 self.empty_cycle_cache.clear();
8345 self.rule_stop_reach_cache.clear();
8346 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Probe;
8347 self.single_outcome_probe_seen.clear();
8348 self.single_outcome_probe_samples = 0;
8349 self.single_outcome_probe_repeats = 0;
8350 self.recovery_symbols_intern.clear();
8351 self.state_expected_cache.clear();
8352 self.state_expected_token_cache.clear();
8353 }
8354
8355 fn record_prediction_diagnostics(
8358 &mut self,
8359 atn: &Atn,
8360 state: &AtnState,
8361 start_index: usize,
8362 outcomes: &[RecognizeOutcome],
8363 ) {
8364 if !self.report_diagnostic_errors || state.transitions.len() < 2 {
8365 return;
8366 }
8367 let Some(decision) = atn
8368 .decision_to_state()
8369 .iter()
8370 .position(|state_number| *state_number == state.state_number)
8371 else {
8372 return;
8373 };
8374 let Some(rule_index) = state.rule_index else {
8375 return;
8376 };
8377 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
8378 for outcome in outcomes
8379 .iter()
8380 .filter(|outcome| outcome.diagnostics.is_empty())
8381 {
8382 let Some(alt) = outcome.decisions.first() else {
8383 continue;
8384 };
8385 alts_by_end
8386 .entry(outcome.index)
8387 .or_default()
8388 .insert(alt + 1);
8389 }
8390 let Some((&end_index, ambig_alts)) = alts_by_end
8391 .iter()
8392 .filter(|(_, alts)| alts.len() > 1)
8393 .max_by_key(|(end, _)| *end)
8394 else {
8395 return;
8396 };
8397 let rule_name = self
8398 .rule_names()
8399 .get(rule_index)
8400 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
8401 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
8402 let input = display_input_text(&self.input.text(start_index, stop_index));
8403 let alts = ambig_alts
8404 .iter()
8405 .map(usize::to_string)
8406 .collect::<Vec<_>>()
8407 .join(", ");
8408 let key = (decision, start_index, format!("{alts}:{input}"));
8409 if !self.reported_prediction_diagnostics.insert(key) {
8410 return;
8411 }
8412 let start_token = self.token_at(start_index);
8413 let stop_token = self.token_at(stop_index);
8414 self.prediction_diagnostics.push(diagnostic_for_token(
8415 start_token.as_ref(),
8416 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
8417 ));
8418 self.prediction_diagnostics.push(diagnostic_for_token(
8419 stop_token.as_ref(),
8420 format!(
8421 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
8422 ),
8423 ));
8424 }
8425
8426 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
8428 expected_symbols_display(
8429 &state_expected_symbols(atn, state_number),
8430 self.vocabulary(),
8431 )
8432 }
8433
8434 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
8439 let state = usize::try_from(self.data().state()).unwrap_or(0);
8440 ExpectedTokenSet {
8441 symbols: state_expected_symbols(atn, state),
8442 }
8443 }
8444
8445 pub const fn set_bail_on_error(&mut self, bail: bool) {
8448 self.bail_on_error = bail;
8449 }
8450
8451 #[must_use]
8453 pub const fn bail_on_error(&self) -> bool {
8454 self.bail_on_error
8455 }
8456
8457 pub fn rule_invocation_stack(&self) -> Vec<String> {
8460 self.rule_context_stack
8461 .iter()
8462 .rev()
8463 .map(|frame| {
8464 self.data()
8465 .rule_names()
8466 .get(frame.rule_index)
8467 .cloned()
8468 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
8469 })
8470 .collect()
8471 }
8472
8473 pub fn token_display_at(&mut self, index: usize) -> Option<String> {
8475 self.token_at(index).map(|token| format!("{token}"))
8476 }
8477
8478 fn recognized_node_tree(
8480 &mut self,
8481 node: &RecognizedNode,
8482 track_alt_numbers: bool,
8483 ) -> Result<ParseTree, AntlrError> {
8484 match node {
8485 RecognizedNode::Token { index } => {
8486 let token = self
8487 .input
8488 .get_ref(*index)
8489 .ok_or_else(|| AntlrError::ParserError {
8490 line: 0,
8491 column: 0,
8492 message: format!("missing token at index {index}"),
8493 })?;
8494 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
8495 }
8496 RecognizedNode::ErrorToken { index } => {
8497 let token = self
8498 .input
8499 .get_ref(*index)
8500 .ok_or_else(|| AntlrError::ParserError {
8501 line: 0,
8502 column: 0,
8503 message: format!("missing error token at index {index}"),
8504 })?;
8505 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
8506 }
8507 RecognizedNode::MissingToken {
8508 token_type,
8509 at_index,
8510 text,
8511 } => {
8512 let current = self.token_at(*at_index);
8513 let token = CommonToken::new(*token_type)
8514 .with_text(text.as_str())
8515 .with_span(usize::MAX, usize::MAX)
8516 .with_position(
8517 current.as_ref().map(Token::line).unwrap_or_default(),
8518 current.as_ref().map(Token::column).unwrap_or_default(),
8519 );
8520 Ok(ParseTree::Error(ErrorNode::new(token)))
8521 }
8522 RecognizedNode::Rule {
8523 rule_index,
8524 invoking_state,
8525 alt_number,
8526 start_index,
8527 stop_index,
8528 return_values,
8529 children,
8530 } => {
8531 let mut context = ParserRuleContext::new(*rule_index, *invoking_state);
8532 if track_alt_numbers {
8533 context.set_alt_number(*alt_number);
8534 }
8535 for (name, value) in return_values {
8536 context.set_int_return(name.clone(), *value);
8537 }
8538 if let Some(token) = self.token_ref_at(*start_index) {
8539 context.set_start_ref(token);
8540 }
8541 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
8542 context.set_stop_ref(token);
8543 }
8544 for child in children {
8545 context.add_child(self.recognized_node_tree(child, track_alt_numbers)?);
8546 }
8547 Ok(self.rule_node(context))
8548 }
8549 RecognizedNode::LeftRecursiveBoundary { rule_index } => Err(AntlrError::Unsupported(
8550 format!("unfolded left-recursive boundary for rule {rule_index}"),
8551 )),
8552 }
8553 }
8554}
8555
8556impl<S, H> DirectAdaptiveParser<'_, '_, S, H>
8557where
8558 S: TokenSource,
8559 H: SemanticHooks,
8560{
8561 fn parse_rule(
8562 &mut self,
8563 rule_index: usize,
8564 invoking_state: isize,
8565 precedence: i32,
8566 ) -> DirectAdaptiveParseResult<ParseTree> {
8567 let start_state = *self.atn.rule_to_start_state().get(rule_index).ok_or(
8568 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
8569 )?;
8570 let stop_state = *self
8571 .atn
8572 .rule_to_stop_state()
8573 .get(rule_index)
8574 .filter(|state| **state != usize::MAX)
8575 .ok_or(DirectAdaptiveParseControl::Fallback(
8576 DirectAdaptiveFallback::MissingAtn,
8577 ))?;
8578 let start_index = self.parser.current_visible_index();
8579 let mut children = Vec::new();
8580 let mut state_number = start_state;
8581 let mut consumed_eof = false;
8582 while state_number != stop_state {
8583 self.step()?;
8584 let (transition, boundary) = self.next_transition(state_number, precedence)?;
8585 if boundary.is_some() {
8586 return Err(DirectAdaptiveParseControl::Fallback(
8587 DirectAdaptiveFallback::LeftRecursiveBoundary,
8588 ));
8589 }
8590 match transition {
8591 Transition::Epsilon { target } => {
8592 state_number = target;
8593 }
8594 Transition::Precedence {
8595 target,
8596 precedence: transition_precedence,
8597 } => {
8598 if transition_precedence < precedence {
8599 return Err(DirectAdaptiveParseControl::Fallback(
8600 DirectAdaptiveFallback::Precedence,
8601 ));
8602 }
8603 state_number = target;
8604 }
8605 Transition::Rule {
8606 rule_index,
8607 follow_state,
8608 precedence: rule_precedence,
8609 ..
8610 } => {
8611 let child = self.parse_rule(
8612 rule_index,
8613 invoking_state_number(state_number),
8614 rule_precedence,
8615 )?;
8616 if self.parser.build_parse_trees {
8617 children.push(child);
8618 }
8619 state_number = follow_state;
8620 }
8621 Transition::Atom { .. }
8622 | Transition::Range { .. }
8623 | Transition::Set { .. }
8624 | Transition::NotSet { .. }
8625 | Transition::Wildcard { .. } => {
8626 let (matched_eof, child) = self.consume_transition(&transition)?;
8627 consumed_eof |= matched_eof;
8628 if let Some(child) = child {
8629 children.push(child);
8630 }
8631 state_number = transition.target();
8632 }
8633 Transition::Predicate { .. } => {
8634 return Err(DirectAdaptiveParseControl::Fallback(
8635 DirectAdaptiveFallback::Predicate,
8636 ));
8637 }
8638 Transition::Action { .. } => {
8639 return Err(DirectAdaptiveParseControl::Fallback(
8640 DirectAdaptiveFallback::Action,
8641 ));
8642 }
8643 }
8644 }
8645
8646 let mut context = ParserRuleContext::with_child_capacity(
8647 rule_index,
8648 invoking_state,
8649 if self.parser.build_parse_trees {
8650 children.len()
8651 } else {
8652 0
8653 },
8654 );
8655 if let Some(token) = self.parser.token_ref_at(start_index) {
8656 context.set_start_ref(token);
8657 }
8658 let stop_index = self
8659 .parser
8660 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
8661 if let Some(token) = stop_index.and_then(|index| self.parser.token_ref_at(index)) {
8662 context.set_stop_ref(token);
8663 }
8664 if self.parser.build_parse_trees {
8665 for child in children {
8666 context.add_child(child);
8667 }
8668 }
8669 Ok(self.parser.rule_node(context))
8670 }
8671
8672 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
8673 self.steps += 1;
8674 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
8675 return Err(DirectAdaptiveParseControl::Fallback(
8676 DirectAdaptiveFallback::StepLimit,
8677 ));
8678 }
8679 Ok(())
8680 }
8681
8682 fn next_transition(
8683 &mut self,
8684 state_number: usize,
8685 precedence: i32,
8686 ) -> DirectAdaptiveParseResult<(Transition, Option<usize>)> {
8687 let state = self
8688 .atn
8689 .state(state_number)
8690 .ok_or(DirectAdaptiveParseControl::Fallback(
8691 DirectAdaptiveFallback::MissingAtn,
8692 ))?;
8693 if state.is_rule_stop() {
8694 return Err(DirectAdaptiveParseControl::Fallback(
8695 DirectAdaptiveFallback::RuleStop,
8696 ));
8697 }
8698 let transition_index =
8699 self.transition_index(state_number, state.transitions.len(), precedence)?;
8700 let transition = state.transitions.get(transition_index).cloned().ok_or(
8701 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
8702 )?;
8703 let boundary = match &transition {
8704 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
8705 left_recursive_boundary(self.atn, state, *target)
8706 }
8707 _ => None,
8708 };
8709 Ok((transition, boundary))
8710 }
8711
8712 fn transition_index(
8713 &mut self,
8714 state_number: usize,
8715 transition_count: usize,
8716 precedence: i32,
8717 ) -> DirectAdaptiveParseResult<usize> {
8718 match transition_count {
8719 0 => Err(DirectAdaptiveParseControl::Fallback(
8720 DirectAdaptiveFallback::NoTransition,
8721 )),
8722 1 => Ok(0),
8723 _ => {
8724 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
8725 return Ok(alt);
8726 }
8727 let decision = self
8728 .decision_by_state
8729 .get(state_number)
8730 .and_then(|decision| *decision)
8731 .ok_or(DirectAdaptiveParseControl::Fallback(
8732 DirectAdaptiveFallback::UnknownDecision,
8733 ))?;
8734 let prediction = self
8735 .simulator
8736 .adaptive_predict_stream_info_with_precedence(
8737 decision,
8738 direct_precedence(precedence),
8739 &mut self.parser.input,
8740 )
8741 .map_err(|_| {
8742 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
8743 })?;
8744 if prediction.has_semantic_context {
8745 return Err(DirectAdaptiveParseControl::Fallback(
8746 DirectAdaptiveFallback::SemanticContext,
8747 ));
8748 }
8749 prediction
8750 .alt
8751 .checked_sub(1)
8752 .filter(|index| *index < transition_count)
8753 .ok_or(DirectAdaptiveParseControl::Fallback(
8754 DirectAdaptiveFallback::InvalidAlt,
8755 ))
8756 }
8757 }
8758 }
8759
8760 fn ll1_transition_index(
8761 &mut self,
8762 state_number: usize,
8763 transition_count: usize,
8764 ) -> DirectAdaptiveParseResult<Option<usize>> {
8765 let state = self
8766 .atn
8767 .state(state_number)
8768 .ok_or(DirectAdaptiveParseControl::Fallback(
8769 DirectAdaptiveFallback::MissingAtn,
8770 ))?;
8771 if state.precedence_rule_decision {
8772 return Ok(None);
8773 }
8774 let Some(rule_stop) = state
8775 .rule_index
8776 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index).copied())
8777 else {
8778 return Ok(None);
8779 };
8780 let symbol = self.parser.input.la_token(1);
8781 let entry = self
8782 .parser
8783 .cached_decision_lookahead(self.atn, state, rule_stop);
8784 Ok(ll1_greedy_alt(&entry, symbol, state.non_greedy).filter(|alt| *alt < transition_count))
8785 }
8786
8787 fn consume_transition(
8788 &mut self,
8789 transition: &Transition,
8790 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
8791 let symbol = self.parser.input.la_token(1);
8792 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
8793 return Err(DirectAdaptiveParseControl::Fallback(
8794 DirectAdaptiveFallback::TokenMismatch,
8795 ));
8796 }
8797 let token = self
8798 .parser
8799 .input
8800 .lt_ref(1)
8801 .ok_or(DirectAdaptiveParseControl::Fallback(
8802 DirectAdaptiveFallback::TokenMismatch,
8803 ))?;
8804 let matched_eof = symbol == TOKEN_EOF;
8805 if !matched_eof {
8806 self.parser.consume();
8807 }
8808 let child = self
8809 .parser
8810 .build_parse_trees
8811 .then(|| ParseTree::Terminal(TerminalNode::from_ref(token)));
8812 Ok((matched_eof, child))
8813 }
8814}
8815
8816fn left_recursive_boundary(atn: &Atn, state: &AtnState, target: usize) -> Option<usize> {
8819 if !state.precedence_rule_decision {
8820 return None;
8821 }
8822 let target_state = atn.state(target)?;
8823 if target_state.kind == AtnStateKind::LoopEnd {
8824 return None;
8825 }
8826 state.rule_index
8827}
8828
8829const fn next_alt_number(
8836 state: &AtnState,
8837 transition_index: usize,
8838 current_alt_number: usize,
8839 track_alt_numbers: bool,
8840) -> usize {
8841 if !track_alt_numbers || current_alt_number != 0 || state.transitions.len() <= 1 {
8842 return current_alt_number;
8843 }
8844 if matches!(
8845 state.kind,
8846 AtnStateKind::Basic
8847 | AtnStateKind::BlockStart
8848 | AtnStateKind::PlusBlockStart
8849 | AtnStateKind::StarBlockStart
8850 | AtnStateKind::StarLoopEntry
8851 ) && !state.precedence_rule_decision
8852 {
8853 return transition_index + 1;
8854 }
8855 current_alt_number
8856}
8857
8858fn fold_left_recursive_boundaries(nodes: Vec<RecognizedNode>) -> Vec<RecognizedNode> {
8861 let mut folded = Vec::new();
8862 for node in nodes {
8863 match node {
8864 RecognizedNode::LeftRecursiveBoundary { rule_index } => {
8865 if !folded.is_empty() {
8866 let children = std::mem::take(&mut folded);
8867 let start_index = recognized_nodes_start_index(&children).unwrap_or_default();
8868 let stop_index = recognized_nodes_stop_index(&children);
8869 folded.push(RecognizedNode::Rule {
8870 rule_index,
8871 invoking_state: -1,
8872 alt_number: 0,
8873 start_index,
8874 stop_index,
8875 return_values: BTreeMap::new(),
8876 children,
8877 });
8878 }
8879 }
8880 node => folded.push(node),
8881 }
8882 }
8883 folded
8884}
8885
8886fn fold_fast_left_recursive_boundaries(
8888 nodes: Vec<Rc<FastRecognizedNode>>,
8889) -> Vec<Rc<FastRecognizedNode>> {
8890 if !nodes.iter().any(|node| {
8895 matches!(
8896 node.as_ref(),
8897 FastRecognizedNode::LeftRecursiveBoundary { .. }
8898 )
8899 }) {
8900 return nodes;
8901 }
8902 let mut folded: Vec<Rc<FastRecognizedNode>> = Vec::with_capacity(nodes.len());
8903 for node in nodes {
8904 match node.as_ref() {
8905 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
8906 if !folded.is_empty() {
8907 let children = std::mem::take(&mut folded);
8908 let start_index =
8909 fast_recognized_nodes_start_index(&children).unwrap_or_default();
8910 let stop_index = fast_recognized_nodes_stop_index(&children);
8911 folded.push(Rc::new(FastRecognizedNode::Rule {
8912 rule_index: *rule_index,
8913 invoking_state: -1,
8914 start_index,
8915 stop_index,
8916 children: NodeList::from_vec(children),
8917 }));
8918 }
8919 }
8920 _ => folded.push(node),
8921 }
8922 }
8923 folded
8924}
8925
8926fn fast_node_has_left_recursive_boundary(node: &FastRecognizedNode) -> bool {
8927 match node {
8928 FastRecognizedNode::LeftRecursiveBoundary { .. } => true,
8929 FastRecognizedNode::Rule { children, .. } => children.has_left_recursive_boundary(),
8930 FastRecognizedNode::Token { .. }
8931 | FastRecognizedNode::ErrorToken { .. }
8932 | FastRecognizedNode::MissingToken { .. } => false,
8933 }
8934}
8935
8936fn fast_recognized_nodes_start_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
8937 nodes
8938 .iter()
8939 .find_map(|node| fast_recognized_node_start_index(node.as_ref()))
8940}
8941
8942const fn fast_recognized_node_start_index(node: &FastRecognizedNode) -> Option<usize> {
8943 match node {
8944 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
8945 Some(*index)
8946 }
8947 FastRecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
8948 FastRecognizedNode::Rule { start_index, .. } => Some(*start_index),
8949 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
8950 }
8951}
8952
8953const fn fast_recognized_node_span(node: &FastRecognizedNode) -> Option<(usize, Option<usize>)> {
8954 match node {
8955 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
8956 Some((*index, Some(*index)))
8957 }
8958 FastRecognizedNode::MissingToken { at_index, .. } => Some((*at_index, None)),
8959 FastRecognizedNode::Rule {
8960 start_index,
8961 stop_index,
8962 ..
8963 } => Some((*start_index, *stop_index)),
8964 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
8965 }
8966}
8967
8968fn fast_recognized_nodes_stop_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
8969 nodes
8970 .iter()
8971 .rev()
8972 .find_map(|node| fast_recognized_node_stop_index(node.as_ref()))
8973}
8974
8975const fn fast_recognized_node_stop_index(node: &FastRecognizedNode) -> Option<usize> {
8976 match node {
8977 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
8978 Some(*index)
8979 }
8980 FastRecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
8981 FastRecognizedNode::Rule { stop_index, .. } => *stop_index,
8982 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
8983 }
8984}
8985
8986fn recognized_nodes_start_index(nodes: &[RecognizedNode]) -> Option<usize> {
8987 nodes.iter().find_map(recognized_node_start_index)
8988}
8989
8990const fn recognized_node_start_index(node: &RecognizedNode) -> Option<usize> {
8991 match node {
8992 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
8993 RecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
8994 RecognizedNode::Rule { start_index, .. } => Some(*start_index),
8995 RecognizedNode::LeftRecursiveBoundary { .. } => None,
8996 }
8997}
8998
8999fn recognized_nodes_stop_index(nodes: &[RecognizedNode]) -> Option<usize> {
9000 nodes.iter().rev().find_map(recognized_node_stop_index)
9001}
9002
9003fn invoking_state_number(state_number: usize) -> isize {
9006 isize::try_from(state_number).unwrap_or(isize::MAX)
9007}
9008
9009fn direct_precedence(precedence: i32) -> usize {
9010 usize::try_from(precedence.max(0)).unwrap_or_default()
9011}
9012
9013const fn recognized_node_stop_index(node: &RecognizedNode) -> Option<usize> {
9014 match node {
9015 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
9016 RecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
9017 RecognizedNode::Rule { stop_index, .. } => *stop_index,
9018 RecognizedNode::LeftRecursiveBoundary { .. } => None,
9019 }
9020}
9021
9022fn token_input_display(token: &impl Token) -> String {
9023 format!("'{}'", token.text().unwrap_or("<EOF>"))
9024}
9025
9026fn display_input_text(text: &str) -> String {
9027 let mut out = String::new();
9028 for ch in text.chars() {
9029 match ch {
9030 '\n' => out.push_str("\\n"),
9031 '\r' => out.push_str("\\r"),
9032 '\t' => out.push_str("\\t"),
9033 other => out.push(other),
9034 }
9035 }
9036 out
9037}
9038
9039fn diagnostic_for_token(token: Option<&impl Token>, message: String) -> ParserDiagnostic {
9040 ParserDiagnostic {
9041 line: token.map(Token::line).unwrap_or_default(),
9042 column: token.map(Token::column).unwrap_or_default(),
9043 message,
9044 }
9045}
9046
9047#[allow(clippy::print_stderr)]
9049fn report_parser_diagnostics(diagnostics: &[ParserDiagnostic]) {
9050 for diagnostic in diagnostics {
9051 eprintln!(
9052 "line {}:{} {}",
9053 diagnostic.line, diagnostic.column, diagnostic.message
9054 );
9055 }
9056}
9057
9058#[allow(clippy::print_stderr)]
9061fn report_generated_diagnostics(
9062 parser_diagnostics: &[ParserDiagnostic],
9063 token_errors: &[TokenSourceError],
9064) {
9065 let mut token_iter = token_errors.iter().peekable();
9072 for diagnostic in parser_diagnostics {
9073 while let Some(error) = token_iter.peek() {
9074 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
9075 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9076 token_iter.next();
9077 } else {
9078 break;
9079 }
9080 }
9081 eprintln!(
9082 "line {}:{} {}",
9083 diagnostic.line, diagnostic.column, diagnostic.message
9084 );
9085 }
9086 for error in token_iter {
9087 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9088 }
9089}
9090
9091#[allow(clippy::print_stderr)]
9094fn report_token_source_errors(errors: &[TokenSourceError]) {
9095 for error in errors {
9096 eprintln!("line {}:{} {}", error.line, error.column, error.message);
9097 }
9098}
9099
9100fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
9101 let items = symbols
9102 .iter()
9103 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
9104 .collect::<Vec<_>>();
9105 if let [single] = items.as_slice() {
9106 return single.clone();
9107 }
9108 format!("{{{}}}", items.join(", "))
9109}
9110
9111fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
9112 if symbol == TOKEN_EOF {
9113 return "<EOF>".to_owned();
9114 }
9115 vocabulary.display_name(symbol)
9116}
9117
9118fn is_caller_follow_boundary_text(text: &str) -> bool {
9119 text.chars().any(|ch| ch == ';' || ch == '\n')
9120 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
9121}
9122
9123fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
9124 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
9125}
9126
9127fn state_is_left_recursive_rule(atn: &Atn, state: &AtnState) -> bool {
9131 let Some(rule_index) = state.rule_index else {
9132 return false;
9133 };
9134 atn.rule_to_start_state()
9135 .get(rule_index)
9136 .and_then(|state_number| atn.state(*state_number))
9137 .is_some_and(|rule_start| rule_start.left_recursive_rule)
9138}
9139
9140fn select_better_top_outcome(
9147 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
9148 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
9149) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
9150 match (first, second) {
9151 (Ok(first), Ok(second)) => {
9152 if first.0.diagnostics.is_empty() {
9153 Ok(first)
9154 } else {
9155 Ok(second)
9156 }
9157 }
9158 (Ok(first), Err(_)) => Ok(first),
9159 (Err(_), Ok(second)) => Ok(second),
9160 (Err(_), Err(second_expected)) => Err(second_expected),
9161 }
9162}
9163
9164fn select_best_fast_outcome(
9170 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
9171 prediction_mode: PredictionMode,
9172 caller_follow: Option<&TokenBitSet>,
9173 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
9174) -> Option<FastRecognizeOutcome> {
9175 let mut best = None;
9176 let mut best_caller_follow = None;
9177 for outcome in outcomes {
9178 if matches!(
9179 prediction_mode,
9180 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9181 ) && outcome.diagnostics.is_empty()
9182 && let Some(follow) = caller_follow
9183 {
9184 let (token_type, is_boundary, _) = token_info_at(outcome.index);
9185 if is_boundary && follow.contains(token_type) {
9186 let replace =
9187 best_caller_follow
9188 .as_ref()
9189 .is_none_or(|existing: &FastRecognizeOutcome| {
9190 (outcome.index, outcome.consumed_eof)
9191 < (existing.index, existing.consumed_eof)
9192 });
9193 if replace {
9194 best_caller_follow = Some(outcome.clone());
9195 }
9196 }
9197 }
9198 let Some(existing) = best else {
9199 best = Some(outcome);
9200 continue;
9201 };
9202 let outcome_position = (outcome.index, outcome.consumed_eof);
9203 let best_position = (existing.index, existing.consumed_eof);
9204 let better = match prediction_mode {
9205 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
9206 outcome_position,
9207 &outcome.diagnostics,
9208 best_position,
9209 &existing.diagnostics,
9210 ),
9211 PredictionMode::Sll => outcome.index > existing.index,
9212 };
9213 best = Some(if better { outcome } else { existing });
9214 }
9215 let should_use_caller_follow =
9216 best_caller_follow
9217 .as_ref()
9218 .zip(best.as_ref())
9219 .is_some_and(|(candidate, selected)| {
9220 if !selected.diagnostics.is_empty() {
9221 return true;
9222 }
9223 candidate.index < selected.index
9224 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
9225 });
9226 if should_use_caller_follow {
9227 best_caller_follow
9228 } else {
9229 best
9230 }
9231}
9232
9233fn select_best_outcome(
9234 outcomes: impl Iterator<Item = RecognizeOutcome>,
9235 prediction_mode: PredictionMode,
9236) -> Option<RecognizeOutcome> {
9237 let outcomes = outcomes.collect::<Vec<_>>();
9238 let prefer_first_tie = outcomes
9239 .iter()
9240 .any(|outcome| nodes_need_stable_tie(&outcome.nodes));
9241 outcomes.into_iter().reduce(|best, outcome| {
9242 let outcome_position = (outcome.index, outcome.consumed_eof);
9243 let best_position = (best.index, best.consumed_eof);
9244 let better = match prediction_mode {
9245 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
9246 outcome_is_better(
9247 outcome_position,
9248 &outcome.diagnostics,
9249 best_position,
9250 &best.diagnostics,
9251 ) || (!prefer_first_tie
9252 && outcome_position == best_position
9253 && outcome.diagnostics.len() == best.diagnostics.len()
9254 && diagnostic_recovery_rank(&outcome.diagnostics)
9255 == diagnostic_recovery_rank(&best.diagnostics)
9256 && (outcome.decisions < best.decisions
9257 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
9258 }
9259 PredictionMode::Sll => {
9260 outcome_position > best_position
9261 || (outcome_position == best_position
9262 && !prefer_first_tie
9263 && (outcome.decisions < best.decisions
9264 || (outcome.decisions == best.decisions
9265 && outcome_is_better(
9266 outcome_position,
9267 &outcome.diagnostics,
9268 best_position,
9269 &best.diagnostics,
9270 ))))
9271 }
9272 };
9273 if better {
9274 return outcome;
9275 }
9276 best
9277 })
9278}
9279
9280fn transition_decision(
9287 atn: &Atn,
9288 state: &AtnState,
9289 transition_index: usize,
9290 predicates: &[(usize, usize, ParserPredicate)],
9291) -> Option<usize> {
9292 if state.transitions.len() <= 1
9293 || state.precedence_rule_decision
9294 || decision_reaches_unsupported_predicate(atn, state, predicates)
9295 {
9296 return None;
9297 }
9298 Some(transition_index)
9299}
9300
9301const fn starts_prediction_decision(state: &AtnState) -> bool {
9307 state.transitions.len() > 1
9308 && !matches!(
9309 state.kind,
9310 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
9311 )
9312}
9313
9314fn record_no_viable_if_ambiguous(
9317 expected: &mut ExpectedTokens,
9318 decision_start_index: Option<usize>,
9319 index: usize,
9320) {
9321 if expected.index == Some(index) && expected.symbols.len() > 1 {
9322 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
9323 expected.record_no_viable(decision_start, index);
9324 }
9325 }
9326}
9327
9328const fn record_predicate_no_viable(
9331 expected: &mut ExpectedTokens,
9332 decision_start_index: Option<usize>,
9333 index: usize,
9334) {
9335 if let Some(decision_start) = decision_start_index {
9336 expected.record_no_viable(decision_start, index);
9337 }
9338}
9339
9340const fn no_viable_decision_start(
9342 decision_start_index: Option<usize>,
9343 index: usize,
9344) -> Option<usize> {
9345 match decision_start_index {
9346 Some(start) if index > start => Some(start),
9347 _ => None,
9348 }
9349}
9350
9351fn restore_expected(
9355 children: &[RecognizeOutcome],
9356 child_start_index: usize,
9357 expected: &mut ExpectedTokens,
9358 snapshot: ExpectedTokens,
9359 preserve_child_expected: bool,
9360) {
9361 if preserve_child_expected {
9362 return;
9363 }
9364 if children
9365 .iter()
9366 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
9367 {
9368 *expected = snapshot;
9369 }
9370}
9371
9372fn decision_reaches_unsupported_predicate(
9375 atn: &Atn,
9376 state: &AtnState,
9377 predicates: &[(usize, usize, ParserPredicate)],
9378) -> bool {
9379 state.transitions.iter().any(|transition| {
9380 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
9381 })
9382}
9383
9384fn transition_reaches_unsupported_predicate(
9386 atn: &Atn,
9387 transition: &Transition,
9388 predicates: &[(usize, usize, ParserPredicate)],
9389 visited: &mut BTreeSet<usize>,
9390) -> bool {
9391 match transition {
9392 Transition::Predicate {
9393 rule_index,
9394 pred_index,
9395 ..
9396 } => !predicates
9397 .iter()
9398 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
9399 Transition::Epsilon { target }
9400 | Transition::Action { target, .. }
9401 | Transition::Rule { target, .. } => {
9402 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
9403 }
9404 Transition::Precedence { .. }
9405 | Transition::Atom { .. }
9406 | Transition::Range { .. }
9407 | Transition::Set { .. }
9408 | Transition::NotSet { .. }
9409 | Transition::Wildcard { .. } => false,
9410 }
9411}
9412
9413fn state_reaches_unsupported_predicate(
9415 atn: &Atn,
9416 state_number: usize,
9417 predicates: &[(usize, usize, ParserPredicate)],
9418 visited: &mut BTreeSet<usize>,
9419) -> bool {
9420 if !visited.insert(state_number) {
9421 return false;
9422 }
9423 let Some(state) = atn.state(state_number) else {
9424 return false;
9425 };
9426 state.transitions.iter().any(|transition| {
9427 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
9428 })
9429}
9430
9431fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
9433 if let Some(decision) = decision {
9434 outcome.decisions.insert(0, decision);
9435 }
9436}
9437
9438fn outcome_is_better(
9439 outcome_position: (usize, bool),
9440 outcome_diagnostics: &[ParserDiagnostic],
9441 best_position: (usize, bool),
9442 best_diagnostics: &[ParserDiagnostic],
9443) -> bool {
9444 outcome_position > best_position
9445 || (outcome_position == best_position
9446 && (outcome_diagnostics.len() < best_diagnostics.len()
9447 || (outcome_diagnostics.len() == best_diagnostics.len()
9448 && diagnostic_recovery_rank(outcome_diagnostics)
9449 < diagnostic_recovery_rank(best_diagnostics))))
9450}
9451
9452fn diagnostic_recovery_rank(diagnostics: &[ParserDiagnostic]) -> usize {
9455 diagnostics
9456 .iter()
9457 .filter(|diagnostic| {
9458 diagnostic.message.starts_with("mismatched input ")
9459 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
9460 })
9461 .count()
9462}
9463
9464fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
9465 if outcomes
9466 .iter()
9467 .any(|outcome| outcome.diagnostics.is_empty())
9468 {
9469 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
9470 }
9471}
9472
9473fn discard_recovered_outcomes_if_clean_path_exists(outcomes: &mut Vec<RecognizeOutcome>) {
9474 if outcomes.iter().any(outcome_has_rule_failure_diagnostic) {
9475 return;
9476 }
9477 if outcomes
9478 .iter()
9479 .any(|outcome| outcome.diagnostics.is_empty())
9480 {
9481 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
9482 }
9483}
9484
9485fn outcome_has_rule_failure_diagnostic(outcome: &RecognizeOutcome) -> bool {
9488 outcome
9489 .diagnostics
9490 .iter()
9491 .any(|diagnostic| diagnostic.message.starts_with("rule "))
9492}
9493
9494fn nodes_need_stable_tie(nodes: &[RecognizedNode]) -> bool {
9497 nodes.iter().any(node_needs_stable_tie)
9498}
9499
9500fn node_needs_stable_tie(node: &RecognizedNode) -> bool {
9501 match node {
9502 RecognizedNode::Token { .. }
9503 | RecognizedNode::ErrorToken { .. }
9504 | RecognizedNode::MissingToken { .. } => false,
9505 RecognizedNode::LeftRecursiveBoundary { .. } => true,
9506 RecognizedNode::Rule {
9507 rule_index,
9508 children,
9509 ..
9510 } => children.iter().any(|child| {
9511 matches!(
9512 child,
9513 RecognizedNode::Rule {
9514 rule_index: child_rule,
9515 ..
9516 } if child_rule == rule_index
9517 ) || node_needs_stable_tie(child)
9518 }),
9519 }
9520}
9521
9522fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
9536 if outcomes.len() < 2 {
9537 return;
9538 }
9539 let mut keep = Vec::with_capacity(outcomes.len());
9540 let mut seen: BTreeMap<(usize, bool), Vec<usize>> = BTreeMap::new();
9541 'outcomes: for (index, outcome) in outcomes.iter().enumerate() {
9542 let bucket = seen
9543 .entry((outcome.index, outcome.consumed_eof))
9544 .or_default();
9545 for &previous in bucket.iter() {
9546 if outcomes[previous].diagnostics == outcome.diagnostics {
9547 continue 'outcomes;
9548 }
9549 }
9550 bucket.push(index);
9551 keep.push(index);
9552 }
9553 if keep.len() == outcomes.len() {
9554 return;
9555 }
9556 let mut iter = keep.into_iter();
9557 let mut next_keep = iter.next();
9558 let mut current = 0_usize;
9559 outcomes.retain(|_| {
9560 let result = next_keep == Some(current);
9561 if result {
9562 next_keep = iter.next();
9563 }
9564 current += 1;
9565 result
9566 });
9567}
9568
9569fn dedupe_clean_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
9570 if outcomes.len() < 2 {
9571 return;
9572 }
9573 let mut inline_keys: [(usize, bool); 8] = [(0, false); 8];
9583 let mut inline_len = 0_usize;
9584 let mut overflow: Vec<(usize, bool)> = Vec::new();
9585 outcomes.retain(|outcome| {
9586 let key = (outcome.index, outcome.consumed_eof);
9587 for &existing in &inline_keys[..inline_len] {
9588 if existing == key {
9589 return false;
9590 }
9591 }
9592 if !overflow.is_empty() {
9593 for &existing in &overflow {
9594 if existing == key {
9595 return false;
9596 }
9597 }
9598 }
9599 if inline_len < inline_keys.len() {
9600 inline_keys[inline_len] = key;
9601 inline_len += 1;
9602 } else {
9603 overflow.push(key);
9604 }
9605 true
9606 });
9607}
9608
9609fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>) {
9611 outcomes.sort_unstable();
9612 outcomes.dedup();
9613}
9614
9615impl<S, H> Recognizer for BaseParser<S, H>
9616where
9617 S: TokenSource,
9618 H: SemanticHooks,
9619{
9620 fn data(&self) -> &RecognizerData {
9621 &self.data
9622 }
9623
9624 fn data_mut(&mut self) -> &mut RecognizerData {
9625 &mut self.data
9626 }
9627}
9628
9629impl<S, H> Parser for BaseParser<S, H>
9630where
9631 S: TokenSource,
9632 H: SemanticHooks,
9633{
9634 fn build_parse_trees(&self) -> bool {
9635 self.build_parse_trees
9636 }
9637
9638 fn set_build_parse_trees(&mut self, build: bool) {
9639 self.build_parse_trees = build;
9640 }
9641
9642 fn number_of_syntax_errors(&self) -> usize {
9643 Self::number_of_syntax_errors(self)
9644 }
9645
9646 fn report_diagnostic_errors(&self) -> bool {
9647 self.report_diagnostic_errors
9648 }
9649
9650 fn set_report_diagnostic_errors(&mut self, report: bool) {
9651 self.report_diagnostic_errors = report;
9652 }
9653
9654 fn prediction_mode(&self) -> PredictionMode {
9655 self.prediction_mode
9656 }
9657
9658 fn set_prediction_mode(&mut self, mode: PredictionMode) {
9659 self.prediction_mode = mode;
9660 }
9661}
9662
9663#[cfg(test)]
9664mod tests {
9665 use super::*;
9666 use crate::atn::AtnType;
9667 use crate::atn::IntervalSet;
9668 use crate::atn::parser::{
9669 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
9670 };
9671 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
9672 use crate::token::{CommonToken, HIDDEN_CHANNEL, Token};
9673 use crate::token_stream::CommonTokenStream;
9674 use crate::vocabulary::Vocabulary;
9675
9676 #[test]
9677 fn fx_hasher_write_matches_typed_methods_for_full_words() {
9678 let value: u64 = 0x0102_0304_0506_0708;
9685 let mut typed = FxHasher::default();
9686 typed.write_u64(value);
9687 let mut bytewise = FxHasher::default();
9688 bytewise.write(&value.to_le_bytes());
9689 assert_eq!(typed.finish(), bytewise.finish());
9690 }
9691
9692 #[derive(Debug)]
9693 struct Source {
9694 tokens: Vec<CommonToken>,
9695 index: usize,
9696 }
9697
9698 impl TokenSource for Source {
9699 fn next_token(&mut self) -> CommonToken {
9700 let token = self
9701 .tokens
9702 .get(self.index)
9703 .cloned()
9704 .unwrap_or_else(|| CommonToken::eof("parser-test", self.index, 1, self.index));
9705 self.index += 1;
9706 token
9707 }
9708
9709 fn line(&self) -> usize {
9710 1
9711 }
9712
9713 fn column(&self) -> usize {
9714 self.index
9715 }
9716
9717 fn source_name(&self) -> &'static str {
9718 "parser-test"
9719 }
9720 }
9721
9722 fn mini_parser_data() -> RecognizerData {
9723 RecognizerData::new(
9724 "Mini.g4",
9725 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
9726 )
9727 .with_rule_names(["s"])
9728 }
9729
9730 fn mini_parser(tokens: Vec<CommonToken>) -> BaseParser<Source> {
9731 let data = mini_parser_data();
9732 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
9733 }
9734
9735 fn mini_parser_with_hooks<H>(tokens: Vec<CommonToken>, hooks: H) -> BaseParser<Source, H>
9736 where
9737 H: SemanticHooks,
9738 {
9739 BaseParser::with_semantic_hooks(
9740 CommonTokenStream::new(Source { tokens, index: 0 }),
9741 mini_parser_data(),
9742 hooks,
9743 )
9744 }
9745
9746 fn token_then_eof_atn() -> Atn {
9747 AtnDeserializer::new(&SerializedAtn::from_i32(&[
9748 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, ]))
9764 .deserialize()
9765 .expect("artificial parser ATN should deserialize")
9766 }
9767
9768 fn eof_then_action_atn() -> Atn {
9769 AtnDeserializer::new(&SerializedAtn::from_i32(&[
9770 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, ]))
9786 .deserialize()
9787 .expect("artificial parser ATN should deserialize")
9788 }
9789
9790 fn two_alt_decision_atn() -> Atn {
9791 let mut atn = Atn::new(AtnType::Parser, 2);
9792 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9793 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
9794 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
9795 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
9796 atn.add_state(AtnState::new(4, AtnStateKind::BlockEnd).with_rule_index(0));
9797 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
9798 atn.set_rule_to_start_state(vec![0]);
9799 atn.set_rule_to_stop_state(vec![5]);
9800 atn.add_decision_state(1);
9801 atn.state_mut(0)
9802 .expect("state 0")
9803 .add_transition(Transition::Epsilon { target: 1 });
9804 atn.state_mut(1)
9805 .expect("state 1")
9806 .add_transition(Transition::Atom {
9807 target: 2,
9808 label: 1,
9809 });
9810 atn.state_mut(1)
9811 .expect("state 1")
9812 .add_transition(Transition::Atom {
9813 target: 3,
9814 label: 2,
9815 });
9816 atn.state_mut(2)
9817 .expect("state 2")
9818 .add_transition(Transition::Epsilon { target: 4 });
9819 atn.state_mut(3)
9820 .expect("state 3")
9821 .add_transition(Transition::Epsilon { target: 4 });
9822 atn.state_mut(4)
9823 .expect("state 4")
9824 .add_transition(Transition::Epsilon { target: 5 });
9825 atn
9826 }
9827
9828 fn optional_then_b_eof_atn() -> Atn {
9831 let mut atn = Atn::new(AtnType::Parser, 3);
9832 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9833 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
9834 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
9835 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
9836 atn.add_state(AtnState::new(4, AtnStateKind::Basic).with_rule_index(0));
9837 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
9838 atn.set_rule_to_start_state(vec![0]);
9839 atn.set_rule_to_stop_state(vec![5]);
9840 atn.add_decision_state(1);
9841 atn.state_mut(0)
9842 .expect("state 0")
9843 .add_transition(Transition::Epsilon { target: 1 });
9844 atn.state_mut(1)
9846 .expect("state 1")
9847 .add_transition(Transition::Atom {
9848 target: 3,
9849 label: 1,
9850 });
9851 atn.state_mut(1)
9852 .expect("state 1")
9853 .add_transition(Transition::Epsilon { target: 3 });
9854 atn.state_mut(3)
9856 .expect("state 3")
9857 .add_transition(Transition::Atom {
9858 target: 4,
9859 label: 2,
9860 });
9861 atn.state_mut(4)
9862 .expect("state 4")
9863 .add_transition(Transition::Atom {
9864 target: 5,
9865 label: TOKEN_EOF,
9866 });
9867 atn
9868 }
9869
9870 #[test]
9871 fn sync_decision_deletes_only_a_single_token() {
9872 let atn = optional_then_b_eof_atn();
9880
9881 let mut single = mini_parser(vec![
9882 CommonToken::new(3).with_text("c"),
9883 CommonToken::new(2).with_text("b"),
9884 CommonToken::eof("parser-test", 1, 2, 2),
9885 ]);
9886 single.rule_context_stack = vec![RuleContextFrame {
9887 rule_index: 0,
9888 invoking_state: 0,
9889 }];
9890 let children = single
9891 .sync_decision(&atn, 1, true, false)
9892 .expect("single extraneous token recovers");
9893 assert_eq!(children.len(), 1);
9894 assert!(matches!(children[0], ParseTree::Error(_)));
9895 assert_eq!(single.number_of_syntax_errors(), 1);
9896 assert_eq!(single.la(1), 2);
9898
9899 let mut double = mini_parser(vec![
9900 CommonToken::new(3).with_text("c"),
9901 CommonToken::new(3).with_text("c"),
9902 CommonToken::new(2).with_text("b"),
9903 CommonToken::eof("parser-test", 1, 3, 3),
9904 ]);
9905 double.rule_context_stack = vec![RuleContextFrame {
9906 rule_index: 0,
9907 invoking_state: 0,
9908 }];
9909 let result = double.sync_decision(&atn, 1, true, false);
9910 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
9915 match error {
9916 AntlrError::ParserError { message, .. } => {
9917 assert!(message.starts_with("mismatched input"), "got: {message}");
9918 }
9919 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
9920 }
9921 assert_eq!(double.la(1), 3);
9922 }
9923
9924 fn star_loop_then_eof_atn() -> Atn {
9928 AtnDeserializer::new(&SerializedAtn::from_i32(&[
9929 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,
9930 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,
9931 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,
9932 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
9933 ]))
9934 .deserialize()
9935 .expect("star-loop-then-EOF ATN should deserialize")
9936 }
9937
9938 #[test]
9939 fn sync_decision_deletes_token_before_eof_at_loop_back() {
9940 let atn = star_loop_then_eof_atn();
9946 let mut parser = mini_parser(vec![
9947 CommonToken::new(2).with_text("c"),
9948 CommonToken::eof("parser-test", 1, 1, 1),
9949 ]);
9950 parser.rule_context_stack = vec![RuleContextFrame {
9951 rule_index: 0,
9952 invoking_state: 0,
9953 }];
9954 let children = parser
9955 .sync_decision(&atn, 5, true, false)
9956 .expect("single token before EOF recovers");
9957 assert_eq!(children.len(), 1);
9958 assert!(matches!(children[0], ParseTree::Error(_)));
9959 assert_eq!(parser.number_of_syntax_errors(), 1);
9960 assert_eq!(
9961 parser.la(1),
9962 TOKEN_EOF,
9963 "EOF is left for the rule's EOF match"
9964 );
9965 }
9966
9967 #[test]
9968 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
9969 let atn = star_loop_then_eof_atn();
9974 let mut parser = mini_parser(vec![
9975 CommonToken::new(2).with_text("c"),
9976 CommonToken::new(2).with_text("c"),
9977 CommonToken::eof("parser-test", 1, 2, 2),
9978 ]);
9979 parser.rule_context_stack = vec![RuleContextFrame {
9980 rule_index: 0,
9981 invoking_state: 0,
9982 }];
9983 let error = parser
9984 .sync_decision(&atn, 5, true, false)
9985 .expect_err("two tokens at the loop entry must not be deleted");
9986 match error {
9987 AntlrError::ParserError { message, .. } => {
9988 assert!(message.starts_with("mismatched input"), "got: {message}");
9989 }
9990 other => panic!("expected mismatched-input ParserError, got {other:?}"),
9991 }
9992 assert_eq!(
9993 parser.la(1),
9994 2,
9995 "nothing consumed; cursor still on first `c`"
9996 );
9997 }
9998
9999 #[test]
10000 fn sync_decision_consumes_until_eof_at_loop_back() {
10001 let atn = star_loop_then_eof_atn();
10007 let mut parser = mini_parser(vec![
10008 CommonToken::new(2).with_text("c"),
10009 CommonToken::new(2).with_text("c"),
10010 CommonToken::eof("parser-test", 1, 2, 2),
10011 ]);
10012 parser.rule_context_stack = vec![RuleContextFrame {
10013 rule_index: 0,
10014 invoking_state: 0,
10015 }];
10016 let children = parser
10017 .sync_decision(&atn, 5, false, true)
10018 .expect("loop-back multi-token deletion recovers onto EOF");
10019 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
10020 assert!(children.iter().all(|c| matches!(c, ParseTree::Error(_))));
10021 assert_eq!(parser.number_of_syntax_errors(), 1);
10022 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
10023 }
10024
10025 fn predicate_after_token_atn() -> Atn {
10026 let mut atn = Atn::new(AtnType::Parser, 2);
10027 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10028 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
10029 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10030 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
10031 atn.add_state(AtnState::new(4, AtnStateKind::RuleStop).with_rule_index(0));
10032 atn.set_rule_to_start_state(vec![0]);
10033 atn.set_rule_to_stop_state(vec![4]);
10034 atn.state_mut(0)
10035 .expect("state 0")
10036 .add_transition(Transition::Atom {
10037 target: 1,
10038 label: 1,
10039 });
10040 atn.state_mut(1)
10041 .expect("state 1")
10042 .add_transition(Transition::Predicate {
10043 target: 2,
10044 rule_index: 0,
10045 pred_index: 0,
10046 context_dependent: false,
10047 });
10048 atn.state_mut(2)
10049 .expect("state 2")
10050 .add_transition(Transition::Atom {
10051 target: 3,
10052 label: 2,
10053 });
10054 atn.state_mut(3)
10055 .expect("state 3")
10056 .add_transition(Transition::Epsilon { target: 4 });
10057 atn
10058 }
10059
10060 fn nested_nullable_context_atn() -> Atn {
10061 let mut atn = Atn::new(AtnType::Parser, 1);
10062 for state_number in 0..=20 {
10063 let kind = match state_number {
10064 0 | 10 | 16 => AtnStateKind::RuleStart,
10065 9 | 15 | 20 => AtnStateKind::RuleStop,
10066 _ => AtnStateKind::Basic,
10067 };
10068 let rule_index = match state_number {
10069 0..=9 => 0,
10070 10..=15 => 1,
10071 _ => 2,
10072 };
10073 atn.add_state(AtnState::new(state_number, kind).with_rule_index(rule_index));
10074 }
10075 atn.set_rule_to_start_state(vec![0, 10, 16]);
10076 atn.set_rule_to_stop_state(vec![9, 15, 20]);
10077 atn.state_mut(1)
10078 .expect("state 1")
10079 .add_transition(Transition::Rule {
10080 target: 10,
10081 rule_index: 1,
10082 follow_state: 8,
10083 precedence: 0,
10084 });
10085 atn.state_mut(8)
10086 .expect("state 8")
10087 .add_transition(Transition::Atom {
10088 target: 9,
10089 label: 1,
10090 });
10091 atn.state_mut(8)
10092 .expect("state 8")
10093 .add_transition(Transition::Epsilon { target: 9 });
10094 atn.state_mut(2)
10095 .expect("state 2")
10096 .add_transition(Transition::Rule {
10097 target: 16,
10098 rule_index: 2,
10099 follow_state: 14,
10100 precedence: 0,
10101 });
10102 atn.state_mut(14)
10103 .expect("state 14")
10104 .add_transition(Transition::Epsilon { target: 15 });
10105 atn
10106 }
10107
10108 fn generated_match_recovery_atn() -> Atn {
10109 let mut atn = Atn::new(AtnType::Parser, 2);
10110 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10111 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
10112 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10113 atn.add_state(AtnState::new(3, AtnStateKind::RuleStop).with_rule_index(0));
10114 atn.add_state(AtnState::new(4, AtnStateKind::RuleStart).with_rule_index(1));
10115 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(1));
10116 atn.set_rule_to_start_state(vec![0, 4]);
10117 atn.set_rule_to_stop_state(vec![3, 5]);
10118 atn.state_mut(1)
10119 .expect("state 1")
10120 .add_transition(Transition::Rule {
10121 target: 4,
10122 rule_index: 1,
10123 follow_state: 2,
10124 precedence: 0,
10125 });
10126 atn.state_mut(2)
10127 .expect("state 2")
10128 .add_transition(Transition::Atom {
10129 target: 3,
10130 label: TOKEN_EOF,
10131 });
10132 atn
10133 }
10134
10135 fn complement_set_atn() -> Atn {
10136 let mut atn = Atn::new(AtnType::Parser, 1);
10137 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10138 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
10139 atn.set_rule_to_start_state(vec![0]);
10140 atn.set_rule_to_stop_state(vec![1]);
10141 let mut excluded = IntervalSet::new();
10142 excluded.add(1);
10143 atn.state_mut(0)
10144 .expect("state 0")
10145 .add_transition(Transition::NotSet {
10146 target: 1,
10147 set: excluded,
10148 });
10149 atn
10150 }
10151
10152 fn wildcard_then_eof_atn() -> Atn {
10155 let mut atn = Atn::new(AtnType::Parser, 1);
10156 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10157 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
10158 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
10159 atn.set_rule_to_start_state(vec![0]);
10160 atn.set_rule_to_stop_state(vec![1]);
10161 atn.state_mut(0)
10162 .expect("state 0")
10163 .add_transition(Transition::Wildcard { target: 2 });
10164 atn.state_mut(2)
10165 .expect("state 2")
10166 .add_transition(Transition::Atom {
10167 target: 1,
10168 label: TOKEN_EOF,
10169 });
10170 atn
10171 }
10172
10173 #[test]
10174 fn parser_matches_token_and_reports_mismatch() {
10175 let source = Source {
10176 tokens: vec![
10177 CommonToken::new(1).with_text("x"),
10178 CommonToken::eof("parser-test", 1, 1, 1),
10179 ],
10180 index: 0,
10181 };
10182 let data = RecognizerData::new(
10183 "Mini.g4",
10184 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10185 );
10186 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
10187 assert_eq!(
10188 parser.match_token(1).expect("token 1 should match").text(),
10189 "x"
10190 );
10191 assert!(parser.match_token(1).is_err());
10192 }
10193
10194 #[test]
10195 fn parser_matches_token_sets() {
10196 let mut parser = mini_parser(vec![
10197 CommonToken::new(1).with_text("x"),
10198 CommonToken::eof("parser-test", 1, 1, 1),
10199 ]);
10200
10201 assert_eq!(
10202 parser
10203 .match_set(&[(1, 1), (3, 4)])
10204 .expect("token set should match")
10205 .text(),
10206 "x"
10207 );
10208 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
10209 }
10210
10211 #[test]
10212 fn generated_rule_api_tracks_state_and_precedence() {
10213 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10214
10215 let context = parser.enter_rule(7, 2);
10216 assert_eq!(context.rule_index(), 2);
10217 assert_eq!(parser.state(), 7);
10218 assert_eq!(
10219 parser.rule_context_stack,
10220 vec![RuleContextFrame {
10221 rule_index: 2,
10222 invoking_state: 7
10223 }]
10224 );
10225
10226 let recursive = parser.enter_recursion_rule(11, 3, 4);
10227 assert_eq!(recursive.rule_index(), 3);
10228 assert!(parser.precpred(4));
10229 assert!(parser.precpred(5));
10230 assert!(!parser.precpred(3));
10231
10232 let next = parser.push_new_recursion_context(13, 3);
10233 assert_eq!(next.invoking_state(), 13);
10234 parser.unroll_recursion_context();
10235 assert_eq!(parser.precedence_stack, vec![0]);
10236 assert_eq!(
10237 parser.rule_context_stack,
10238 vec![RuleContextFrame {
10239 rule_index: 2,
10240 invoking_state: 7
10241 }]
10242 );
10243
10244 parser.exit_rule();
10245 assert!(parser.rule_context_stack.is_empty());
10246 }
10247
10248 #[test]
10249 fn parser_predicates_support_token_adjacency() {
10250 let mut parser = mini_parser(vec![
10251 CommonToken::new(1).with_text("=").with_span(0, 0),
10252 CommonToken::new(1).with_text(">").with_span(1, 1),
10253 CommonToken::eof("parser-test", 2, 1, 2),
10254 ]);
10255 parser.consume();
10256 parser.consume();
10257
10258 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
10259
10260 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
10261
10262 let mut parser = mini_parser(vec![
10263 CommonToken::new(1).with_text("=").with_span(0, 0),
10264 CommonToken::new(1)
10265 .with_text(" ")
10266 .with_channel(HIDDEN_CHANNEL)
10267 .with_span(1, 1),
10268 CommonToken::new(1).with_text(">").with_span(2, 2),
10269 CommonToken::eof("parser-test", 3, 1, 3),
10270 ]);
10271 parser.consume();
10272 parser.consume();
10273
10274 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
10275 }
10276
10277 #[test]
10278 fn parser_predicates_support_context_child_text_checks() {
10279 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10280 let mut context = ParserRuleContext::new(1, 0);
10281 let mut child_context = ParserRuleContext::new(2, 0);
10282 child_context.add_child(ParseTree::Terminal(TerminalNode::new(
10283 CommonToken::new(1).with_text("var"),
10284 )));
10285 context.add_child(ParseTree::Rule(RuleNode::new(child_context)));
10286 let predicates = [(
10287 1,
10288 0,
10289 ParserPredicate::ContextChildRuleTextNotEquals {
10290 rule_index: 2,
10291 text: "var",
10292 },
10293 )];
10294
10295 assert!(
10296 !parser.parser_semantic_predicate_matches_with_context_and_local(
10297 &predicates,
10298 1,
10299 0,
10300 &context,
10301 0,
10302 )
10303 );
10304 }
10305
10306 #[test]
10307 fn context_expected_symbols_walks_nullable_parent_contexts() {
10308 let atn = nested_nullable_context_atn();
10309 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10310 parser.rule_context_stack = vec![
10311 RuleContextFrame {
10312 rule_index: 0,
10313 invoking_state: 0,
10314 },
10315 RuleContextFrame {
10316 rule_index: 1,
10317 invoking_state: 1,
10318 },
10319 RuleContextFrame {
10320 rule_index: 2,
10321 invoking_state: 2,
10322 },
10323 ];
10324
10325 let expected = parser.context_expected_symbols(&atn);
10326
10327 assert!(expected.contains(&1));
10328 assert!(expected.contains(&TOKEN_EOF));
10329 }
10330
10331 #[test]
10332 fn prediction_context_reuses_cached_stack_until_rule_stack_changes() {
10333 let atn = nested_nullable_context_atn();
10334 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10335 parser.rule_context_stack = vec![
10336 RuleContextFrame {
10337 rule_index: 0,
10338 invoking_state: 0,
10339 },
10340 RuleContextFrame {
10341 rule_index: 1,
10342 invoking_state: 1,
10343 },
10344 RuleContextFrame {
10345 rule_index: 2,
10346 invoking_state: 2,
10347 },
10348 ];
10349
10350 let first = parser.prediction_context(&atn);
10351 let second = parser.prediction_context(&atn);
10352 assert!(Rc::ptr_eq(&first, &second));
10353
10354 parser.exit_rule();
10355 let after_pop = parser.prediction_context(&atn);
10356 assert!(!Rc::ptr_eq(&first, &after_pop));
10357 }
10358
10359 #[test]
10360 fn generated_match_token_recovers_missing_token_from_context_follow() {
10361 let atn = generated_match_recovery_atn();
10362 let data = RecognizerData::new(
10363 "Mini.g4",
10364 Vocabulary::new(
10365 [None, Some("'X'"), Some("'Y'")],
10366 [None, Some("X"), Some("Y")],
10367 [None::<&str>, None, None],
10368 ),
10369 );
10370 let mut parser = BaseParser::new(
10371 CommonTokenStream::new(Source {
10372 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
10373 index: 0,
10374 }),
10375 data,
10376 );
10377 parser.rule_context_stack = vec![
10378 RuleContextFrame {
10379 rule_index: 0,
10380 invoking_state: 0,
10381 },
10382 RuleContextFrame {
10383 rule_index: 1,
10384 invoking_state: 1,
10385 },
10386 ];
10387 assert_eq!(parser.number_of_syntax_errors(), 0);
10388
10389 let node = parser
10390 .match_token_recovering(2, 5, &atn)
10391 .expect("generated match should insert missing token");
10392
10393 assert_eq!(node.children().len(), 1);
10394 assert_eq!(node.children()[0].text(), "<missing 'Y'>");
10395 assert!(!node.consumed_eof());
10398 assert_eq!(parser.la(1), TOKEN_EOF);
10399 assert_eq!(parser.number_of_syntax_errors(), 1);
10400 assert_eq!(
10401 parser.generated_parser_diagnostics,
10402 [ParserDiagnostic {
10403 line: 1,
10404 column: 3,
10405 message: "missing 'Y' at '<EOF>'".to_owned(),
10406 }]
10407 );
10408 }
10409
10410 #[test]
10411 fn generated_match_token_counts_single_token_deletion_recovery() {
10412 let atn = generated_match_recovery_atn();
10413 let data = RecognizerData::new(
10414 "Mini.g4",
10415 Vocabulary::new(
10416 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
10417 [None, Some("X"), Some("Y"), Some("Z")],
10418 [None::<&str>, None, None, None],
10419 ),
10420 );
10421 let mut parser = BaseParser::new(
10422 CommonTokenStream::new(Source {
10423 tokens: vec![
10424 CommonToken::new(3).with_text("z"),
10425 CommonToken::new(2).with_text("y"),
10426 CommonToken::eof("parser-test", 3, 1, 3),
10427 ],
10428 index: 0,
10429 }),
10430 data,
10431 );
10432
10433 let node = parser
10434 .match_token_recovering(2, 5, &atn)
10435 .expect("generated match should delete the extraneous token");
10436
10437 assert_eq!(node.children().len(), 2);
10438 assert!(matches!(node.children()[0], ParseTree::Error(_)));
10439 assert_eq!(node.children()[0].text(), "z");
10440 assert_eq!(node.children()[1].text(), "y");
10441 assert_eq!(parser.number_of_syntax_errors(), 1);
10442 }
10443
10444 #[test]
10445 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
10446 let atn = generated_match_recovery_atn();
10447 let data = RecognizerData::new(
10448 "Mini.g4",
10449 Vocabulary::new(
10450 [None, Some("'X'"), Some("'Y'")],
10451 [None, Some("X"), Some("Y")],
10452 [None::<&str>, None, None],
10453 ),
10454 );
10455 let mut parser = BaseParser::new(
10456 CommonTokenStream::new(Source {
10457 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
10458 index: 0,
10459 }),
10460 data,
10461 );
10462 parser.rule_context_stack = vec![
10463 RuleContextFrame {
10464 rule_index: 0,
10465 invoking_state: 0,
10466 },
10467 RuleContextFrame {
10468 rule_index: 1,
10469 invoking_state: 1,
10470 },
10471 ];
10472 let marker = parser.generated_diagnostics_checkpoint();
10473
10474 let _ = parser
10475 .match_token_recovering(2, 5, &atn)
10476 .expect("generated match should insert missing token");
10477 assert_eq!(parser.number_of_syntax_errors(), 1);
10478
10479 parser.restore_generated_diagnostics(marker);
10480
10481 assert_eq!(parser.number_of_syntax_errors(), 0);
10482 assert!(parser.generated_parser_diagnostics.is_empty());
10483 }
10484
10485 #[test]
10486 fn generated_prediction_diagnostics_use_adaptive_context() {
10487 let atn = two_alt_decision_atn();
10488 let data = RecognizerData::new(
10489 "Mini.g4",
10490 Vocabulary::new(
10491 [None, Some("'x'"), Some("'y'")],
10492 [None, Some("X"), Some("Y")],
10493 [None::<&str>, None, None],
10494 ),
10495 )
10496 .with_rule_names(["s"]);
10497 let mut parser = BaseParser::new(
10498 CommonTokenStream::new(Source {
10499 tokens: vec![
10500 CommonToken::new(1)
10501 .with_text("x")
10502 .with_position(1, 0)
10503 .with_span(0, 0),
10504 CommonToken::new(2)
10505 .with_text("y")
10506 .with_position(1, 2)
10507 .with_span(1, 1),
10508 CommonToken::eof("parser-test", 2, 1, 3),
10509 ],
10510 index: 0,
10511 }),
10512 data,
10513 );
10514 parser.set_report_diagnostic_errors(true);
10515
10516 parser.record_generated_prediction_diagnostic(
10517 &atn,
10518 1,
10519 &ParserAtnPrediction {
10520 alt: 1,
10521 requires_full_context: true,
10522 has_semantic_context: false,
10523 diagnostic: Some(ParserAtnPredictionDiagnostic {
10524 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
10525 start_index: 0,
10526 sll_stop_index: 1,
10527 ll_stop_index: 0,
10528 conflicting_alts: vec![1, 2],
10529 exact: false,
10530 }),
10531 },
10532 );
10533 parser.record_generated_prediction_diagnostic(
10538 &atn,
10539 1,
10540 &ParserAtnPrediction {
10541 alt: 1,
10542 requires_full_context: true,
10543 has_semantic_context: false,
10544 diagnostic: Some(ParserAtnPredictionDiagnostic {
10545 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
10546 start_index: 0,
10547 sll_stop_index: 1,
10548 ll_stop_index: 1,
10549 conflicting_alts: vec![1, 2],
10550 exact: false,
10551 }),
10552 },
10553 );
10554
10555 assert_eq!(
10556 parser.generated_parser_diagnostics,
10557 [
10558 ParserDiagnostic {
10559 line: 1,
10560 column: 2,
10561 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
10562 },
10563 ParserDiagnostic {
10564 line: 1,
10565 column: 0,
10566 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
10567 },
10568 ParserDiagnostic {
10569 line: 1,
10570 column: 2,
10571 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
10572 },
10573 ]
10574 );
10575 }
10576
10577 #[test]
10578 fn generated_match_not_set_recovers_empty_complement_at_eof() {
10579 let atn = complement_set_atn();
10580 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10581 parser.rule_context_stack = vec![RuleContextFrame {
10582 rule_index: 0,
10583 invoking_state: 0,
10584 }];
10585
10586 let node = parser
10587 .match_not_set_recovering(&[(1, 1)], 1, 1, 1, &atn)
10588 .expect("empty complement should recover at EOF");
10589
10590 assert_eq!(node.children().len(), 1);
10591 assert!(!node.consumed_eof());
10594 assert_eq!(parser.la(1), TOKEN_EOF);
10595 assert_eq!(
10596 parser.generated_parser_diagnostics,
10597 [ParserDiagnostic {
10598 line: 1,
10599 column: 1,
10600 message: "missing {} at '<EOF>'".to_owned(),
10601 }]
10602 );
10603 }
10604
10605 #[test]
10606 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
10607 let atn = wildcard_then_eof_atn();
10613 let data = RecognizerData::new(
10614 "Mini.g4",
10615 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10616 );
10617 let mut parser = BaseParser::new(
10618 CommonTokenStream::new(Source {
10619 tokens: vec![CommonToken::eof("parser-test", 1, 1, 1)],
10620 index: 0,
10621 }),
10622 data,
10623 );
10624 parser.rule_context_stack = vec![RuleContextFrame {
10625 rule_index: 0,
10626 invoking_state: 0,
10627 }];
10628
10629 let node = parser
10630 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
10631 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
10632
10633 assert_eq!(node.children().len(), 1);
10635 assert!(!node.consumed_eof());
10636 assert!(node.children()[0].text().starts_with("<missing"));
10637 assert_eq!(parser.la(1), TOKEN_EOF);
10638 assert_eq!(
10639 parser.generated_parser_diagnostics,
10640 [ParserDiagnostic {
10641 line: 1,
10642 column: 1,
10643 message: "missing 'x' at '<EOF>'".to_owned(),
10644 }]
10645 );
10646 }
10647
10648 #[test]
10649 fn generated_rule_recovery_consumes_to_parent_follow() {
10650 let atn = generated_match_recovery_atn();
10651 let data = RecognizerData::new(
10652 "Mini.g4",
10653 Vocabulary::new(
10654 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
10655 [None, Some("X"), Some("Y"), Some("Z")],
10656 [None::<&str>, None, None, None],
10657 ),
10658 );
10659 let mut parser = BaseParser::new(
10660 CommonTokenStream::new(Source {
10661 tokens: vec![
10662 CommonToken::new(3).with_text("z"),
10663 CommonToken::eof("parser-test", 1, 1, 1),
10664 ],
10665 index: 0,
10666 }),
10667 data,
10668 );
10669 let _parent = parser.enter_rule(0, 0);
10670 let marker = parser.push_invoking_state(1);
10671 let mut child = parser.enter_rule(4, 1);
10672 parser.discard_invoking_state(marker);
10673
10674 parser.recover_generated_rule(
10675 &mut child,
10676 &atn,
10677 AntlrError::ParserError {
10678 line: 1,
10679 column: 0,
10680 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
10681 },
10682 );
10683 let tree = parser.finish_rule(child, false);
10684
10685 assert_eq!(parser.la(1), TOKEN_EOF);
10686 assert_eq!(tree.to_string_tree_with_names(&["s", "a"]), "(a z)");
10687 assert_eq!(parser.number_of_syntax_errors(), 1);
10688 assert_eq!(
10689 parser.generated_parser_diagnostics,
10690 [ParserDiagnostic {
10691 line: 1,
10692 column: 0,
10693 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
10694 }]
10695 );
10696 parser.exit_rule();
10697 }
10698
10699 #[test]
10700 fn greedy_ll1_alt_handles_nullable_loop_exit() {
10701 let mut body_symbols = TokenBitSet::default();
10702 body_symbols.insert(1);
10703 let entry = DecisionLookahead {
10704 transitions: vec![
10705 TransitionLookSet {
10706 symbols: body_symbols,
10707 nullable: false,
10708 },
10709 TransitionLookSet {
10710 symbols: TokenBitSet::default(),
10711 nullable: true,
10712 },
10713 ],
10714 };
10715
10716 assert_eq!(ll1_unique_alt(&entry, 2), None);
10717 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
10718 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
10719 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
10720 }
10721
10722 #[test]
10723 fn single_outcome_memo_probe_selects_sparse_or_promote_mode() {
10724 let key = |state_number| FastRecognizeKey {
10725 state_number,
10726 stop_state: 10,
10727 index: state_number,
10728 rule_start_index: 0,
10729 decision_start_index: None,
10730 precedence: 0,
10731 recovery_symbols_id: 0,
10732 recovery_state: None,
10733 };
10734
10735 let mut sparse = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10736 for state_number in 0..(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT - 1) {
10737 assert!(sparse.should_memoize_single_outcome(&key(state_number)));
10738 }
10739 assert!(!sparse.should_memoize_single_outcome(&key(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT)));
10740 assert_eq!(
10741 sparse.single_outcome_memo_mode,
10742 SingleOutcomeMemoMode::Sparse
10743 );
10744
10745 let mut promote = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10746 let repeated = key(1);
10747 for _ in 0..=CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
10748 assert!(promote.should_memoize_single_outcome(&repeated));
10749 }
10750 assert_eq!(
10751 promote.single_outcome_memo_mode,
10752 SingleOutcomeMemoMode::Promote
10753 );
10754 }
10755
10756 #[test]
10757 fn clean_empty_multi_alt_outcomes_are_memoized() {
10758 let mut atn = Atn::new(AtnType::Parser, 2);
10759 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
10760 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
10761 atn.add_state(AtnState::new(2, AtnStateKind::RuleStop).with_rule_index(0));
10762 atn.set_rule_to_start_state(vec![0]);
10763 atn.set_rule_to_stop_state(vec![2]);
10764 atn.state_mut(0)
10765 .expect("state 0")
10766 .add_transition(Transition::Epsilon { target: 1 });
10767 atn.state_mut(1)
10768 .expect("state 1")
10769 .add_transition(Transition::Atom {
10770 target: 2,
10771 label: 1,
10772 });
10773 atn.state_mut(1)
10774 .expect("state 1")
10775 .add_transition(Transition::Atom {
10776 target: 2,
10777 label: 2,
10778 });
10779
10780 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
10781 parser.fast_recovery_enabled = false;
10782 let mut visiting = FxHashSet::default();
10783 let mut memo = FxHashMap::default();
10784 let mut expected = ExpectedTokens::default();
10785 let outcomes = parser.recognize_state_fast(
10786 &atn,
10787 FastRecognizeRequest {
10788 state_number: 1,
10789 stop_state: 2,
10790 index: 0,
10791 rule_start_index: 0,
10792 decision_start_index: None,
10793 precedence: 0,
10794 depth: 0,
10795 recovery_symbols: parser.empty_recovery_symbols(),
10796 recovery_state: None,
10797 },
10798 &mut visiting,
10799 &mut memo,
10800 &mut expected,
10801 );
10802
10803 assert!(outcomes.is_empty());
10804 assert_eq!(memo.len(), 1);
10805 assert!(memo.values().next().expect("memo entry").is_empty());
10806 }
10807
10808 #[test]
10809 fn wildcard_matches_non_eof_only() {
10810 let mut parser = mini_parser(vec![
10811 CommonToken::new(1).with_text("x"),
10812 CommonToken::eof("parser-test", 1, 1, 1),
10813 ]);
10814 assert_eq!(parser.match_wildcard().expect("wildcard").text(), "x");
10815 assert!(parser.match_wildcard().is_err());
10816 }
10817
10818 #[test]
10819 fn add_parse_child_records_match_even_without_tree_building() {
10820 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
10825 let token = CommonToken::new(1).with_text("x");
10826
10827 parser.set_build_parse_trees(false);
10828 let mut ctx = ParserRuleContext::new(0, 0);
10829 assert!(!ctx.has_matched_child());
10830 parser.add_parse_child(
10831 &mut ctx,
10832 ParseTree::Terminal(TerminalNode::new(token.clone())),
10833 );
10834 assert!(ctx.children().is_empty());
10836 assert!(ctx.has_matched_child());
10838
10839 parser.set_build_parse_trees(true);
10841 let mut ctx = ParserRuleContext::new(0, 0);
10842 parser.add_parse_child(&mut ctx, ParseTree::Terminal(TerminalNode::new(token)));
10843 assert_eq!(ctx.children().len(), 1);
10844 assert!(ctx.has_matched_child());
10845 }
10846
10847 #[test]
10848 fn parser_interprets_simple_atn_rule() {
10849 let atn = token_then_eof_atn();
10850 let mut parser = mini_parser(vec![
10851 CommonToken::new(1).with_text("x"),
10852 CommonToken::eof("parser-test", 1, 1, 1),
10853 ]);
10854
10855 let tree = parser
10856 .parse_atn_rule(&atn, 0)
10857 .expect("artificial parser rule should parse");
10858 assert_eq!(tree.text(), "x<EOF>");
10859 assert_eq!(parser.number_of_syntax_errors(), 0);
10860 assert_eq!(
10861 tree.first_rule_stop(0)
10862 .expect("rule should stop at EOF")
10863 .token_type(),
10864 TOKEN_EOF
10865 );
10866
10867 let mut parser = mini_parser(vec![
10868 CommonToken::new(1).with_text("x"),
10869 CommonToken::eof("parser-test", 1, 1, 1),
10870 ]);
10871 let (tree, actions) = parser
10872 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
10873 .expect("runtime-option parser rule should parse");
10874 assert!(actions.is_empty());
10875 assert_eq!(
10876 tree.first_rule_stop(0)
10877 .expect("rule should stop at EOF")
10878 .token_type(),
10879 TOKEN_EOF
10880 );
10881 }
10882
10883 #[test]
10884 fn parser_exposes_buffered_token_stream_after_parse() {
10885 let atn = token_then_eof_atn();
10886 let mut parser = mini_parser(vec![
10887 CommonToken::new(1).with_text("x"),
10888 CommonToken::eof("parser-test", 1, 1, 1),
10889 ]);
10890
10891 let tree = parser
10892 .parse_atn_rule(&atn, 0)
10893 .expect("artificial parser rule should parse");
10894 assert_eq!(tree.text(), "x<EOF>");
10895
10896 let stream = parser.token_stream();
10897 let source_index_after_parse = stream.token_source().index;
10898 let buffered = stream.tokens();
10899 assert_eq!(buffered.len(), 2);
10900 assert_eq!(buffered[0].text(), "x");
10901 assert_eq!(buffered[0].token_index(), 0);
10902 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
10903 assert_eq!(stream.token_source().index, source_index_after_parse);
10904
10905 let stream = parser.into_token_stream();
10906 assert_eq!(stream.token_source().index, source_index_after_parse);
10907 assert_eq!(stream.tokens()[0].text(), "x");
10908 assert_eq!(stream.tokens()[1].token_type(), TOKEN_EOF);
10909 }
10910
10911 #[test]
10912 fn parser_syntax_error_count_tracks_interpreted_recovery() {
10913 let atn = token_then_eof_atn();
10914 let mut parser = mini_parser(vec![
10915 CommonToken::new(1).with_text("x"),
10916 CommonToken::new(2).with_text("y"),
10917 CommonToken::eof("parser-test", 2, 1, 2),
10918 ]);
10919
10920 let tree = parser
10921 .parse_atn_rule(&atn, 0)
10922 .expect("invalid token should recover into an error node");
10923
10924 assert_eq!(parser.number_of_syntax_errors(), 1);
10925 assert_eq!(
10926 tree.first_error_token()
10927 .expect("recovery should embed an error token")
10928 .text(),
10929 "y"
10930 );
10931 }
10932
10933 #[test]
10934 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
10935 let atn = token_then_eof_atn();
10936 let mut parser = mini_parser(vec![
10937 CommonToken::new(2).with_text("y"),
10938 CommonToken::eof("parser-test", 1, 1, 1),
10939 ]);
10940
10941 let error = parser
10942 .parse_atn_rule(&atn, 0)
10943 .expect_err("start-rule mismatch should remain a parser error");
10944
10945 assert_eq!(parser.number_of_syntax_errors(), 1);
10946 assert!(matches!(error, AntlrError::ParserError { .. }));
10947 }
10948
10949 #[test]
10950 fn adaptive_direct_rule_uses_simulator_decision() {
10951 let atn = two_alt_decision_atn();
10952 let mut simulator = ParserAtnSimulator::new(&atn);
10953 let mut parser = mini_parser(vec![
10954 CommonToken::new(2).with_text("y"),
10955 CommonToken::eof("parser-test", 1, 1, 1),
10956 ]);
10957
10958 let tree = parser
10959 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
10960 .expect("direct adaptive rule should parse");
10961
10962 assert_eq!(tree.text(), "y");
10963 assert_eq!(parser.input.index(), 1);
10964 }
10965
10966 #[test]
10967 fn adaptive_direct_rule_restores_input_on_fallback() {
10968 let atn = predicate_after_token_atn();
10969 let mut simulator = ParserAtnSimulator::new(&atn);
10970 let mut parser = mini_parser(vec![
10971 CommonToken::new(1).with_text("x"),
10972 CommonToken::new(2).with_text("y"),
10973 CommonToken::eof("parser-test", 2, 1, 2),
10974 ]);
10975
10976 let tree = parser
10977 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
10978 .expect("fallback recognizer should parse");
10979
10980 assert_eq!(tree.text(), "xy");
10981 assert_eq!(parser.input.index(), 2);
10982 }
10983
10984 #[test]
10985 fn unknown_predicate_policy_defaults_to_assume_true() {
10986 let atn = predicate_after_token_atn();
10987 let mut parser = mini_parser(vec![
10988 CommonToken::new(1).with_text("x"),
10989 CommonToken::new(2).with_text("y"),
10990 CommonToken::eof("parser-test", 2, 1, 2),
10991 ]);
10992
10993 let (tree, _) = parser
10994 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
10995 .expect("unknown predicate should pass under the default policy");
10996
10997 assert_eq!(tree.text(), "xy");
10998 assert_eq!(parser.number_of_syntax_errors(), 0);
10999 }
11000
11001 #[test]
11002 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
11003 let atn = token_then_eof_atn();
11007 let mut parser = mini_parser(vec![
11008 CommonToken::new(1).with_text("x"),
11009 CommonToken::eof("parser-test", 1, 1, 1),
11010 ]);
11011
11012 parser.unknown_predicate_hits.push((7, 3));
11014
11015 parser
11017 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11018 .expect("child rule parses");
11019
11020 let error = parser
11022 .take_unknown_semantic_error()
11023 .expect("parent's recorded coordinate must survive the nested interpreted parse");
11024 let AntlrError::Unsupported(message) = error else {
11025 panic!("expected AntlrError::Unsupported, got {error:?}");
11026 };
11027 assert!(message.contains("pred_index=3"), "message: {message}");
11028 }
11029
11030 #[test]
11031 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
11032 let atn = predicate_after_token_atn();
11033 let mut parser = mini_parser(vec![
11034 CommonToken::new(1).with_text("x"),
11035 CommonToken::new(2).with_text("y"),
11036 CommonToken::eof("parser-test", 2, 1, 2),
11037 ]);
11038
11039 let result = parser.parse_atn_rule_with_runtime_options(
11040 &atn,
11041 0,
11042 ParserRuntimeOptions {
11043 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
11044 ..ParserRuntimeOptions::default()
11045 },
11046 );
11047
11048 assert!(
11049 result.is_err(),
11050 "the only path is predicate-guarded, so assume-false must fail the parse"
11051 );
11052 }
11053
11054 #[test]
11055 fn unknown_predicate_policy_error_names_the_coordinate() {
11056 let atn = predicate_after_token_atn();
11057 let mut parser = mini_parser(vec![
11058 CommonToken::new(1).with_text("x"),
11059 CommonToken::new(2).with_text("y"),
11060 CommonToken::eof("parser-test", 2, 1, 2),
11061 ]);
11062
11063 let error = parser
11064 .parse_atn_rule_with_runtime_options(
11065 &atn,
11066 0,
11067 ParserRuntimeOptions {
11068 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11069 ..ParserRuntimeOptions::default()
11070 },
11071 )
11072 .expect_err("evaluating an unknown predicate under Error policy must fail");
11073
11074 let AntlrError::Unsupported(message) = error else {
11075 panic!("expected AntlrError::Unsupported, got {error:?}");
11076 };
11077 assert!(
11078 message.contains("unsupported semantic predicate"),
11079 "message should name the failure class: {message}"
11080 );
11081 assert!(
11082 message.contains("pred_index=0"),
11083 "message should carry the coordinate: {message}"
11084 );
11085 }
11086
11087 #[test]
11088 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
11089 let atn = predicate_after_token_atn();
11095 let mut parser = mini_parser(vec![
11096 CommonToken::new(1).with_text("x"),
11097 CommonToken::new(2).with_text("y"),
11098 CommonToken::eof("parser-test", 2, 1, 2),
11099 ]);
11100
11101 parser
11102 .parse_atn_rule_with_runtime_options(
11103 &atn,
11104 0,
11105 ParserRuntimeOptions {
11106 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11107 ..ParserRuntimeOptions::default()
11108 },
11109 )
11110 .expect_err("first parse fails loud under the Error policy");
11111
11112 parser.reset_unknown_semantic_hits();
11117 assert!(
11118 parser.take_unknown_semantic_error().is_none(),
11119 "reset must drop stale unknown-predicate coordinates before a reused parse"
11120 );
11121 }
11122
11123 #[derive(Debug, Default)]
11124 struct RecordingHooks {
11125 predicates: Vec<(usize, usize, usize, Option<String>)>,
11126 actions: Vec<(usize, String, Option<String>)>,
11127 }
11128
11129 impl SemanticHooks for RecordingHooks {
11130 fn sempred<S>(
11131 &mut self,
11132 ctx: &mut ParserSemCtx<'_, S>,
11133 rule_index: usize,
11134 pred_index: usize,
11135 ) -> Option<bool>
11136 where
11137 S: TokenSource,
11138 {
11139 self.predicates.push((
11140 ctx.input_index(),
11141 rule_index,
11142 pred_index,
11143 ctx.token_text(1).map(str::to_owned),
11144 ));
11145 Some(true)
11146 }
11147
11148 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
11149 where
11150 S: TokenSource,
11151 {
11152 self.actions.push((
11153 action.source_state(),
11154 ctx.action_text(),
11155 ctx.rule_name().map(str::to_owned),
11156 ));
11157 true
11158 }
11159 }
11160
11161 #[test]
11162 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
11163 let atn = predicate_after_token_atn();
11164 let mut parser = mini_parser_with_hooks(
11165 vec![
11166 CommonToken::new(1).with_text("x"),
11167 CommonToken::new(2).with_text("y"),
11168 CommonToken::eof("parser-test", 2, 1, 2),
11169 ],
11170 RecordingHooks::default(),
11171 );
11172
11173 let (tree, _) = parser
11174 .parse_atn_rule_with_runtime_options(
11175 &atn,
11176 0,
11177 ParserRuntimeOptions {
11178 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11179 ..ParserRuntimeOptions::default()
11180 },
11181 )
11182 .expect("hook supplies the missing predicate result");
11183
11184 assert_eq!(tree.text(), "xy");
11185 assert_eq!(
11186 parser.semantic_hooks.predicates,
11187 vec![(1, 0, 0, Some("y".to_owned()))]
11188 );
11189 }
11190
11191 #[test]
11192 fn semantic_hook_handles_committed_parser_action() {
11193 let atn = token_then_eof_atn();
11194 let mut parser = mini_parser_with_hooks(
11195 vec![
11196 CommonToken::new(1).with_text("x"),
11197 CommonToken::eof("parser-test", 1, 1, 1),
11198 ],
11199 RecordingHooks::default(),
11200 );
11201 let (tree, _) = parser
11202 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11203 .expect("rule parses before action hook is tested");
11204
11205 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
11206 assert_eq!(
11207 parser.semantic_hooks.actions,
11208 vec![(42, "x".to_owned(), Some("s".to_owned()))]
11209 );
11210 }
11211
11212 #[test]
11213 fn unhandled_committed_action_fails_loud_under_error_policy() {
11214 let mut parser =
11218 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11219 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
11220 let tree = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, -1)));
11221
11222 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
11224
11225 let error = parser
11226 .take_unknown_semantic_error()
11227 .expect("an unhandled committed action under Error policy must fail loud");
11228 let AntlrError::Unsupported(message) = error else {
11229 panic!("expected AntlrError::Unsupported, got {error:?}");
11230 };
11231 assert!(
11232 message.contains("unhandled semantic action") && message.contains("state=42"),
11233 "message should name the dropped action coordinate: {message}"
11234 );
11235
11236 let mut lenient =
11238 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11239 let tree = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, -1)));
11240 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), &tree));
11241 assert!(lenient.take_unknown_semantic_error().is_none());
11242 }
11243
11244 #[test]
11245 fn translated_predicate_is_unaffected_by_error_policy() {
11246 let atn = predicate_after_token_atn();
11247 let mut parser = mini_parser(vec![
11248 CommonToken::new(1).with_text("x"),
11249 CommonToken::new(2).with_text("y"),
11250 CommonToken::eof("parser-test", 2, 1, 2),
11251 ]);
11252
11253 let (tree, _) = parser
11254 .parse_atn_rule_with_runtime_options(
11255 &atn,
11256 0,
11257 ParserRuntimeOptions {
11258 predicates: &[(0, 0, ParserPredicate::True)],
11259 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11260 ..ParserRuntimeOptions::default()
11261 },
11262 )
11263 .expect("a predicate covered by the table is not an unknown coordinate");
11264
11265 assert_eq!(tree.text(), "xy");
11266 }
11267
11268 fn hook_predicate_semantics() -> ParserSemantics {
11273 let mut ir = SemIr::new();
11274 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
11275 ParserSemantics {
11276 ir,
11277 predicates: vec![ParserSemanticPredicate {
11278 rule_index: 0,
11279 pred_index: 0,
11280 expr,
11281 failure_message: None,
11282 }],
11283 actions: Vec::new(),
11284 }
11285 }
11286
11287 #[derive(Debug, Default)]
11288 struct DecliningHooks;
11289
11290 impl SemanticHooks for DecliningHooks {}
11291
11292 #[test]
11293 fn semir_hook_none_falls_through_to_assume_true() {
11294 let atn = predicate_after_token_atn();
11295 let semantics = hook_predicate_semantics();
11296 let mut parser = mini_parser_with_hooks(
11297 vec![
11298 CommonToken::new(1).with_text("x"),
11299 CommonToken::new(2).with_text("y"),
11300 CommonToken::eof("parser-test", 2, 1, 2),
11301 ],
11302 DecliningHooks,
11303 );
11304
11305 let (tree, _) = parser
11306 .parse_atn_rule_with_runtime_options(
11307 &atn,
11308 0,
11309 ParserRuntimeOptions {
11310 semantics: Some(&semantics),
11311 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
11312 ..ParserRuntimeOptions::default()
11313 },
11314 )
11315 .expect("a declined SemIR hook must pass under assume-true");
11316
11317 assert_eq!(tree.text(), "xy");
11318 }
11319
11320 #[test]
11321 fn semir_hook_none_falls_through_to_assume_false() {
11322 let atn = predicate_after_token_atn();
11323 let semantics = hook_predicate_semantics();
11324 let mut parser = mini_parser_with_hooks(
11325 vec![
11326 CommonToken::new(1).with_text("x"),
11327 CommonToken::new(2).with_text("y"),
11328 CommonToken::eof("parser-test", 2, 1, 2),
11329 ],
11330 DecliningHooks,
11331 );
11332
11333 let result = parser.parse_atn_rule_with_runtime_options(
11334 &atn,
11335 0,
11336 ParserRuntimeOptions {
11337 semantics: Some(&semantics),
11338 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
11339 ..ParserRuntimeOptions::default()
11340 },
11341 );
11342
11343 assert!(
11344 result.is_err(),
11345 "a declined SemIR hook must fail the only guarded path under assume-false"
11346 );
11347 }
11348
11349 #[test]
11350 fn semir_hook_none_records_coordinate_under_error_policy() {
11351 let atn = predicate_after_token_atn();
11352 let semantics = hook_predicate_semantics();
11353 let mut parser = mini_parser_with_hooks(
11354 vec![
11355 CommonToken::new(1).with_text("x"),
11356 CommonToken::new(2).with_text("y"),
11357 CommonToken::eof("parser-test", 2, 1, 2),
11358 ],
11359 DecliningHooks,
11360 );
11361
11362 let error = parser
11363 .parse_atn_rule_with_runtime_options(
11364 &atn,
11365 0,
11366 ParserRuntimeOptions {
11367 semantics: Some(&semantics),
11368 unknown_predicate_policy: UnknownSemanticPolicy::Error,
11369 ..ParserRuntimeOptions::default()
11370 },
11371 )
11372 .expect_err("a declined SemIR hook under Error policy must fail the parse");
11373
11374 let AntlrError::Unsupported(message) = error else {
11375 panic!("expected AntlrError::Unsupported, got {error:?}");
11376 };
11377 assert!(
11378 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
11379 "message should name the unresolved coordinate: {message}"
11380 );
11381 }
11382
11383 #[test]
11384 fn generated_direct_predicate_honors_installed_policy() {
11385 let semantics = hook_predicate_semantics();
11391 let context = ParserRuleContext::new(0, -1);
11392
11393 let mut assume_true =
11394 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11395 assert!(
11396 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
11397 &semantics, 0, 0, &context, 0
11398 ),
11399 "default AssumeTrue accepts a declined hook"
11400 );
11401 assert!(assume_true.take_unknown_semantic_error().is_none());
11402
11403 let mut error_policy =
11404 mini_parser_with_hooks(vec![CommonToken::eof("t", 0, 1, 0)], DecliningHooks);
11405 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
11406 assert!(
11407 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
11408 &semantics, 0, 0, &context, 0
11409 ),
11410 "Error policy rejects a declined hook on the generated-direct path"
11411 );
11412 let error = error_policy
11413 .take_unknown_semantic_error()
11414 .expect("Error policy records the unresolved coordinate for the generated path");
11415 let AntlrError::Unsupported(message) = error else {
11416 panic!("expected AntlrError::Unsupported, got {error:?}");
11417 };
11418 assert!(message.contains("pred_index=0"), "message: {message}");
11419 }
11420
11421 #[test]
11422 fn parser_rule_start_skips_leading_hidden_tokens() {
11423 let atn = token_then_eof_atn();
11424 let mut parser = mini_parser(vec![
11425 CommonToken::new(99)
11426 .with_text(" ")
11427 .with_channel(HIDDEN_CHANNEL),
11428 CommonToken::new(1).with_text("x"),
11429 CommonToken::eof("parser-test", 2, 1, 2),
11430 ]);
11431
11432 let tree = parser
11433 .parse_atn_rule(&atn, 0)
11434 .expect("artificial parser rule should parse");
11435 let Some(ParseTree::Rule(rule)) = tree.first_rule(0) else {
11436 panic!("rule node should be present");
11437 };
11438 assert_eq!(
11439 rule.context()
11440 .start()
11441 .expect("rule should have a start token")
11442 .token_type(),
11443 1
11444 );
11445 }
11446
11447 #[test]
11448 fn parser_action_after_eof_stops_at_eof_token() {
11449 let atn = eof_then_action_atn();
11450 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
11451
11452 let (_, actions) = parser
11453 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
11454 .expect("EOF action rule should parse");
11455
11456 assert_eq!(actions.len(), 1);
11457 assert_eq!(actions[0].stop_index(), Some(0));
11458 assert_eq!(
11459 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
11460 ""
11461 );
11462 }
11463
11464 #[test]
11465 fn after_action_stop_uses_rule_context_stop_not_cursor() {
11466 let mut id = CommonToken::new(1).with_text("x");
11471 id.set_token_index(0);
11472 let mut eof = CommonToken::eof("parser-test", 1, 1, 1);
11473 eof.set_token_index(1);
11474 let mut parser = mini_parser(vec![id.clone(), eof]);
11475 parser.consume();
11477 assert_eq!(parser.la(1), TOKEN_EOF);
11478
11479 let mut ctx = ParserRuleContext::new(0, 0);
11482 ctx.set_stop(id);
11483 let tree = ParseTree::Rule(RuleNode::new(ctx));
11484
11485 let current_index = parser.input.index();
11486 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
11488 assert_eq!(
11490 parser.after_action_stop_index_for_tree(&tree, current_index),
11491 Some(0)
11492 );
11493 }
11494
11495 #[test]
11496 fn after_action_start_uses_rule_context_start_not_cursor() {
11497 let parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
11502 let mut id = CommonToken::new(1).with_text("x");
11503 id.set_token_index(2);
11505
11506 let mut ctx = ParserRuleContext::new(0, 0);
11507 ctx.set_start(id);
11508 let tree = ParseTree::Rule(RuleNode::new(ctx));
11509
11510 assert_eq!(parser.after_action_start_index_for_tree(&tree, 0), 2);
11513
11514 let empty = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, 0)));
11516 assert_eq!(parser.after_action_start_index_for_tree(&empty, 7), 7);
11517 }
11518
11519 #[test]
11520 fn fast_outcome_selection_respects_sll_tie_order() {
11521 let first = FastRecognizeOutcome {
11522 index: 1,
11523 consumed_eof: false,
11524 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
11525 line: 1,
11526 column: 0,
11527 message: "mismatched input 'x'".to_owned(),
11528 }]),
11529 nodes: NodeList::new(),
11530 };
11531 let second = FastRecognizeOutcome {
11532 index: first.index,
11533 consumed_eof: first.consumed_eof,
11534 diagnostics: FastDiagnostics::new(),
11535 nodes: NodeList::new(),
11536 };
11537
11538 let selected = select_best_fast_outcome(
11539 [first.clone(), second.clone()].into_iter(),
11540 PredictionMode::Sll,
11541 None,
11542 |_| panic!("caller-follow token probe should not run"),
11543 )
11544 .expect("one outcome should be selected");
11545 assert_eq!(selected.diagnostics.len(), 1);
11546 let eof_second = FastRecognizeOutcome {
11547 index: second.index,
11548 consumed_eof: true,
11549 diagnostics: FastDiagnostics::new(),
11550 nodes: NodeList::new(),
11551 };
11552 let selected = select_best_fast_outcome(
11553 [first.clone(), eof_second].into_iter(),
11554 PredictionMode::Sll,
11555 None,
11556 |_| panic!("caller-follow token probe should not run"),
11557 )
11558 .expect("one outcome should be selected");
11559 assert!(!selected.consumed_eof);
11560 let selected = select_best_fast_outcome(
11561 [first, second].into_iter(),
11562 PredictionMode::Ll,
11563 None,
11564 |_| panic!("caller-follow token probe should not run"),
11565 )
11566 .expect("one outcome should be selected");
11567 assert!(selected.diagnostics.is_empty());
11568 }
11569
11570 #[test]
11571 fn fast_outcome_selection_prefers_generated_caller_follow() {
11572 let earlier = FastRecognizeOutcome {
11573 index: 7,
11574 consumed_eof: false,
11575 diagnostics: FastDiagnostics::new(),
11576 nodes: NodeList::new(),
11577 };
11578 let later = FastRecognizeOutcome {
11579 index: 8,
11580 consumed_eof: false,
11581 diagnostics: FastDiagnostics::new(),
11582 nodes: NodeList::new(),
11583 };
11584 let mut follow = TokenBitSet::default();
11585 follow.insert(5);
11586
11587 let selected = select_best_fast_outcome(
11588 [later.clone(), earlier.clone()].into_iter(),
11589 PredictionMode::Ll,
11590 Some(&follow),
11591 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
11592 )
11593 .expect("one outcome should be selected");
11594 assert_eq!(selected.index, 7);
11595
11596 let selected = select_best_fast_outcome(
11597 [later.clone(), earlier.clone()].into_iter(),
11598 PredictionMode::Ll,
11599 Some(&follow),
11600 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
11601 )
11602 .expect("one outcome should be selected");
11603 assert_eq!(selected.index, 8);
11604
11605 let indented_next_statement = FastRecognizeOutcome {
11606 index: 9,
11607 consumed_eof: false,
11608 diagnostics: FastDiagnostics::new(),
11609 nodes: NodeList::new(),
11610 };
11611 let selected = select_best_fast_outcome(
11612 [indented_next_statement, earlier.clone()].into_iter(),
11613 PredictionMode::Ll,
11614 Some(&follow),
11615 |index| {
11616 let is_boundary = index == 7;
11617 let is_boundary_gap = matches!(index, 7 | 8);
11618 (
11619 if index == 7 { 5 } else { TOKEN_EOF },
11620 is_boundary,
11621 is_boundary_gap,
11622 )
11623 },
11624 )
11625 .expect("one outcome should be selected");
11626 assert_eq!(selected.index, 7);
11627
11628 let continuation = FastRecognizeOutcome {
11629 index: 10,
11630 consumed_eof: false,
11631 diagnostics: FastDiagnostics::new(),
11632 nodes: NodeList::new(),
11633 };
11634 let selected = select_best_fast_outcome(
11635 [continuation, earlier.clone()].into_iter(),
11636 PredictionMode::Ll,
11637 Some(&follow),
11638 |index| {
11639 let is_boundary = matches!(index, 7 | 9);
11640 (
11641 if index == 7 { 5 } else { TOKEN_EOF },
11642 is_boundary,
11643 is_boundary,
11644 )
11645 },
11646 )
11647 .expect("one outcome should be selected");
11648 assert_eq!(selected.index, 10);
11649
11650 let selected = select_best_fast_outcome(
11651 [earlier, later].into_iter(),
11652 PredictionMode::Sll,
11653 Some(&follow),
11654 |_| panic!("caller-follow token probe should not run in SLL mode"),
11655 )
11656 .expect("one outcome should be selected");
11657 assert_eq!(selected.index, 8);
11658 }
11659
11660 #[test]
11661 fn caller_follow_boundary_text_requires_separator_shape() {
11662 assert!(is_caller_follow_boundary_text(";"));
11663 assert!(is_caller_follow_boundary_text("\n"));
11664 assert!(is_caller_follow_boundary_text("\r\n "));
11665 assert!(is_caller_follow_boundary_text(";\n"));
11666 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
11667 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
11668 assert!(!is_caller_follow_boundary_text("identifier"));
11669 assert!(is_caller_follow_boundary_gap_text(" \t "));
11670 assert!(is_caller_follow_boundary_gap_text("\n "));
11671 assert!(is_caller_follow_boundary_gap_text(";\t"));
11672 assert!(!is_caller_follow_boundary_gap_text(
11673 "\"\"\"line1\nline2\"\"\""
11674 ));
11675 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
11676 }
11677
11678 #[test]
11679 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
11680 let mut parser = mini_parser(vec![
11681 CommonToken::new(5).with_text("\n"),
11682 CommonToken::new(6)
11683 .with_text("// comment\n")
11684 .with_channel(HIDDEN_CHANNEL),
11685 CommonToken::new(1).with_text("x"),
11686 CommonToken::eof("parser-test", 1, 2, 0),
11687 ]);
11688
11689 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
11690 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
11691 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
11692 }
11693
11694 #[test]
11695 fn caller_follow_token_info_uses_stream_visible_channel() {
11696 let source = Source {
11697 tokens: vec![
11698 CommonToken::new(5).with_text("\n").with_channel(2),
11699 CommonToken::new(1).with_text("x").with_channel(2),
11700 CommonToken::new(6)
11701 .with_text("// comment\n")
11702 .with_channel(HIDDEN_CHANNEL),
11703 CommonToken::eof("parser-test", 1, 2, 0),
11704 ],
11705 index: 0,
11706 };
11707 let data = RecognizerData::new(
11708 "Mini.g4",
11709 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
11710 );
11711 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
11712
11713 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
11714 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
11715 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
11716 }
11717
11718 #[test]
11719 fn reset_per_parse_caches_clears_state_expected_token_cache() {
11720 let atn = token_then_eof_atn();
11721 let mut parser = mini_parser(Vec::new());
11722
11723 let _ = parser.cached_state_expected_token_set(&atn, 0);
11724 assert!(!parser.state_expected_token_cache.is_empty());
11725
11726 parser.reset_per_parse_caches();
11727 assert!(parser.state_expected_token_cache.is_empty());
11728 }
11729
11730 #[test]
11731 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
11732 let source = Source {
11733 tokens: vec![
11734 CommonToken::new(1).with_text("x"),
11735 CommonToken::eof("parser-test", 1, 1, 1),
11736 ],
11737 index: 0,
11738 };
11739 let data = RecognizerData::new(
11740 "Mini.g4",
11741 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
11742 );
11743 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
11744 let expected = ExpectedTokens {
11745 index: Some(0),
11746 symbols: BTreeSet::new(),
11747 no_viable: None,
11748 };
11749
11750 let (_, message) = parser.expected_error_message(0, 0, &expected);
11751
11752 assert_eq!(message, "mismatched input 'x'");
11753 }
11754
11755 #[test]
11756 fn eof_rule_stop_index_points_at_eof_token() {
11757 let source = Source {
11758 tokens: vec![
11759 CommonToken::new(1).with_text("x"),
11760 CommonToken::eof("parser-test", 1, 1, 1),
11761 ],
11762 index: 0,
11763 };
11764 let data = RecognizerData::new(
11765 "Mini.g4",
11766 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
11767 );
11768 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
11769
11770 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
11771 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
11772 }
11773
11774 #[test]
11775 fn generated_parser_action_uses_current_rule_stop_boundary() {
11776 let mut parser = mini_parser(vec![
11777 CommonToken::new(1).with_text("x"),
11778 CommonToken::eof("parser-test", 1, 1, 1),
11779 ]);
11780
11781 parser.match_token(1).expect("token should match");
11782 let action = parser.parser_action_at_current(7, 0, 0, false);
11783 assert_eq!(action.source_state(), 7);
11784 assert_eq!(action.rule_index(), 0);
11785 assert_eq!(action.start_index(), 0);
11786 assert_eq!(action.stop_index(), Some(0));
11787
11788 parser.match_eof().expect("EOF should match");
11789 let action = parser.parser_action_at_current(8, 0, 0, true);
11790 assert_eq!(action.stop_index(), Some(1));
11791 }
11792
11793 #[test]
11794 fn folds_left_recursive_boundary_into_rule_node() {
11795 let nodes = fold_left_recursive_boundaries(vec![
11796 RecognizedNode::Token { index: 0 },
11797 RecognizedNode::LeftRecursiveBoundary { rule_index: 1 },
11798 RecognizedNode::Token { index: 1 },
11799 ]);
11800
11801 assert_eq!(
11802 nodes,
11803 vec![
11804 RecognizedNode::Rule {
11805 rule_index: 1,
11806 invoking_state: -1,
11807 alt_number: 0,
11808 start_index: 0,
11809 stop_index: Some(0),
11810 return_values: BTreeMap::new(),
11811 children: vec![RecognizedNode::Token { index: 0 }],
11812 },
11813 RecognizedNode::Token { index: 1 },
11814 ]
11815 );
11816 }
11817
11818 #[test]
11819 fn outcome_ties_keep_later_non_recursive_alternative() {
11820 let first = RecognizeOutcome {
11821 index: 1,
11822 consumed_eof: false,
11823 alt_number: 0,
11824 member_values: BTreeMap::new(),
11825 return_values: BTreeMap::new(),
11826 diagnostics: Vec::new(),
11827 decisions: Vec::new(),
11828 actions: vec![ParserAction::new(1, 0, 0, None)],
11829 nodes: vec![RecognizedNode::Token { index: 0 }],
11830 };
11831 let second = RecognizeOutcome {
11832 actions: vec![ParserAction::new(2, 0, 0, None)],
11833 ..first.clone()
11834 };
11835
11836 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
11837 .expect("one outcome should be selected");
11838 assert_eq!(selected.actions[0].source_state(), 2);
11839 }
11840
11841 #[test]
11842 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
11843 let first = RecognizeOutcome {
11844 index: 1,
11845 consumed_eof: false,
11846 alt_number: 0,
11847 member_values: BTreeMap::new(),
11848 return_values: BTreeMap::new(),
11849 diagnostics: Vec::new(),
11850 decisions: Vec::new(),
11851 actions: vec![ParserAction::new(1, 0, 0, None)],
11852 nodes: vec![RecognizedNode::Token { index: 0 }],
11853 };
11854 let second = RecognizeOutcome {
11855 actions: vec![
11856 ParserAction::new(2, 0, 0, None),
11857 ParserAction::new(3, 0, 0, None),
11858 ],
11859 ..first.clone()
11860 };
11861
11862 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll)
11863 .expect("one outcome should be selected");
11864 assert_eq!(selected.actions.len(), 2);
11865 }
11866
11867 #[test]
11868 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
11869 let first = RecognizeOutcome {
11870 index: 7,
11871 consumed_eof: false,
11872 alt_number: 0,
11873 member_values: BTreeMap::new(),
11874 return_values: BTreeMap::new(),
11875 diagnostics: Vec::new(),
11876 decisions: vec![1, 0],
11877 actions: vec![
11878 ParserAction::new(23, 2, 2, Some(4)),
11879 ParserAction::new(23, 2, 0, Some(6)),
11880 ],
11881 nodes: vec![RecognizedNode::Token { index: 0 }],
11882 };
11883 let second = RecognizeOutcome {
11884 decisions: vec![0, 1],
11885 actions: vec![
11886 ParserAction::new(23, 2, 2, Some(6)),
11887 ParserAction::new(23, 2, 0, Some(6)),
11888 ],
11889 ..first.clone()
11890 };
11891
11892 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
11893 .expect("one outcome should be selected");
11894 assert_eq!(selected.actions[0].stop_index(), Some(6));
11895 }
11896
11897 #[test]
11898 fn outcome_ties_keep_first_recursive_tree_shape() {
11899 let recursive_nodes = vec![RecognizedNode::Rule {
11900 rule_index: 1,
11901 invoking_state: -1,
11902 alt_number: 0,
11903 start_index: 0,
11904 stop_index: Some(0),
11905 return_values: BTreeMap::new(),
11906 children: vec![RecognizedNode::Rule {
11907 rule_index: 1,
11908 invoking_state: -1,
11909 alt_number: 0,
11910 start_index: 0,
11911 stop_index: Some(0),
11912 return_values: BTreeMap::new(),
11913 children: vec![RecognizedNode::Token { index: 0 }],
11914 }],
11915 }];
11916 let first = RecognizeOutcome {
11917 index: 1,
11918 consumed_eof: false,
11919 alt_number: 0,
11920 member_values: BTreeMap::new(),
11921 return_values: BTreeMap::new(),
11922 diagnostics: Vec::new(),
11923 decisions: Vec::new(),
11924 actions: vec![ParserAction::new(1, 0, 0, None)],
11925 nodes: recursive_nodes.clone(),
11926 };
11927 let second = RecognizeOutcome {
11928 index: 1,
11929 consumed_eof: false,
11930 alt_number: 0,
11931 member_values: BTreeMap::new(),
11932 return_values: BTreeMap::new(),
11933 diagnostics: Vec::new(),
11934 decisions: Vec::new(),
11935 actions: vec![ParserAction::new(2, 0, 0, None)],
11936 nodes: recursive_nodes,
11937 };
11938
11939 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
11940 .expect("one outcome should be selected");
11941 assert_eq!(selected.actions[0].source_state(), 1);
11942 }
11943
11944 #[test]
11945 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
11946 let first_alt = RecognizeOutcome {
11947 index: 2,
11948 consumed_eof: true,
11949 alt_number: 0,
11950 member_values: BTreeMap::new(),
11951 return_values: BTreeMap::new(),
11952 diagnostics: vec![ParserDiagnostic {
11953 line: 1,
11954 column: 3,
11955 message: "missing 'Y' at '<EOF>'".to_owned(),
11956 }],
11957 decisions: vec![0],
11958 actions: vec![ParserAction::new(1, 0, 0, None)],
11959 nodes: vec![RecognizedNode::Token { index: 0 }],
11960 };
11961 let second_alt = RecognizeOutcome {
11962 diagnostics: Vec::new(),
11963 decisions: vec![1],
11964 actions: vec![ParserAction::new(2, 0, 0, None)],
11965 ..first_alt.clone()
11966 };
11967
11968 let selected =
11969 select_best_outcome([second_alt, first_alt].into_iter(), PredictionMode::Sll)
11970 .expect("one outcome should be selected");
11971 assert_eq!(selected.diagnostics.len(), 1);
11972 assert_eq!(selected.decisions, [0]);
11973 }
11974}