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 if let Some((index, _)) = self
1292 .transitions
1293 .iter()
1294 .enumerate()
1295 .find(|(_, existing)| existing.source == source && existing.spec() == transition)
1296 {
1297 return TransitionId::try_from(index);
1298 }
1299 let record = self.transition_record(source, transition)?;
1300 let id = TransitionId::try_from(self.transitions.len())?;
1301 self.transitions.push(record);
1302 Ok(id)
1303 }
1304
1305 pub fn set_rule_to_start_state(&mut self, states: Vec<usize>) -> Result<(), ParserAtnError> {
1306 self.rule_starts = self.checked_states(states, "rule start state")?;
1307 Ok(())
1308 }
1309
1310 pub fn set_rule_to_stop_state(&mut self, states: Vec<usize>) -> Result<(), ParserAtnError> {
1311 self.rule_stops = self.checked_states(states, "rule stop state")?;
1312 Ok(())
1313 }
1314
1315 pub fn add_decision_state(&mut self, state: usize) -> Result<(), ParserAtnError> {
1316 let state = self.checked_state(state, "decision state")?;
1317 self.decisions.push(state);
1318 Ok(())
1319 }
1320
1321 pub fn state_kind(&self, state: usize) -> Option<AtnStateKind> {
1322 self.states.get(state).map(|record| record.kind)
1323 }
1324
1325 pub const fn state_count(&self) -> usize {
1326 self.states.len()
1327 }
1328
1329 pub fn state_rule_index(&self, state: usize) -> Option<usize> {
1330 self.states
1331 .get(state)
1332 .and_then(|record| unpack_index(record.rule_index))
1333 }
1334
1335 pub fn rule_stop_state(&self, rule: usize) -> Option<usize> {
1336 self.rule_stops.get(rule).copied().map(AtnStateId::index)
1337 }
1338
1339 pub fn transitions_from(
1340 &self,
1341 source: usize,
1342 ) -> impl DoubleEndedIterator<Item = ParserTransitionSpec> + '_ {
1343 self.transitions
1344 .iter()
1345 .filter(move |transition| transition.source.index() == source)
1346 .map(TransitionBuild::spec)
1347 }
1348
1349 pub fn finish(mut self) -> Result<ParserAtn, ParserAtnError> {
1350 self.mark_precedence_decisions();
1351 self.transitions.sort_by_key(|transition| transition.source);
1352 let transition_ranges = self.transition_ranges()?;
1353 self.precompute_state_flags(&transition_ranges);
1354 let words = self.encode(&transition_ranges)?;
1355 ParserAtn::from_owned(words)
1356 }
1357
1358 fn state_mut(&mut self, state: usize, label: &str) -> Result<&mut StateBuild, ParserAtnError> {
1359 self.states.get_mut(state).ok_or_else(|| {
1360 ParserAtnError::InvalidData(format!("{label} {state} outside state list"))
1361 })
1362 }
1363
1364 fn checked_state(&self, state: usize, label: &str) -> Result<AtnStateId, ParserAtnError> {
1365 let id = AtnStateId::try_from(state)?;
1366 if state >= self.states.len() {
1367 return Err(ParserAtnError::InvalidData(format!(
1368 "{label} {state} outside state list"
1369 )));
1370 }
1371 Ok(id)
1372 }
1373
1374 fn checked_states(
1375 &self,
1376 states: Vec<usize>,
1377 label: &str,
1378 ) -> Result<Vec<AtnStateId>, ParserAtnError> {
1379 states
1380 .into_iter()
1381 .map(|state| self.checked_state(state, label))
1382 .collect()
1383 }
1384
1385 fn transition_record(
1386 &self,
1387 source: AtnStateId,
1388 spec: ParserTransitionSpec,
1389 ) -> Result<TransitionBuild, ParserAtnError> {
1390 let target = self.checked_state(spec.target(), "transition target")?;
1391 let (kind, arg0, arg1, arg2) = match spec {
1392 ParserTransitionSpec::Epsilon { .. } => (ParserTransitionKind::Epsilon, 0, 0, 0),
1393 ParserTransitionSpec::Atom { label, .. } => {
1394 (ParserTransitionKind::Atom, pack_i32(label), 0, 0)
1395 }
1396 ParserTransitionSpec::Range { start, stop, .. } => (
1397 ParserTransitionKind::Range,
1398 pack_i32(start),
1399 pack_i32(stop),
1400 0,
1401 ),
1402 ParserTransitionSpec::Set { set, .. } => {
1403 self.checked_set(set)?;
1404 (ParserTransitionKind::Set, set.raw(), 0, 0)
1405 }
1406 ParserTransitionSpec::NotSet { set, .. } => {
1407 self.checked_set(set)?;
1408 (ParserTransitionKind::NotSet, set.raw(), 0, 0)
1409 }
1410 ParserTransitionSpec::Wildcard { .. } => (ParserTransitionKind::Wildcard, 0, 0, 0),
1411 ParserTransitionSpec::Rule {
1412 rule_index,
1413 follow_state,
1414 precedence,
1415 ..
1416 } => (
1417 ParserTransitionKind::Rule,
1418 compact_id("rule transition rule", rule_index)?,
1419 self.checked_state(follow_state, "rule follow state")?.raw(),
1420 pack_i32(precedence),
1421 ),
1422 ParserTransitionSpec::Predicate {
1423 rule_index,
1424 pred_index,
1425 context_dependent,
1426 ..
1427 } => (
1428 ParserTransitionKind::Predicate,
1429 compact_id("predicate rule", rule_index)?,
1430 compact_id("predicate index", pred_index)?,
1431 u32::from(context_dependent),
1432 ),
1433 ParserTransitionSpec::Action {
1434 rule_index,
1435 action_index,
1436 context_dependent,
1437 ..
1438 } => (
1439 ParserTransitionKind::Action,
1440 compact_id("action rule", rule_index)?,
1441 pack_optional_index("action", action_index)?,
1442 u32::from(context_dependent),
1443 ),
1444 ParserTransitionSpec::Precedence { precedence, .. } => {
1445 (ParserTransitionKind::Precedence, pack_i32(precedence), 0, 0)
1446 }
1447 };
1448 Ok(TransitionBuild {
1449 source,
1450 kind,
1451 target,
1452 arg0,
1453 arg1,
1454 arg2,
1455 })
1456 }
1457
1458 fn checked_set(&self, set: ParserIntervalSetId) -> Result<(), ParserAtnError> {
1459 if set.index() >= self.interval_sets.len() {
1460 return Err(ParserAtnError::InvalidData(format!(
1461 "interval set {} outside set list",
1462 set.index()
1463 )));
1464 }
1465 Ok(())
1466 }
1467
1468 fn transition_ranges(&self) -> Result<Vec<(u32, u32)>, ParserAtnError> {
1469 let mut ranges = vec![(0, 0); self.states.len()];
1470 let mut cursor = 0;
1471 for (state, range) in ranges.iter_mut().enumerate() {
1472 let start = cursor;
1473 while cursor < self.transitions.len()
1474 && self.transitions[cursor].source.index() == state
1475 {
1476 cursor += 1;
1477 }
1478 *range = (
1479 compact_id("state transition start", start)?,
1480 compact_id("state transition count", cursor - start)?,
1481 );
1482 }
1483 Ok(ranges)
1484 }
1485
1486 fn precompute_state_flags(&mut self, ranges: &[(u32, u32)]) {
1487 for (state, &(start, len)) in self.states.iter_mut().zip(ranges) {
1488 let transitions = &self.transitions[start as usize..start as usize + len as usize];
1489 if !transitions.is_empty()
1490 && transitions
1491 .iter()
1492 .all(|transition| transition.kind.is_epsilon())
1493 {
1494 state.flags |= FLAG_EPSILON_ONLY;
1495 }
1496 if transitions
1497 .iter()
1498 .any(|transition| transition.kind.is_consuming())
1499 {
1500 state.flags |= FLAG_HAS_CONSUMING;
1501 }
1502 if transitions
1503 .iter()
1504 .any(|transition| transition.kind.is_semantic())
1505 {
1506 state.flags |= FLAG_HAS_SEMANTIC;
1507 }
1508 }
1509 }
1510
1511 fn mark_precedence_decisions(&mut self) {
1512 let candidates = (0..self.states.len())
1513 .filter(|&state| self.is_precedence_decision(state))
1514 .collect::<Vec<_>>();
1515 for state in candidates {
1516 self.states[state].flags |= FLAG_PRECEDENCE_DECISION;
1517 }
1518 }
1519
1520 fn is_precedence_decision(&self, state: usize) -> bool {
1521 let record = &self.states[state];
1522 if record.kind != AtnStateKind::StarLoopEntry {
1523 return false;
1524 }
1525 let Some(rule_index) = unpack_index(record.rule_index) else {
1526 return false;
1527 };
1528 let Some(rule_start) = self.rule_starts.get(rule_index) else {
1529 return false;
1530 };
1531 if self.states[rule_start.index()].flags & FLAG_LEFT_RECURSIVE_RULE == 0 {
1532 return false;
1533 }
1534 let Some(loop_end) = self.transitions_from(state).next_back() else {
1535 return false;
1536 };
1537 let loop_end = loop_end.target();
1538 if self.state_kind(loop_end) != Some(AtnStateKind::LoopEnd) {
1539 return false;
1540 }
1541 self.transitions_from(loop_end)
1542 .next()
1543 .and_then(|transition| self.state_kind(transition.target()))
1544 == Some(AtnStateKind::RuleStop)
1545 }
1546
1547 fn encode(&self, transition_ranges: &[(u32, u32)]) -> Result<Vec<u32>, ParserAtnError> {
1548 let layout = EncodedLayout::new(self)?;
1549 let mut words = vec![0; layout.total_len];
1550 self.encode_header(&mut words, layout)?;
1551 self.encode_states(&mut words, layout.states, transition_ranges);
1552 self.encode_transitions(&mut words, layout.transitions);
1553 self.encode_sets(&mut words, layout.sets);
1554 self.encode_intervals(&mut words, layout.intervals);
1555 self.encode_token_bits(&mut words, layout.token_bits);
1556 encode_ids(&mut words, layout.decisions, &self.decisions);
1557 encode_ids(&mut words, layout.rule_starts, &self.rule_starts);
1558 encode_ids(&mut words, layout.rule_stops, &self.rule_stops);
1559 Ok(words)
1560 }
1561
1562 fn encode_header(
1563 &self,
1564 words: &mut [u32],
1565 layout: EncodedLayout,
1566 ) -> Result<(), ParserAtnError> {
1567 words[HEADER_MAGIC] = PARSER_ATN_MAGIC;
1568 words[HEADER_VERSION] = PARSER_ATN_FORMAT_VERSION;
1569 words[HEADER_BYTE_ORDER] = PARSER_ATN_BYTE_ORDER;
1570 words[HEADER_SIZE] = compact_id("parser ATN header size", HEADER_WORDS)?;
1571 words[HEADER_MAX_TOKEN_TYPE] = pack_i32(self.max_token_type);
1572 words[HEADER_STATE_COUNT] = compact_id("parser ATN state count", self.states.len())?;
1573 words[HEADER_TRANSITION_COUNT] =
1574 compact_id("parser ATN transition count", self.transitions.len())?;
1575 words[HEADER_SET_COUNT] =
1576 compact_id("parser ATN interval-set count", self.interval_sets.len())?;
1577 words[HEADER_INTERVAL_COUNT] =
1578 compact_id("parser ATN interval count", self.interval_ranges.len())?;
1579 words[HEADER_DECISION_COUNT] =
1580 compact_id("parser ATN decision count", self.decisions.len())?;
1581 words[HEADER_RULE_COUNT] = compact_id("parser ATN rule count", self.rule_starts.len())?;
1582 write_section(words, HEADER_STATES_OFFSET, layout.states)?;
1583 write_section(words, HEADER_TRANSITIONS_OFFSET, layout.transitions)?;
1584 write_section(words, HEADER_SETS_OFFSET, layout.sets)?;
1585 write_section(words, HEADER_INTERVALS_OFFSET, layout.intervals)?;
1586 words[HEADER_TOKEN_BIT_WORD_COUNT] = compact_id(
1587 "parser token-set bit word count",
1588 self.token_bit_words.len(),
1589 )?;
1590 write_section(words, HEADER_TOKEN_BITS_OFFSET, layout.token_bits)?;
1591 write_section(words, HEADER_DECISIONS_OFFSET, layout.decisions)?;
1592 write_section(words, HEADER_RULE_STARTS_OFFSET, layout.rule_starts)?;
1593 write_section(words, HEADER_RULE_STOPS_OFFSET, layout.rule_stops)?;
1594 words[HEADER_TOTAL_LEN] = compact_id("packed parser ATN word", layout.total_len)?;
1595 Ok(())
1596 }
1597
1598 fn encode_states(&self, words: &mut [u32], section: Section, transition_ranges: &[(u32, u32)]) {
1599 for (index, (state, &(start, len))) in self.states.iter().zip(transition_ranges).enumerate()
1600 {
1601 let base = section.offset + index * STATE_WORDS;
1602 words[base] = state_kind_word(state.kind);
1603 words[base + 1] = state.rule_index;
1604 words[base + 2] = state.flags;
1605 words[base + 3] = start;
1606 words[base + 4] = len;
1607 words[base + 5] = state.end_state;
1608 words[base + 6] = state.loop_back_state;
1609 }
1610 }
1611
1612 fn encode_transitions(&self, words: &mut [u32], section: Section) {
1613 for (index, transition) in self.transitions.iter().enumerate() {
1614 let base = section.offset + index * TRANSITION_WORDS;
1615 words[base] = transition.kind as u32;
1616 words[base + 1] = transition.target.raw();
1617 words[base + 2] = transition.arg0;
1618 words[base + 3] = transition.arg1;
1619 words[base + 4] = transition.arg2;
1620 }
1621 }
1622
1623 fn encode_sets(&self, words: &mut [u32], section: Section) {
1624 for (index, set) in self.interval_sets.iter().enumerate() {
1625 let base = section.offset + index * SET_WORDS;
1626 words[base] = set.interval_start;
1627 words[base + 1] = set.interval_len;
1628 words[base + 2] = set.kind as u32;
1629 words[base + 3] = set.bit_start;
1630 words[base + 4] = set.bit_len;
1631 }
1632 }
1633
1634 fn encode_intervals(&self, words: &mut [u32], section: Section) {
1635 for (index, &(start, stop)) in self.interval_ranges.iter().enumerate() {
1636 let base = section.offset + index * 2;
1637 words[base] = pack_i32(start);
1638 words[base + 1] = pack_i32(stop);
1639 }
1640 }
1641
1642 fn encode_token_bits(&self, words: &mut [u32], section: Section) {
1643 for (index, &bits) in self.token_bit_words.iter().enumerate() {
1644 let base = section.offset + index * PACKED_U64_WORDS;
1645 words[base] = bits as u32;
1646 words[base + 1] = (bits >> u32::BITS) as u32;
1647 }
1648 }
1649}
1650
1651#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1653pub enum ParserTransitionSpec {
1654 Epsilon {
1655 target: usize,
1656 },
1657 Atom {
1658 target: usize,
1659 label: i32,
1660 },
1661 Range {
1662 target: usize,
1663 start: i32,
1664 stop: i32,
1665 },
1666 Set {
1667 target: usize,
1668 set: ParserIntervalSetId,
1669 },
1670 NotSet {
1671 target: usize,
1672 set: ParserIntervalSetId,
1673 },
1674 Wildcard {
1675 target: usize,
1676 },
1677 Rule {
1678 target: usize,
1679 rule_index: usize,
1680 follow_state: usize,
1681 precedence: i32,
1682 },
1683 Predicate {
1684 target: usize,
1685 rule_index: usize,
1686 pred_index: usize,
1687 context_dependent: bool,
1688 },
1689 Action {
1690 target: usize,
1691 rule_index: usize,
1692 action_index: Option<usize>,
1693 context_dependent: bool,
1694 },
1695 Precedence {
1696 target: usize,
1697 precedence: i32,
1698 },
1699}
1700
1701impl ParserTransitionSpec {
1702 pub const fn target(self) -> usize {
1703 match self {
1704 Self::Epsilon { target }
1705 | Self::Atom { target, .. }
1706 | Self::Range { target, .. }
1707 | Self::Set { target, .. }
1708 | Self::NotSet { target, .. }
1709 | Self::Wildcard { target }
1710 | Self::Rule { target, .. }
1711 | Self::Predicate { target, .. }
1712 | Self::Action { target, .. }
1713 | Self::Precedence { target, .. } => target,
1714 }
1715 }
1716}
1717
1718#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1719struct ParserAtnLayout {
1720 format_version: u32,
1721 max_token_type: i32,
1722 state_count: usize,
1723 transition_count: usize,
1724 set_words: usize,
1725 states: Section,
1726 transitions: Section,
1727 sets: Section,
1728 intervals: Section,
1729 token_bits: Section,
1730 decisions: Section,
1731 rule_starts: Section,
1732 rule_stops: Section,
1733}
1734
1735#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1736struct Section {
1737 offset: usize,
1738 len: usize,
1739}
1740
1741#[derive(Clone, Copy, Debug)]
1742struct EncodedLayout {
1743 states: Section,
1744 transitions: Section,
1745 sets: Section,
1746 intervals: Section,
1747 token_bits: Section,
1748 decisions: Section,
1749 rule_starts: Section,
1750 rule_stops: Section,
1751 total_len: usize,
1752}
1753
1754impl EncodedLayout {
1755 fn new(builder: &ParserAtnBuilder) -> Result<Self, ParserAtnError> {
1756 let mut cursor = HEADER_WORDS;
1757 let states = next_section(&mut cursor, builder.states.len(), STATE_WORDS, "states")?;
1758 let transitions = next_section(
1759 &mut cursor,
1760 builder.transitions.len(),
1761 TRANSITION_WORDS,
1762 "transitions",
1763 )?;
1764 let sets = next_section(
1765 &mut cursor,
1766 builder.interval_sets.len(),
1767 SET_WORDS,
1768 "interval sets",
1769 )?;
1770 let intervals = next_section(
1771 &mut cursor,
1772 builder.interval_ranges.len(),
1773 2,
1774 "interval ranges",
1775 )?;
1776 let token_bits = next_section(
1777 &mut cursor,
1778 builder.token_bit_words.len(),
1779 PACKED_U64_WORDS,
1780 "token-set bits",
1781 )?;
1782 let decisions = next_section(&mut cursor, builder.decisions.len(), 1, "decisions")?;
1783 let rule_starts = next_section(&mut cursor, builder.rule_starts.len(), 1, "rule starts")?;
1784 let rule_stops = next_section(&mut cursor, builder.rule_stops.len(), 1, "rule stops")?;
1785 compact_id("packed parser ATN word", cursor)?;
1786 Ok(Self {
1787 states,
1788 transitions,
1789 sets,
1790 intervals,
1791 token_bits,
1792 decisions,
1793 rule_starts,
1794 rule_stops,
1795 total_len: cursor,
1796 })
1797 }
1798}
1799
1800#[derive(Clone, Debug)]
1801struct StateBuild {
1802 kind: AtnStateKind,
1803 rule_index: u32,
1804 flags: u32,
1805 end_state: u32,
1806 loop_back_state: u32,
1807}
1808
1809#[derive(Clone, Debug)]
1810struct TokenSetBuild {
1811 interval_start: u32,
1812 interval_len: u32,
1813 kind: ParserTokenSetKind,
1814 bit_start: u32,
1815 bit_len: u32,
1816}
1817
1818#[derive(Debug)]
1819struct PreparedTokenSet {
1820 kind: ParserTokenSetKind,
1821 words: Vec<u64>,
1822}
1823
1824#[derive(Clone, Debug)]
1825struct TransitionBuild {
1826 source: AtnStateId,
1827 kind: ParserTransitionKind,
1828 target: AtnStateId,
1829 arg0: u32,
1830 arg1: u32,
1831 arg2: u32,
1832}
1833
1834impl TransitionBuild {
1835 const fn spec(&self) -> ParserTransitionSpec {
1836 let target = self.target.index();
1837 match self.kind {
1838 ParserTransitionKind::Epsilon => ParserTransitionSpec::Epsilon { target },
1839 ParserTransitionKind::Atom => ParserTransitionSpec::Atom {
1840 target,
1841 label: unpack_i32(self.arg0),
1842 },
1843 ParserTransitionKind::Range => ParserTransitionSpec::Range {
1844 target,
1845 start: unpack_i32(self.arg0),
1846 stop: unpack_i32(self.arg1),
1847 },
1848 ParserTransitionKind::Set => ParserTransitionSpec::Set {
1849 target,
1850 set: ParserIntervalSetId(self.arg0),
1851 },
1852 ParserTransitionKind::NotSet => ParserTransitionSpec::NotSet {
1853 target,
1854 set: ParserIntervalSetId(self.arg0),
1855 },
1856 ParserTransitionKind::Wildcard => ParserTransitionSpec::Wildcard { target },
1857 ParserTransitionKind::Rule => ParserTransitionSpec::Rule {
1858 target,
1859 rule_index: self.arg0 as usize,
1860 follow_state: self.arg1 as usize,
1861 precedence: unpack_i32(self.arg2),
1862 },
1863 ParserTransitionKind::Predicate => ParserTransitionSpec::Predicate {
1864 target,
1865 rule_index: self.arg0 as usize,
1866 pred_index: self.arg1 as usize,
1867 context_dependent: self.arg2 != 0,
1868 },
1869 ParserTransitionKind::Action => ParserTransitionSpec::Action {
1870 target,
1871 rule_index: self.arg0 as usize,
1872 action_index: unpack_index(self.arg1),
1873 context_dependent: self.arg2 != 0,
1874 },
1875 ParserTransitionKind::Precedence => ParserTransitionSpec::Precedence {
1876 target,
1877 precedence: unpack_i32(self.arg0),
1878 },
1879 }
1880 }
1881}
1882
1883impl ParserTransitionKind {
1884 const fn is_epsilon(self) -> bool {
1885 matches!(
1886 self,
1887 Self::Epsilon | Self::Rule | Self::Predicate | Self::Action | Self::Precedence
1888 )
1889 }
1890
1891 const fn is_consuming(self) -> bool {
1892 matches!(
1893 self,
1894 Self::Atom | Self::Range | Self::Set | Self::NotSet | Self::Wildcard
1895 )
1896 }
1897
1898 const fn is_semantic(self) -> bool {
1899 matches!(self, Self::Predicate | Self::Action | Self::Precedence)
1900 }
1901}
1902
1903fn validate_packed(words: &[u32]) -> Result<ParserAtnLayout, ParserAtnError> {
1904 validate_header(words)?;
1905 let layout = read_layout(words)?;
1906 validate_sections(words, layout)?;
1907 validate_states(words, layout)?;
1908 validate_transitions(words, layout)?;
1909 validate_state_flags(words, layout)?;
1910 validate_sets(words, layout)?;
1911 validate_side_tables(words, layout)?;
1912 Ok(layout)
1913}
1914
1915fn validate_header(words: &[u32]) -> Result<(), ParserAtnError> {
1916 if words.len() < LEGACY_HEADER_WORDS {
1917 return Err(ParserAtnError::InvalidData(format!(
1918 "header has {} words; expected at least {LEGACY_HEADER_WORDS}",
1919 words.len()
1920 )));
1921 }
1922 if words[HEADER_MAGIC] != PARSER_ATN_MAGIC {
1923 return Err(ParserAtnError::InvalidData(format!(
1924 "magic 0x{:08x}; expected 0x{PARSER_ATN_MAGIC:08x}",
1925 words[HEADER_MAGIC]
1926 )));
1927 }
1928 let version = words[HEADER_VERSION];
1929 if !(PARSER_ATN_MIN_FORMAT_VERSION..=PARSER_ATN_MAX_FORMAT_VERSION).contains(&version) {
1930 return Err(ParserAtnError::UnsupportedVersion {
1931 found: version,
1932 minimum: PARSER_ATN_MIN_FORMAT_VERSION,
1933 maximum: PARSER_ATN_MAX_FORMAT_VERSION,
1934 });
1935 }
1936 let header_words = if version == 1 {
1937 LEGACY_HEADER_WORDS
1938 } else {
1939 HEADER_WORDS
1940 };
1941 if words.len() < header_words {
1942 return Err(ParserAtnError::InvalidData(format!(
1943 "format {version} header has {} words; expected at least {header_words}",
1944 words.len()
1945 )));
1946 }
1947 if words[HEADER_BYTE_ORDER] != PARSER_ATN_BYTE_ORDER {
1948 return Err(ParserAtnError::InvalidData(format!(
1949 "byte-order marker 0x{:08x}; expected 0x{PARSER_ATN_BYTE_ORDER:08x}",
1950 words[HEADER_BYTE_ORDER]
1951 )));
1952 }
1953 if words[HEADER_SIZE] as usize != header_words {
1954 return Err(ParserAtnError::InvalidData(format!(
1955 "format {version} header length {}; expected {header_words}",
1956 words[HEADER_SIZE],
1957 )));
1958 }
1959 if words[HEADER_TOTAL_LEN] as usize != words.len() {
1960 return Err(ParserAtnError::InvalidData(format!(
1961 "declared total length {} does not match {} words",
1962 words[HEADER_TOTAL_LEN],
1963 words.len()
1964 )));
1965 }
1966 Ok(())
1967}
1968
1969fn read_layout(words: &[u32]) -> Result<ParserAtnLayout, ParserAtnError> {
1970 let format_version = words[HEADER_VERSION];
1971 let set_words = if format_version == 1 {
1972 LEGACY_SET_WORDS
1973 } else {
1974 SET_WORDS
1975 };
1976 let states = read_section(words, HEADER_STATES_OFFSET)?;
1977 let transitions = read_section(words, HEADER_TRANSITIONS_OFFSET)?;
1978 let sets = read_section(words, HEADER_SETS_OFFSET)?;
1979 let intervals = read_section(words, HEADER_INTERVALS_OFFSET)?;
1980 let token_bits = if format_version == 1 {
1981 Section {
1982 offset: intervals.offset + intervals.len,
1983 len: 0,
1984 }
1985 } else {
1986 read_section(words, HEADER_TOKEN_BITS_OFFSET)?
1987 };
1988 let decisions = read_section(words, HEADER_DECISIONS_OFFSET)?;
1989 let rule_starts = read_section(words, HEADER_RULE_STARTS_OFFSET)?;
1990 let rule_stops = read_section(words, HEADER_RULE_STOPS_OFFSET)?;
1991 let state_count = words[HEADER_STATE_COUNT] as usize;
1992 let transition_count = words[HEADER_TRANSITION_COUNT] as usize;
1993 expect_section_len("states", states, state_count, STATE_WORDS)?;
1994 expect_section_len(
1995 "transitions",
1996 transitions,
1997 transition_count,
1998 TRANSITION_WORDS,
1999 )?;
2000 expect_section_len(
2001 "interval sets",
2002 sets,
2003 words[HEADER_SET_COUNT] as usize,
2004 set_words,
2005 )?;
2006 expect_section_len(
2007 "intervals",
2008 intervals,
2009 words[HEADER_INTERVAL_COUNT] as usize,
2010 2,
2011 )?;
2012 if format_version != 1 {
2013 expect_section_len(
2014 "token-set bits",
2015 token_bits,
2016 words[HEADER_TOKEN_BIT_WORD_COUNT] as usize,
2017 PACKED_U64_WORDS,
2018 )?;
2019 }
2020 expect_section_len(
2021 "decisions",
2022 decisions,
2023 words[HEADER_DECISION_COUNT] as usize,
2024 1,
2025 )?;
2026 expect_section_len(
2027 "rule starts",
2028 rule_starts,
2029 words[HEADER_RULE_COUNT] as usize,
2030 1,
2031 )?;
2032 expect_section_len(
2033 "rule stops",
2034 rule_stops,
2035 words[HEADER_RULE_COUNT] as usize,
2036 1,
2037 )?;
2038 Ok(ParserAtnLayout {
2039 format_version,
2040 max_token_type: unpack_i32(words[HEADER_MAX_TOKEN_TYPE]),
2041 state_count,
2042 transition_count,
2043 set_words,
2044 states,
2045 transitions,
2046 sets,
2047 intervals,
2048 token_bits,
2049 decisions,
2050 rule_starts,
2051 rule_stops,
2052 })
2053}
2054
2055fn validate_sections(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2056 let sections = [
2057 ("states", layout.states),
2058 ("transitions", layout.transitions),
2059 ("sets", layout.sets),
2060 ("intervals", layout.intervals),
2061 ("token-set bits", layout.token_bits),
2062 ("decisions", layout.decisions),
2063 ("rule starts", layout.rule_starts),
2064 ("rule stops", layout.rule_stops),
2065 ];
2066 let mut expected_offset = if layout.format_version == 1 {
2067 LEGACY_HEADER_WORDS
2068 } else {
2069 HEADER_WORDS
2070 };
2071 for (name, section) in sections {
2072 if section.offset != expected_offset {
2073 return Err(ParserAtnError::InvalidData(format!(
2074 "{name} section starts at {}, expected {expected_offset}",
2075 section.offset
2076 )));
2077 }
2078 expected_offset = section_end(section, words.len(), name)?;
2079 }
2080 if expected_offset != words.len() {
2081 return Err(ParserAtnError::InvalidData(format!(
2082 "sections end at {expected_offset}, stream ends at {}",
2083 words.len()
2084 )));
2085 }
2086 Ok(())
2087}
2088
2089fn validate_states(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2090 let mut transition_cursor = 0;
2091 for state in 0..layout.state_count {
2092 let base = layout.states.offset + state * STATE_WORDS;
2093 decode_state_kind(words[base])?;
2094 let flags = words[base + 2];
2095 if flags & !STATE_FLAGS != 0 {
2096 return Err(ParserAtnError::InvalidData(format!(
2097 "state {state} has unknown flags 0x{:x}",
2098 flags & !STATE_FLAGS
2099 )));
2100 }
2101 validate_optional_index(words[base + 1], layout.rule_starts.len, "state rule index")?;
2102 let transition_start = words[base + 3] as usize;
2103 if transition_start != transition_cursor {
2104 return Err(ParserAtnError::InvalidData(format!(
2105 "state {state} transition range starts at {transition_start}, expected {transition_cursor}"
2106 )));
2107 }
2108 validate_range(
2109 words[base + 3],
2110 words[base + 4],
2111 layout.transition_count,
2112 "state transition",
2113 )?;
2114 transition_cursor += words[base + 4] as usize;
2115 validate_optional_index(words[base + 5], layout.state_count, "block end state")?;
2116 validate_optional_index(words[base + 6], layout.state_count, "loop back state")?;
2117 }
2118 if transition_cursor != layout.transition_count {
2119 return Err(ParserAtnError::InvalidData(format!(
2120 "state transition ranges cover {transition_cursor} transitions; expected {}",
2121 layout.transition_count
2122 )));
2123 }
2124 Ok(())
2125}
2126
2127fn validate_transitions(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2128 for transition in 0..layout.transition_count {
2129 let base = layout.transitions.offset + transition * TRANSITION_WORDS;
2130 let kind = decode_transition_kind(words[base])?;
2131 validate_index(words[base + 1], layout.state_count, "transition target")?;
2132 match kind {
2133 ParserTransitionKind::Range => {
2134 let start = unpack_i32(words[base + 2]);
2135 let stop = unpack_i32(words[base + 3]);
2136 if start > stop {
2137 return Err(ParserAtnError::InvalidData(format!(
2138 "transition {transition} range starts at {start} after stop {stop}"
2139 )));
2140 }
2141 }
2142 ParserTransitionKind::Set | ParserTransitionKind::NotSet => {
2143 validate_index(
2144 words[base + 2],
2145 layout.sets.len / layout.set_words,
2146 "interval set",
2147 )?;
2148 }
2149 ParserTransitionKind::Rule => {
2150 validate_index(words[base + 2], layout.rule_starts.len, "rule index")?;
2151 validate_index(words[base + 3], layout.state_count, "rule follow state")?;
2152 }
2153 ParserTransitionKind::Predicate => {
2154 validate_index(words[base + 2], layout.rule_starts.len, "predicate rule")?;
2155 validate_bool(words[base + 4], "predicate context-dependent flag")?;
2156 }
2157 ParserTransitionKind::Action => {
2158 validate_index(words[base + 2], layout.rule_starts.len, "action rule")?;
2159 validate_bool(words[base + 4], "action context-dependent flag")?;
2160 }
2161 ParserTransitionKind::Epsilon
2162 | ParserTransitionKind::Atom
2163 | ParserTransitionKind::Wildcard
2164 | ParserTransitionKind::Precedence => {}
2165 }
2166 }
2167 Ok(())
2168}
2169
2170fn validate_state_flags(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2171 for state in 0..layout.state_count {
2172 let base = layout.states.offset + state * STATE_WORDS;
2173 let kind = decode_state_kind(words[base])?;
2174 let start = words[base + 3] as usize;
2175 let len = words[base + 4] as usize;
2176 let mut all_epsilon = len != 0;
2177 let mut has_consuming = false;
2178 let mut has_semantic = false;
2179 for transition in start..start + len {
2180 let base = layout.transitions.offset + transition * TRANSITION_WORDS;
2181 let kind = decode_transition_kind(words[base])
2182 .expect("packed parser transition kind was already validated");
2183 all_epsilon &= kind.is_epsilon();
2184 has_consuming |= kind.is_consuming();
2185 has_semantic |= kind.is_semantic();
2186 }
2187 let mut expected = u32::from(kind == AtnStateKind::RuleStop) * FLAG_RULE_STOP;
2188 expected |= u32::from(all_epsilon) * FLAG_EPSILON_ONLY;
2189 expected |= u32::from(has_consuming) * FLAG_HAS_CONSUMING;
2190 expected |= u32::from(has_semantic) * FLAG_HAS_SEMANTIC;
2191 let derived = words[base + 2]
2192 & (FLAG_EPSILON_ONLY | FLAG_RULE_STOP | FLAG_HAS_CONSUMING | FLAG_HAS_SEMANTIC);
2193 if derived != expected {
2194 return Err(ParserAtnError::InvalidData(format!(
2195 "state {state} has inconsistent precomputed flags 0x{derived:x}; expected 0x{expected:x}"
2196 )));
2197 }
2198 }
2199 Ok(())
2200}
2201
2202fn validate_sets(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2203 let set_count = layout.sets.len / layout.set_words;
2204 let mut bit_cursor = 0;
2205 for set in 0..set_count {
2206 let base = layout.sets.offset + set * layout.set_words;
2207 validate_range(
2208 words[base],
2209 words[base + 1],
2210 layout.intervals.len / 2,
2211 "interval set",
2212 )?;
2213 let start = words[base] as usize;
2214 let len = words[base + 1] as usize;
2215 let mut previous_stop: Option<i32> = None;
2216 for interval in start..start + len {
2217 let interval_base = layout.intervals.offset + interval * 2;
2218 let range_start = unpack_i32(words[interval_base]);
2219 let range_stop = unpack_i32(words[interval_base + 1]);
2220 if range_start > range_stop {
2221 return Err(ParserAtnError::InvalidData(format!(
2222 "interval {interval} starts at {range_start} after stop {range_stop}"
2223 )));
2224 }
2225 if previous_stop.is_some_and(|stop| range_start <= stop.saturating_add(1)) {
2226 return Err(ParserAtnError::InvalidData(format!(
2227 "interval set {set} is not sorted and coalesced"
2228 )));
2229 }
2230 previous_stop = Some(range_stop);
2231 }
2232 if layout.format_version == 1 {
2233 continue;
2234 }
2235 let kind = decode_token_set_kind(words[base + 2])?;
2236 let bit_start = words[base + 3];
2237 let bit_len = words[base + 4];
2238 if bit_start as usize != bit_cursor {
2239 return Err(ParserAtnError::InvalidData(format!(
2240 "parser token set {set} bit range starts at {bit_start}, expected {bit_cursor}"
2241 )));
2242 }
2243 validate_range(
2244 bit_start,
2245 bit_len,
2246 layout.token_bits.len / PACKED_U64_WORDS,
2247 "parser token-set bits",
2248 )?;
2249 let (expected_kind, expected_bit_len) =
2250 token_set_shape((start..start + len).map(|interval| {
2251 let interval_base = layout.intervals.offset + interval * 2;
2252 (
2253 unpack_i32(words[interval_base]),
2254 unpack_i32(words[interval_base + 1]),
2255 )
2256 }));
2257 if kind != expected_kind || bit_len as usize != expected_bit_len {
2258 return Err(ParserAtnError::InvalidData(format!(
2259 "parser token set {set} uses {kind:?} with {bit_len} words; \
2260 expected {expected_kind:?} with {expected_bit_len} words"
2261 )));
2262 }
2263 for bit_word in 0..expected_bit_len {
2264 let expected = expected_token_set_word(
2265 (start..start + len).map(|interval| {
2266 let interval_base = layout.intervals.offset + interval * 2;
2267 (
2268 unpack_i32(words[interval_base]),
2269 unpack_i32(words[interval_base + 1]),
2270 )
2271 }),
2272 bit_word,
2273 );
2274 let actual = packed_u64(words, layout.token_bits, bit_cursor + bit_word);
2275 if actual != expected {
2276 return Err(ParserAtnError::InvalidData(format!(
2277 "parser token set {set} bit word {bit_word} is 0x{actual:016x}; \
2278 expected 0x{expected:016x}"
2279 )));
2280 }
2281 }
2282 bit_cursor += expected_bit_len;
2283 }
2284 if layout.format_version != 1 && bit_cursor != layout.token_bits.len / PACKED_U64_WORDS {
2285 return Err(ParserAtnError::InvalidData(format!(
2286 "parser token sets cover {bit_cursor} bit words; expected {}",
2287 layout.token_bits.len / PACKED_U64_WORDS
2288 )));
2289 }
2290 Ok(())
2291}
2292
2293fn validate_side_tables(words: &[u32], layout: ParserAtnLayout) -> Result<(), ParserAtnError> {
2294 for (name, section) in [
2295 ("decision state", layout.decisions),
2296 ("rule start state", layout.rule_starts),
2297 ("rule stop state", layout.rule_stops),
2298 ] {
2299 for &state in &words[section.offset..section.offset + section.len] {
2300 validate_index(state, layout.state_count, name)?;
2301 }
2302 }
2303 Ok(())
2304}
2305
2306#[inline(always)]
2307fn decode_state_kind(value: u32) -> Result<AtnStateKind, ParserAtnError> {
2308 let kind = match value {
2309 0 => AtnStateKind::Invalid,
2310 1 => AtnStateKind::Basic,
2311 2 => AtnStateKind::RuleStart,
2312 3 => AtnStateKind::BlockStart,
2313 4 => AtnStateKind::PlusBlockStart,
2314 5 => AtnStateKind::StarBlockStart,
2315 6 => AtnStateKind::TokenStart,
2316 7 => AtnStateKind::RuleStop,
2317 8 => AtnStateKind::BlockEnd,
2318 9 => AtnStateKind::StarLoopBack,
2319 10 => AtnStateKind::StarLoopEntry,
2320 11 => AtnStateKind::PlusLoopBack,
2321 12 => AtnStateKind::LoopEnd,
2322 other => {
2323 return Err(ParserAtnError::InvalidData(format!(
2324 "parser ATN state kind {other}"
2325 )));
2326 }
2327 };
2328 Ok(kind)
2329}
2330
2331#[inline(always)]
2332fn decode_transition_kind(value: u32) -> Result<ParserTransitionKind, ParserAtnError> {
2333 let kind = match value {
2334 1 => ParserTransitionKind::Epsilon,
2335 2 => ParserTransitionKind::Range,
2336 3 => ParserTransitionKind::Rule,
2337 4 => ParserTransitionKind::Predicate,
2338 5 => ParserTransitionKind::Atom,
2339 6 => ParserTransitionKind::Action,
2340 7 => ParserTransitionKind::Set,
2341 8 => ParserTransitionKind::NotSet,
2342 9 => ParserTransitionKind::Wildcard,
2343 10 => ParserTransitionKind::Precedence,
2344 other => {
2345 return Err(ParserAtnError::InvalidData(format!(
2346 "parser ATN transition kind {other}"
2347 )));
2348 }
2349 };
2350 Ok(kind)
2351}
2352
2353fn decode_token_set_kind(value: u32) -> Result<ParserTokenSetKind, ParserAtnError> {
2354 match value {
2355 0 => Ok(ParserTokenSetKind::Intervals),
2356 1 => Ok(ParserTokenSetKind::Inline128),
2357 2 => Ok(ParserTokenSetKind::Dense),
2358 other => Err(ParserAtnError::InvalidData(format!(
2359 "parser token-set kind {other}"
2360 ))),
2361 }
2362}
2363
2364const fn state_kind_word(kind: AtnStateKind) -> u32 {
2365 match kind {
2366 AtnStateKind::Invalid => 0,
2367 AtnStateKind::Basic => 1,
2368 AtnStateKind::RuleStart => 2,
2369 AtnStateKind::BlockStart => 3,
2370 AtnStateKind::PlusBlockStart => 4,
2371 AtnStateKind::StarBlockStart => 5,
2372 AtnStateKind::TokenStart => 6,
2373 AtnStateKind::RuleStop => 7,
2374 AtnStateKind::BlockEnd => 8,
2375 AtnStateKind::StarLoopBack => 9,
2376 AtnStateKind::StarLoopEntry => 10,
2377 AtnStateKind::PlusLoopBack => 11,
2378 AtnStateKind::LoopEnd => 12,
2379 }
2380}
2381
2382fn compact_id(field: &'static str, value: usize) -> Result<u32, ParserAtnError> {
2383 u32::try_from(value).map_err(|_| ParserAtnError::Overflow { field, value })
2384}
2385
2386fn pack_optional_index(field: &'static str, value: Option<usize>) -> Result<u32, ParserAtnError> {
2387 match value {
2388 Some(value) => {
2389 let compact = compact_id(field, value)?;
2390 if compact == NO_INDEX {
2391 return Err(ParserAtnError::Overflow { field, value });
2392 }
2393 Ok(compact)
2394 }
2395 None => Ok(NO_INDEX),
2396 }
2397}
2398
2399const fn unpack_index(value: u32) -> Option<usize> {
2400 if value == NO_INDEX {
2401 None
2402 } else {
2403 Some(value as usize)
2404 }
2405}
2406
2407const fn pack_i32(value: i32) -> u32 {
2408 u32::from_le_bytes(value.to_le_bytes())
2409}
2410
2411const fn unpack_i32(value: u32) -> i32 {
2412 i32::from_le_bytes(value.to_le_bytes())
2413}
2414
2415fn normalize_ranges(ranges: impl IntoIterator<Item = (i32, i32)>) -> Vec<(i32, i32)> {
2416 let mut ranges = ranges
2417 .into_iter()
2418 .map(|(start, stop)| {
2419 if start <= stop {
2420 (start, stop)
2421 } else {
2422 (stop, start)
2423 }
2424 })
2425 .collect::<Vec<_>>();
2426 ranges.sort_unstable();
2427 let mut normalized: Vec<(i32, i32)> = Vec::with_capacity(ranges.len());
2428 for (start, stop) in ranges {
2429 if let Some((_, previous_stop)) = normalized.last_mut()
2430 && start <= previous_stop.saturating_add(1)
2431 {
2432 *previous_stop = (*previous_stop).max(stop);
2433 continue;
2434 }
2435 normalized.push((start, stop));
2436 }
2437 normalized
2438}
2439
2440fn token_set_shape(ranges: impl IntoIterator<Item = (i32, i32)>) -> (ParserTokenSetKind, usize) {
2448 let mut compatible = true;
2449 let mut max_slot = 0;
2450 let mut represented = 0_u64;
2451 let mut range_count = 0_usize;
2452 for (start, stop) in ranges {
2453 range_count += 1;
2454 represented = represented.saturating_add(
2455 u64::try_from(i64::from(stop) - i64::from(start) + 1).unwrap_or(u64::MAX),
2456 );
2457 if start == TOKEN_EOF && stop == TOKEN_EOF {
2458 continue;
2459 }
2460 if start < 1 {
2461 compatible = false;
2462 continue;
2463 }
2464 let stop = usize::try_from(stop).expect("positive i32 token type fits usize");
2465 max_slot = max_slot.max(stop);
2466 }
2467 if !compatible {
2468 return (ParserTokenSetKind::Intervals, 0);
2469 }
2470 if max_slot <= INLINE_TOKEN_SET_MAX_SLOT {
2471 return (ParserTokenSetKind::Inline128, INLINE_TOKEN_SET_WORDS);
2472 }
2473 let word_len = max_slot / u64::BITS as usize + 1;
2474 let Some(dense_bytes) = word_len.checked_mul(size_of::<u64>()) else {
2475 return (ParserTokenSetKind::Intervals, 0);
2476 };
2477 let interval_bytes = range_count.saturating_mul(size_of::<(i32, i32)>());
2478 let dense_enough = represented.saturating_mul(DENSE_TOKEN_SET_MIN_DENSITY_DENOMINATOR)
2479 >= u64::try_from(max_slot)
2480 .unwrap_or(u64::MAX)
2481 .saturating_add(1);
2482 let cost_effective = dense_bytes <= interval_bytes
2483 || (dense_bytes <= interval_bytes.saturating_mul(DENSE_TOKEN_SET_COST_MULTIPLIER)
2484 && dense_enough);
2485 if word_len <= MAX_DENSE_TOKEN_SET_WORDS && cost_effective {
2486 (ParserTokenSetKind::Dense, word_len)
2487 } else {
2488 (ParserTokenSetKind::Intervals, 0)
2489 }
2490}
2491
2492fn prepare_token_set(ranges: &[(i32, i32)]) -> PreparedTokenSet {
2493 let (kind, word_len) = token_set_shape(ranges.iter().copied());
2494 let mut words = vec![0; word_len];
2495 for &(start, stop) in ranges {
2496 insert_token_set_range(&mut words, start, stop);
2497 }
2498 PreparedTokenSet { kind, words }
2499}
2500
2501fn insert_token_set_range(words: &mut [u64], start: i32, stop: i32) {
2502 if words.is_empty() {
2503 return;
2504 }
2505 if start == TOKEN_EOF && stop == TOKEN_EOF {
2506 words[0] |= 1;
2507 return;
2508 }
2509 debug_assert!(start >= 1 && stop >= start);
2510 let start = usize::try_from(start).expect("positive i32 token type fits usize");
2511 let stop = usize::try_from(stop).expect("positive i32 token type fits usize");
2512 let start_word = start / u64::BITS as usize;
2513 let stop_word = stop / u64::BITS as usize;
2514 if start_word == stop_word {
2515 words[start_word] |= token_word_mask(start % u64::BITS as usize, stop % u64::BITS as usize);
2516 return;
2517 }
2518 words[start_word] |= !0_u64 << (start % u64::BITS as usize);
2519 words[(start_word + 1)..stop_word].fill(!0);
2520 words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop % u64::BITS as usize);
2521}
2522
2523fn expected_token_set_word(ranges: impl IntoIterator<Item = (i32, i32)>, word_index: usize) -> u64 {
2524 let word_start = word_index * u64::BITS as usize;
2525 let word_stop = word_start + u64::BITS as usize - 1;
2526 let mut expected = 0;
2527 for (start, stop) in ranges {
2528 if start == TOKEN_EOF && stop == TOKEN_EOF {
2529 if word_index == 0 {
2530 expected |= 1;
2531 }
2532 continue;
2533 }
2534 let start = usize::try_from(start).expect("positive i32 token type fits usize");
2535 let stop = usize::try_from(stop).expect("positive i32 token type fits usize");
2536 if stop < word_start || start > word_stop {
2537 continue;
2538 }
2539 expected |= token_word_mask(
2540 start.max(word_start) - word_start,
2541 stop.min(word_stop) - word_start,
2542 );
2543 }
2544 expected
2545}
2546
2547const fn token_word_mask(start: usize, stop: usize) -> u64 {
2548 (!0_u64 << start) & (!0_u64 >> (u64::BITS as usize - 1 - stop))
2549}
2550
2551fn packed_u64(words: &[u32], section: Section, index: usize) -> u64 {
2552 let offset = section.offset + index * PACKED_U64_WORDS;
2553 u64::from(words[offset]) | (u64::from(words[offset + 1]) << u32::BITS)
2554}
2555
2556fn token_set_slot(value: i32) -> Option<usize> {
2557 if value == TOKEN_EOF {
2558 Some(0)
2559 } else if value > 0 {
2560 usize::try_from(value).ok()
2561 } else {
2562 None
2563 }
2564}
2565
2566fn next_section(
2567 cursor: &mut usize,
2568 count: usize,
2569 width: usize,
2570 name: &str,
2571) -> Result<Section, ParserAtnError> {
2572 let len = count.checked_mul(width).ok_or_else(|| {
2573 ParserAtnError::InvalidData(format!("{name} section length overflows usize"))
2574 })?;
2575 let section = Section {
2576 offset: *cursor,
2577 len,
2578 };
2579 *cursor = cursor.checked_add(len).ok_or_else(|| {
2580 ParserAtnError::InvalidData(format!("{name} section end overflows usize"))
2581 })?;
2582 Ok(section)
2583}
2584
2585fn write_section(
2586 words: &mut [u32],
2587 header_offset: usize,
2588 section: Section,
2589) -> Result<(), ParserAtnError> {
2590 words[header_offset] = compact_id("parser ATN section offset", section.offset)?;
2591 words[header_offset + 1] = compact_id("parser ATN section length", section.len)?;
2592 Ok(())
2593}
2594
2595fn encode_ids(words: &mut [u32], section: Section, ids: &[AtnStateId]) {
2596 for (target, id) in words[section.offset..section.offset + section.len]
2597 .iter_mut()
2598 .zip(ids)
2599 {
2600 *target = id.raw();
2601 }
2602}
2603
2604fn read_section(words: &[u32], header_offset: usize) -> Result<Section, ParserAtnError> {
2605 let offset = words[header_offset] as usize;
2606 let len = words[header_offset + 1] as usize;
2607 section_end(Section { offset, len }, words.len(), "declared")?;
2608 Ok(Section { offset, len })
2609}
2610
2611fn section_end(section: Section, total: usize, name: &str) -> Result<usize, ParserAtnError> {
2612 let end = section.offset.checked_add(section.len).ok_or_else(|| {
2613 ParserAtnError::InvalidData(format!("{name} section offset arithmetic overflow"))
2614 })?;
2615 if end > total {
2616 return Err(ParserAtnError::InvalidData(format!(
2617 "{name} section {0}..{end} exceeds stream length {total}",
2618 section.offset
2619 )));
2620 }
2621 Ok(end)
2622}
2623
2624fn expect_section_len(
2625 name: &str,
2626 section: Section,
2627 count: usize,
2628 width: usize,
2629) -> Result<(), ParserAtnError> {
2630 let expected = count.checked_mul(width).ok_or_else(|| {
2631 ParserAtnError::InvalidData(format!("{name} count/width multiplication overflow"))
2632 })?;
2633 if section.len != expected {
2634 return Err(ParserAtnError::InvalidData(format!(
2635 "{name} section has {} words; expected {expected}",
2636 section.len
2637 )));
2638 }
2639 Ok(())
2640}
2641
2642fn validate_index(value: u32, count: usize, name: &str) -> Result<(), ParserAtnError> {
2643 if value as usize >= count {
2644 return Err(ParserAtnError::InvalidData(format!(
2645 "{name} {value} outside 0..{count}"
2646 )));
2647 }
2648 Ok(())
2649}
2650
2651fn validate_optional_index(value: u32, count: usize, name: &str) -> Result<(), ParserAtnError> {
2652 if value == NO_INDEX {
2653 return Ok(());
2654 }
2655 validate_index(value, count, name)
2656}
2657
2658fn validate_bool(value: u32, name: &str) -> Result<(), ParserAtnError> {
2659 if value > 1 {
2660 return Err(ParserAtnError::InvalidData(format!(
2661 "{name} is {value}; expected 0 or 1"
2662 )));
2663 }
2664 Ok(())
2665}
2666
2667fn validate_range(start: u32, len: u32, count: usize, name: &str) -> Result<(), ParserAtnError> {
2668 let start = start as usize;
2669 let len = len as usize;
2670 let end = start
2671 .checked_add(len)
2672 .ok_or_else(|| ParserAtnError::InvalidData(format!("{name} range arithmetic overflow")))?;
2673 if end > count {
2674 return Err(ParserAtnError::InvalidData(format!(
2675 "{name} range {start}..{end} exceeds count {count}"
2676 )));
2677 }
2678 Ok(())
2679}
2680
2681#[cfg(test)]
2682mod tests {
2683 use super::*;
2684
2685 fn sample_atn() -> ParserAtn {
2686 let mut builder = ParserAtnBuilder::new(9);
2687 builder
2688 .add_state(AtnStateKind::RuleStart, Some(0))
2689 .expect("rule start");
2690 builder
2691 .add_state(AtnStateKind::RuleStop, Some(0))
2692 .expect("rule stop");
2693 builder
2694 .set_rule_to_start_state(vec![0])
2695 .expect("rule starts");
2696 builder.set_rule_to_stop_state(vec![1]).expect("rule stops");
2697 builder.add_decision_state(0).expect("decision");
2698 builder
2699 .add_transition(
2700 0,
2701 ParserTransitionSpec::Atom {
2702 target: 1,
2703 label: 7,
2704 },
2705 )
2706 .expect("transition");
2707 builder.finish().expect("packed parser ATN")
2708 }
2709
2710 fn token_set_atn(max_token_type: i32, ranges: &[(i32, i32)]) -> ParserAtn {
2711 let mut builder = ParserAtnBuilder::new(max_token_type);
2712 builder
2713 .add_interval_set(ranges.iter().copied())
2714 .expect("token set");
2715 builder.finish().expect("packed parser ATN")
2716 }
2717
2718 #[test]
2719 fn duplicate_transitions_reuse_the_existing_edge() {
2720 let mut builder = ParserAtnBuilder::new(1);
2721 builder
2722 .add_state(AtnStateKind::RuleStop, None)
2723 .expect("source");
2724 builder
2725 .add_state(AtnStateKind::Basic, None)
2726 .expect("target");
2727 let transition = ParserTransitionSpec::Epsilon { target: 1 };
2728
2729 let first = builder
2730 .add_transition(0, transition)
2731 .expect("first transition");
2732 let duplicate = builder
2733 .add_transition(0, transition)
2734 .expect("duplicate transition");
2735 assert_eq!(duplicate, first);
2736
2737 let atn = builder.finish().expect("packed parser ATN");
2738 assert_eq!(atn.transition_count(), 1);
2739 }
2740
2741 fn legacy_words(atn: &ParserAtn) -> Vec<u32> {
2742 let source = atn.packed_words();
2743 let source_layout = atn.layout;
2744 let set_count = source_layout.sets.len / source_layout.set_words;
2745 let mut cursor = LEGACY_HEADER_WORDS;
2746 let states = next_section(
2747 &mut cursor,
2748 source_layout.state_count,
2749 STATE_WORDS,
2750 "states",
2751 )
2752 .expect("legacy states");
2753 let transitions = next_section(
2754 &mut cursor,
2755 source_layout.transition_count,
2756 TRANSITION_WORDS,
2757 "transitions",
2758 )
2759 .expect("legacy transitions");
2760 let sets =
2761 next_section(&mut cursor, set_count, LEGACY_SET_WORDS, "sets").expect("legacy sets");
2762 let intervals = next_section(&mut cursor, source_layout.intervals.len / 2, 2, "intervals")
2763 .expect("legacy intervals");
2764 let decisions = next_section(&mut cursor, source_layout.decisions.len, 1, "decisions")
2765 .expect("legacy decisions");
2766 let rule_starts =
2767 next_section(&mut cursor, source_layout.rule_starts.len, 1, "rule starts")
2768 .expect("legacy rule starts");
2769 let rule_stops = next_section(&mut cursor, source_layout.rule_stops.len, 1, "rule stops")
2770 .expect("legacy rule stops");
2771 let mut words = vec![0; cursor];
2772 words[..=HEADER_RULE_COUNT].copy_from_slice(&source[..=HEADER_RULE_COUNT]);
2773 words[HEADER_VERSION] = 1;
2774 words[HEADER_SIZE] = LEGACY_HEADER_WORDS as u32;
2775 write_section(&mut words, HEADER_STATES_OFFSET, states).expect("states header");
2776 write_section(&mut words, HEADER_TRANSITIONS_OFFSET, transitions)
2777 .expect("transitions header");
2778 write_section(&mut words, HEADER_SETS_OFFSET, sets).expect("sets header");
2779 write_section(&mut words, HEADER_INTERVALS_OFFSET, intervals).expect("intervals header");
2780 write_section(&mut words, HEADER_DECISIONS_OFFSET, decisions).expect("decisions header");
2781 write_section(&mut words, HEADER_RULE_STARTS_OFFSET, rule_starts)
2782 .expect("rule starts header");
2783 write_section(&mut words, HEADER_RULE_STOPS_OFFSET, rule_stops).expect("rule stops header");
2784 words[HEADER_TOTAL_LEN] = cursor as u32;
2785 for (target, section) in [
2786 (states, source_layout.states),
2787 (transitions, source_layout.transitions),
2788 (intervals, source_layout.intervals),
2789 (decisions, source_layout.decisions),
2790 (rule_starts, source_layout.rule_starts),
2791 (rule_stops, source_layout.rule_stops),
2792 ] {
2793 words[target.offset..target.offset + target.len]
2794 .copy_from_slice(&source[section.offset..section.offset + section.len]);
2795 }
2796 for set in 0..set_count {
2797 let source_base = source_layout.sets.offset + set * source_layout.set_words;
2798 let target_base = sets.offset + set * LEGACY_SET_WORDS;
2799 words[target_base..target_base + LEGACY_SET_WORDS]
2800 .copy_from_slice(&source[source_base..source_base + LEGACY_SET_WORDS]);
2801 }
2802 words
2803 }
2804
2805 #[test]
2806 fn packed_views_preserve_state_and_transition_semantics() {
2807 let atn = sample_atn();
2808 let start = atn.state(0).expect("start");
2809 assert_eq!(start.kind(), AtnStateKind::RuleStart);
2810 assert_eq!(start.rule_index(), Some(0));
2811 assert!(start.has_consuming_transition());
2812 let transition = start.transitions().first().expect("transition");
2813 assert_eq!(
2814 transition.data(),
2815 ParserTransitionData::Atom {
2816 target: 1,
2817 label: 7
2818 }
2819 );
2820 assert!(transition.matches(7, 1, 9));
2821 assert!(!transition.matches(8, 1, 9));
2822 assert_eq!(atn.rule_to_stop_state().get(0), Some(1));
2823 }
2824
2825 #[test]
2826 fn static_format_is_allocation_free_and_version_checked() {
2827 let atn = sample_atn();
2828 let words = Box::leak(atn.packed_words().to_vec().into_boxed_slice());
2829 let borrowed = ParserAtn::from_static(words).expect("static packed ATN");
2830 assert!(matches!(borrowed.words, Cow::Borrowed(_)));
2831
2832 let mut wrong_version = words.to_vec();
2833 wrong_version[HEADER_VERSION] = PARSER_ATN_FORMAT_VERSION + 1;
2834 assert_eq!(
2835 ParserAtn::from_owned(wrong_version),
2836 Err(ParserAtnError::UnsupportedVersion {
2837 found: 3,
2838 minimum: 1,
2839 maximum: 2,
2840 })
2841 );
2842 }
2843
2844 #[test]
2845 fn legacy_interval_format_remains_readable() {
2846 let current = token_set_atn(200, &[(TOKEN_EOF, TOKEN_EOF), (2, 8), (150, 150)]);
2847 let legacy = ParserAtn::from_owned(legacy_words(¤t)).expect("legacy packed ATN");
2848 let set = legacy.token_set(0).expect("legacy token set");
2849
2850 assert_eq!(legacy.format_version(), 1);
2851 assert_eq!(set.kind(), ParserTokenSetKind::Intervals);
2852 assert_eq!(
2853 set.ranges().collect::<Vec<_>>(),
2854 [(TOKEN_EOF, TOKEN_EOF), (2, 8), (150, 150)]
2855 );
2856 assert!(set.contains(TOKEN_EOF));
2857 assert!(set.contains(6));
2858 assert!(set.contains(150));
2859 assert!(!set.contains(149));
2860 }
2861
2862 #[test]
2863 fn adaptive_token_sets_cover_boundaries_and_safe_fallbacks() {
2864 let inline = token_set_atn(127, &[(TOKEN_EOF, TOKEN_EOF), (1, 1), (63, 64), (127, 127)]);
2865 let inline = inline.token_set(0).expect("inline set");
2866 assert_eq!(inline.kind(), ParserTokenSetKind::Inline128);
2867 for token in [TOKEN_EOF, 1, 63, 64, 127] {
2868 assert!(inline.contains(token), "missing token {token}");
2869 }
2870 for token in [-2, 0, 2, 62, 65, 126, 128] {
2871 assert!(!inline.contains(token), "unexpected token {token}");
2872 }
2873
2874 let singleton_atn = token_set_atn(127, &[(42, 42)]);
2875 let singleton = singleton_atn.token_set(0).expect("singleton set");
2876 assert_eq!(singleton.kind(), ParserTokenSetKind::Inline128);
2877 assert!(singleton.contains(42));
2878 assert!(!singleton.contains(41));
2879 assert!(!singleton.contains(43));
2880
2881 let dense_ranges = (1..=512)
2882 .step_by(2)
2883 .map(|token| (token, token))
2884 .collect::<Vec<_>>();
2885 let dense_atn = token_set_atn(512, &dense_ranges);
2886 let dense = dense_atn.token_set(0).expect("dense set");
2887 assert_eq!(dense.kind(), ParserTokenSetKind::Dense);
2888 assert!(dense.contains(511));
2889 assert!(!dense.contains(512));
2890
2891 let at_cap_max =
2892 i32::try_from(MAX_DENSE_TOKEN_SET_WORDS * u64::BITS as usize - 1).expect("test bound");
2893 assert_eq!(
2894 token_set_shape((1..=at_cap_max).step_by(2).map(|token| (token, token))),
2895 (ParserTokenSetKind::Dense, MAX_DENSE_TOKEN_SET_WORDS)
2896 );
2897 let over_cap_max = at_cap_max + 1;
2898 assert_eq!(
2899 token_set_shape(
2900 (1..=over_cap_max)
2901 .step_by(2)
2902 .map(|token| (token, token))
2903 .chain([(over_cap_max, over_cap_max)])
2904 ),
2905 (ParserTokenSetKind::Intervals, 0)
2906 );
2907
2908 for ranges in [
2909 vec![(1, 1), (1_000_000, 1_000_000)],
2910 vec![(1, 1), (i32::MAX, i32::MAX)],
2911 vec![(-2, -2), (1, 4)],
2912 vec![(0, 4)],
2913 ] {
2914 let atn = token_set_atn(i32::MAX, &ranges);
2915 let set = atn.token_set(0).expect("interval set");
2916 assert_eq!(set.kind(), ParserTokenSetKind::Intervals, "{ranges:?}");
2917 assert_eq!(atn.stats().token_bitset_bytes, 0);
2918 for &(start, stop) in &ranges {
2919 assert!(set.contains(start));
2920 assert!(set.contains(stop));
2921 }
2922 }
2923
2924 let empty_atn = token_set_atn(0, &[]);
2925 let empty = empty_atn.token_set(0).expect("empty set");
2926 assert_eq!(empty.kind(), ParserTokenSetKind::Inline128);
2927 assert!(empty.is_empty());
2928 assert!(!empty.contains(TOKEN_EOF));
2929 assert!(!empty.contains(1));
2930 assert!(empty_atn.token_set(usize::MAX).is_none());
2931 }
2932
2933 #[test]
2934 fn adaptive_membership_matches_randomized_normalized_intervals() {
2935 let mut random = 0x9e37_79b9_7f4a_7c15_u64;
2936 for case in 0..256 {
2937 let range_count = (next_random(&mut random) % 24) as usize;
2938 let mut ranges = Vec::with_capacity(range_count);
2939 for _ in 0..range_count {
2940 let start = (next_random(&mut random) % 2_100) as i32 - 4;
2941 let width = (next_random(&mut random) % 24) as i32;
2942 ranges.push((start, start.saturating_add(width)));
2943 }
2944 if case % 17 == 0 {
2945 ranges.push((TOKEN_EOF, TOKEN_EOF));
2946 }
2947 if case % 29 == 0 {
2948 ranges.push((i32::MAX, i32::MAX));
2949 }
2950 let normalized = normalize_ranges(ranges);
2951 let atn = token_set_atn(i32::MAX, &normalized);
2952 let set = atn.token_set(0).expect("randomized set");
2953 for token in [TOKEN_EOF, -3, 0, 1, 63, 64, 127, 128, 2_048, i32::MAX] {
2954 let expected = normalized
2955 .iter()
2956 .any(|(start, stop)| (*start..=*stop).contains(&token));
2957 assert_eq!(
2958 set.contains(token),
2959 expected,
2960 "case {case}, token {token}, kind {:?}, ranges {normalized:?}",
2961 set.kind()
2962 );
2963 }
2964 for _ in 0..64 {
2965 let token = (next_random(&mut random) % 2_200) as i32 - 16;
2966 let expected = normalized
2967 .iter()
2968 .any(|(start, stop)| (*start..=*stop).contains(&token));
2969 assert_eq!(set.contains(token), expected, "case {case}, token {token}");
2970 }
2971 }
2972 }
2973
2974 fn next_random(state: &mut u64) -> u64 {
2975 *state ^= *state << 13;
2976 *state ^= *state >> 7;
2977 *state ^= *state << 17;
2978 *state
2979 }
2980
2981 #[cfg(target_pointer_width = "64")]
2982 #[test]
2983 fn header_encoding_rejects_values_outside_u32() {
2984 let builder = ParserAtnBuilder::new(0);
2985 let section = Section {
2986 offset: HEADER_WORDS,
2987 len: 0,
2988 };
2989 let mut layout = EncodedLayout {
2990 states: section,
2991 transitions: section,
2992 sets: section,
2993 intervals: section,
2994 token_bits: section,
2995 decisions: section,
2996 rule_starts: section,
2997 rule_stops: section,
2998 total_len: usize::MAX,
2999 };
3000 let mut words = [0; HEADER_WORDS];
3001
3002 assert_eq!(
3003 builder.encode_header(&mut words, layout),
3004 Err(ParserAtnError::Overflow {
3005 field: "packed parser ATN word",
3006 value: usize::MAX,
3007 })
3008 );
3009
3010 layout.states.offset = usize::MAX;
3011 layout.total_len = HEADER_WORDS;
3012 assert_eq!(
3013 builder.encode_header(&mut words, layout),
3014 Err(ParserAtnError::Overflow {
3015 field: "parser ATN section offset",
3016 value: usize::MAX,
3017 })
3018 );
3019 }
3020
3021 #[test]
3022 fn rejects_invalid_header_and_section_layout() {
3023 let atn = sample_atn();
3024 let cases = [
3025 (HEADER_MAGIC, 0, "magic"),
3026 (HEADER_BYTE_ORDER, 0x0403_0201, "byte-order marker"),
3027 (HEADER_SIZE, 0, "header length"),
3028 (HEADER_STATES_OFFSET, 0, "states section starts"),
3029 (HEADER_STATES_OFFSET + 1, 0, "states section has 0 words"),
3030 (HEADER_TOTAL_LEN, 0, "declared total length"),
3031 ];
3032 for (word, value, expected) in cases {
3033 let mut words = atn.packed_words().to_vec();
3034 words[word] = value;
3035 let error = ParserAtn::from_owned(words).expect_err("invalid format must fail");
3036 assert!(
3037 error.to_string().contains(expected),
3038 "{error} did not contain {expected:?}"
3039 );
3040 }
3041 }
3042
3043 #[test]
3044 fn rejects_non_contiguous_state_transition_ranges() {
3045 let atn = sample_atn();
3046 let mut words = atn.packed_words().to_vec();
3047 let second_state = atn.layout.states.offset + STATE_WORDS;
3048 words[second_state + 3] = 0;
3049 let error = ParserAtn::from_owned(words).expect_err("overlapping ranges must fail");
3050 assert!(error.to_string().contains("transition range starts"));
3051 }
3052
3053 #[test]
3054 fn interval_sets_share_one_range_pool() {
3055 let mut builder = ParserAtnBuilder::new(20);
3056 builder
3057 .add_state(AtnStateKind::RuleStart, Some(0))
3058 .expect("start");
3059 builder
3060 .add_state(AtnStateKind::RuleStop, Some(0))
3061 .expect("stop");
3062 builder
3063 .set_rule_to_start_state(vec![0])
3064 .expect("rule starts");
3065 builder.set_rule_to_stop_state(vec![1]).expect("rule stops");
3066 let set = builder
3067 .add_interval_set([(2, 4), (4, 8), (10, 10)])
3068 .expect("set");
3069 builder
3070 .add_transition(0, ParserTransitionSpec::Set { target: 1, set })
3071 .expect("set transition");
3072 let atn = builder.finish().expect("ATN");
3073 let transition = atn
3074 .state(0)
3075 .expect("start")
3076 .transitions()
3077 .first()
3078 .expect("transition");
3079 let ParserTransitionData::Set { set, .. } = transition.data() else {
3080 panic!("expected set transition");
3081 };
3082 assert_eq!(set.ranges().collect::<Vec<_>>(), vec![(2, 8), (10, 10)]);
3083 assert!(set.contains(7));
3084 assert!(!set.contains(9));
3085 assert_eq!(atn.stats().interval_ranges, 2);
3086 }
3087
3088 #[test]
3089 fn rejects_out_of_range_transition_target() {
3090 let atn = sample_atn();
3091 let mut words = atn.packed_words().to_vec();
3092 let target = atn.layout.transitions.offset + 1;
3093 words[target] = 99;
3094 assert!(matches!(
3095 ParserAtn::from_owned(words),
3096 Err(ParserAtnError::InvalidData(message))
3097 if message.contains("transition target")
3098 ));
3099 }
3100
3101 #[test]
3102 fn not_set_membership_preserves_vocabulary_bounds() {
3103 let mut builder = ParserAtnBuilder::new(5);
3104 builder
3105 .add_state(AtnStateKind::RuleStart, Some(0))
3106 .expect("start");
3107 builder
3108 .add_state(AtnStateKind::RuleStop, Some(0))
3109 .expect("stop");
3110 builder
3111 .set_rule_to_start_state(vec![0])
3112 .expect("rule starts");
3113 builder.set_rule_to_stop_state(vec![1]).expect("rule stops");
3114 let excluded = builder.add_interval_set([(2, 4)]).expect("excluded set");
3115 builder
3116 .add_transition(
3117 0,
3118 ParserTransitionSpec::NotSet {
3119 target: 1,
3120 set: excluded,
3121 },
3122 )
3123 .expect("not-set transition");
3124 let atn = builder.finish().expect("ATN");
3125 let transition = atn
3126 .state(0)
3127 .expect("start")
3128 .transitions()
3129 .first()
3130 .expect("transition");
3131
3132 assert!(transition.matches(1, 1, 5));
3133 assert!(!transition.matches(2, 1, 5));
3134 assert!(!transition.matches(4, 1, 5));
3135 assert!(transition.matches(5, 1, 5));
3136 assert!(!transition.matches(TOKEN_EOF, 1, 5));
3137 assert!(!transition.matches(0, 1, 5));
3138 assert!(!transition.matches(6, 1, 5));
3139 }
3140
3141 #[test]
3142 fn rejects_inconsistent_adaptive_token_set_bits() {
3143 let atn = token_set_atn(127, &[(1, 3), (63, 64), (127, 127)]);
3144 let mut words = atn.packed_words().to_vec();
3145 words[atn.layout.token_bits.offset] ^= 1 << 1;
3146 let error = ParserAtn::from_owned(words).expect_err("corrupted token bits must fail");
3147 assert!(error.to_string().contains("bit word"), "{error}");
3148
3149 let mut words = atn.packed_words().to_vec();
3150 words[atn.layout.sets.offset + 2] = 99;
3151 let error = ParserAtn::from_owned(words).expect_err("unknown token-set kind must fail");
3152 assert!(error.to_string().contains("token-set kind"), "{error}");
3153 }
3154
3155 #[cfg(feature = "perf-counters")]
3156 #[test]
3157 fn token_set_counters_report_selection_and_probes() {
3158 crate::perf::reset();
3159 let before = crate::perf::parser_token_set_snapshot();
3160 let inline_atn = token_set_atn(10, &[(1, 4)]);
3161 let dense_ranges = (1..=256)
3162 .step_by(2)
3163 .map(|token| (token, token))
3164 .collect::<Vec<_>>();
3165 let dense_atn = token_set_atn(256, &dense_ranges);
3166 let interval_atn = token_set_atn(i32::MAX, &[(1, 1), (i32::MAX, i32::MAX)]);
3167 let inline = inline_atn.token_set(0).expect("inline");
3168 let dense = dense_atn.token_set(0).expect("dense");
3169 let intervals = interval_atn.token_set(0).expect("intervals");
3170
3171 assert!(inline.contains(2));
3172 assert!(!inline.contains(9));
3173 assert!(dense.contains(255));
3174 assert!(!dense.contains(256));
3175 assert!(intervals.contains(i32::MAX));
3176 assert!(!intervals.contains(2));
3177
3178 let after = crate::perf::parser_token_set_snapshot();
3179 assert!(after[0] > before[0], "{before:?} -> {after:?}");
3180 assert!(after[1] > before[1], "{before:?} -> {after:?}");
3181 assert!(after[2] > before[2], "{before:?} -> {after:?}");
3182 assert_eq!(after[5] - before[5], 1);
3183 assert_eq!(after[6] - before[6], 1);
3184 assert_eq!(after[7] - before[7], 1);
3185 assert_eq!(after[8] - before[8], 1);
3186 assert_eq!(after[9] - before[9], 1);
3187 assert_eq!(after[10] - before[10], 1);
3188 assert_eq!(after[11] - before[11], 4);
3189 assert_eq!(after[12] - before[12], 2);
3190 }
3191
3192 #[test]
3193 fn eof_interval_is_preserved_as_signed_data() {
3194 let mut builder = ParserAtnBuilder::new(3);
3195 builder
3196 .add_state(AtnStateKind::RuleStart, Some(0))
3197 .expect("start");
3198 builder
3199 .add_state(AtnStateKind::RuleStop, Some(0))
3200 .expect("stop");
3201 builder
3202 .set_rule_to_start_state(vec![0])
3203 .expect("rule starts");
3204 builder.set_rule_to_stop_state(vec![1]).expect("rule stops");
3205 let set = builder
3206 .add_interval_set([(TOKEN_EOF, TOKEN_EOF)])
3207 .expect("set");
3208 builder
3209 .add_transition(0, ParserTransitionSpec::Set { target: 1, set })
3210 .expect("transition");
3211 let atn = builder.finish().expect("ATN");
3212 let transition = atn
3213 .state(0)
3214 .expect("start")
3215 .transitions()
3216 .first()
3217 .expect("transition");
3218 assert!(transition.matches(TOKEN_EOF, 1, 3));
3219 }
3220}