1#![allow(clippy::inline_always)]
11
12use std::borrow::Cow;
13use std::fmt;
14use std::iter::FusedIterator;
15
16use crate::token::TOKEN_EOF;
17
18use super::AtnStateKind;
19
20const PARSER_ATN_MAGIC: u32 = 0x5041_544e;
21const PARSER_ATN_FORMAT_VERSION: u32 = 2;
22const PARSER_ATN_MIN_FORMAT_VERSION: u32 = 1;
23const PARSER_ATN_MAX_FORMAT_VERSION: u32 = 2;
24const PARSER_ATN_BYTE_ORDER: u32 = 0x0102_0304;
25
26const LEGACY_HEADER_WORDS: usize = 26;
27const HEADER_WORDS: usize = 29;
28const STATE_WORDS: usize = 7;
29const TRANSITION_WORDS: usize = 5;
30const LEGACY_SET_WORDS: usize = 2;
31const SET_WORDS: usize = 5;
32const PACKED_U64_WORDS: usize = 2;
33
34const INLINE_TOKEN_SET_WORDS: usize = 2;
35const INLINE_TOKEN_SET_MAX_SLOT: usize = INLINE_TOKEN_SET_WORDS * u64::BITS as usize - 1;
36const MAX_DENSE_TOKEN_SET_BYTES: usize = 64 * 1024;
37const MAX_DENSE_TOKEN_SET_WORDS: usize = MAX_DENSE_TOKEN_SET_BYTES / size_of::<u64>();
38const DENSE_TOKEN_SET_COST_MULTIPLIER: usize = 2;
39const DENSE_TOKEN_SET_MIN_DENSITY_DENOMINATOR: u64 = 8;
40
41const NO_INDEX: u32 = u32::MAX;
42
43const FLAG_NON_GREEDY: u32 = 1 << 0;
44const FLAG_PRECEDENCE_DECISION: u32 = 1 << 1;
45const FLAG_LEFT_RECURSIVE_RULE: u32 = 1 << 2;
46const FLAG_EPSILON_ONLY: u32 = 1 << 3;
47const FLAG_RULE_STOP: u32 = 1 << 4;
48const FLAG_HAS_CONSUMING: u32 = 1 << 5;
49const FLAG_HAS_SEMANTIC: u32 = 1 << 6;
50const STATE_FLAGS: u32 = FLAG_NON_GREEDY
51 | FLAG_PRECEDENCE_DECISION
52 | FLAG_LEFT_RECURSIVE_RULE
53 | FLAG_EPSILON_ONLY
54 | FLAG_RULE_STOP
55 | FLAG_HAS_CONSUMING
56 | FLAG_HAS_SEMANTIC;
57
58const HEADER_MAGIC: usize = 0;
59const HEADER_VERSION: usize = 1;
60const HEADER_BYTE_ORDER: usize = 2;
61const HEADER_SIZE: usize = 3;
62const HEADER_MAX_TOKEN_TYPE: usize = 4;
63const HEADER_STATE_COUNT: usize = 5;
64const HEADER_TRANSITION_COUNT: usize = 6;
65const HEADER_SET_COUNT: usize = 7;
66const HEADER_INTERVAL_COUNT: usize = 8;
67const HEADER_DECISION_COUNT: usize = 9;
68const HEADER_RULE_COUNT: usize = 10;
69const HEADER_STATES_OFFSET: usize = 11;
70const HEADER_TRANSITIONS_OFFSET: usize = 13;
71const HEADER_SETS_OFFSET: usize = 15;
72const HEADER_INTERVALS_OFFSET: usize = 17;
73const HEADER_DECISIONS_OFFSET: usize = 19;
74const HEADER_RULE_STARTS_OFFSET: usize = 21;
75const HEADER_RULE_STOPS_OFFSET: usize = 23;
76const HEADER_TOTAL_LEN: usize = 25;
77const HEADER_TOKEN_BIT_WORD_COUNT: usize = 26;
78const HEADER_TOKEN_BITS_OFFSET: usize = 27;
79
80#[repr(transparent)]
82#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
83pub struct AtnStateId(u32);
84
85impl AtnStateId {
86 pub const fn index(self) -> usize {
87 self.0 as usize
88 }
89
90 const fn raw(self) -> u32 {
91 self.0
92 }
93}
94
95impl TryFrom<usize> for AtnStateId {
96 type Error = ParserAtnError;
97
98 fn try_from(value: usize) -> Result<Self, Self::Error> {
99 compact_id("parser ATN state", value).map(Self)
100 }
101}
102
103#[repr(transparent)]
105#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
106pub struct TransitionId(u32);
107
108impl TransitionId {
109 pub const fn index(self) -> usize {
110 self.0 as usize
111 }
112}
113
114impl TryFrom<usize> for TransitionId {
115 type Error = ParserAtnError;
116
117 fn try_from(value: usize) -> Result<Self, Self::Error> {
118 compact_id("parser ATN transition", value).map(Self)
119 }
120}
121
122#[repr(transparent)]
124#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
125pub struct ParserIntervalSetId(u32);
126
127impl ParserIntervalSetId {
128 pub const fn index(self) -> usize {
129 self.0 as usize
130 }
131
132 const fn raw(self) -> u32 {
133 self.0
134 }
135}
136
137impl TryFrom<usize> for ParserIntervalSetId {
138 type Error = ParserAtnError;
139
140 fn try_from(value: usize) -> Result<Self, Self::Error> {
141 compact_id("parser ATN interval set", value).map(Self)
142 }
143}
144
145#[derive(Clone, Copy, Debug, Eq, PartialEq)]
147#[repr(u32)]
148pub enum ParserTokenSetKind {
149 Intervals = 0,
151 Inline128 = 1,
153 Dense = 2,
155}
156
157#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
159pub enum ParserAtnError {
160 #[error(
161 "generated parser ATN format version {found} is unsupported; \
162 this runtime requires generator/runtime format {minimum}..={maximum}"
163 )]
164 UnsupportedVersion {
165 found: u32,
166 minimum: u32,
167 maximum: u32,
168 },
169 #[error("invalid packed parser ATN: {0}")]
170 InvalidData(String),
171 #[error("{field} count/index {value} exceeds the compact u32 range")]
172 Overflow { field: &'static str, value: usize },
173}
174
175#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
177pub struct ParserAtnStats {
178 pub states: usize,
179 pub transitions: usize,
180 pub interval_sets: usize,
181 pub interval_ranges: usize,
182 pub inline_token_sets: usize,
183 pub dense_token_sets: usize,
184 pub interval_token_sets: usize,
185 pub token_bitset_bytes: usize,
186 pub decisions: usize,
187 pub rules: usize,
188 pub packed_bytes: usize,
189}
190
191pub struct ParserAtn {
197 words: Cow<'static, [u32]>,
198 words_address: usize,
199 layout: ParserAtnLayout,
200}
201
202impl Clone for ParserAtn {
203 fn clone(&self) -> Self {
204 let words = self.words.clone();
205 let words_address = words.as_ptr() as usize;
206 Self {
207 words,
208 words_address,
209 layout: self.layout,
210 }
211 }
212}
213
214impl PartialEq for ParserAtn {
215 fn eq(&self, other: &Self) -> bool {
216 self.words == other.words && self.layout == other.layout
217 }
218}
219
220impl Eq for ParserAtn {}
221
222impl fmt::Debug for ParserAtn {
223 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
224 formatter
225 .debug_struct("ParserAtn")
226 .field("max_token_type", &self.max_token_type())
227 .field("stats", &self.stats())
228 .finish_non_exhaustive()
229 }
230}
231
232impl ParserAtn {
233 pub fn from_static(words: &'static [u32]) -> Result<Self, ParserAtnError> {
235 let layout = validate_packed(words)?;
236 let atn = Self {
237 words: Cow::Borrowed(words),
238 words_address: words.as_ptr() as usize,
239 layout,
240 };
241 #[cfg(feature = "perf-counters")]
242 atn.record_token_set_inventory();
243 Ok(atn)
244 }
245
246 pub fn from_owned(words: Vec<u32>) -> Result<Self, ParserAtnError> {
248 let layout = validate_packed(&words)?;
249 let words: Cow<'static, [u32]> = Cow::Owned(words);
250 let words_address = words.as_ptr() as usize;
251 let atn = Self {
252 words,
253 words_address,
254 layout,
255 };
256 #[cfg(feature = "perf-counters")]
257 atn.record_token_set_inventory();
258 Ok(atn)
259 }
260
261 pub fn format_version(&self) -> u32 {
263 self.words[HEADER_VERSION]
264 }
265
266 #[inline(always)]
267 pub const fn max_token_type(&self) -> i32 {
268 self.layout.max_token_type
269 }
270
271 pub const fn state_count(&self) -> usize {
272 self.layout.state_count
273 }
274
275 pub const fn transition_count(&self) -> usize {
276 self.layout.transition_count
277 }
278
279 pub const fn decision_count(&self) -> usize {
280 self.layout.decisions.len
281 }
282
283 pub const fn rule_count(&self) -> usize {
284 self.layout.rule_starts.len
285 }
286
287 #[inline(always)]
288 pub fn state(&self, state_number: usize) -> Option<ParserAtnState<'_>> {
289 (state_number < self.state_count())
290 .then(|| ParserAtnState::new(self, AtnStateId(state_number as u32)))
291 }
292
293 #[inline(always)]
294 pub fn state_by_id(&self, id: AtnStateId) -> Option<ParserAtnState<'_>> {
295 (id.index() < self.state_count()).then(|| ParserAtnState::new(self, id))
296 }
297
298 pub const fn states(&self) -> ParserAtnStates<'_> {
299 ParserAtnStates {
300 atn: self,
301 next: 0,
302 end: self.state_count(),
303 }
304 }
305
306 #[inline(always)]
307 pub fn transition(&self, id: TransitionId) -> Option<ParserTransition<'_>> {
308 (id.index() < self.transition_count()).then(|| ParserTransition::new(self, id))
309 }
310
311 pub const fn decision_to_state(&self) -> ParserStateIdTable<'_> {
312 ParserStateIdTable::new(self, self.layout.decisions)
313 }
314
315 pub const fn rule_to_start_state(&self) -> ParserStateIdTable<'_> {
316 ParserStateIdTable::new(self, self.layout.rule_starts)
317 }
318
319 pub const fn rule_to_stop_state(&self) -> ParserStateIdTable<'_> {
320 ParserStateIdTable::new(self, self.layout.rule_stops)
321 }
322
323 pub fn packed_words(&self) -> &[u32] {
325 &self.words
326 }
327
328 #[inline(always)]
333 pub fn token_set(&self, index: usize) -> Option<ParserIntervalSet<'_>> {
334 let id = ParserIntervalSetId::try_from(index).ok()?;
335 (index < self.set_count()).then(|| self.interval_set(id))
336 }
337
338 pub(crate) fn storage_identity(&self) -> (usize, usize) {
340 (self.words.as_ptr() as usize, self.words.len())
341 }
342
343 pub fn stats(&self) -> ParserAtnStats {
344 let mut inline_token_sets = 0;
345 let mut dense_token_sets = 0;
346 let mut interval_token_sets = 0;
347 let mut token_bitset_bytes = 0;
348 for index in 0..self.set_count() {
349 let set = self
350 .token_set(index)
351 .expect("in-bounds parser token-set index");
352 match set.kind() {
353 ParserTokenSetKind::Inline128 => inline_token_sets += 1,
354 ParserTokenSetKind::Dense => dense_token_sets += 1,
355 ParserTokenSetKind::Intervals => interval_token_sets += 1,
356 }
357 token_bitset_bytes += set.bit_len * size_of::<u64>();
358 }
359 ParserAtnStats {
360 states: self.state_count(),
361 transitions: self.transition_count(),
362 interval_sets: self.set_count(),
363 interval_ranges: self.layout.intervals.len / 2,
364 inline_token_sets,
365 dense_token_sets,
366 interval_token_sets,
367 token_bitset_bytes,
368 decisions: self.decision_count(),
369 rules: self.rule_count(),
370 packed_bytes: self.words.len() * size_of::<u32>(),
371 }
372 }
373
374 const fn set_count(&self) -> usize {
375 self.layout.sets.len / self.layout.set_words
376 }
377
378 #[inline(always)]
379 fn word(&self, section: Section, record: usize, field: usize, width: usize) -> u32 {
380 self.packed_word(section.offset + record * width + field)
381 }
382
383 #[inline(always)]
384 fn interval_set(&self, id: ParserIntervalSetId) -> ParserIntervalSet<'_> {
385 let width = self.layout.set_words;
386 let start = self.word(self.layout.sets, id.index(), 0, width) as usize;
387 let len = self.word(self.layout.sets, id.index(), 1, width) as usize;
388 let (kind, bit_start, bit_len) = if self.layout.format_version == 1 {
389 (ParserTokenSetKind::Intervals, 0, 0)
390 } else {
391 (
392 decode_token_set_kind(self.word(self.layout.sets, id.index(), 2, width))
393 .expect("packed parser token-set kind was validated"),
394 self.word(self.layout.sets, id.index(), 3, width) as usize,
395 self.word(self.layout.sets, id.index(), 4, width) as usize,
396 )
397 };
398 ParserIntervalSet {
399 atn: self,
400 id,
401 start,
402 len,
403 kind,
404 bit_start,
405 bit_len,
406 }
407 }
408
409 #[inline(always)]
410 fn token_bit_word(&self, index: usize) -> u64 {
411 let offset = self.layout.token_bits.offset + index * PACKED_U64_WORDS;
412 u64::from(self.packed_word(offset)) | (u64::from(self.packed_word(offset + 1)) << u32::BITS)
413 }
414
415 #[cfg(feature = "perf-counters")]
416 fn record_token_set_inventory(&self) {
417 for index in 0..self.set_count() {
418 let set = self
419 .token_set(index)
420 .expect("in-bounds parser token-set index");
421 crate::perf::record_parser_token_set_selection(
422 set.kind(),
423 set.bit_len * size_of::<u64>(),
424 );
425 }
426 }
427
428 #[inline(always)]
429 fn packed_address(&self, index: usize) -> usize {
430 debug_assert!(index < self.words.len());
431 self.words_address + index * size_of::<u32>()
432 }
433
434 #[inline(always)]
435 #[allow(unsafe_code)]
436 fn packed_word(&self, index: usize) -> u32 {
437 debug_assert!(index < self.words.len());
438 unsafe { *((self.words_address as *const u32).add(index)) }
443 }
444}
445
446#[derive(Clone, Copy)]
448pub struct ParserAtnState<'a> {
449 atn: &'a ParserAtn,
450 record_address: usize,
451}
452
453impl fmt::Debug for ParserAtnState<'_> {
454 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
455 formatter
456 .debug_struct("ParserAtnState")
457 .field("id", &self.id())
458 .field("kind", &self.kind())
459 .field("rule_index", &self.rule_index())
460 .field("transition_count", &self.transitions().len())
461 .finish()
462 }
463}
464
465impl<'a> ParserAtnState<'a> {
466 #[inline(always)]
467 fn new(atn: &'a ParserAtn, id: AtnStateId) -> Self {
468 Self {
469 atn,
470 record_address: atn.packed_address(atn.layout.states.offset + id.index() * STATE_WORDS),
471 }
472 }
473
474 pub const fn id(self) -> AtnStateId {
475 let word = (self.record_address - self.atn.words_address) / size_of::<u32>();
476 AtnStateId(((word - self.atn.layout.states.offset) / STATE_WORDS) as u32)
477 }
478
479 pub const fn state_number(self) -> usize {
480 self.id().index()
481 }
482
483 #[inline(always)]
484 pub fn kind(self) -> AtnStateKind {
485 decode_state_kind(self.word(0)).expect("packed parser ATN state kind was validated")
486 }
487
488 #[inline(always)]
489 pub fn rule_index(self) -> Option<usize> {
490 unpack_index(self.word(1))
491 }
492
493 #[inline(always)]
494 pub fn end_state(self) -> Option<usize> {
495 unpack_index(self.word(5))
496 }
497
498 #[inline(always)]
499 pub fn loop_back_state(self) -> Option<usize> {
500 unpack_index(self.word(6))
501 }
502
503 #[inline(always)]
504 pub fn non_greedy(self) -> bool {
505 self.flags() & FLAG_NON_GREEDY != 0
506 }
507
508 #[inline(always)]
509 pub fn precedence_rule_decision(self) -> bool {
510 self.flags() & FLAG_PRECEDENCE_DECISION != 0
511 }
512
513 #[inline(always)]
514 pub fn left_recursive_rule(self) -> bool {
515 self.flags() & FLAG_LEFT_RECURSIVE_RULE != 0
516 }
517
518 #[inline]
519 pub fn is_rule_stop(self) -> bool {
520 self.flags() & FLAG_RULE_STOP != 0
521 }
522
523 #[inline]
524 pub fn epsilon_only(self) -> bool {
525 self.flags() & FLAG_EPSILON_ONLY != 0
526 }
527
528 #[inline]
529 pub fn has_consuming_transition(self) -> bool {
530 self.flags() & FLAG_HAS_CONSUMING != 0
531 }
532
533 #[inline]
534 pub fn has_semantic_transition(self) -> bool {
535 self.flags() & FLAG_HAS_SEMANTIC != 0
536 }
537
538 #[inline(always)]
539 pub fn transitions(self) -> ParserTransitions<'a> {
540 let start = self.word(3) as usize;
541 ParserTransitions {
542 atn: self.atn,
543 record_address: self
544 .atn
545 .packed_address(self.atn.layout.transitions.offset + start * TRANSITION_WORDS),
546 len: self.word(4) as usize,
547 }
548 }
549
550 #[inline(always)]
551 fn flags(self) -> u32 {
552 self.word(2)
553 }
554
555 #[inline(always)]
556 #[allow(unsafe_code)]
557 fn word(self, field: usize) -> u32 {
558 debug_assert!(field < STATE_WORDS);
559 unsafe { *((self.record_address as *const u32).add(field)) }
562 }
563}
564
565#[derive(Clone, Copy, Debug)]
567pub struct ParserTransitions<'a> {
568 atn: &'a ParserAtn,
569 record_address: usize,
570 len: usize,
571}
572
573impl<'a> ParserTransitions<'a> {
574 pub const fn len(self) -> usize {
575 self.len
576 }
577
578 pub const fn is_empty(self) -> bool {
579 self.len == 0
580 }
581
582 #[inline(always)]
583 pub fn get(self, index: usize) -> Option<ParserTransition<'a>> {
584 (index < self.len).then(|| ParserTransition {
585 atn: self.atn,
586 record_address: self.record_address + index * TRANSITION_WORDS * size_of::<u32>(),
587 })
588 }
589
590 #[inline(always)]
591 pub fn first(self) -> Option<ParserTransition<'a>> {
592 self.get(0)
593 }
594
595 #[inline]
596 pub fn last(self) -> Option<ParserTransition<'a>> {
597 self.len.checked_sub(1).and_then(|index| self.get(index))
598 }
599
600 pub const fn iter(self) -> ParserTransitionIter<'a> {
601 ParserTransitionIter {
602 atn: self.atn,
603 next_record_address: self.record_address,
604 remaining: self.len,
605 }
606 }
607}
608
609impl<'a> IntoIterator for ParserTransitions<'a> {
610 type Item = ParserTransition<'a>;
611 type IntoIter = ParserTransitionIter<'a>;
612
613 fn into_iter(self) -> Self::IntoIter {
614 self.iter()
615 }
616}
617
618impl<'a> IntoIterator for &'a ParserTransitions<'a> {
619 type Item = ParserTransition<'a>;
620 type IntoIter = ParserTransitionIter<'a>;
621
622 fn into_iter(self) -> Self::IntoIter {
623 self.iter()
624 }
625}
626
627#[derive(Clone, Debug)]
629pub struct ParserTransitionIter<'a> {
630 atn: &'a ParserAtn,
631 next_record_address: usize,
632 remaining: usize,
633}
634
635impl<'a> Iterator for ParserTransitionIter<'a> {
636 type Item = ParserTransition<'a>;
637
638 #[inline(always)]
639 fn next(&mut self) -> Option<Self::Item> {
640 if self.remaining == 0 {
641 return None;
642 }
643 let transition = ParserTransition {
644 atn: self.atn,
645 record_address: self.next_record_address,
646 };
647 self.next_record_address += TRANSITION_WORDS * size_of::<u32>();
648 self.remaining -= 1;
649 Some(transition)
650 }
651
652 fn size_hint(&self) -> (usize, Option<usize>) {
653 (self.remaining, Some(self.remaining))
654 }
655}
656
657impl ExactSizeIterator for ParserTransitionIter<'_> {}
658impl FusedIterator for ParserTransitionIter<'_> {}
659
660#[derive(Clone, Copy)]
662pub struct ParserTransition<'a> {
663 atn: &'a ParserAtn,
664 record_address: usize,
665}
666
667impl fmt::Debug for ParserTransition<'_> {
668 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
669 self.data().fmt(formatter)
670 }
671}
672
673impl<'a> ParserTransition<'a> {
674 #[inline(always)]
675 fn new(atn: &'a ParserAtn, id: TransitionId) -> Self {
676 Self {
677 atn,
678 record_address: atn
679 .packed_address(atn.layout.transitions.offset + id.index() * TRANSITION_WORDS),
680 }
681 }
682
683 #[inline(always)]
684 pub const fn id(self) -> TransitionId {
685 let word = (self.record_address - self.atn.words_address) / size_of::<u32>();
686 TransitionId(((word - self.atn.layout.transitions.offset) / TRANSITION_WORDS) as u32)
687 }
688
689 #[inline(always)]
690 pub fn target_id(self) -> AtnStateId {
691 AtnStateId(self.word(1))
692 }
693
694 #[inline(always)]
695 pub fn target(self) -> usize {
696 self.target_id().index()
697 }
698
699 #[inline(always)]
700 pub fn kind(self) -> ParserTransitionKind {
701 decode_transition_kind(self.word(0))
702 .expect("packed parser ATN transition kind was validated")
703 }
704
705 #[inline(always)]
706 pub fn is_epsilon(self) -> bool {
707 matches!(
708 self.kind(),
709 ParserTransitionKind::Epsilon
710 | ParserTransitionKind::Rule
711 | ParserTransitionKind::Predicate
712 | ParserTransitionKind::Action
713 | ParserTransitionKind::Precedence
714 )
715 }
716
717 #[inline(always)]
718 pub fn is_action(self) -> bool {
719 self.kind() == ParserTransitionKind::Action
720 }
721
722 #[inline(always)]
723 pub fn matches(self, symbol: i32, min_vocabulary: i32, max_vocabulary: i32) -> bool {
724 self.matches_kind(self.kind(), symbol, min_vocabulary, max_vocabulary)
725 }
726
727 #[inline(always)]
728 pub(crate) fn matches_kind(
729 self,
730 kind: ParserTransitionKind,
731 symbol: i32,
732 min_vocabulary: i32,
733 max_vocabulary: i32,
734 ) -> bool {
735 match kind {
736 ParserTransitionKind::Atom => unpack_i32(self.arg0()) == symbol,
737 ParserTransitionKind::Range => {
738 (unpack_i32(self.arg0())..=unpack_i32(self.arg1())).contains(&symbol)
739 }
740 ParserTransitionKind::Set => self
741 .atn
742 .interval_set(ParserIntervalSetId(self.arg0()))
743 .contains(symbol),
744 ParserTransitionKind::NotSet => {
745 (min_vocabulary..=max_vocabulary).contains(&symbol)
746 && !self
747 .atn
748 .interval_set(ParserIntervalSetId(self.arg0()))
749 .contains(symbol)
750 }
751 ParserTransitionKind::Wildcard => (min_vocabulary..=max_vocabulary).contains(&symbol),
752 ParserTransitionKind::Epsilon
753 | ParserTransitionKind::Rule
754 | ParserTransitionKind::Predicate
755 | ParserTransitionKind::Action
756 | ParserTransitionKind::Precedence => false,
757 }
758 }
759
760 #[inline(always)]
761 pub(crate) fn arg0(self) -> u32 {
762 self.word(2)
763 }
764
765 #[inline(always)]
766 pub(crate) fn arg1(self) -> u32 {
767 self.word(3)
768 }
769
770 #[inline(always)]
771 pub(crate) fn arg2(self) -> u32 {
772 self.word(4)
773 }
774
775 #[inline(always)]
776 pub fn data(self) -> ParserTransitionData<'a> {
777 match decode_transition_kind(self.word(0))
778 .expect("packed parser ATN transition kind was validated")
779 {
780 ParserTransitionKind::Epsilon => ParserTransitionData::Epsilon {
781 target: self.word(1) as usize,
782 },
783 ParserTransitionKind::Atom => ParserTransitionData::Atom {
784 target: self.word(1) as usize,
785 label: unpack_i32(self.word(2)),
786 },
787 ParserTransitionKind::Range => ParserTransitionData::Range {
788 target: self.word(1) as usize,
789 start: unpack_i32(self.word(2)),
790 stop: unpack_i32(self.word(3)),
791 },
792 ParserTransitionKind::Set => ParserTransitionData::Set {
793 target: self.word(1) as usize,
794 set: self.atn.interval_set(ParserIntervalSetId(self.word(2))),
795 },
796 ParserTransitionKind::NotSet => ParserTransitionData::NotSet {
797 target: self.word(1) as usize,
798 set: self.atn.interval_set(ParserIntervalSetId(self.word(2))),
799 },
800 ParserTransitionKind::Wildcard => ParserTransitionData::Wildcard {
801 target: self.word(1) as usize,
802 },
803 ParserTransitionKind::Rule => ParserTransitionData::Rule {
804 target: self.word(1) as usize,
805 rule_index: self.word(2) as usize,
806 follow_state: self.word(3) as usize,
807 precedence: unpack_i32(self.word(4)),
808 },
809 ParserTransitionKind::Predicate => ParserTransitionData::Predicate {
810 target: self.word(1) as usize,
811 rule_index: self.word(2) as usize,
812 pred_index: self.word(3) as usize,
813 context_dependent: self.word(4) != 0,
814 },
815 ParserTransitionKind::Action => ParserTransitionData::Action {
816 target: self.word(1) as usize,
817 rule_index: self.word(2) as usize,
818 action_index: unpack_index(self.word(3)),
819 context_dependent: self.word(4) != 0,
820 },
821 ParserTransitionKind::Precedence => ParserTransitionData::Precedence {
822 target: self.word(1) as usize,
823 precedence: unpack_i32(self.word(2)),
824 },
825 }
826 }
827
828 #[inline(always)]
829 #[allow(unsafe_code)]
830 fn word(self, field: usize) -> u32 {
831 debug_assert!(field < TRANSITION_WORDS);
832 unsafe { *((self.record_address as *const u32).add(field)) }
835 }
836}
837
838#[derive(Clone, Copy, Debug, Eq, PartialEq)]
840#[repr(u8)]
841pub enum ParserTransitionKind {
842 Epsilon = 1,
843 Range = 2,
844 Rule = 3,
845 Predicate = 4,
846 Atom = 5,
847 Action = 6,
848 Set = 7,
849 NotSet = 8,
850 Wildcard = 9,
851 Precedence = 10,
852}
853
854#[derive(Clone, Copy, Debug, Eq, PartialEq)]
856pub enum ParserTransitionData<'a> {
857 Epsilon {
858 target: usize,
859 },
860 Atom {
861 target: usize,
862 label: i32,
863 },
864 Range {
865 target: usize,
866 start: i32,
867 stop: i32,
868 },
869 Set {
870 target: usize,
871 set: ParserIntervalSet<'a>,
872 },
873 NotSet {
874 target: usize,
875 set: ParserIntervalSet<'a>,
876 },
877 Wildcard {
878 target: usize,
879 },
880 Rule {
881 target: usize,
882 rule_index: usize,
883 follow_state: usize,
884 precedence: i32,
885 },
886 Predicate {
887 target: usize,
888 rule_index: usize,
889 pred_index: usize,
890 context_dependent: bool,
891 },
892 Action {
893 target: usize,
894 rule_index: usize,
895 action_index: Option<usize>,
896 context_dependent: bool,
897 },
898 Precedence {
899 target: usize,
900 precedence: i32,
901 },
902}
903
904impl ParserTransitionData<'_> {
905 pub const fn target(self) -> usize {
906 match self {
907 Self::Epsilon { target }
908 | Self::Atom { target, .. }
909 | Self::Range { target, .. }
910 | Self::Set { target, .. }
911 | Self::NotSet { target, .. }
912 | Self::Wildcard { target }
913 | Self::Rule { target, .. }
914 | Self::Predicate { target, .. }
915 | Self::Action { target, .. }
916 | Self::Precedence { target, .. } => target,
917 }
918 }
919
920 pub const fn is_epsilon(self) -> bool {
921 matches!(
922 self,
923 Self::Epsilon { .. }
924 | Self::Rule { .. }
925 | Self::Predicate { .. }
926 | Self::Action { .. }
927 | Self::Precedence { .. }
928 )
929 }
930
931 pub const fn is_action(self) -> bool {
932 matches!(self, Self::Action { .. })
933 }
934
935 pub fn matches(self, symbol: i32, min_vocabulary: i32, max_vocabulary: i32) -> bool {
936 match self {
937 Self::Atom { label, .. } => label == symbol,
938 Self::Range { start, stop, .. } => (start..=stop).contains(&symbol),
939 Self::Set { set, .. } => set.contains(symbol),
940 Self::NotSet { set, .. } => {
941 (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol)
942 }
943 Self::Wildcard { .. } => (min_vocabulary..=max_vocabulary).contains(&symbol),
944 Self::Epsilon { .. }
945 | Self::Rule { .. }
946 | Self::Predicate { .. }
947 | Self::Action { .. }
948 | Self::Precedence { .. } => false,
949 }
950 }
951}
952
953#[derive(Clone, Copy, Eq, PartialEq)]
955pub struct ParserIntervalSet<'a> {
956 atn: &'a ParserAtn,
957 id: ParserIntervalSetId,
958 start: usize,
959 len: usize,
960 kind: ParserTokenSetKind,
961 bit_start: usize,
962 bit_len: usize,
963}
964
965impl fmt::Debug for ParserIntervalSet<'_> {
966 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
967 formatter.debug_list().entries(self.ranges()).finish()
968 }
969}
970
971impl<'a> ParserIntervalSet<'a> {
972 pub const fn index(self) -> usize {
974 self.id.index()
975 }
976
977 pub const fn kind(self) -> ParserTokenSetKind {
979 self.kind
980 }
981
982 pub const fn is_empty(self) -> bool {
983 self.len == 0
984 }
985
986 #[inline]
988 pub fn contains(self, value: i32) -> bool {
989 let hit = match self.kind {
990 ParserTokenSetKind::Inline128 | ParserTokenSetKind::Dense => {
991 self.contains_bitset(value)
992 }
993 ParserTokenSetKind::Intervals => self.contains_intervals(value),
994 };
995 #[cfg(feature = "perf-counters")]
996 crate::perf::record_parser_token_set_probe(self.kind, hit);
997 hit
998 }
999
1000 #[inline(always)]
1001 fn contains_bitset(self, value: i32) -> bool {
1002 let Some(slot) = token_set_slot(value) else {
1003 return false;
1004 };
1005 let word = slot / u64::BITS as usize;
1006 word < self.bit_len
1007 && self.atn.token_bit_word(self.bit_start + word)
1008 & (1_u64 << (slot % u64::BITS as usize))
1009 != 0
1010 }
1011
1012 #[inline(always)]
1013 fn contains_intervals(self, value: i32) -> bool {
1014 let mut low = 0;
1015 let mut high = self.len;
1016 while low < high {
1017 let middle = low + (high - low) / 2;
1018 if self.range_start(middle) <= value {
1019 low = middle + 1;
1020 } else {
1021 high = middle;
1022 }
1023 }
1024 low > 0 && self.range_stop(low - 1) >= value
1025 }
1026
1027 pub const fn ranges(self) -> ParserIntervalRanges<'a> {
1028 ParserIntervalRanges { set: self, next: 0 }
1029 }
1030
1031 #[inline(always)]
1032 fn range(self, index: usize) -> (i32, i32) {
1033 (self.range_start(index), self.range_stop(index))
1034 }
1035
1036 #[inline(always)]
1037 fn range_start(self, index: usize) -> i32 {
1038 let word = self.atn.layout.intervals.offset + (self.start + index) * 2;
1039 unpack_i32(self.atn.packed_word(word))
1040 }
1041
1042 #[inline(always)]
1043 fn range_stop(self, index: usize) -> i32 {
1044 let word = self.atn.layout.intervals.offset + (self.start + index) * 2 + 1;
1045 unpack_i32(self.atn.packed_word(word))
1046 }
1047}
1048
1049#[derive(Clone, Debug)]
1051pub struct ParserIntervalRanges<'a> {
1052 set: ParserIntervalSet<'a>,
1053 next: usize,
1054}
1055
1056impl Iterator for ParserIntervalRanges<'_> {
1057 type Item = (i32, i32);
1058
1059 #[inline]
1060 fn next(&mut self) -> Option<Self::Item> {
1061 if self.next >= self.set.len {
1062 return None;
1063 }
1064 let range = self.set.range(self.next);
1065 self.next += 1;
1066 Some(range)
1067 }
1068
1069 fn size_hint(&self) -> (usize, Option<usize>) {
1070 let remaining = self.set.len.saturating_sub(self.next);
1071 (remaining, Some(remaining))
1072 }
1073}
1074
1075impl ExactSizeIterator for ParserIntervalRanges<'_> {}
1076impl FusedIterator for ParserIntervalRanges<'_> {}
1077
1078#[derive(Clone, Copy, Debug)]
1080pub struct ParserStateIdTable<'a> {
1081 atn: &'a ParserAtn,
1082 section: Section,
1083}
1084
1085impl<'a> ParserStateIdTable<'a> {
1086 const fn new(atn: &'a ParserAtn, section: Section) -> Self {
1087 Self { atn, section }
1088 }
1089
1090 pub const fn len(self) -> usize {
1091 self.section.len
1092 }
1093
1094 pub const fn is_empty(self) -> bool {
1095 self.section.len == 0
1096 }
1097
1098 #[inline(always)]
1099 pub fn get(self, index: usize) -> Option<usize> {
1100 (index < self.len()).then(|| self.atn.packed_word(self.section.offset + index) as usize)
1101 }
1102
1103 pub fn get_id(self, index: usize) -> Option<AtnStateId> {
1104 self.get(index).map(|value| {
1105 AtnStateId::try_from(value).expect("validated side-table state fits compact ID")
1106 })
1107 }
1108
1109 pub const fn iter(self) -> ParserStateIdIter<'a> {
1110 ParserStateIdIter {
1111 table: self,
1112 next: 0,
1113 }
1114 }
1115}
1116
1117impl<'a> IntoIterator for ParserStateIdTable<'a> {
1118 type Item = usize;
1119 type IntoIter = ParserStateIdIter<'a>;
1120
1121 fn into_iter(self) -> Self::IntoIter {
1122 self.iter()
1123 }
1124}
1125
1126#[derive(Clone, Debug)]
1128pub struct ParserStateIdIter<'a> {
1129 table: ParserStateIdTable<'a>,
1130 next: usize,
1131}
1132
1133impl Iterator for ParserStateIdIter<'_> {
1134 type Item = usize;
1135
1136 #[inline]
1137 fn next(&mut self) -> Option<Self::Item> {
1138 let value = self.table.get(self.next)?;
1139 self.next += 1;
1140 Some(value)
1141 }
1142
1143 fn size_hint(&self) -> (usize, Option<usize>) {
1144 let remaining = self.table.len().saturating_sub(self.next);
1145 (remaining, Some(remaining))
1146 }
1147}
1148
1149impl ExactSizeIterator for ParserStateIdIter<'_> {}
1150impl FusedIterator for ParserStateIdIter<'_> {}
1151
1152#[derive(Clone, Debug)]
1154pub struct ParserAtnStates<'a> {
1155 atn: &'a ParserAtn,
1156 next: usize,
1157 end: usize,
1158}
1159
1160impl<'a> Iterator for ParserAtnStates<'a> {
1161 type Item = ParserAtnState<'a>;
1162
1163 #[inline]
1164 fn next(&mut self) -> Option<Self::Item> {
1165 if self.next >= self.end {
1166 return None;
1167 }
1168 let state = self.atn.state(self.next);
1169 self.next += 1;
1170 state
1171 }
1172
1173 fn size_hint(&self) -> (usize, Option<usize>) {
1174 let remaining = self.end.saturating_sub(self.next);
1175 (remaining, Some(remaining))
1176 }
1177}
1178
1179impl ExactSizeIterator for ParserAtnStates<'_> {}
1180impl FusedIterator for ParserAtnStates<'_> {}
1181
1182#[derive(Debug)]
1187pub struct ParserAtnBuilder {
1188 max_token_type: i32,
1189 states: Vec<StateBuild>,
1190 transitions: Vec<TransitionBuild>,
1191 interval_sets: Vec<TokenSetBuild>,
1192 interval_ranges: Vec<(i32, i32)>,
1193 token_bit_words: Vec<u64>,
1194 decisions: Vec<AtnStateId>,
1195 rule_starts: Vec<AtnStateId>,
1196 rule_stops: Vec<AtnStateId>,
1197}
1198
1199impl ParserAtnBuilder {
1200 pub const fn new(max_token_type: i32) -> Self {
1201 Self {
1202 max_token_type,
1203 states: Vec::new(),
1204 transitions: Vec::new(),
1205 interval_sets: Vec::new(),
1206 interval_ranges: Vec::new(),
1207 token_bit_words: Vec::new(),
1208 decisions: Vec::new(),
1209 rule_starts: Vec::new(),
1210 rule_stops: Vec::new(),
1211 }
1212 }
1213
1214 pub fn add_state(
1215 &mut self,
1216 kind: AtnStateKind,
1217 rule_index: Option<usize>,
1218 ) -> Result<AtnStateId, ParserAtnError> {
1219 let id = AtnStateId::try_from(self.states.len())?;
1220 let rule_index = pack_optional_index("parser ATN rule", rule_index)?;
1221 self.states.push(StateBuild {
1222 kind,
1223 rule_index,
1224 flags: u32::from(kind == AtnStateKind::RuleStop) * FLAG_RULE_STOP,
1225 end_state: NO_INDEX,
1226 loop_back_state: NO_INDEX,
1227 });
1228 Ok(id)
1229 }
1230
1231 pub fn set_end_state(&mut self, state: usize, end_state: usize) -> Result<(), ParserAtnError> {
1232 let end_state = self.checked_state(end_state, "block end state")?;
1233 self.state_mut(state, "block start state")?.end_state = end_state.raw();
1234 Ok(())
1235 }
1236
1237 pub fn set_loop_back_state(
1238 &mut self,
1239 state: usize,
1240 loop_back_state: usize,
1241 ) -> Result<(), ParserAtnError> {
1242 let loop_back_state = self.checked_state(loop_back_state, "loop back state")?;
1243 self.state_mut(state, "loop end state")?.loop_back_state = loop_back_state.raw();
1244 Ok(())
1245 }
1246
1247 pub fn set_non_greedy(&mut self, state: usize) -> Result<(), ParserAtnError> {
1248 self.state_mut(state, "non-greedy state")?.flags |= FLAG_NON_GREEDY;
1249 Ok(())
1250 }
1251
1252 pub fn set_left_recursive_rule(&mut self, state: usize) -> Result<(), ParserAtnError> {
1253 self.state_mut(state, "precedence rule state")?.flags |= FLAG_LEFT_RECURSIVE_RULE;
1254 Ok(())
1255 }
1256
1257 pub fn set_precedence_rule_decision(&mut self, state: usize) -> Result<(), ParserAtnError> {
1258 self.state_mut(state, "precedence decision state")?.flags |= FLAG_PRECEDENCE_DECISION;
1259 Ok(())
1260 }
1261
1262 pub fn add_interval_set(
1263 &mut self,
1264 ranges: impl IntoIterator<Item = (i32, i32)>,
1265 ) -> Result<ParserIntervalSetId, ParserAtnError> {
1266 let id = ParserIntervalSetId::try_from(self.interval_sets.len())?;
1267 let normalized = normalize_ranges(ranges);
1268 let interval_start = compact_id("parser ATN interval start", self.interval_ranges.len())?;
1269 let interval_len = compact_id("parser ATN interval count", normalized.len())?;
1270 let prepared = prepare_token_set(&normalized);
1271 let bit_start = compact_id("parser token-set bit start", self.token_bit_words.len())?;
1272 let bit_len = compact_id("parser token-set bit count", prepared.words.len())?;
1273 self.interval_ranges.extend(normalized);
1274 self.token_bit_words.extend(prepared.words);
1275 self.interval_sets.push(TokenSetBuild {
1276 interval_start,
1277 interval_len,
1278 kind: prepared.kind,
1279 bit_start,
1280 bit_len,
1281 });
1282 Ok(id)
1283 }
1284
1285 pub fn add_transition(
1286 &mut self,
1287 source: usize,
1288 transition: ParserTransitionSpec,
1289 ) -> Result<TransitionId, ParserAtnError> {
1290 let source = self.checked_state(source, "transition source")?;
1291 let record = self.transition_record(source, transition)?;
1292 let id = TransitionId::try_from(self.transitions.len())?;
1293 self.transitions.push(record);
1294 Ok(id)
1295 }
1296
1297 pub fn set_rule_to_start_state(&mut self, states: Vec<usize>) -> Result<(), ParserAtnError> {
1298 self.rule_starts = self.checked_states(states, "rule start state")?;
1299 Ok(())
1300 }
1301
1302 pub fn set_rule_to_stop_state(&mut self, states: Vec<usize>) -> Result<(), ParserAtnError> {
1303 self.rule_stops = self.checked_states(states, "rule stop state")?;
1304 Ok(())
1305 }
1306
1307 pub fn add_decision_state(&mut self, state: usize) -> Result<(), ParserAtnError> {
1308 let state = self.checked_state(state, "decision state")?;
1309 self.decisions.push(state);
1310 Ok(())
1311 }
1312
1313 pub fn state_kind(&self, state: usize) -> Option<AtnStateKind> {
1314 self.states.get(state).map(|record| record.kind)
1315 }
1316
1317 pub const fn state_count(&self) -> usize {
1318 self.states.len()
1319 }
1320
1321 pub fn state_rule_index(&self, state: usize) -> Option<usize> {
1322 self.states
1323 .get(state)
1324 .and_then(|record| unpack_index(record.rule_index))
1325 }
1326
1327 pub fn rule_stop_state(&self, rule: usize) -> Option<usize> {
1328 self.rule_stops.get(rule).copied().map(AtnStateId::index)
1329 }
1330
1331 pub fn transitions_from(
1332 &self,
1333 source: usize,
1334 ) -> impl DoubleEndedIterator<Item = ParserTransitionSpec> + '_ {
1335 self.transitions
1336 .iter()
1337 .filter(move |transition| transition.source.index() == source)
1338 .map(TransitionBuild::spec)
1339 }
1340
1341 pub fn finish(mut self) -> Result<ParserAtn, ParserAtnError> {
1342 self.mark_precedence_decisions();
1343 self.transitions.sort_by_key(|transition| transition.source);
1344 let transition_ranges = self.transition_ranges()?;
1345 self.precompute_state_flags(&transition_ranges);
1346 let words = self.encode(&transition_ranges)?;
1347 ParserAtn::from_owned(words)
1348 }
1349
1350 fn state_mut(&mut self, state: usize, label: &str) -> Result<&mut StateBuild, ParserAtnError> {
1351 self.states.get_mut(state).ok_or_else(|| {
1352 ParserAtnError::InvalidData(format!("{label} {state} outside state list"))
1353 })
1354 }
1355
1356 fn checked_state(&self, state: usize, label: &str) -> Result<AtnStateId, ParserAtnError> {
1357 let id = AtnStateId::try_from(state)?;
1358 if state >= self.states.len() {
1359 return Err(ParserAtnError::InvalidData(format!(
1360 "{label} {state} outside state list"
1361 )));
1362 }
1363 Ok(id)
1364 }
1365
1366 fn checked_states(
1367 &self,
1368 states: Vec<usize>,
1369 label: &str,
1370 ) -> Result<Vec<AtnStateId>, ParserAtnError> {
1371 states
1372 .into_iter()
1373 .map(|state| self.checked_state(state, label))
1374 .collect()
1375 }
1376
1377 fn transition_record(
1378 &self,
1379 source: AtnStateId,
1380 spec: ParserTransitionSpec,
1381 ) -> Result<TransitionBuild, ParserAtnError> {
1382 let target = self.checked_state(spec.target(), "transition target")?;
1383 let (kind, arg0, arg1, arg2) = match spec {
1384 ParserTransitionSpec::Epsilon { .. } => (ParserTransitionKind::Epsilon, 0, 0, 0),
1385 ParserTransitionSpec::Atom { label, .. } => {
1386 (ParserTransitionKind::Atom, pack_i32(label), 0, 0)
1387 }
1388 ParserTransitionSpec::Range { start, stop, .. } => (
1389 ParserTransitionKind::Range,
1390 pack_i32(start),
1391 pack_i32(stop),
1392 0,
1393 ),
1394 ParserTransitionSpec::Set { set, .. } => {
1395 self.checked_set(set)?;
1396 (ParserTransitionKind::Set, set.raw(), 0, 0)
1397 }
1398 ParserTransitionSpec::NotSet { set, .. } => {
1399 self.checked_set(set)?;
1400 (ParserTransitionKind::NotSet, set.raw(), 0, 0)
1401 }
1402 ParserTransitionSpec::Wildcard { .. } => (ParserTransitionKind::Wildcard, 0, 0, 0),
1403 ParserTransitionSpec::Rule {
1404 rule_index,
1405 follow_state,
1406 precedence,
1407 ..
1408 } => (
1409 ParserTransitionKind::Rule,
1410 compact_id("rule transition rule", rule_index)?,
1411 self.checked_state(follow_state, "rule follow state")?.raw(),
1412 pack_i32(precedence),
1413 ),
1414 ParserTransitionSpec::Predicate {
1415 rule_index,
1416 pred_index,
1417 context_dependent,
1418 ..
1419 } => (
1420 ParserTransitionKind::Predicate,
1421 compact_id("predicate rule", rule_index)?,
1422 compact_id("predicate index", pred_index)?,
1423 u32::from(context_dependent),
1424 ),
1425 ParserTransitionSpec::Action {
1426 rule_index,
1427 action_index,
1428 context_dependent,
1429 ..
1430 } => (
1431 ParserTransitionKind::Action,
1432 compact_id("action rule", rule_index)?,
1433 pack_optional_index("action", action_index)?,
1434 u32::from(context_dependent),
1435 ),
1436 ParserTransitionSpec::Precedence { precedence, .. } => {
1437 (ParserTransitionKind::Precedence, pack_i32(precedence), 0, 0)
1438 }
1439 };
1440 Ok(TransitionBuild {
1441 source,
1442 kind,
1443 target,
1444 arg0,
1445 arg1,
1446 arg2,
1447 })
1448 }
1449
1450 fn checked_set(&self, set: ParserIntervalSetId) -> Result<(), ParserAtnError> {
1451 if set.index() >= self.interval_sets.len() {
1452 return Err(ParserAtnError::InvalidData(format!(
1453 "interval set {} outside set list",
1454 set.index()
1455 )));
1456 }
1457 Ok(())
1458 }
1459
1460 fn transition_ranges(&self) -> Result<Vec<(u32, u32)>, ParserAtnError> {
1461 let mut ranges = vec![(0, 0); self.states.len()];
1462 let mut cursor = 0;
1463 for (state, range) in ranges.iter_mut().enumerate() {
1464 let start = cursor;
1465 while cursor < self.transitions.len()
1466 && self.transitions[cursor].source.index() == state
1467 {
1468 cursor += 1;
1469 }
1470 *range = (
1471 compact_id("state transition start", start)?,
1472 compact_id("state transition count", cursor - start)?,
1473 );
1474 }
1475 Ok(ranges)
1476 }
1477
1478 fn precompute_state_flags(&mut self, ranges: &[(u32, u32)]) {
1479 for (state, &(start, len)) in self.states.iter_mut().zip(ranges) {
1480 let transitions = &self.transitions[start as usize..start as usize + len as usize];
1481 if !transitions.is_empty()
1482 && transitions
1483 .iter()
1484 .all(|transition| transition.kind.is_epsilon())
1485 {
1486 state.flags |= FLAG_EPSILON_ONLY;
1487 }
1488 if transitions
1489 .iter()
1490 .any(|transition| transition.kind.is_consuming())
1491 {
1492 state.flags |= FLAG_HAS_CONSUMING;
1493 }
1494 if transitions
1495 .iter()
1496 .any(|transition| transition.kind.is_semantic())
1497 {
1498 state.flags |= FLAG_HAS_SEMANTIC;
1499 }
1500 }
1501 }
1502
1503 fn mark_precedence_decisions(&mut self) {
1504 let candidates = (0..self.states.len())
1505 .filter(|&state| self.is_precedence_decision(state))
1506 .collect::<Vec<_>>();
1507 for state in candidates {
1508 self.states[state].flags |= FLAG_PRECEDENCE_DECISION;
1509 }
1510 }
1511
1512 fn is_precedence_decision(&self, state: usize) -> bool {
1513 let record = &self.states[state];
1514 if record.kind != AtnStateKind::StarLoopEntry {
1515 return false;
1516 }
1517 let Some(rule_index) = unpack_index(record.rule_index) else {
1518 return false;
1519 };
1520 let Some(rule_start) = self.rule_starts.get(rule_index) else {
1521 return false;
1522 };
1523 if self.states[rule_start.index()].flags & FLAG_LEFT_RECURSIVE_RULE == 0 {
1524 return false;
1525 }
1526 let Some(loop_end) = self.transitions_from(state).next_back() else {
1527 return false;
1528 };
1529 let loop_end = loop_end.target();
1530 if self.state_kind(loop_end) != Some(AtnStateKind::LoopEnd) {
1531 return false;
1532 }
1533 self.transitions_from(loop_end)
1534 .next()
1535 .and_then(|transition| self.state_kind(transition.target()))
1536 == Some(AtnStateKind::RuleStop)
1537 }
1538
1539 fn encode(&self, transition_ranges: &[(u32, u32)]) -> Result<Vec<u32>, ParserAtnError> {
1540 let layout = EncodedLayout::new(self)?;
1541 let mut words = vec![0; layout.total_len];
1542 self.encode_header(&mut words, layout)?;
1543 self.encode_states(&mut words, layout.states, transition_ranges);
1544 self.encode_transitions(&mut words, layout.transitions);
1545 self.encode_sets(&mut words, layout.sets);
1546 self.encode_intervals(&mut words, layout.intervals);
1547 self.encode_token_bits(&mut words, layout.token_bits);
1548 encode_ids(&mut words, layout.decisions, &self.decisions);
1549 encode_ids(&mut words, layout.rule_starts, &self.rule_starts);
1550 encode_ids(&mut words, layout.rule_stops, &self.rule_stops);
1551 Ok(words)
1552 }
1553
1554 fn encode_header(
1555 &self,
1556 words: &mut [u32],
1557 layout: EncodedLayout,
1558 ) -> Result<(), ParserAtnError> {
1559 words[HEADER_MAGIC] = PARSER_ATN_MAGIC;
1560 words[HEADER_VERSION] = PARSER_ATN_FORMAT_VERSION;
1561 words[HEADER_BYTE_ORDER] = PARSER_ATN_BYTE_ORDER;
1562 words[HEADER_SIZE] = compact_id("parser ATN header size", HEADER_WORDS)?;
1563 words[HEADER_MAX_TOKEN_TYPE] = pack_i32(self.max_token_type);
1564 words[HEADER_STATE_COUNT] = compact_id("parser ATN state count", self.states.len())?;
1565 words[HEADER_TRANSITION_COUNT] =
1566 compact_id("parser ATN transition count", self.transitions.len())?;
1567 words[HEADER_SET_COUNT] =
1568 compact_id("parser ATN interval-set count", self.interval_sets.len())?;
1569 words[HEADER_INTERVAL_COUNT] =
1570 compact_id("parser ATN interval count", self.interval_ranges.len())?;
1571 words[HEADER_DECISION_COUNT] =
1572 compact_id("parser ATN decision count", self.decisions.len())?;
1573 words[HEADER_RULE_COUNT] = compact_id("parser ATN rule count", self.rule_starts.len())?;
1574 write_section(words, HEADER_STATES_OFFSET, layout.states)?;
1575 write_section(words, HEADER_TRANSITIONS_OFFSET, layout.transitions)?;
1576 write_section(words, HEADER_SETS_OFFSET, layout.sets)?;
1577 write_section(words, HEADER_INTERVALS_OFFSET, layout.intervals)?;
1578 words[HEADER_TOKEN_BIT_WORD_COUNT] = compact_id(
1579 "parser token-set bit word count",
1580 self.token_bit_words.len(),
1581 )?;
1582 write_section(words, HEADER_TOKEN_BITS_OFFSET, layout.token_bits)?;
1583 write_section(words, HEADER_DECISIONS_OFFSET, layout.decisions)?;
1584 write_section(words, HEADER_RULE_STARTS_OFFSET, layout.rule_starts)?;
1585 write_section(words, HEADER_RULE_STOPS_OFFSET, layout.rule_stops)?;
1586 words[HEADER_TOTAL_LEN] = compact_id("packed parser ATN word", layout.total_len)?;
1587 Ok(())
1588 }
1589
1590 fn encode_states(&self, words: &mut [u32], section: Section, transition_ranges: &[(u32, u32)]) {
1591 for (index, (state, &(start, len))) in self.states.iter().zip(transition_ranges).enumerate()
1592 {
1593 let base = section.offset + index * STATE_WORDS;
1594 words[base] = state_kind_word(state.kind);
1595 words[base + 1] = state.rule_index;
1596 words[base + 2] = state.flags;
1597 words[base + 3] = start;
1598 words[base + 4] = len;
1599 words[base + 5] = state.end_state;
1600 words[base + 6] = state.loop_back_state;
1601 }
1602 }
1603
1604 fn encode_transitions(&self, words: &mut [u32], section: Section) {
1605 for (index, transition) in self.transitions.iter().enumerate() {
1606 let base = section.offset + index * TRANSITION_WORDS;
1607 words[base] = transition.kind as u32;
1608 words[base + 1] = transition.target.raw();
1609 words[base + 2] = transition.arg0;
1610 words[base + 3] = transition.arg1;
1611 words[base + 4] = transition.arg2;
1612 }
1613 }
1614
1615 fn encode_sets(&self, words: &mut [u32], section: Section) {
1616 for (index, set) in self.interval_sets.iter().enumerate() {
1617 let base = section.offset + index * SET_WORDS;
1618 words[base] = set.interval_start;
1619 words[base + 1] = set.interval_len;
1620 words[base + 2] = set.kind as u32;
1621 words[base + 3] = set.bit_start;
1622 words[base + 4] = set.bit_len;
1623 }
1624 }
1625
1626 fn encode_intervals(&self, words: &mut [u32], section: Section) {
1627 for (index, &(start, stop)) in self.interval_ranges.iter().enumerate() {
1628 let base = section.offset + index * 2;
1629 words[base] = pack_i32(start);
1630 words[base + 1] = pack_i32(stop);
1631 }
1632 }
1633
1634 fn encode_token_bits(&self, words: &mut [u32], section: Section) {
1635 for (index, &bits) in self.token_bit_words.iter().enumerate() {
1636 let base = section.offset + index * PACKED_U64_WORDS;
1637 words[base] = bits as u32;
1638 words[base + 1] = (bits >> u32::BITS) as u32;
1639 }
1640 }
1641}
1642
1643#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1645pub enum ParserTransitionSpec {
1646 Epsilon {
1647 target: usize,
1648 },
1649 Atom {
1650 target: usize,
1651 label: i32,
1652 },
1653 Range {
1654 target: usize,
1655 start: i32,
1656 stop: i32,
1657 },
1658 Set {
1659 target: usize,
1660 set: ParserIntervalSetId,
1661 },
1662 NotSet {
1663 target: usize,
1664 set: ParserIntervalSetId,
1665 },
1666 Wildcard {
1667 target: usize,
1668 },
1669 Rule {
1670 target: usize,
1671 rule_index: usize,
1672 follow_state: usize,
1673 precedence: i32,
1674 },
1675 Predicate {
1676 target: usize,
1677 rule_index: usize,
1678 pred_index: usize,
1679 context_dependent: bool,
1680 },
1681 Action {
1682 target: usize,
1683 rule_index: usize,
1684 action_index: Option<usize>,
1685 context_dependent: bool,
1686 },
1687 Precedence {
1688 target: usize,
1689 precedence: i32,
1690 },
1691}
1692
1693impl ParserTransitionSpec {
1694 pub const fn target(self) -> usize {
1695 match self {
1696 Self::Epsilon { target }
1697 | Self::Atom { target, .. }
1698 | Self::Range { target, .. }
1699 | Self::Set { target, .. }
1700 | Self::NotSet { target, .. }
1701 | Self::Wildcard { target }
1702 | Self::Rule { target, .. }
1703 | Self::Predicate { target, .. }
1704 | Self::Action { target, .. }
1705 | Self::Precedence { target, .. } => target,
1706 }
1707 }
1708}
1709
1710#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1711struct ParserAtnLayout {
1712 format_version: u32,
1713 max_token_type: i32,
1714 state_count: usize,
1715 transition_count: usize,
1716 set_words: usize,
1717 states: Section,
1718 transitions: Section,
1719 sets: Section,
1720 intervals: Section,
1721 token_bits: Section,
1722 decisions: Section,
1723 rule_starts: Section,
1724 rule_stops: Section,
1725}
1726
1727#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1728struct Section {
1729 offset: usize,
1730 len: usize,
1731}
1732
1733#[derive(Clone, Copy, Debug)]
1734struct EncodedLayout {
1735 states: Section,
1736 transitions: Section,
1737 sets: Section,
1738 intervals: Section,
1739 token_bits: Section,
1740 decisions: Section,
1741 rule_starts: Section,
1742 rule_stops: Section,
1743 total_len: usize,
1744}
1745
1746impl EncodedLayout {
1747 fn new(builder: &ParserAtnBuilder) -> Result<Self, ParserAtnError> {
1748 let mut cursor = HEADER_WORDS;
1749 let states = next_section(&mut cursor, builder.states.len(), STATE_WORDS, "states")?;
1750 let transitions = next_section(
1751 &mut cursor,
1752 builder.transitions.len(),
1753 TRANSITION_WORDS,
1754 "transitions",
1755 )?;
1756 let sets = next_section(
1757 &mut cursor,
1758 builder.interval_sets.len(),
1759 SET_WORDS,
1760 "interval sets",
1761 )?;
1762 let intervals = next_section(
1763 &mut cursor,
1764 builder.interval_ranges.len(),
1765 2,
1766 "interval ranges",
1767 )?;
1768 let token_bits = next_section(
1769 &mut cursor,
1770 builder.token_bit_words.len(),
1771 PACKED_U64_WORDS,
1772 "token-set bits",
1773 )?;
1774 let decisions = next_section(&mut cursor, builder.decisions.len(), 1, "decisions")?;
1775 let rule_starts = next_section(&mut cursor, builder.rule_starts.len(), 1, "rule starts")?;
1776 let rule_stops = next_section(&mut cursor, builder.rule_stops.len(), 1, "rule stops")?;
1777 compact_id("packed parser ATN word", cursor)?;
1778 Ok(Self {
1779 states,
1780 transitions,
1781 sets,
1782 intervals,
1783 token_bits,
1784 decisions,
1785 rule_starts,
1786 rule_stops,
1787 total_len: cursor,
1788 })
1789 }
1790}
1791
1792#[derive(Clone, Debug)]
1793struct StateBuild {
1794 kind: AtnStateKind,
1795 rule_index: u32,
1796 flags: u32,
1797 end_state: u32,
1798 loop_back_state: u32,
1799}
1800
1801#[derive(Clone, Debug)]
1802struct TokenSetBuild {
1803 interval_start: u32,
1804 interval_len: u32,
1805 kind: ParserTokenSetKind,
1806 bit_start: u32,
1807 bit_len: u32,
1808}
1809
1810#[derive(Debug)]
1811struct PreparedTokenSet {
1812 kind: ParserTokenSetKind,
1813 words: Vec<u64>,
1814}
1815
1816#[derive(Clone, Debug)]
1817struct TransitionBuild {
1818 source: AtnStateId,
1819 kind: ParserTransitionKind,
1820 target: AtnStateId,
1821 arg0: u32,
1822 arg1: u32,
1823 arg2: u32,
1824}
1825
1826impl TransitionBuild {
1827 const fn spec(&self) -> ParserTransitionSpec {
1828 let target = self.target.index();
1829 match self.kind {
1830 ParserTransitionKind::Epsilon => ParserTransitionSpec::Epsilon { target },
1831 ParserTransitionKind::Atom => ParserTransitionSpec::Atom {
1832 target,
1833 label: unpack_i32(self.arg0),
1834 },
1835 ParserTransitionKind::Range => ParserTransitionSpec::Range {
1836 target,
1837 start: unpack_i32(self.arg0),
1838 stop: unpack_i32(self.arg1),
1839 },
1840 ParserTransitionKind::Set => ParserTransitionSpec::Set {
1841 target,
1842 set: ParserIntervalSetId(self.arg0),
1843 },
1844 ParserTransitionKind::NotSet => ParserTransitionSpec::NotSet {
1845 target,
1846 set: ParserIntervalSetId(self.arg0),
1847 },
1848 ParserTransitionKind::Wildcard => ParserTransitionSpec::Wildcard { target },
1849 ParserTransitionKind::Rule => ParserTransitionSpec::Rule {
1850 target,
1851 rule_index: self.arg0 as usize,
1852 follow_state: self.arg1 as usize,
1853 precedence: unpack_i32(self.arg2),
1854 },
1855 ParserTransitionKind::Predicate => ParserTransitionSpec::Predicate {
1856 target,
1857 rule_index: self.arg0 as usize,
1858 pred_index: self.arg1 as usize,
1859 context_dependent: self.arg2 != 0,
1860 },
1861 ParserTransitionKind::Action => ParserTransitionSpec::Action {
1862 target,
1863 rule_index: self.arg0 as usize,
1864 action_index: unpack_index(self.arg1),
1865 context_dependent: self.arg2 != 0,
1866 },
1867 ParserTransitionKind::Precedence => ParserTransitionSpec::Precedence {
1868 target,
1869 precedence: unpack_i32(self.arg0),
1870 },
1871 }
1872 }
1873}
1874
1875impl ParserTransitionKind {
1876 const fn is_epsilon(self) -> bool {
1877 matches!(
1878 self,
1879 Self::Epsilon | Self::Rule | Self::Predicate | Self::Action | Self::Precedence
1880 )
1881 }
1882
1883 const fn is_consuming(self) -> bool {
1884 matches!(
1885 self,
1886 Self::Atom | Self::Range | Self::Set | Self::NotSet | Self::Wildcard
1887 )
1888 }
1889
1890 const fn is_semantic(self) -> bool {
1891 matches!(self, Self::Predicate | Self::Action | Self::Precedence)
1892 }
1893}
1894
1895fn validate_packed(words: &[u32]) -> Result<ParserAtnLayout, ParserAtnError> {
1896 validate_header(words)?;
1897 let layout = read_layout(words)?;
1898 validate_sections(words, layout)?;
1899 validate_states(words, layout)?;
1900 validate_transitions(words, layout)?;
1901 validate_state_flags(words, layout)?;
1902 validate_sets(words, layout)?;
1903 validate_side_tables(words, layout)?;
1904 Ok(layout)
1905}
1906
1907fn validate_header(words: &[u32]) -> Result<(), ParserAtnError> {
1908 if words.len() < LEGACY_HEADER_WORDS {
1909 return Err(ParserAtnError::InvalidData(format!(
1910 "header has {} words; expected at least {LEGACY_HEADER_WORDS}",
1911 words.len()
1912 )));
1913 }
1914 if words[HEADER_MAGIC] != PARSER_ATN_MAGIC {
1915 return Err(ParserAtnError::InvalidData(format!(
1916 "magic 0x{:08x}; expected 0x{PARSER_ATN_MAGIC:08x}",
1917 words[HEADER_MAGIC]
1918 )));
1919 }
1920 let version = words[HEADER_VERSION];
1921 if !(PARSER_ATN_MIN_FORMAT_VERSION..=PARSER_ATN_MAX_FORMAT_VERSION).contains(&version) {
1922 return Err(ParserAtnError::UnsupportedVersion {
1923 found: version,
1924 minimum: PARSER_ATN_MIN_FORMAT_VERSION,
1925 maximum: PARSER_ATN_MAX_FORMAT_VERSION,
1926 });
1927 }
1928 let header_words = if version == 1 {
1929 LEGACY_HEADER_WORDS
1930 } else {
1931 HEADER_WORDS
1932 };
1933 if words.len() < header_words {
1934 return Err(ParserAtnError::InvalidData(format!(
1935 "format {version} header has {} words; expected at least {header_words}",
1936 words.len()
1937 )));
1938 }
1939 if words[HEADER_BYTE_ORDER] != PARSER_ATN_BYTE_ORDER {
1940 return Err(ParserAtnError::InvalidData(format!(
1941 "byte-order marker 0x{:08x}; expected 0x{PARSER_ATN_BYTE_ORDER:08x}",
1942 words[HEADER_BYTE_ORDER]
1943 )));
1944 }
1945 if words[HEADER_SIZE] as usize != header_words {
1946 return Err(ParserAtnError::InvalidData(format!(
1947 "format {version} header length {}; expected {header_words}",
1948 words[HEADER_SIZE],
1949 )));
1950 }
1951 if words[HEADER_TOTAL_LEN] as usize != words.len() {
1952 return Err(ParserAtnError::InvalidData(format!(
1953 "declared total length {} does not match {} words",
1954 words[HEADER_TOTAL_LEN],
1955 words.len()
1956 )));
1957 }
1958 Ok(())
1959}
1960
1961fn read_layout(words: &[u32]) -> Result<ParserAtnLayout, ParserAtnError> {
1962 let format_version = words[HEADER_VERSION];
1963 let set_words = if format_version == 1 {
1964 LEGACY_SET_WORDS
1965 } else {
1966 SET_WORDS
1967 };
1968 let states = read_section(words, HEADER_STATES_OFFSET)?;
1969 let transitions = read_section(words, HEADER_TRANSITIONS_OFFSET)?;
1970 let sets = read_section(words, HEADER_SETS_OFFSET)?;
1971 let intervals = read_section(words, HEADER_INTERVALS_OFFSET)?;
1972 let token_bits = if format_version == 1 {
1973 Section {
1974 offset: intervals.offset + intervals.len,
1975 len: 0,
1976 }
1977 } else {
1978 read_section(words, HEADER_TOKEN_BITS_OFFSET)?
1979 };
1980 let decisions = read_section(words, HEADER_DECISIONS_OFFSET)?;
1981 let rule_starts = read_section(words, HEADER_RULE_STARTS_OFFSET)?;
1982 let rule_stops = read_section(words, HEADER_RULE_STOPS_OFFSET)?;
1983 let state_count = words[HEADER_STATE_COUNT] as usize;
1984 let transition_count = words[HEADER_TRANSITION_COUNT] as usize;
1985 expect_section_len("states", states, state_count, STATE_WORDS)?;
1986 expect_section_len(
1987 "transitions",
1988 transitions,
1989 transition_count,
1990 TRANSITION_WORDS,
1991 )?;
1992 expect_section_len(
1993 "interval sets",
1994 sets,
1995 words[HEADER_SET_COUNT] as usize,
1996 set_words,
1997 )?;
1998 expect_section_len(
1999 "intervals",
2000 intervals,
2001 words[HEADER_INTERVAL_COUNT] as usize,
2002 2,
2003 )?;
2004 if format_version != 1 {
2005 expect_section_len(
2006 "token-set bits",
2007 token_bits,
2008 words[HEADER_TOKEN_BIT_WORD_COUNT] as usize,
2009 PACKED_U64_WORDS,
2010 )?;
2011 }
2012 expect_section_len(
2013 "decisions",
2014 decisions,
2015 words[HEADER_DECISION_COUNT] as usize,
2016 1,
2017 )?;
2018 expect_section_len(
2019 "rule starts",
2020 rule_starts,
2021 words[HEADER_RULE_COUNT] as usize,
2022 1,
2023 )?;
2024 expect_section_len(
2025 "rule stops",
2026 rule_stops,
2027 words[HEADER_RULE_COUNT] as usize,
2028 1,
2029 )?;
2030 Ok(ParserAtnLayout {
2031 format_version,
2032 max_token_type: unpack_i32(words[HEADER_MAX_TOKEN_TYPE]),
2033 state_count,
2034 transition_count,
2035 set_words,
2036 states,
2037 transitions,
2038 sets,
2039 intervals,
2040 token_bits,
2041 decisions,
2042 rule_starts,
2043 rule_stops,
2044 })
2045}
2046
2047fn validate_sections(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2048 let sections = [
2049 ("states", layout.states),
2050 ("transitions", layout.transitions),
2051 ("sets", layout.sets),
2052 ("intervals", layout.intervals),
2053 ("token-set bits", layout.token_bits),
2054 ("decisions", layout.decisions),
2055 ("rule starts", layout.rule_starts),
2056 ("rule stops", layout.rule_stops),
2057 ];
2058 let mut expected_offset = if layout.format_version == 1 {
2059 LEGACY_HEADER_WORDS
2060 } else {
2061 HEADER_WORDS
2062 };
2063 for (name, section) in sections {
2064 if section.offset != expected_offset {
2065 return Err(ParserAtnError::InvalidData(format!(
2066 "{name} section starts at {}, expected {expected_offset}",
2067 section.offset
2068 )));
2069 }
2070 expected_offset = section_end(section, words.len(), name)?;
2071 }
2072 if expected_offset != words.len() {
2073 return Err(ParserAtnError::InvalidData(format!(
2074 "sections end at {expected_offset}, stream ends at {}",
2075 words.len()
2076 )));
2077 }
2078 Ok(())
2079}
2080
2081fn validate_states(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2082 let mut transition_cursor = 0;
2083 for state in 0..layout.state_count {
2084 let base = layout.states.offset + state * STATE_WORDS;
2085 decode_state_kind(words[base])?;
2086 let flags = words[base + 2];
2087 if flags & !STATE_FLAGS != 0 {
2088 return Err(ParserAtnError::InvalidData(format!(
2089 "state {state} has unknown flags 0x{:x}",
2090 flags & !STATE_FLAGS
2091 )));
2092 }
2093 validate_optional_index(words[base + 1], layout.rule_starts.len, "state rule index")?;
2094 let transition_start = words[base + 3] as usize;
2095 if transition_start != transition_cursor {
2096 return Err(ParserAtnError::InvalidData(format!(
2097 "state {state} transition range starts at {transition_start}, expected {transition_cursor}"
2098 )));
2099 }
2100 validate_range(
2101 words[base + 3],
2102 words[base + 4],
2103 layout.transition_count,
2104 "state transition",
2105 )?;
2106 transition_cursor += words[base + 4] as usize;
2107 validate_optional_index(words[base + 5], layout.state_count, "block end state")?;
2108 validate_optional_index(words[base + 6], layout.state_count, "loop back state")?;
2109 }
2110 if transition_cursor != layout.transition_count {
2111 return Err(ParserAtnError::InvalidData(format!(
2112 "state transition ranges cover {transition_cursor} transitions; expected {}",
2113 layout.transition_count
2114 )));
2115 }
2116 Ok(())
2117}
2118
2119fn validate_transitions(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2120 for transition in 0..layout.transition_count {
2121 let base = layout.transitions.offset + transition * TRANSITION_WORDS;
2122 let kind = decode_transition_kind(words[base])?;
2123 validate_index(words[base + 1], layout.state_count, "transition target")?;
2124 match kind {
2125 ParserTransitionKind::Range => {
2126 let start = unpack_i32(words[base + 2]);
2127 let stop = unpack_i32(words[base + 3]);
2128 if start > stop {
2129 return Err(ParserAtnError::InvalidData(format!(
2130 "transition {transition} range starts at {start} after stop {stop}"
2131 )));
2132 }
2133 }
2134 ParserTransitionKind::Set | ParserTransitionKind::NotSet => {
2135 validate_index(
2136 words[base + 2],
2137 layout.sets.len / layout.set_words,
2138 "interval set",
2139 )?;
2140 }
2141 ParserTransitionKind::Rule => {
2142 validate_index(words[base + 2], layout.rule_starts.len, "rule index")?;
2143 validate_index(words[base + 3], layout.state_count, "rule follow state")?;
2144 }
2145 ParserTransitionKind::Predicate => {
2146 validate_index(words[base + 2], layout.rule_starts.len, "predicate rule")?;
2147 validate_bool(words[base + 4], "predicate context-dependent flag")?;
2148 }
2149 ParserTransitionKind::Action => {
2150 validate_index(words[base + 2], layout.rule_starts.len, "action rule")?;
2151 validate_bool(words[base + 4], "action context-dependent flag")?;
2152 }
2153 ParserTransitionKind::Epsilon
2154 | ParserTransitionKind::Atom
2155 | ParserTransitionKind::Wildcard
2156 | ParserTransitionKind::Precedence => {}
2157 }
2158 }
2159 Ok(())
2160}
2161
2162fn validate_state_flags(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2163 for state in 0..layout.state_count {
2164 let base = layout.states.offset + state * STATE_WORDS;
2165 let kind = decode_state_kind(words[base])?;
2166 let start = words[base + 3] as usize;
2167 let len = words[base + 4] as usize;
2168 let mut all_epsilon = len != 0;
2169 let mut has_consuming = false;
2170 let mut has_semantic = false;
2171 for transition in start..start + len {
2172 let base = layout.transitions.offset + transition * TRANSITION_WORDS;
2173 let kind = decode_transition_kind(words[base])
2174 .expect("packed parser transition kind was already validated");
2175 all_epsilon &= kind.is_epsilon();
2176 has_consuming |= kind.is_consuming();
2177 has_semantic |= kind.is_semantic();
2178 }
2179 let mut expected = u32::from(kind == AtnStateKind::RuleStop) * FLAG_RULE_STOP;
2180 expected |= u32::from(all_epsilon) * FLAG_EPSILON_ONLY;
2181 expected |= u32::from(has_consuming) * FLAG_HAS_CONSUMING;
2182 expected |= u32::from(has_semantic) * FLAG_HAS_SEMANTIC;
2183 let derived = words[base + 2]
2184 & (FLAG_EPSILON_ONLY | FLAG_RULE_STOP | FLAG_HAS_CONSUMING | FLAG_HAS_SEMANTIC);
2185 if derived != expected {
2186 return Err(ParserAtnError::InvalidData(format!(
2187 "state {state} has inconsistent precomputed flags 0x{derived:x}; expected 0x{expected:x}"
2188 )));
2189 }
2190 }
2191 Ok(())
2192}
2193
2194fn validate_sets(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2195 let set_count = layout.sets.len / layout.set_words;
2196 let mut bit_cursor = 0;
2197 for set in 0..set_count {
2198 let base = layout.sets.offset + set * layout.set_words;
2199 validate_range(
2200 words[base],
2201 words[base + 1],
2202 layout.intervals.len / 2,
2203 "interval set",
2204 )?;
2205 let start = words[base] as usize;
2206 let len = words[base + 1] as usize;
2207 let mut previous_stop: Option<i32> = None;
2208 for interval in start..start + len {
2209 let interval_base = layout.intervals.offset + interval * 2;
2210 let range_start = unpack_i32(words[interval_base]);
2211 let range_stop = unpack_i32(words[interval_base + 1]);
2212 if range_start > range_stop {
2213 return Err(ParserAtnError::InvalidData(format!(
2214 "interval {interval} starts at {range_start} after stop {range_stop}"
2215 )));
2216 }
2217 if previous_stop.is_some_and(|stop| range_start <= stop.saturating_add(1)) {
2218 return Err(ParserAtnError::InvalidData(format!(
2219 "interval set {set} is not sorted and coalesced"
2220 )));
2221 }
2222 previous_stop = Some(range_stop);
2223 }
2224 if layout.format_version == 1 {
2225 continue;
2226 }
2227 let kind = decode_token_set_kind(words[base + 2])?;
2228 let bit_start = words[base + 3];
2229 let bit_len = words[base + 4];
2230 if bit_start as usize != bit_cursor {
2231 return Err(ParserAtnError::InvalidData(format!(
2232 "parser token set {set} bit range starts at {bit_start}, expected {bit_cursor}"
2233 )));
2234 }
2235 validate_range(
2236 bit_start,
2237 bit_len,
2238 layout.token_bits.len / PACKED_U64_WORDS,
2239 "parser token-set bits",
2240 )?;
2241 let (expected_kind, expected_bit_len) =
2242 token_set_shape((start..start + len).map(|interval| {
2243 let interval_base = layout.intervals.offset + interval * 2;
2244 (
2245 unpack_i32(words[interval_base]),
2246 unpack_i32(words[interval_base + 1]),
2247 )
2248 }));
2249 if kind != expected_kind || bit_len as usize != expected_bit_len {
2250 return Err(ParserAtnError::InvalidData(format!(
2251 "parser token set {set} uses {kind:?} with {bit_len} words; \
2252 expected {expected_kind:?} with {expected_bit_len} words"
2253 )));
2254 }
2255 for bit_word in 0..expected_bit_len {
2256 let expected = expected_token_set_word(
2257 (start..start + len).map(|interval| {
2258 let interval_base = layout.intervals.offset + interval * 2;
2259 (
2260 unpack_i32(words[interval_base]),
2261 unpack_i32(words[interval_base + 1]),
2262 )
2263 }),
2264 bit_word,
2265 );
2266 let actual = packed_u64(words, layout.token_bits, bit_cursor + bit_word);
2267 if actual != expected {
2268 return Err(ParserAtnError::InvalidData(format!(
2269 "parser token set {set} bit word {bit_word} is 0x{actual:016x}; \
2270 expected 0x{expected:016x}"
2271 )));
2272 }
2273 }
2274 bit_cursor += expected_bit_len;
2275 }
2276 if layout.format_version != 1 && bit_cursor != layout.token_bits.len / PACKED_U64_WORDS {
2277 return Err(ParserAtnError::InvalidData(format!(
2278 "parser token sets cover {bit_cursor} bit words; expected {}",
2279 layout.token_bits.len / PACKED_U64_WORDS
2280 )));
2281 }
2282 Ok(())
2283}
2284
2285fn validate_side_tables(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2286 for (name, section) in [
2287 ("decision state", layout.decisions),
2288 ("rule start state", layout.rule_starts),
2289 ("rule stop state", layout.rule_stops),
2290 ] {
2291 for &state in &words[section.offset..section.offset + section.len] {
2292 validate_index(state, layout.state_count, name)?;
2293 }
2294 }
2295 Ok(())
2296}
2297
2298#[inline(always)]
2299fn decode_state_kind(value: u32) -> Result<AtnStateKind, ParserAtnError> {
2300 let kind = match value {
2301 0 => AtnStateKind::Invalid,
2302 1 => AtnStateKind::Basic,
2303 2 => AtnStateKind::RuleStart,
2304 3 => AtnStateKind::BlockStart,
2305 4 => AtnStateKind::PlusBlockStart,
2306 5 => AtnStateKind::StarBlockStart,
2307 6 => AtnStateKind::TokenStart,
2308 7 => AtnStateKind::RuleStop,
2309 8 => AtnStateKind::BlockEnd,
2310 9 => AtnStateKind::StarLoopBack,
2311 10 => AtnStateKind::StarLoopEntry,
2312 11 => AtnStateKind::PlusLoopBack,
2313 12 => AtnStateKind::LoopEnd,
2314 other => {
2315 return Err(ParserAtnError::InvalidData(format!(
2316 "parser ATN state kind {other}"
2317 )));
2318 }
2319 };
2320 Ok(kind)
2321}
2322
2323#[inline(always)]
2324fn decode_transition_kind(value: u32) -> Result<ParserTransitionKind, ParserAtnError> {
2325 let kind = match value {
2326 1 => ParserTransitionKind::Epsilon,
2327 2 => ParserTransitionKind::Range,
2328 3 => ParserTransitionKind::Rule,
2329 4 => ParserTransitionKind::Predicate,
2330 5 => ParserTransitionKind::Atom,
2331 6 => ParserTransitionKind::Action,
2332 7 => ParserTransitionKind::Set,
2333 8 => ParserTransitionKind::NotSet,
2334 9 => ParserTransitionKind::Wildcard,
2335 10 => ParserTransitionKind::Precedence,
2336 other => {
2337 return Err(ParserAtnError::InvalidData(format!(
2338 "parser ATN transition kind {other}"
2339 )));
2340 }
2341 };
2342 Ok(kind)
2343}
2344
2345fn decode_token_set_kind(value: u32) -> Result<ParserTokenSetKind, ParserAtnError> {
2346 match value {
2347 0 => Ok(ParserTokenSetKind::Intervals),
2348 1 => Ok(ParserTokenSetKind::Inline128),
2349 2 => Ok(ParserTokenSetKind::Dense),
2350 other => Err(ParserAtnError::InvalidData(format!(
2351 "parser token-set kind {other}"
2352 ))),
2353 }
2354}
2355
2356const fn state_kind_word(kind: AtnStateKind) -> u32 {
2357 match kind {
2358 AtnStateKind::Invalid => 0,
2359 AtnStateKind::Basic => 1,
2360 AtnStateKind::RuleStart => 2,
2361 AtnStateKind::BlockStart => 3,
2362 AtnStateKind::PlusBlockStart => 4,
2363 AtnStateKind::StarBlockStart => 5,
2364 AtnStateKind::TokenStart => 6,
2365 AtnStateKind::RuleStop => 7,
2366 AtnStateKind::BlockEnd => 8,
2367 AtnStateKind::StarLoopBack => 9,
2368 AtnStateKind::StarLoopEntry => 10,
2369 AtnStateKind::PlusLoopBack => 11,
2370 AtnStateKind::LoopEnd => 12,
2371 }
2372}
2373
2374fn compact_id(field: &'static str, value: usize) -> Result<u32, ParserAtnError> {
2375 u32::try_from(value).map_err(|_| ParserAtnError::Overflow { field, value })
2376}
2377
2378fn pack_optional_index(field: &'static str, value: Option<usize>) -> Result<u32, ParserAtnError> {
2379 match value {
2380 Some(value) => {
2381 let compact = compact_id(field, value)?;
2382 if compact == NO_INDEX {
2383 return Err(ParserAtnError::Overflow { field, value });
2384 }
2385 Ok(compact)
2386 }
2387 None => Ok(NO_INDEX),
2388 }
2389}
2390
2391const fn unpack_index(value: u32) -> Option<usize> {
2392 if value == NO_INDEX {
2393 None
2394 } else {
2395 Some(value as usize)
2396 }
2397}
2398
2399const fn pack_i32(value: i32) -> u32 {
2400 u32::from_le_bytes(value.to_le_bytes())
2401}
2402
2403const fn unpack_i32(value: u32) -> i32 {
2404 i32::from_le_bytes(value.to_le_bytes())
2405}
2406
2407fn normalize_ranges(ranges: impl IntoIterator<Item = (i32, i32)>) -> Vec<(i32, i32)> {
2408 let mut ranges = ranges
2409 .into_iter()
2410 .map(|(start, stop)| {
2411 if start <= stop {
2412 (start, stop)
2413 } else {
2414 (stop, start)
2415 }
2416 })
2417 .collect::<Vec<_>>();
2418 ranges.sort_unstable();
2419 let mut normalized: Vec<(i32, i32)> = Vec::with_capacity(ranges.len());
2420 for (start, stop) in ranges {
2421 if let Some((_, previous_stop)) = normalized.last_mut()
2422 && start <= previous_stop.saturating_add(1)
2423 {
2424 *previous_stop = (*previous_stop).max(stop);
2425 continue;
2426 }
2427 normalized.push((start, stop));
2428 }
2429 normalized
2430}
2431
2432fn token_set_shape(ranges: impl IntoIterator<Item = (i32, i32)>) -> (ParserTokenSetKind, usize) {
2440 let mut compatible = true;
2441 let mut max_slot = 0;
2442 let mut represented = 0_u64;
2443 let mut range_count = 0_usize;
2444 for (start, stop) in ranges {
2445 range_count += 1;
2446 represented = represented.saturating_add(
2447 u64::try_from(i64::from(stop) - i64::from(start) + 1).unwrap_or(u64::MAX),
2448 );
2449 if start == TOKEN_EOF && stop == TOKEN_EOF {
2450 continue;
2451 }
2452 if start < 1 {
2453 compatible = false;
2454 continue;
2455 }
2456 let stop = usize::try_from(stop).expect("positive i32 token type fits usize");
2457 max_slot = max_slot.max(stop);
2458 }
2459 if !compatible {
2460 return (ParserTokenSetKind::Intervals, 0);
2461 }
2462 if max_slot <= INLINE_TOKEN_SET_MAX_SLOT {
2463 return (ParserTokenSetKind::Inline128, INLINE_TOKEN_SET_WORDS);
2464 }
2465 let word_len = max_slot / u64::BITS as usize + 1;
2466 let Some(dense_bytes) = word_len.checked_mul(size_of::<u64>()) else {
2467 return (ParserTokenSetKind::Intervals, 0);
2468 };
2469 let interval_bytes = range_count.saturating_mul(size_of::<(i32, i32)>());
2470 let dense_enough = represented.saturating_mul(DENSE_TOKEN_SET_MIN_DENSITY_DENOMINATOR)
2471 >= u64::try_from(max_slot)
2472 .unwrap_or(u64::MAX)
2473 .saturating_add(1);
2474 let cost_effective = dense_bytes <= interval_bytes
2475 || (dense_bytes <= interval_bytes.saturating_mul(DENSE_TOKEN_SET_COST_MULTIPLIER)
2476 && dense_enough);
2477 if word_len <= MAX_DENSE_TOKEN_SET_WORDS && cost_effective {
2478 (ParserTokenSetKind::Dense, word_len)
2479 } else {
2480 (ParserTokenSetKind::Intervals, 0)
2481 }
2482}
2483
2484fn prepare_token_set(ranges: &[(i32, i32)]) -> PreparedTokenSet {
2485 let (kind, word_len) = token_set_shape(ranges.iter().copied());
2486 let mut words = vec![0; word_len];
2487 for &(start, stop) in ranges {
2488 insert_token_set_range(&mut words, start, stop);
2489 }
2490 PreparedTokenSet { kind, words }
2491}
2492
2493fn insert_token_set_range(words: &mut [u64], start: i32, stop: i32) {
2494 if words.is_empty() {
2495 return;
2496 }
2497 if start == TOKEN_EOF && stop == TOKEN_EOF {
2498 words[0] |= 1;
2499 return;
2500 }
2501 debug_assert!(start >= 1 && stop >= start);
2502 let start = usize::try_from(start).expect("positive i32 token type fits usize");
2503 let stop = usize::try_from(stop).expect("positive i32 token type fits usize");
2504 let start_word = start / u64::BITS as usize;
2505 let stop_word = stop / u64::BITS as usize;
2506 if start_word == stop_word {
2507 words[start_word] |= token_word_mask(start % u64::BITS as usize, stop % u64::BITS as usize);
2508 return;
2509 }
2510 words[start_word] |= !0_u64 << (start % u64::BITS as usize);
2511 words[(start_word + 1)..stop_word].fill(!0);
2512 words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop % u64::BITS as usize);
2513}
2514
2515fn expected_token_set_word(ranges: impl IntoIterator<Item = (i32, i32)>, word_index: usize) -> u64 {
2516 let word_start = word_index * u64::BITS as usize;
2517 let word_stop = word_start + u64::BITS as usize - 1;
2518 let mut expected = 0;
2519 for (start, stop) in ranges {
2520 if start == TOKEN_EOF && stop == TOKEN_EOF {
2521 if word_index == 0 {
2522 expected |= 1;
2523 }
2524 continue;
2525 }
2526 let start = usize::try_from(start).expect("positive i32 token type fits usize");
2527 let stop = usize::try_from(stop).expect("positive i32 token type fits usize");
2528 if stop < word_start || start > word_stop {
2529 continue;
2530 }
2531 expected |= token_word_mask(
2532 start.max(word_start) - word_start,
2533 stop.min(word_stop) - word_start,
2534 );
2535 }
2536 expected
2537}
2538
2539const fn token_word_mask(start: usize, stop: usize) -> u64 {
2540 (!0_u64 << start) & (!0_u64 >> (u64::BITS as usize - 1 - stop))
2541}
2542
2543fn packed_u64(words: &[u32], section: Section, index: usize) -> u64 {
2544 let offset = section.offset + index * PACKED_U64_WORDS;
2545 u64::from(words[offset]) | (u64::from(words[offset + 1]) << u32::BITS)
2546}
2547
2548fn token_set_slot(value: i32) -> Option<usize> {
2549 if value == TOKEN_EOF {
2550 Some(0)
2551 } else if value > 0 {
2552 usize::try_from(value).ok()
2553 } else {
2554 None
2555 }
2556}
2557
2558fn next_section(
2559 cursor: &mut usize,
2560 count: usize,
2561 width: usize,
2562 name: &str,
2563) -> Result<Section, ParserAtnError> {
2564 let len = count.checked_mul(width).ok_or_else(|| {
2565 ParserAtnError::InvalidData(format!("{name} section length overflows usize"))
2566 })?;
2567 let section = Section {
2568 offset: *cursor,
2569 len,
2570 };
2571 *cursor = cursor.checked_add(len).ok_or_else(|| {
2572 ParserAtnError::InvalidData(format!("{name} section end overflows usize"))
2573 })?;
2574 Ok(section)
2575}
2576
2577fn write_section(
2578 words: &mut [u32],
2579 header_offset: usize,
2580 section: Section,
2581) -> Result<(), ParserAtnError> {
2582 words[header_offset] = compact_id("parser ATN section offset", section.offset)?;
2583 words[header_offset + 1] = compact_id("parser ATN section length", section.len)?;
2584 Ok(())
2585}
2586
2587fn encode_ids(words: &mut [u32], section: Section, ids: &[AtnStateId]) {
2588 for (target, id) in words[section.offset..section.offset + section.len]
2589 .iter_mut()
2590 .zip(ids)
2591 {
2592 *target = id.raw();
2593 }
2594}
2595
2596fn read_section(words: &[u32], header_offset: usize) -> Result<Section, ParserAtnError> {
2597 let offset = words[header_offset] as usize;
2598 let len = words[header_offset + 1] as usize;
2599 section_end(Section { offset, len }, words.len(), "declared")?;
2600 Ok(Section { offset, len })
2601}
2602
2603fn section_end(section: Section, total: usize, name: &str) -> Result<usize, ParserAtnError> {
2604 let end = section.offset.checked_add(section.len).ok_or_else(|| {
2605 ParserAtnError::InvalidData(format!("{name} section offset arithmetic overflow"))
2606 })?;
2607 if end > total {
2608 return Err(ParserAtnError::InvalidData(format!(
2609 "{name} section {0}..{end} exceeds stream length {total}",
2610 section.offset
2611 )));
2612 }
2613 Ok(end)
2614}
2615
2616fn expect_section_len(
2617 name: &str,
2618 section: Section,
2619 count: usize,
2620 width: usize,
2621) -> Result<(), ParserAtnError> {
2622 let expected = count.checked_mul(width).ok_or_else(|| {
2623 ParserAtnError::InvalidData(format!("{name} count/width multiplication overflow"))
2624 })?;
2625 if section.len != expected {
2626 return Err(ParserAtnError::InvalidData(format!(
2627 "{name} section has {} words; expected {expected}",
2628 section.len
2629 )));
2630 }
2631 Ok(())
2632}
2633
2634fn validate_index(value: u32, count: usize, name: &str) -> Result<(), ParserAtnError> {
2635 if value as usize >= count {
2636 return Err(ParserAtnError::InvalidData(format!(
2637 "{name} {value} outside 0..{count}"
2638 )));
2639 }
2640 Ok(())
2641}
2642
2643fn validate_optional_index(value: u32, count: usize, name: &str) -> Result<(), ParserAtnError> {
2644 if value == NO_INDEX {
2645 return Ok(());
2646 }
2647 validate_index(value, count, name)
2648}
2649
2650fn validate_bool(value: u32, name: &str) -> Result<(), ParserAtnError> {
2651 if value > 1 {
2652 return Err(ParserAtnError::InvalidData(format!(
2653 "{name} is {value}; expected 0 or 1"
2654 )));
2655 }
2656 Ok(())
2657}
2658
2659fn validate_range(start: u32, len: u32, count: usize, name: &str) -> Result<(), ParserAtnError> {
2660 let start = start as usize;
2661 let len = len as usize;
2662 let end = start
2663 .checked_add(len)
2664 .ok_or_else(|| ParserAtnError::InvalidData(format!("{name} range arithmetic overflow")))?;
2665 if end > count {
2666 return Err(ParserAtnError::InvalidData(format!(
2667 "{name} range {start}..{end} exceeds count {count}"
2668 )));
2669 }
2670 Ok(())
2671}
2672
2673#[cfg(test)]
2674mod tests {
2675 use super::*;
2676
2677 fn sample_atn() -> ParserAtn {
2678 let mut builder = ParserAtnBuilder::new(9);
2679 builder
2680 .add_state(AtnStateKind::RuleStart, Some(0))
2681 .expect("rule start");
2682 builder
2683 .add_state(AtnStateKind::RuleStop, Some(0))
2684 .expect("rule stop");
2685 builder
2686 .set_rule_to_start_state(vec![0])
2687 .expect("rule starts");
2688 builder.set_rule_to_stop_state(vec![1]).expect("rule stops");
2689 builder.add_decision_state(0).expect("decision");
2690 builder
2691 .add_transition(
2692 0,
2693 ParserTransitionSpec::Atom {
2694 target: 1,
2695 label: 7,
2696 },
2697 )
2698 .expect("transition");
2699 builder.finish().expect("packed parser ATN")
2700 }
2701
2702 fn token_set_atn(max_token_type: i32, ranges: &[(i32, i32)]) -> ParserAtn {
2703 let mut builder = ParserAtnBuilder::new(max_token_type);
2704 builder
2705 .add_interval_set(ranges.iter().copied())
2706 .expect("token set");
2707 builder.finish().expect("packed parser ATN")
2708 }
2709
2710 fn legacy_words(atn: &ParserAtn) -> Vec<u32> {
2711 let source = atn.packed_words();
2712 let source_layout = atn.layout;
2713 let set_count = source_layout.sets.len / source_layout.set_words;
2714 let mut cursor = LEGACY_HEADER_WORDS;
2715 let states = next_section(
2716 &mut cursor,
2717 source_layout.state_count,
2718 STATE_WORDS,
2719 "states",
2720 )
2721 .expect("legacy states");
2722 let transitions = next_section(
2723 &mut cursor,
2724 source_layout.transition_count,
2725 TRANSITION_WORDS,
2726 "transitions",
2727 )
2728 .expect("legacy transitions");
2729 let sets =
2730 next_section(&mut cursor, set_count, LEGACY_SET_WORDS, "sets").expect("legacy sets");
2731 let intervals = next_section(&mut cursor, source_layout.intervals.len / 2, 2, "intervals")
2732 .expect("legacy intervals");
2733 let decisions = next_section(&mut cursor, source_layout.decisions.len, 1, "decisions")
2734 .expect("legacy decisions");
2735 let rule_starts =
2736 next_section(&mut cursor, source_layout.rule_starts.len, 1, "rule starts")
2737 .expect("legacy rule starts");
2738 let rule_stops = next_section(&mut cursor, source_layout.rule_stops.len, 1, "rule stops")
2739 .expect("legacy rule stops");
2740 let mut words = vec![0; cursor];
2741 words[..=HEADER_RULE_COUNT].copy_from_slice(&source[..=HEADER_RULE_COUNT]);
2742 words[HEADER_VERSION] = 1;
2743 words[HEADER_SIZE] = LEGACY_HEADER_WORDS as u32;
2744 write_section(&mut words, HEADER_STATES_OFFSET, states).expect("states header");
2745 write_section(&mut words, HEADER_TRANSITIONS_OFFSET, transitions)
2746 .expect("transitions header");
2747 write_section(&mut words, HEADER_SETS_OFFSET, sets).expect("sets header");
2748 write_section(&mut words, HEADER_INTERVALS_OFFSET, intervals).expect("intervals header");
2749 write_section(&mut words, HEADER_DECISIONS_OFFSET, decisions).expect("decisions header");
2750 write_section(&mut words, HEADER_RULE_STARTS_OFFSET, rule_starts)
2751 .expect("rule starts header");
2752 write_section(&mut words, HEADER_RULE_STOPS_OFFSET, rule_stops).expect("rule stops header");
2753 words[HEADER_TOTAL_LEN] = cursor as u32;
2754 for (target, section) in [
2755 (states, source_layout.states),
2756 (transitions, source_layout.transitions),
2757 (intervals, source_layout.intervals),
2758 (decisions, source_layout.decisions),
2759 (rule_starts, source_layout.rule_starts),
2760 (rule_stops, source_layout.rule_stops),
2761 ] {
2762 words[target.offset..target.offset + target.len]
2763 .copy_from_slice(&source[section.offset..section.offset + section.len]);
2764 }
2765 for set in 0..set_count {
2766 let source_base = source_layout.sets.offset + set * source_layout.set_words;
2767 let target_base = sets.offset + set * LEGACY_SET_WORDS;
2768 words[target_base..target_base + LEGACY_SET_WORDS]
2769 .copy_from_slice(&source[source_base..source_base + LEGACY_SET_WORDS]);
2770 }
2771 words
2772 }
2773
2774 #[test]
2775 fn packed_views_preserve_state_and_transition_semantics() {
2776 let atn = sample_atn();
2777 let start = atn.state(0).expect("start");
2778 assert_eq!(start.kind(), AtnStateKind::RuleStart);
2779 assert_eq!(start.rule_index(), Some(0));
2780 assert!(start.has_consuming_transition());
2781 let transition = start.transitions().first().expect("transition");
2782 assert_eq!(
2783 transition.data(),
2784 ParserTransitionData::Atom {
2785 target: 1,
2786 label: 7
2787 }
2788 );
2789 assert!(transition.matches(7, 1, 9));
2790 assert!(!transition.matches(8, 1, 9));
2791 assert_eq!(atn.rule_to_stop_state().get(0), Some(1));
2792 }
2793
2794 #[test]
2795 fn static_format_is_allocation_free_and_version_checked() {
2796 let atn = sample_atn();
2797 let words = Box::leak(atn.packed_words().to_vec().into_boxed_slice());
2798 let borrowed = ParserAtn::from_static(words).expect("static packed ATN");
2799 assert!(matches!(borrowed.words, Cow::Borrowed(_)));
2800
2801 let mut wrong_version = words.to_vec();
2802 wrong_version[HEADER_VERSION] = PARSER_ATN_FORMAT_VERSION + 1;
2803 assert_eq!(
2804 ParserAtn::from_owned(wrong_version),
2805 Err(ParserAtnError::UnsupportedVersion {
2806 found: 3,
2807 minimum: 1,
2808 maximum: 2,
2809 })
2810 );
2811 }
2812
2813 #[test]
2814 fn legacy_interval_format_remains_readable() {
2815 let current = token_set_atn(200, &[(TOKEN_EOF, TOKEN_EOF), (2, 8), (150, 150)]);
2816 let legacy = ParserAtn::from_owned(legacy_words(¤t)).expect("legacy packed ATN");
2817 let set = legacy.token_set(0).expect("legacy token set");
2818
2819 assert_eq!(legacy.format_version(), 1);
2820 assert_eq!(set.kind(), ParserTokenSetKind::Intervals);
2821 assert_eq!(
2822 set.ranges().collect::<Vec<_>>(),
2823 [(TOKEN_EOF, TOKEN_EOF), (2, 8), (150, 150)]
2824 );
2825 assert!(set.contains(TOKEN_EOF));
2826 assert!(set.contains(6));
2827 assert!(set.contains(150));
2828 assert!(!set.contains(149));
2829 }
2830
2831 #[test]
2832 fn adaptive_token_sets_cover_boundaries_and_safe_fallbacks() {
2833 let inline = token_set_atn(127, &[(TOKEN_EOF, TOKEN_EOF), (1, 1), (63, 64), (127, 127)]);
2834 let inline = inline.token_set(0).expect("inline set");
2835 assert_eq!(inline.kind(), ParserTokenSetKind::Inline128);
2836 for token in [TOKEN_EOF, 1, 63, 64, 127] {
2837 assert!(inline.contains(token), "missing token {token}");
2838 }
2839 for token in [-2, 0, 2, 62, 65, 126, 128] {
2840 assert!(!inline.contains(token), "unexpected token {token}");
2841 }
2842
2843 let singleton_atn = token_set_atn(127, &[(42, 42)]);
2844 let singleton = singleton_atn.token_set(0).expect("singleton set");
2845 assert_eq!(singleton.kind(), ParserTokenSetKind::Inline128);
2846 assert!(singleton.contains(42));
2847 assert!(!singleton.contains(41));
2848 assert!(!singleton.contains(43));
2849
2850 let dense_ranges = (1..=512)
2851 .step_by(2)
2852 .map(|token| (token, token))
2853 .collect::<Vec<_>>();
2854 let dense_atn = token_set_atn(512, &dense_ranges);
2855 let dense = dense_atn.token_set(0).expect("dense set");
2856 assert_eq!(dense.kind(), ParserTokenSetKind::Dense);
2857 assert!(dense.contains(511));
2858 assert!(!dense.contains(512));
2859
2860 let at_cap_max =
2861 i32::try_from(MAX_DENSE_TOKEN_SET_WORDS * u64::BITS as usize - 1).expect("test bound");
2862 assert_eq!(
2863 token_set_shape((1..=at_cap_max).step_by(2).map(|token| (token, token))),
2864 (ParserTokenSetKind::Dense, MAX_DENSE_TOKEN_SET_WORDS)
2865 );
2866 let over_cap_max = at_cap_max + 1;
2867 assert_eq!(
2868 token_set_shape(
2869 (1..=over_cap_max)
2870 .step_by(2)
2871 .map(|token| (token, token))
2872 .chain([(over_cap_max, over_cap_max)])
2873 ),
2874 (ParserTokenSetKind::Intervals, 0)
2875 );
2876
2877 for ranges in [
2878 vec![(1, 1), (1_000_000, 1_000_000)],
2879 vec![(1, 1), (i32::MAX, i32::MAX)],
2880 vec![(-2, -2), (1, 4)],
2881 vec![(0, 4)],
2882 ] {
2883 let atn = token_set_atn(i32::MAX, &ranges);
2884 let set = atn.token_set(0).expect("interval set");
2885 assert_eq!(set.kind(), ParserTokenSetKind::Intervals, "{ranges:?}");
2886 assert_eq!(atn.stats().token_bitset_bytes, 0);
2887 for &(start, stop) in &ranges {
2888 assert!(set.contains(start));
2889 assert!(set.contains(stop));
2890 }
2891 }
2892
2893 let empty_atn = token_set_atn(0, &[]);
2894 let empty = empty_atn.token_set(0).expect("empty set");
2895 assert_eq!(empty.kind(), ParserTokenSetKind::Inline128);
2896 assert!(empty.is_empty());
2897 assert!(!empty.contains(TOKEN_EOF));
2898 assert!(!empty.contains(1));
2899 assert!(empty_atn.token_set(usize::MAX).is_none());
2900 }
2901
2902 #[test]
2903 fn adaptive_membership_matches_randomized_normalized_intervals() {
2904 let mut random = 0x9e37_79b9_7f4a_7c15_u64;
2905 for case in 0..256 {
2906 let range_count = (next_random(&mut random) % 24) as usize;
2907 let mut ranges = Vec::with_capacity(range_count);
2908 for _ in 0..range_count {
2909 let start = (next_random(&mut random) % 2_100) as i32 - 4;
2910 let width = (next_random(&mut random) % 24) as i32;
2911 ranges.push((start, start.saturating_add(width)));
2912 }
2913 if case % 17 == 0 {
2914 ranges.push((TOKEN_EOF, TOKEN_EOF));
2915 }
2916 if case % 29 == 0 {
2917 ranges.push((i32::MAX, i32::MAX));
2918 }
2919 let normalized = normalize_ranges(ranges);
2920 let atn = token_set_atn(i32::MAX, &normalized);
2921 let set = atn.token_set(0).expect("randomized set");
2922 for token in [TOKEN_EOF, -3, 0, 1, 63, 64, 127, 128, 2_048, i32::MAX] {
2923 let expected = normalized
2924 .iter()
2925 .any(|(start, stop)| (*start..=*stop).contains(&token));
2926 assert_eq!(
2927 set.contains(token),
2928 expected,
2929 "case {case}, token {token}, kind {:?}, ranges {normalized:?}",
2930 set.kind()
2931 );
2932 }
2933 for _ in 0..64 {
2934 let token = (next_random(&mut random) % 2_200) as i32 - 16;
2935 let expected = normalized
2936 .iter()
2937 .any(|(start, stop)| (*start..=*stop).contains(&token));
2938 assert_eq!(set.contains(token), expected, "case {case}, token {token}");
2939 }
2940 }
2941 }
2942
2943 fn next_random(state: &mut u64) -> u64 {
2944 *state ^= *state << 13;
2945 *state ^= *state >> 7;
2946 *state ^= *state << 17;
2947 *state
2948 }
2949
2950 #[cfg(target_pointer_width = "64")]
2951 #[test]
2952 fn header_encoding_rejects_values_outside_u32() {
2953 let builder = ParserAtnBuilder::new(0);
2954 let section = Section {
2955 offset: HEADER_WORDS,
2956 len: 0,
2957 };
2958 let mut layout = EncodedLayout {
2959 states: section,
2960 transitions: section,
2961 sets: section,
2962 intervals: section,
2963 token_bits: section,
2964 decisions: section,
2965 rule_starts: section,
2966 rule_stops: section,
2967 total_len: usize::MAX,
2968 };
2969 let mut words = [0; HEADER_WORDS];
2970
2971 assert_eq!(
2972 builder.encode_header(&mut words, layout),
2973 Err(ParserAtnError::Overflow {
2974 field: "packed parser ATN word",
2975 value: usize::MAX,
2976 })
2977 );
2978
2979 layout.states.offset = usize::MAX;
2980 layout.total_len = HEADER_WORDS;
2981 assert_eq!(
2982 builder.encode_header(&mut words, layout),
2983 Err(ParserAtnError::Overflow {
2984 field: "parser ATN section offset",
2985 value: usize::MAX,
2986 })
2987 );
2988 }
2989
2990 #[test]
2991 fn rejects_invalid_header_and_section_layout() {
2992 let atn = sample_atn();
2993 let cases = [
2994 (HEADER_MAGIC, 0, "magic"),
2995 (HEADER_BYTE_ORDER, 0x0403_0201, "byte-order marker"),
2996 (HEADER_SIZE, 0, "header length"),
2997 (HEADER_STATES_OFFSET, 0, "states section starts"),
2998 (HEADER_STATES_OFFSET + 1, 0, "states section has 0 words"),
2999 (HEADER_TOTAL_LEN, 0, "declared total length"),
3000 ];
3001 for (word, value, expected) in cases {
3002 let mut words = atn.packed_words().to_vec();
3003 words[word] = value;
3004 let error = ParserAtn::from_owned(words).expect_err("invalid format must fail");
3005 assert!(
3006 error.to_string().contains(expected),
3007 "{error} did not contain {expected:?}"
3008 );
3009 }
3010 }
3011
3012 #[test]
3013 fn rejects_non_contiguous_state_transition_ranges() {
3014 let atn = sample_atn();
3015 let mut words = atn.packed_words().to_vec();
3016 let second_state = atn.layout.states.offset + STATE_WORDS;
3017 words[second_state + 3] = 0;
3018 let error = ParserAtn::from_owned(words).expect_err("overlapping ranges must fail");
3019 assert!(error.to_string().contains("transition range starts"));
3020 }
3021
3022 #[test]
3023 fn interval_sets_share_one_range_pool() {
3024 let mut builder = ParserAtnBuilder::new(20);
3025 builder
3026 .add_state(AtnStateKind::RuleStart, Some(0))
3027 .expect("start");
3028 builder
3029 .add_state(AtnStateKind::RuleStop, Some(0))
3030 .expect("stop");
3031 builder
3032 .set_rule_to_start_state(vec![0])
3033 .expect("rule starts");
3034 builder.set_rule_to_stop_state(vec![1]).expect("rule stops");
3035 let set = builder
3036 .add_interval_set([(2, 4), (4, 8), (10, 10)])
3037 .expect("set");
3038 builder
3039 .add_transition(0, ParserTransitionSpec::Set { target: 1, set })
3040 .expect("set transition");
3041 let atn = builder.finish().expect("ATN");
3042 let transition = atn
3043 .state(0)
3044 .expect("start")
3045 .transitions()
3046 .first()
3047 .expect("transition");
3048 let ParserTransitionData::Set { set, .. } = transition.data() else {
3049 panic!("expected set transition");
3050 };
3051 assert_eq!(set.ranges().collect::<Vec<_>>(), vec![(2, 8), (10, 10)]);
3052 assert!(set.contains(7));
3053 assert!(!set.contains(9));
3054 assert_eq!(atn.stats().interval_ranges, 2);
3055 }
3056
3057 #[test]
3058 fn rejects_out_of_range_transition_target() {
3059 let atn = sample_atn();
3060 let mut words = atn.packed_words().to_vec();
3061 let target = atn.layout.transitions.offset + 1;
3062 words[target] = 99;
3063 assert!(matches!(
3064 ParserAtn::from_owned(words),
3065 Err(ParserAtnError::InvalidData(message))
3066 if message.contains("transition target")
3067 ));
3068 }
3069
3070 #[test]
3071 fn not_set_membership_preserves_vocabulary_bounds() {
3072 let mut builder = ParserAtnBuilder::new(5);
3073 builder
3074 .add_state(AtnStateKind::RuleStart, Some(0))
3075 .expect("start");
3076 builder
3077 .add_state(AtnStateKind::RuleStop, Some(0))
3078 .expect("stop");
3079 builder
3080 .set_rule_to_start_state(vec![0])
3081 .expect("rule starts");
3082 builder.set_rule_to_stop_state(vec![1]).expect("rule stops");
3083 let excluded = builder.add_interval_set([(2, 4)]).expect("excluded set");
3084 builder
3085 .add_transition(
3086 0,
3087 ParserTransitionSpec::NotSet {
3088 target: 1,
3089 set: excluded,
3090 },
3091 )
3092 .expect("not-set transition");
3093 let atn = builder.finish().expect("ATN");
3094 let transition = atn
3095 .state(0)
3096 .expect("start")
3097 .transitions()
3098 .first()
3099 .expect("transition");
3100
3101 assert!(transition.matches(1, 1, 5));
3102 assert!(!transition.matches(2, 1, 5));
3103 assert!(!transition.matches(4, 1, 5));
3104 assert!(transition.matches(5, 1, 5));
3105 assert!(!transition.matches(TOKEN_EOF, 1, 5));
3106 assert!(!transition.matches(0, 1, 5));
3107 assert!(!transition.matches(6, 1, 5));
3108 }
3109
3110 #[test]
3111 fn rejects_inconsistent_adaptive_token_set_bits() {
3112 let atn = token_set_atn(127, &[(1, 3), (63, 64), (127, 127)]);
3113 let mut words = atn.packed_words().to_vec();
3114 words[atn.layout.token_bits.offset] ^= 1 << 1;
3115 let error = ParserAtn::from_owned(words).expect_err("corrupted token bits must fail");
3116 assert!(error.to_string().contains("bit word"), "{error}");
3117
3118 let mut words = atn.packed_words().to_vec();
3119 words[atn.layout.sets.offset + 2] = 99;
3120 let error = ParserAtn::from_owned(words).expect_err("unknown token-set kind must fail");
3121 assert!(error.to_string().contains("token-set kind"), "{error}");
3122 }
3123
3124 #[cfg(feature = "perf-counters")]
3125 #[test]
3126 fn token_set_counters_report_selection_and_probes() {
3127 crate::perf::reset();
3128 let before = crate::perf::parser_token_set_snapshot();
3129 let inline_atn = token_set_atn(10, &[(1, 4)]);
3130 let dense_ranges = (1..=256)
3131 .step_by(2)
3132 .map(|token| (token, token))
3133 .collect::<Vec<_>>();
3134 let dense_atn = token_set_atn(256, &dense_ranges);
3135 let interval_atn = token_set_atn(i32::MAX, &[(1, 1), (i32::MAX, i32::MAX)]);
3136 let inline = inline_atn.token_set(0).expect("inline");
3137 let dense = dense_atn.token_set(0).expect("dense");
3138 let intervals = interval_atn.token_set(0).expect("intervals");
3139
3140 assert!(inline.contains(2));
3141 assert!(!inline.contains(9));
3142 assert!(dense.contains(255));
3143 assert!(!dense.contains(256));
3144 assert!(intervals.contains(i32::MAX));
3145 assert!(!intervals.contains(2));
3146
3147 let after = crate::perf::parser_token_set_snapshot();
3148 assert!(after[0] > before[0], "{before:?} -> {after:?}");
3149 assert!(after[1] > before[1], "{before:?} -> {after:?}");
3150 assert!(after[2] > before[2], "{before:?} -> {after:?}");
3151 assert_eq!(after[5] - before[5], 1);
3152 assert_eq!(after[6] - before[6], 1);
3153 assert_eq!(after[7] - before[7], 1);
3154 assert_eq!(after[8] - before[8], 1);
3155 assert_eq!(after[9] - before[9], 1);
3156 assert_eq!(after[10] - before[10], 1);
3157 assert_eq!(after[11] - before[11], 4);
3158 assert_eq!(after[12] - before[12], 2);
3159 }
3160
3161 #[test]
3162 fn eof_interval_is_preserved_as_signed_data() {
3163 let mut builder = ParserAtnBuilder::new(3);
3164 builder
3165 .add_state(AtnStateKind::RuleStart, Some(0))
3166 .expect("start");
3167 builder
3168 .add_state(AtnStateKind::RuleStop, Some(0))
3169 .expect("stop");
3170 builder
3171 .set_rule_to_start_state(vec![0])
3172 .expect("rule starts");
3173 builder.set_rule_to_stop_state(vec![1]).expect("rule stops");
3174 let set = builder
3175 .add_interval_set([(TOKEN_EOF, TOKEN_EOF)])
3176 .expect("set");
3177 builder
3178 .add_transition(0, ParserTransitionSpec::Set { target: 1, set })
3179 .expect("transition");
3180 let atn = builder.finish().expect("ATN");
3181 let transition = atn
3182 .state(0)
3183 .expect("start")
3184 .transitions()
3185 .first()
3186 .expect("transition");
3187 assert!(transition.matches(TOKEN_EOF, 1, 3));
3188 }
3189}