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