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