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