1use crate::errors::AntlrError;
2use crate::recognizer::Recognizer;
3use crate::token::{Token, TokenId, TokenStore, TokenView};
4use std::any::Any;
5use std::collections::BTreeMap;
6use std::fmt;
7use std::mem::size_of;
8
9const NONE: u32 = u32::MAX;
10const FLAG_MATCHED_CHILD: u8 = 1 << 0;
11const FLAG_START_PRESENT: u8 = 1 << 1;
12const FLAG_STOP_PRESENT: u8 = 1 << 2;
13
14#[repr(transparent)]
15#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
16pub struct NodeId(u32);
17
18impl NodeId {
19 pub(crate) const fn placeholder() -> Self {
20 Self(NONE)
21 }
22
23 #[must_use]
24 pub const fn index(self) -> usize {
25 self.0 as usize
26 }
27}
28
29pub type ParseTree = NodeId;
31
32#[repr(u8)]
33#[derive(Clone, Copy, Debug, Eq, PartialEq)]
34pub enum NodeKind {
35 Rule,
36 Terminal,
37 Error,
38}
39
40#[derive(Debug)]
41struct ChildLink {
42 node: NodeId,
43 next: u32,
44}
45
46#[derive(Debug)]
47struct RuleExtra {
48 int_returns: BTreeMap<String, i64>,
49 exception: Option<AntlrError>,
50 attrs: Option<GeneratedAttrs>,
51}
52
53#[derive(Debug)]
54enum ParseTreeExtra {
55 Rule(RuleExtra),
56}
57
58#[derive(Debug, Default)]
64pub struct ParseTreeStorage {
65 kinds: Vec<NodeKind>,
66 child_starts: Vec<u32>,
67 child_lens: Vec<u32>,
68 payload_a: Vec<u32>,
69 payload_b: Vec<u32>,
70 starts: Vec<u32>,
71 stops: Vec<u32>,
72 alt_numbers: Vec<u32>,
73 extra_ids: Vec<u32>,
74 parents: Vec<u32>,
75 flags: Vec<u8>,
76 children: Vec<NodeId>,
77 extras: Vec<ParseTreeExtra>,
78 child_links: Vec<ChildLink>,
79}
80
81#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
82pub struct ParseTreeStats {
83 pub nodes: usize,
84 pub edges: usize,
85 pub extras: usize,
86 pub scratch_links: usize,
87 pub allocated_bytes: usize,
88}
89
90#[derive(Clone, Copy, Debug, Eq, PartialEq)]
91pub(crate) struct ParseTreeCheckpoint {
92 nodes: usize,
93 children: usize,
94 extras: usize,
95 child_links: usize,
96}
97
98impl ParseTreeStorage {
99 #[must_use]
100 pub const fn new() -> Self {
101 Self {
102 kinds: Vec::new(),
103 child_starts: Vec::new(),
104 child_lens: Vec::new(),
105 payload_a: Vec::new(),
106 payload_b: Vec::new(),
107 starts: Vec::new(),
108 stops: Vec::new(),
109 alt_numbers: Vec::new(),
110 extra_ids: Vec::new(),
111 parents: Vec::new(),
112 flags: Vec::new(),
113 children: Vec::new(),
114 extras: Vec::new(),
115 child_links: Vec::new(),
116 }
117 }
118
119 #[must_use]
120 pub const fn node_count(&self) -> usize {
121 self.kinds.len()
122 }
123
124 #[must_use]
125 pub const fn edge_count(&self) -> usize {
126 self.children.len()
127 }
128
129 #[must_use]
130 pub const fn extra_count(&self) -> usize {
131 self.extras.len()
132 }
133
134 #[must_use]
135 pub const fn stats(&self) -> ParseTreeStats {
136 ParseTreeStats {
137 nodes: self.node_count(),
138 edges: self.edge_count(),
139 extras: self.extra_count(),
140 scratch_links: self.child_links.len(),
141 allocated_bytes: self.kinds.capacity() * size_of::<NodeKind>()
142 + self.child_starts.capacity() * size_of::<u32>()
143 + self.child_lens.capacity() * size_of::<u32>()
144 + self.payload_a.capacity() * size_of::<u32>()
145 + self.payload_b.capacity() * size_of::<u32>()
146 + self.starts.capacity() * size_of::<u32>()
147 + self.stops.capacity() * size_of::<u32>()
148 + self.alt_numbers.capacity() * size_of::<u32>()
149 + self.extra_ids.capacity() * size_of::<u32>()
150 + self.parents.capacity() * size_of::<u32>()
151 + self.flags.capacity() * size_of::<u8>()
152 + self.children.capacity() * size_of::<NodeId>()
153 + self.extras.capacity() * size_of::<ParseTreeExtra>()
154 + self.child_links.capacity() * size_of::<ChildLink>(),
155 }
156 }
157
158 pub(crate) fn release_scratch(&mut self) {
159 self.child_links.clear();
160 }
161
162 pub(crate) fn discard_scratch(&mut self) {
163 self.child_links = Vec::new();
164 }
165
166 pub(crate) const fn checkpoint(&self) -> ParseTreeCheckpoint {
167 ParseTreeCheckpoint {
168 nodes: self.kinds.len(),
169 children: self.children.len(),
170 extras: self.extras.len(),
171 child_links: self.child_links.len(),
172 }
173 }
174
175 pub(crate) fn rollback(&mut self, checkpoint: ParseTreeCheckpoint) {
176 self.kinds.truncate(checkpoint.nodes);
177 self.child_starts.truncate(checkpoint.nodes);
178 self.child_lens.truncate(checkpoint.nodes);
179 self.payload_a.truncate(checkpoint.nodes);
180 self.payload_b.truncate(checkpoint.nodes);
181 self.starts.truncate(checkpoint.nodes);
182 self.stops.truncate(checkpoint.nodes);
183 self.alt_numbers.truncate(checkpoint.nodes);
184 self.extra_ids.truncate(checkpoint.nodes);
185 self.parents.truncate(checkpoint.nodes);
186 self.flags.truncate(checkpoint.nodes);
187 self.children.truncate(checkpoint.children);
188 self.extras.truncate(checkpoint.extras);
189 self.child_links.truncate(checkpoint.child_links);
190 }
191
192 pub(crate) fn terminal(&mut self, token: TokenId) -> NodeId {
193 self.push_node(NodeRecord {
194 kind: NodeKind::Terminal,
195 payload_a: token.index() as u32,
196 ..NodeRecord::default()
197 })
198 }
199
200 pub(crate) fn error(&mut self, token: TokenId) -> NodeId {
201 self.push_node(NodeRecord {
202 kind: NodeKind::Error,
203 payload_a: token.index() as u32,
204 ..NodeRecord::default()
205 })
206 }
207
208 pub(crate) fn add_child(&mut self, context: &mut ParserRuleContext, child: NodeId) {
209 context.matched_child = true;
210 let link = self.child_links.len_u32("parse-tree scratch child links");
211 self.child_links.push(ChildLink {
212 node: child,
213 next: NONE,
214 });
215 if context.first_child == NONE {
216 context.first_child = link;
217 } else {
218 self.child_links[context.last_child as usize].next = link;
219 }
220 context.last_child = link;
221 context.child_count = context
222 .child_count
223 .checked_add(1)
224 .expect("rule child count exceeds u32");
225 }
226
227 pub(crate) fn finish_rule(&mut self, context: ParserRuleContext) -> NodeId {
228 let parent = NodeId(self.kinds.len_u32("parse-tree node pool"));
229 let child_start = self.children.len_u32("parse-tree child pool");
230 let mut link = context.first_child;
231 while link != NONE {
232 let child = &self.child_links[link as usize];
233 self.children.push(child.node);
234 self.parents[child.node.index()] = parent.0;
235 link = child.next;
236 }
237
238 let extra_id = if context.int_returns.is_empty()
239 && context.exception.is_none()
240 && context.attrs.is_none()
241 {
242 NONE
243 } else {
244 let id = self.extras.len_u32("parse-tree extra pool");
245 self.extras.push(ParseTreeExtra::Rule(RuleExtra {
246 int_returns: context.int_returns,
247 exception: context.exception,
248 attrs: context.attrs,
249 }));
250 id
251 };
252
253 self.push_node(NodeRecord {
254 kind: NodeKind::Rule,
255 child_start,
256 child_len: context.child_count,
257 payload_a: u32::try_from(context.rule_index).expect("rule index exceeds u32"),
258 payload_b: i32::try_from(context.invoking_state)
259 .expect("invoking state exceeds i32")
260 .cast_unsigned(),
261 start: context.start.map_or(NONE, |token| token.index() as u32),
262 stop: context.stop.map_or(NONE, |token| token.index() as u32),
263 alt_number: u32::try_from(context.alt_number).expect("alternative number exceeds u32"),
264 extra_id,
265 flags: (u8::from(context.matched_child) * FLAG_MATCHED_CHILD)
266 | (u8::from(context.start.is_some()) * FLAG_START_PRESENT)
267 | (u8::from(context.stop.is_some()) * FLAG_STOP_PRESENT),
268 })
269 }
270
271 fn push_node(&mut self, record: NodeRecord) -> NodeId {
272 let id = NodeId(self.kinds.len_u32("parse-tree node pool"));
273 self.kinds.push(record.kind);
274 self.child_starts.push(record.child_start);
275 self.child_lens.push(record.child_len);
276 self.payload_a.push(record.payload_a);
277 self.payload_b.push(record.payload_b);
278 self.starts.push(record.start);
279 self.stops.push(record.stop);
280 self.alt_numbers.push(record.alt_number);
281 self.extra_ids.push(record.extra_id);
282 self.parents.push(NONE);
283 self.flags.push(record.flags);
284 id
285 }
286
287 #[must_use]
288 pub fn node<'tree>(&'tree self, tokens: &'tree TokenStore, id: NodeId) -> Option<Node<'tree>> {
289 (id.index() < self.node_count()).then_some(Node {
290 storage: self,
291 tokens,
292 id,
293 })
294 }
295
296 fn kind(&self, id: NodeId) -> NodeKind {
297 self.kinds[id.index()]
298 }
299
300 fn child_ids(&self, id: NodeId) -> &[NodeId] {
301 let index = id.index();
302 let start = self.child_starts[index] as usize;
303 let len = self.child_lens[index] as usize;
304 &self.children[start..start + len]
305 }
306
307 const fn context_child_ids<'a>(
308 &'a self,
309 context: &'a ParserRuleContext,
310 ) -> ContextChildIds<'a> {
311 ContextChildIds {
312 storage: self,
313 next: context.first_child,
314 remaining: context.child_count as usize,
315 }
316 }
317
318 fn token_id(&self, id: NodeId) -> Option<TokenId> {
319 match self.kind(id) {
320 NodeKind::Terminal | NodeKind::Error => {
321 Some(stored_token_id(self.payload_a[id.index()]))
322 }
323 NodeKind::Rule => None,
324 }
325 }
326
327 fn rule_extra(&self, id: NodeId) -> Option<&RuleExtra> {
328 let extra = *self.extra_ids.get(id.index())?;
329 if extra == NONE {
330 return None;
331 }
332 match &self.extras[extra as usize] {
333 ParseTreeExtra::Rule(extra) => Some(extra),
334 }
335 }
336}
337
338#[derive(Clone, Copy)]
339struct NodeRecord {
340 kind: NodeKind,
341 child_start: u32,
342 child_len: u32,
343 payload_a: u32,
344 payload_b: u32,
345 start: u32,
346 stop: u32,
347 alt_number: u32,
348 extra_id: u32,
349 flags: u8,
350}
351
352impl Default for NodeRecord {
353 fn default() -> Self {
354 Self {
355 kind: NodeKind::Rule,
356 child_start: 0,
357 child_len: 0,
358 payload_a: 0,
359 payload_b: 0,
360 start: NONE,
361 stop: NONE,
362 alt_number: 0,
363 extra_id: NONE,
364 flags: 0,
365 }
366 }
367}
368
369trait LenU32 {
370 fn len_u32(&self, name: &str) -> u32;
371}
372
373impl<T> LenU32 for Vec<T> {
374 fn len_u32(&self, name: &str) -> u32 {
375 u32::try_from(self.len()).unwrap_or_else(|_| panic!("{name} exceeds u32"))
376 }
377}
378
379#[derive(Clone, Copy, Debug)]
380pub struct Node<'tree> {
381 storage: &'tree ParseTreeStorage,
382 tokens: &'tree TokenStore,
383 id: NodeId,
384}
385
386impl<'tree> Node<'tree> {
387 #[must_use]
388 pub const fn id(self) -> NodeId {
389 self.id
390 }
391
392 #[must_use]
393 pub fn kind(self) -> NodeKind {
394 self.storage.kind(self.id)
395 }
396
397 #[must_use]
398 pub fn as_rule(self) -> Option<RuleNodeView<'tree>> {
399 (self.kind() == NodeKind::Rule).then_some(RuleNodeView { node: self })
400 }
401
402 #[must_use]
403 pub fn as_terminal(self) -> Option<TerminalNodeView<'tree>> {
404 (self.kind() == NodeKind::Terminal).then_some(TerminalNodeView { node: self })
405 }
406
407 #[must_use]
408 pub fn as_error(self) -> Option<ErrorNodeView<'tree>> {
409 (self.kind() == NodeKind::Error).then_some(ErrorNodeView { node: self })
410 }
411
412 #[must_use]
413 pub fn children(self) -> NodeChildren<'tree> {
414 NodeChildren {
415 storage: self.storage,
416 tokens: self.tokens,
417 ids: self.storage.child_ids(self.id).iter(),
418 }
419 }
420
421 #[must_use]
422 pub fn parent(self) -> Option<Self> {
423 let parent = self.storage.parents[self.id.index()];
424 (parent != NONE)
425 .then(|| self.storage.node(self.tokens, NodeId(parent)))
426 .flatten()
427 }
428
429 #[must_use]
430 pub fn descendants(self) -> ParseTreeDescendants<'tree> {
431 ParseTreeDescendants {
432 storage: self.storage,
433 tokens: self.tokens,
434 stack: vec![self.id],
435 }
436 }
437
438 #[must_use]
439 pub fn pre_order(self) -> ParseTreeDescendants<'tree> {
440 self.descendants()
441 }
442
443 #[must_use]
444 pub fn text(self) -> String {
445 match self.kind() {
446 NodeKind::Terminal | NodeKind::Error => self
447 .storage
448 .token_id(self.id)
449 .and_then(|id| self.tokens.text(id))
450 .unwrap_or("")
451 .to_owned(),
452 NodeKind::Rule => {
453 let mut text = String::new();
454 let mut stack = self
455 .storage
456 .child_ids(self.id)
457 .iter()
458 .rev()
459 .copied()
460 .collect::<Vec<_>>();
461 while let Some(id) = stack.pop() {
462 match self.storage.kind(id) {
463 NodeKind::Rule => {
464 stack.extend(self.storage.child_ids(id).iter().rev().copied());
465 }
466 NodeKind::Terminal | NodeKind::Error => text.push_str(
467 self.storage
468 .token_id(id)
469 .and_then(|token| self.tokens.text(token))
470 .unwrap_or(""),
471 ),
472 }
473 }
474 text
475 }
476 }
477 }
478
479 #[must_use]
480 pub fn to_string_tree_with_names<S: AsRef<str>>(self, rule_names: &[S]) -> String {
481 match self.kind() {
482 NodeKind::Rule => self
483 .as_rule()
484 .expect("rule node kind checked")
485 .to_string_tree_with_names(rule_names),
486 NodeKind::Terminal | NodeKind::Error => escape_tree_text(
487 self.storage
488 .token_id(self.id)
489 .and_then(|id| self.tokens.text(id))
490 .unwrap_or(""),
491 ),
492 }
493 }
494
495 #[must_use]
496 pub fn to_string_tree<R: Recognizer>(
497 self,
498 recognizer: Option<&R>,
499 _tokens: &TokenStore,
500 ) -> String {
501 recognizer.map_or_else(
502 || self.to_string_tree_with_names::<&str>(&[]),
503 |recognizer| self.to_string_tree_with_names(recognizer.data().rule_names()),
504 )
505 }
506
507 #[must_use]
508 pub fn first_rule(self, rule_index: usize) -> Option<Self> {
509 self.descendants().find(|node| {
510 node.as_rule()
511 .is_some_and(|rule| rule.rule_index() == rule_index)
512 })
513 }
514
515 #[must_use]
516 pub fn first_rule_stop(self, rule_index: usize) -> Option<TokenView<'tree>> {
517 self.first_rule(rule_index)?.as_rule()?.stop()
518 }
519
520 #[must_use]
521 pub fn first_rule_int_return(self, rule_index: usize, name: &str) -> Option<i64> {
522 self.first_rule(rule_index)?.as_rule()?.int_return(name)
523 }
524
525 #[must_use]
526 pub fn rule_attrs<T: Any>(self) -> Option<&'tree T> {
527 self.as_rule()?.generated_attrs::<T>()
528 }
529
530 #[must_use]
531 pub fn first_error_token(self) -> Option<TokenView<'tree>> {
532 self.descendants()
533 .find_map(Node::as_error)
534 .map(ErrorNodeView::symbol)
535 }
536
537 #[must_use]
538 pub fn rule_invocation_stack<S: AsRef<str>>(
539 self,
540 rule_index: usize,
541 rule_names: &[S],
542 ) -> Option<Vec<String>> {
543 let mut stack = vec![(self.id, 0_usize)];
544 let mut names = Vec::new();
545 while let Some((id, child_index)) = stack.last_mut() {
546 if *child_index == 0 {
547 let Some(rule) = self.storage.node(self.tokens, *id).and_then(Node::as_rule) else {
548 stack.pop();
549 continue;
550 };
551 names.push(
552 rule_names
553 .get(rule.rule_index())
554 .map_or("<unknown>", |name| name.as_ref())
555 .to_owned(),
556 );
557 if rule.rule_index() == rule_index {
558 names.reverse();
559 return Some(names);
560 }
561 }
562 let children = self.storage.child_ids(*id);
563 let next = children.get(*child_index).copied();
564 *child_index += 1;
565 if let Some(child) = next {
566 if self.storage.kind(child) == NodeKind::Rule {
567 stack.push((child, 0));
568 }
569 } else {
570 stack.pop();
571 names.pop();
572 }
573 }
574 None
575 }
576}
577
578#[derive(Clone, Debug)]
579pub struct NodeChildren<'tree> {
580 storage: &'tree ParseTreeStorage,
581 tokens: &'tree TokenStore,
582 ids: std::slice::Iter<'tree, NodeId>,
583}
584
585impl<'tree> Iterator for NodeChildren<'tree> {
586 type Item = Node<'tree>;
587
588 fn next(&mut self) -> Option<Self::Item> {
589 self.ids
590 .next()
591 .and_then(|id| self.storage.node(self.tokens, *id))
592 }
593
594 fn size_hint(&self) -> (usize, Option<usize>) {
595 self.ids.size_hint()
596 }
597}
598
599impl DoubleEndedIterator for NodeChildren<'_> {
600 fn next_back(&mut self) -> Option<Self::Item> {
601 self.ids
602 .next_back()
603 .and_then(|id| self.storage.node(self.tokens, *id))
604 }
605}
606
607impl ExactSizeIterator for NodeChildren<'_> {}
608
609#[derive(Clone, Debug)]
610pub struct ParseTreeDescendants<'tree> {
611 storage: &'tree ParseTreeStorage,
612 tokens: &'tree TokenStore,
613 stack: Vec<NodeId>,
614}
615
616impl<'tree> Iterator for ParseTreeDescendants<'tree> {
617 type Item = Node<'tree>;
618
619 fn next(&mut self) -> Option<Self::Item> {
620 let id = self.stack.pop()?;
621 self.stack
622 .extend(self.storage.child_ids(id).iter().rev().copied());
623 Some(Node {
624 storage: self.storage,
625 tokens: self.tokens,
626 id,
627 })
628 }
629}
630
631#[derive(Clone, Copy, Debug)]
632pub struct RuleNodeView<'tree> {
633 node: Node<'tree>,
634}
635
636impl<'tree> RuleNodeView<'tree> {
637 #[must_use]
638 pub const fn node(self) -> Node<'tree> {
639 self.node
640 }
641
642 #[must_use]
643 pub fn rule_index(self) -> usize {
644 self.node.storage.payload_a[self.node.id.index()] as usize
645 }
646
647 #[must_use]
648 pub fn invoking_state(self) -> isize {
649 self.node.storage.payload_b[self.node.id.index()].cast_signed() as isize
650 }
651
652 #[must_use]
653 pub fn alt_number(self) -> usize {
654 self.node.storage.alt_numbers[self.node.id.index()] as usize
655 }
656
657 #[must_use]
658 pub fn start(self) -> Option<TokenView<'tree>> {
659 self.start_id().and_then(|id| self.node.tokens.view(id))
660 }
661
662 #[must_use]
663 pub fn start_id(self) -> Option<TokenId> {
664 let index = self.node.id.index();
665 (self.node.storage.flags[index] & FLAG_START_PRESENT != 0)
666 .then(|| stored_token_id(self.node.storage.starts[index]))
667 }
668
669 #[must_use]
670 pub fn stop(self) -> Option<TokenView<'tree>> {
671 self.stop_id().and_then(|id| self.node.tokens.view(id))
672 }
673
674 #[must_use]
675 pub fn stop_id(self) -> Option<TokenId> {
676 let index = self.node.id.index();
677 (self.node.storage.flags[index] & FLAG_STOP_PRESENT != 0)
678 .then(|| stored_token_id(self.node.storage.stops[index]))
679 }
680
681 #[must_use]
682 pub fn children(self) -> NodeChildren<'tree> {
683 self.node.children()
684 }
685
686 #[must_use]
687 pub fn child_count(self) -> usize {
688 self.node.storage.child_lens[self.node.id.index()] as usize
689 }
690
691 #[must_use]
692 pub fn child_rule(self, rule_index: usize) -> Option<Self> {
693 self.child_rules(rule_index).next()
694 }
695
696 pub fn child_rules(self, rule_index: usize) -> impl DoubleEndedIterator<Item = Self> + 'tree {
697 self.children().filter_map(move |child| {
698 let rule = child.as_rule()?;
699 (rule.rule_index() == rule_index).then_some(rule)
700 })
701 }
702
703 pub fn child_rule_trees(
704 self,
705 rule_index: usize,
706 ) -> impl DoubleEndedIterator<Item = Node<'tree>> + 'tree {
707 self.child_rules(rule_index).map(Self::node)
708 }
709
710 #[must_use]
711 pub fn child_token(self, token_type: i32) -> Option<TerminalNodeView<'tree>> {
712 self.child_tokens(token_type).next()
713 }
714
715 pub fn child_tokens(
716 self,
717 token_type: i32,
718 ) -> impl DoubleEndedIterator<Item = TerminalNodeView<'tree>> + 'tree {
719 self.children().filter_map(move |child| {
720 let terminal = match child.kind() {
721 NodeKind::Terminal => child.as_terminal(),
722 NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
723 NodeKind::Rule => None,
724 }?;
725 (terminal.symbol().token_type() == token_type).then_some(terminal)
726 })
727 }
728
729 pub fn terminal_children(
730 self,
731 ) -> impl DoubleEndedIterator<Item = TerminalNodeView<'tree>> + 'tree {
732 self.children().filter_map(|child| match child.kind() {
733 NodeKind::Terminal => child.as_terminal(),
734 NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
735 NodeKind::Rule => None,
736 })
737 }
738
739 #[must_use]
740 pub fn has_token(self, token_type: i32) -> bool {
741 self.child_token(token_type).is_some()
742 }
743
744 #[must_use]
745 pub fn text(self) -> String {
746 self.node.text()
747 }
748
749 #[must_use]
750 pub fn int_return(self, name: &str) -> Option<i64> {
751 self.node
752 .storage
753 .rule_extra(self.node.id)?
754 .int_returns
755 .get(name)
756 .copied()
757 }
758
759 #[must_use]
760 pub fn generated_attrs<T: Any>(self) -> Option<&'tree T> {
761 self.node
762 .storage
763 .rule_extra(self.node.id)?
764 .attrs
765 .as_ref()?
766 .downcast_ref::<T>()
767 }
768
769 #[must_use]
770 pub fn exception(self) -> Option<&'tree AntlrError> {
771 self.node
772 .storage
773 .rule_extra(self.node.id)?
774 .exception
775 .as_ref()
776 }
777
778 #[must_use]
779 pub fn downcast_ref<T: FromRuleNode<'tree>>(self) -> Option<T> {
780 T::from_rule_node(self)
781 }
782
783 pub fn invocation_states(self) -> impl Iterator<Item = isize> + 'tree {
784 std::iter::successors(Some(self), |rule| rule.node.parent()?.as_rule())
785 .take_while(|rule| rule.node.parent().is_some() && rule.invoking_state() >= 0)
786 .map(Self::invoking_state)
787 }
788
789 #[must_use]
790 pub fn to_string_tree_with_names<S: AsRef<str>>(self, rule_names: &[S]) -> String {
791 let name = rule_names
792 .get(self.rule_index())
793 .map_or("<unknown>", |name| name.as_ref());
794 let display_name = if self.alt_number() == 0 {
795 name.to_owned()
796 } else {
797 format!("{name}:{}", self.alt_number())
798 };
799 if self.child_count() == 0 {
800 return display_name;
801 }
802 let children = self
803 .children()
804 .map(|child| child.to_string_tree_with_names(rule_names))
805 .collect::<Vec<_>>()
806 .join(" ");
807 format!("({display_name} {children})")
808 }
809
810 #[must_use]
811 pub fn to_string_tree<R: Recognizer>(self, recognizer: Option<&R>) -> String {
812 recognizer.map_or_else(
813 || self.to_string_tree_with_names::<&str>(&[]),
814 |recognizer| self.to_string_tree_with_names(recognizer.data().rule_names()),
815 )
816 }
817}
818
819#[derive(Clone, Copy, Debug)]
820pub struct TerminalNodeView<'tree> {
821 node: Node<'tree>,
822}
823
824impl<'tree> TerminalNodeView<'tree> {
825 #[must_use]
826 pub const fn node(self) -> Node<'tree> {
827 self.node
828 }
829
830 #[must_use]
831 pub fn token_id(self) -> TokenId {
832 self.node
833 .storage
834 .token_id(self.node.id)
835 .expect("terminal node should contain a token ID")
836 }
837
838 #[must_use]
839 pub fn symbol(self) -> TokenView<'tree> {
840 self.node
841 .tokens
842 .view(self.token_id())
843 .expect("terminal node token ID should remain valid")
844 }
845
846 #[must_use]
847 pub fn text(self) -> &'tree str {
848 self.node.tokens.text(self.token_id()).unwrap_or("")
849 }
850}
851
852#[derive(Clone, Copy, Debug)]
853pub struct ErrorNodeView<'tree> {
854 node: Node<'tree>,
855}
856
857impl<'tree> ErrorNodeView<'tree> {
858 #[must_use]
859 pub const fn node(self) -> Node<'tree> {
860 self.node
861 }
862
863 #[must_use]
864 pub const fn terminal(self) -> TerminalNodeView<'tree> {
865 TerminalNodeView { node: self.node }
866 }
867
868 #[must_use]
869 pub fn token_id(self) -> TokenId {
870 self.terminal().token_id()
871 }
872
873 #[must_use]
874 pub fn symbol(self) -> TokenView<'tree> {
875 self.terminal().symbol()
876 }
877
878 #[must_use]
879 pub fn text(self) -> &'tree str {
880 self.terminal().text()
881 }
882}
883
884#[derive(Debug)]
885struct ContextChildIds<'a> {
886 storage: &'a ParseTreeStorage,
887 next: u32,
888 remaining: usize,
889}
890
891impl Iterator for ContextChildIds<'_> {
892 type Item = NodeId;
893
894 fn next(&mut self) -> Option<Self::Item> {
895 if self.next == NONE {
896 return None;
897 }
898 let link = &self.storage.child_links[self.next as usize];
899 self.next = link.next;
900 self.remaining -= 1;
901 Some(link.node)
902 }
903
904 fn size_hint(&self) -> (usize, Option<usize>) {
905 (self.remaining, Some(self.remaining))
906 }
907}
908
909impl ExactSizeIterator for ContextChildIds<'_> {}
910
911#[derive(Debug)]
917pub struct ParserRuleContext {
918 rule_index: usize,
919 invoking_state: isize,
920 alt_number: usize,
921 start: Option<TokenId>,
922 stop: Option<TokenId>,
923 int_returns: BTreeMap<String, i64>,
924 first_child: u32,
925 last_child: u32,
926 child_count: u32,
927 matched_child: bool,
928 exception: Option<AntlrError>,
929 attrs: Option<GeneratedAttrs>,
930}
931
932impl ParserRuleContext {
933 #[must_use]
934 pub const fn new(rule_index: usize, invoking_state: isize) -> Self {
935 Self {
936 rule_index,
937 invoking_state,
938 alt_number: 0,
939 start: None,
940 stop: None,
941 int_returns: BTreeMap::new(),
942 first_child: NONE,
943 last_child: NONE,
944 child_count: 0,
945 matched_child: false,
946 exception: None,
947 attrs: None,
948 }
949 }
950
951 pub(crate) const fn with_child_capacity(
952 rule_index: usize,
953 invoking_state: isize,
954 _capacity: usize,
955 ) -> Self {
956 Self::new(rule_index, invoking_state)
957 }
958
959 #[must_use]
960 pub const fn rule_index(&self) -> usize {
961 self.rule_index
962 }
963
964 #[must_use]
965 pub const fn invoking_state(&self) -> isize {
966 self.invoking_state
967 }
968
969 #[must_use]
970 pub const fn alt_number(&self) -> usize {
971 self.alt_number
972 }
973
974 pub const fn set_alt_number(&mut self, alt_number: usize) {
975 self.alt_number = alt_number;
976 }
977
978 pub fn start<'a>(&self, tokens: &'a TokenStore) -> Option<TokenView<'a>> {
979 self.start.and_then(|id| tokens.view(id))
980 }
981
982 pub(crate) const fn start_id(&self) -> Option<TokenId> {
983 self.start
984 }
985
986 pub fn stop<'a>(&self, tokens: &'a TokenStore) -> Option<TokenView<'a>> {
987 self.stop.and_then(|id| tokens.view(id))
988 }
989
990 pub(crate) const fn set_start_id(&mut self, token: TokenId) {
991 self.start = Some(token);
992 }
993
994 pub(crate) const fn set_stop_id(&mut self, token: TokenId) {
995 self.stop = Some(token);
996 }
997
998 pub(crate) const fn set_start_from_context(&mut self, other: &Self) {
999 self.start = other.start;
1000 }
1001
1002 pub fn set_int_return(&mut self, name: impl Into<String>, value: i64) {
1003 self.int_returns.insert(name.into(), value);
1004 }
1005
1006 #[must_use]
1007 pub fn int_return(&self, name: &str) -> Option<i64> {
1008 self.int_returns.get(name).copied()
1009 }
1010
1011 pub fn set_generated_attrs(&mut self, attrs: GeneratedAttrs) {
1012 self.attrs = Some(attrs);
1013 }
1014
1015 #[must_use]
1016 pub fn generated_attrs<T: Any>(&self) -> Option<&T> {
1017 self.attrs.as_ref().and_then(GeneratedAttrs::downcast_ref)
1018 }
1019
1020 #[must_use]
1021 pub const fn exception(&self) -> Option<&AntlrError> {
1022 self.exception.as_ref()
1023 }
1024
1025 pub fn set_exception(&mut self, error: AntlrError) {
1026 self.exception = Some(error);
1027 }
1028
1029 #[must_use]
1030 pub const fn child_count(&self) -> usize {
1031 self.child_count as usize
1032 }
1033
1034 #[must_use]
1035 pub const fn has_matched_child(&self) -> bool {
1036 self.matched_child
1037 }
1038
1039 pub const fn note_matched_child(&mut self) {
1040 self.matched_child = true;
1041 }
1042
1043 pub fn child_nodes<'a>(
1044 &'a self,
1045 storage: &'a ParseTreeStorage,
1046 tokens: &'a TokenStore,
1047 ) -> impl Iterator<Item = Node<'a>> + 'a {
1048 storage
1049 .context_child_ids(self)
1050 .filter_map(move |id| storage.node(tokens, id))
1051 }
1052
1053 pub fn child_rules<'a>(
1054 &'a self,
1055 storage: &'a ParseTreeStorage,
1056 tokens: &'a TokenStore,
1057 rule_index: usize,
1058 ) -> impl Iterator<Item = RuleNodeView<'a>> + 'a {
1059 self.child_nodes(storage, tokens).filter_map(move |child| {
1060 let rule = child.as_rule()?;
1061 (rule.rule_index() == rule_index).then_some(rule)
1062 })
1063 }
1064
1065 pub fn child_rule_trees<'a>(
1066 &'a self,
1067 storage: &'a ParseTreeStorage,
1068 tokens: &'a TokenStore,
1069 rule_index: usize,
1070 ) -> impl Iterator<Item = Node<'a>> + 'a {
1071 self.child_rules(storage, tokens, rule_index)
1072 .map(RuleNodeView::node)
1073 }
1074
1075 pub fn child_tokens<'a>(
1076 &'a self,
1077 storage: &'a ParseTreeStorage,
1078 tokens: &'a TokenStore,
1079 token_type: i32,
1080 ) -> impl Iterator<Item = TerminalNodeView<'a>> + 'a {
1081 self.child_nodes(storage, tokens).filter_map(move |child| {
1082 let terminal = match child.kind() {
1083 NodeKind::Terminal => child.as_terminal(),
1084 NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
1085 NodeKind::Rule => None,
1086 }?;
1087 (terminal.symbol().token_type() == token_type).then_some(terminal)
1088 })
1089 }
1090
1091 pub fn terminal_children<'a>(
1092 &'a self,
1093 storage: &'a ParseTreeStorage,
1094 tokens: &'a TokenStore,
1095 ) -> impl Iterator<Item = TerminalNodeView<'a>> + 'a {
1096 self.child_nodes(storage, tokens)
1097 .filter_map(|child| match child.kind() {
1098 NodeKind::Terminal => child.as_terminal(),
1099 NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
1100 NodeKind::Rule => None,
1101 })
1102 }
1103
1104 #[must_use]
1105 pub fn text(&self, storage: &ParseTreeStorage, tokens: &TokenStore) -> String {
1106 self.child_nodes(storage, tokens).map(Node::text).collect()
1107 }
1108
1109 #[must_use]
1110 pub fn to_string_tree_with_names<S: AsRef<str>>(
1111 &self,
1112 storage: &ParseTreeStorage,
1113 tokens: &TokenStore,
1114 rule_names: &[S],
1115 ) -> String {
1116 let name = rule_names
1117 .get(self.rule_index)
1118 .map_or("<unknown>", |name| name.as_ref());
1119 let display_name = if self.alt_number == 0 {
1120 name.to_owned()
1121 } else {
1122 format!("{name}:{}", self.alt_number)
1123 };
1124 if self.child_count == 0 {
1125 return display_name;
1126 }
1127 let children = self
1128 .child_nodes(storage, tokens)
1129 .map(|child| child.to_string_tree_with_names(rule_names))
1130 .collect::<Vec<_>>()
1131 .join(" ");
1132 format!("({display_name} {children})")
1133 }
1134
1135 #[must_use]
1136 pub fn to_string_tree<R: Recognizer>(
1137 &self,
1138 recognizer: Option<&R>,
1139 storage: &ParseTreeStorage,
1140 tokens: &TokenStore,
1141 ) -> String {
1142 recognizer.map_or_else(
1143 || self.to_string_tree_with_names::<&str>(storage, tokens, &[]),
1144 |recognizer| {
1145 self.to_string_tree_with_names(storage, tokens, recognizer.data().rule_names())
1146 },
1147 )
1148 }
1149}
1150
1151pub struct GeneratedAttrs(Box<dyn Any>);
1153
1154impl GeneratedAttrs {
1155 #[must_use]
1156 pub fn new<T: Any>(attrs: T) -> Self {
1157 Self(Box::new(attrs))
1158 }
1159
1160 #[must_use]
1161 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
1162 self.0.downcast_ref::<T>()
1163 }
1164}
1165
1166impl fmt::Debug for GeneratedAttrs {
1167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1168 f.write_str("GeneratedAttrs(..)")
1169 }
1170}
1171
1172pub trait FromRuleNode<'tree>: Sized {
1173 fn from_rule_node(node: RuleNodeView<'tree>) -> Option<Self>;
1174}
1175
1176pub trait ParseTreeListener {
1177 fn enter_every_rule(&mut self, _ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1178 Ok(())
1179 }
1180
1181 fn exit_every_rule(&mut self, _ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1182 Ok(())
1183 }
1184
1185 fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Result<(), AntlrError> {
1186 Ok(())
1187 }
1188
1189 fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Result<(), AntlrError> {
1190 Ok(())
1191 }
1192}
1193
1194#[derive(Debug, Default)]
1195pub struct ParseTreeWalker;
1196
1197impl ParseTreeWalker {
1198 pub fn walk<L: ParseTreeListener>(listener: &mut L, tree: Node<'_>) -> Result<(), AntlrError> {
1199 enum Event {
1200 Enter(NodeId),
1201 Exit(NodeId),
1202 }
1203
1204 let storage = tree.storage;
1205 let tokens = tree.tokens;
1206 let mut stack = vec![Event::Enter(tree.id)];
1207 while let Some(event) = stack.pop() {
1208 match event {
1209 Event::Enter(id) => {
1210 let node = storage
1211 .node(tokens, id)
1212 .expect("walker node ID should remain valid");
1213 match node.kind() {
1214 NodeKind::Rule => {
1215 let rule = node.as_rule().expect("rule node kind checked");
1216 listener.enter_every_rule(rule)?;
1217 stack.push(Event::Exit(id));
1218 stack.extend(
1219 storage
1220 .child_ids(id)
1221 .iter()
1222 .rev()
1223 .copied()
1224 .map(Event::Enter),
1225 );
1226 }
1227 NodeKind::Terminal => listener.visit_terminal(
1228 node.as_terminal().expect("terminal node kind checked"),
1229 )?,
1230 NodeKind::Error => {
1231 listener.visit_error_node(
1232 node.as_error().expect("error node kind checked"),
1233 )?;
1234 }
1235 }
1236 }
1237 Event::Exit(id) => {
1238 let rule = storage
1239 .node(tokens, id)
1240 .and_then(Node::as_rule)
1241 .expect("walker exit node should remain a rule");
1242 listener.exit_every_rule(rule)?;
1243 }
1244 }
1245 }
1246 Ok(())
1247 }
1248}
1249
1250#[derive(Debug)]
1251pub struct ParsedFile {
1252 tokens: TokenStore,
1253 tree: ParseTreeStorage,
1254 root: NodeId,
1255}
1256
1257impl ParsedFile {
1258 #[must_use]
1259 pub fn new(tokens: TokenStore, mut tree: ParseTreeStorage, root: NodeId) -> Self {
1260 tree.discard_scratch();
1261 Self { tokens, tree, root }
1262 }
1263
1264 #[must_use]
1265 pub const fn tokens(&self) -> &TokenStore {
1266 &self.tokens
1267 }
1268
1269 #[must_use]
1270 pub const fn storage(&self) -> &ParseTreeStorage {
1271 &self.tree
1272 }
1273
1274 #[must_use]
1275 pub const fn root_id(&self) -> NodeId {
1276 self.root
1277 }
1278
1279 #[must_use]
1280 pub fn tree(&self) -> Node<'_> {
1281 self.tree
1282 .node(&self.tokens, self.root)
1283 .expect("parsed file root ID should remain valid")
1284 }
1285
1286 #[must_use]
1287 pub fn node(&self, id: NodeId) -> Option<Node<'_>> {
1288 self.tree.node(&self.tokens, id)
1289 }
1290
1291 #[must_use]
1292 pub fn into_parts(self) -> (TokenStore, ParseTreeStorage, NodeId) {
1293 (self.tokens, self.tree, self.root)
1294 }
1295}
1296
1297fn escape_tree_text(text: &str) -> String {
1298 let mut escaped = String::with_capacity(text.len());
1299 for ch in text.chars() {
1300 match ch {
1301 '\n' => escaped.push_str("\\n"),
1302 '\r' => escaped.push_str("\\r"),
1303 '\t' => escaped.push_str("\\t"),
1304 _ => escaped.push(ch),
1305 }
1306 }
1307 escaped
1308}
1309
1310fn stored_token_id(raw: u32) -> TokenId {
1311 TokenId::try_from(raw as usize).expect("stored token ID should fit in u32")
1312}
1313
1314#[cfg(test)]
1315mod tests {
1316 use super::*;
1317 use crate::token::TokenSpec;
1318
1319 fn token(store: &mut TokenStore, token_type: i32, text: &str) -> TokenId {
1320 store
1321 .push(TokenSpec::explicit(token_type, text))
1322 .expect("test token should fit")
1323 }
1324
1325 #[test]
1326 fn stores_rule_children_in_one_pooled_range() {
1327 let mut tokens = TokenStore::new(None, "");
1328 let first = token(&mut tokens, 1, "a");
1329 let second = token(&mut tokens, 2, "b");
1330 let mut storage = ParseTreeStorage::new();
1331 let first = storage.terminal(first);
1332 let second = storage.error(second);
1333 let mut context = ParserRuleContext::new(0, -1);
1334 storage.add_child(&mut context, first);
1335 storage.add_child(&mut context, second);
1336 let root = storage.finish_rule(context);
1337 let parsed = ParsedFile::new(tokens, storage, root);
1338
1339 assert_eq!(parsed.tree().text(), "ab");
1340 assert_eq!(parsed.tree().children().count(), 2);
1341 assert_eq!(parsed.storage().stats().edges, 2);
1342 assert_eq!(parsed.storage().stats().scratch_links, 0);
1343 assert_eq!(
1344 parsed.tree().to_string_tree_with_names(&["root"]),
1345 "(root a b)"
1346 );
1347 }
1348
1349 #[test]
1350 fn descendants_and_walker_preserve_antlr_order() {
1351 let mut tokens = TokenStore::new(None, "");
1352 let a = token(&mut tokens, 1, "a");
1353 let b = token(&mut tokens, 2, "b");
1354 let mut storage = ParseTreeStorage::new();
1355 let a = storage.terminal(a);
1356 let b = storage.terminal(b);
1357 let mut child = ParserRuleContext::new(1, 7);
1358 storage.add_child(&mut child, b);
1359 let child = storage.finish_rule(child);
1360 let mut root = ParserRuleContext::new(0, -1);
1361 storage.add_child(&mut root, a);
1362 storage.add_child(&mut root, child);
1363 let root = storage.finish_rule(root);
1364 let parsed = ParsedFile::new(tokens, storage, root);
1365
1366 let visited = parsed
1367 .tree()
1368 .descendants()
1369 .map(|node| match node.kind() {
1370 NodeKind::Rule => format!(
1371 "r{}",
1372 node.as_rule().expect("rule node kind checked").rule_index()
1373 ),
1374 NodeKind::Terminal => node
1375 .as_terminal()
1376 .expect("terminal node kind checked")
1377 .text()
1378 .to_owned(),
1379 NodeKind::Error => node
1380 .as_error()
1381 .expect("error node kind checked")
1382 .text()
1383 .to_owned(),
1384 })
1385 .collect::<Vec<_>>();
1386 assert_eq!(visited, ["r0", "a", "r1", "b"]);
1387
1388 #[derive(Default)]
1389 struct Listener(Vec<String>);
1390 impl ParseTreeListener for Listener {
1391 fn enter_every_rule(&mut self, ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1392 self.0.push(format!("enter{}", ctx.rule_index()));
1393 Ok(())
1394 }
1395
1396 fn exit_every_rule(&mut self, ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1397 self.0.push(format!("exit{}", ctx.rule_index()));
1398 Ok(())
1399 }
1400
1401 fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Result<(), AntlrError> {
1402 self.0.push(node.text().to_owned());
1403 Ok(())
1404 }
1405 }
1406 let mut listener = Listener::default();
1407 ParseTreeWalker::walk(&mut listener, parsed.tree())
1408 .expect("test listener should accept every node");
1409 assert_eq!(listener.0, ["enter0", "a", "enter1", "b", "exit1", "exit0"]);
1410 }
1411
1412 #[test]
1413 fn invocation_states_exclude_a_nonnegative_root_frame() {
1414 let tokens = TokenStore::new(None, "");
1415 let mut storage = ParseTreeStorage::new();
1416 let grandchild = storage.finish_rule(ParserRuleContext::new(2, 13));
1417 let mut child = ParserRuleContext::new(1, 7);
1418 storage.add_child(&mut child, grandchild);
1419 let child = storage.finish_rule(child);
1420 let mut root = ParserRuleContext::new(0, 4);
1421 storage.add_child(&mut root, child);
1422 let root = storage.finish_rule(root);
1423 let parsed = ParsedFile::new(tokens, storage, root);
1424
1425 let root = parsed
1426 .node(root)
1427 .and_then(Node::as_rule)
1428 .expect("root rule should be stored");
1429 let child = parsed
1430 .node(child)
1431 .and_then(Node::as_rule)
1432 .expect("child rule should be stored");
1433 let grandchild = parsed
1434 .node(grandchild)
1435 .and_then(Node::as_rule)
1436 .expect("grandchild rule should be stored");
1437
1438 assert_eq!(root.invocation_states().collect::<Vec<_>>(), []);
1439 assert_eq!(child.invocation_states().collect::<Vec<_>>(), [7]);
1440 assert_eq!(grandchild.invocation_states().collect::<Vec<_>>(), [13, 7]);
1441 }
1442
1443 #[test]
1444 fn uncommon_rule_payloads_live_in_sparse_extras() {
1445 let tokens = TokenStore::new(None, "");
1446 let mut storage = ParseTreeStorage::new();
1447 let plain = storage.finish_rule(ParserRuleContext::new(0, -1));
1448 let mut rich = ParserRuleContext::new(1, 3);
1449 rich.set_int_return("value", 42);
1450 let rich = storage.finish_rule(rich);
1451 let parsed = ParsedFile::new(tokens, storage, rich);
1452
1453 assert_eq!(parsed.storage().extra_count(), 1);
1454 assert_eq!(
1455 parsed
1456 .node(rich)
1457 .expect("rich rule should be stored")
1458 .as_rule()
1459 .expect("rich node should be a rule")
1460 .int_return("value"),
1461 Some(42)
1462 );
1463 assert!(
1464 parsed
1465 .node(plain)
1466 .expect("plain rule should be stored")
1467 .as_rule()
1468 .expect("plain node should be a rule")
1469 .int_return("value")
1470 .is_none()
1471 );
1472 }
1473
1474 #[test]
1475 fn preserves_maximum_token_id_in_nodes_and_rule_spans() {
1476 let max = TokenId::try_from(u32::MAX as usize).expect("maximum token ID should fit");
1477 let tokens = TokenStore::new(None, "");
1478 let mut storage = ParseTreeStorage::new();
1479 let terminal = storage.terminal(max);
1480 assert_eq!(storage.token_id(terminal), Some(max));
1481
1482 let mut context = ParserRuleContext::new(0, -1);
1483 context.set_start_id(max);
1484 context.set_stop_id(max);
1485 let rule = storage.finish_rule(context);
1486 let rule = storage
1487 .node(&tokens, rule)
1488 .and_then(Node::as_rule)
1489 .expect("rule should be stored");
1490 assert_eq!(rule.start_id(), Some(max));
1491 assert_eq!(rule.stop_id(), Some(max));
1492 }
1493}