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