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;
13const VISITOR_STACK_RED_ZONE: usize = 1024 * 1024;
14const VISITOR_STACK_SIZE: usize = 4 * 1024 * 1024;
15
16#[repr(transparent)]
17#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
18pub struct NodeId(u32);
19
20impl NodeId {
21 pub(crate) const fn placeholder() -> Self {
22 Self(NONE)
23 }
24
25 #[must_use]
26 pub const fn index(self) -> usize {
27 self.0 as usize
28 }
29}
30
31pub type ParseTree = NodeId;
33
34#[repr(u8)]
35#[derive(Clone, Copy, Debug, Eq, PartialEq)]
36pub enum NodeKind {
37 Rule,
38 Terminal,
39 Error,
40}
41
42#[derive(Debug)]
43struct ChildLink {
44 node: NodeId,
45 next: u32,
46}
47
48#[derive(Debug)]
49struct RuleExtra {
50 int_returns: BTreeMap<String, i64>,
51 exception: Option<AntlrError>,
52 attrs: Option<GeneratedAttrs>,
53}
54
55#[derive(Debug)]
56enum ParseTreeExtra {
57 Rule(RuleExtra),
58}
59
60#[derive(Debug, Default)]
66pub struct ParseTreeStorage {
67 kinds: Vec<NodeKind>,
68 child_starts: Vec<u32>,
69 child_lens: Vec<u32>,
70 payload_a: Vec<u32>,
71 payload_b: Vec<u32>,
72 starts: Vec<u32>,
73 stops: Vec<u32>,
74 alt_numbers: Vec<u32>,
75 context_alt_numbers: Vec<u32>,
76 extra_ids: Vec<u32>,
77 parents: Vec<u32>,
78 flags: Vec<u8>,
79 children: Vec<NodeId>,
80 extras: Vec<ParseTreeExtra>,
81 child_links: Vec<ChildLink>,
82}
83
84#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
85pub struct ParseTreeStats {
86 pub nodes: usize,
87 pub edges: usize,
88 pub extras: usize,
89 pub scratch_links: usize,
90 pub allocated_bytes: usize,
91}
92
93#[derive(Clone, Copy, Debug, Eq, PartialEq)]
94pub(crate) struct ParseTreeCheckpoint {
95 nodes: usize,
96 children: usize,
97 extras: usize,
98 child_links: usize,
99}
100
101impl ParseTreeStorage {
102 #[must_use]
103 pub const fn new() -> Self {
104 Self {
105 kinds: Vec::new(),
106 child_starts: Vec::new(),
107 child_lens: Vec::new(),
108 payload_a: Vec::new(),
109 payload_b: Vec::new(),
110 starts: Vec::new(),
111 stops: Vec::new(),
112 alt_numbers: Vec::new(),
113 context_alt_numbers: Vec::new(),
114 extra_ids: Vec::new(),
115 parents: Vec::new(),
116 flags: Vec::new(),
117 children: Vec::new(),
118 extras: Vec::new(),
119 child_links: Vec::new(),
120 }
121 }
122
123 #[must_use]
124 pub const fn node_count(&self) -> usize {
125 self.kinds.len()
126 }
127
128 #[must_use]
129 pub const fn edge_count(&self) -> usize {
130 self.children.len()
131 }
132
133 #[must_use]
134 pub const fn extra_count(&self) -> usize {
135 self.extras.len()
136 }
137
138 #[must_use]
139 pub const fn stats(&self) -> ParseTreeStats {
140 ParseTreeStats {
141 nodes: self.node_count(),
142 edges: self.edge_count(),
143 extras: self.extra_count(),
144 scratch_links: self.child_links.len(),
145 allocated_bytes: self.kinds.capacity() * size_of::<NodeKind>()
146 + self.child_starts.capacity() * size_of::<u32>()
147 + self.child_lens.capacity() * size_of::<u32>()
148 + self.payload_a.capacity() * size_of::<u32>()
149 + self.payload_b.capacity() * size_of::<u32>()
150 + self.starts.capacity() * size_of::<u32>()
151 + self.stops.capacity() * size_of::<u32>()
152 + self.alt_numbers.capacity() * size_of::<u32>()
153 + self.context_alt_numbers.capacity() * size_of::<u32>()
154 + self.extra_ids.capacity() * size_of::<u32>()
155 + self.parents.capacity() * size_of::<u32>()
156 + self.flags.capacity() * size_of::<u8>()
157 + self.children.capacity() * size_of::<NodeId>()
158 + self.extras.capacity() * size_of::<ParseTreeExtra>()
159 + self.child_links.capacity() * size_of::<ChildLink>(),
160 }
161 }
162
163 pub(crate) fn reset(&mut self) {
164 self.kinds.clear();
165 self.child_starts.clear();
166 self.child_lens.clear();
167 self.payload_a.clear();
168 self.payload_b.clear();
169 self.starts.clear();
170 self.stops.clear();
171 self.alt_numbers.clear();
172 self.context_alt_numbers.clear();
173 self.extra_ids.clear();
174 self.parents.clear();
175 self.flags.clear();
176 self.children.clear();
177 self.extras.clear();
178 self.child_links.clear();
179 }
180
181 pub(crate) fn release_scratch(&mut self) {
182 self.child_links.clear();
183 }
184
185 pub(crate) fn discard_scratch(&mut self) {
186 self.child_links = Vec::new();
187 }
188
189 pub(crate) const fn checkpoint(&self) -> ParseTreeCheckpoint {
190 ParseTreeCheckpoint {
191 nodes: self.kinds.len(),
192 children: self.children.len(),
193 extras: self.extras.len(),
194 child_links: self.child_links.len(),
195 }
196 }
197
198 pub(crate) fn rollback(&mut self, checkpoint: ParseTreeCheckpoint) {
199 self.kinds.truncate(checkpoint.nodes);
200 self.child_starts.truncate(checkpoint.nodes);
201 self.child_lens.truncate(checkpoint.nodes);
202 self.payload_a.truncate(checkpoint.nodes);
203 self.payload_b.truncate(checkpoint.nodes);
204 self.starts.truncate(checkpoint.nodes);
205 self.stops.truncate(checkpoint.nodes);
206 self.alt_numbers.truncate(checkpoint.nodes);
207 self.context_alt_numbers.truncate(checkpoint.nodes);
208 self.extra_ids.truncate(checkpoint.nodes);
209 self.parents.truncate(checkpoint.nodes);
210 self.flags.truncate(checkpoint.nodes);
211 self.children.truncate(checkpoint.children);
212 self.extras.truncate(checkpoint.extras);
213 self.child_links.truncate(checkpoint.child_links);
214 }
215
216 pub(crate) fn terminal(&mut self, token: TokenId) -> NodeId {
217 self.push_node(NodeRecord {
218 kind: NodeKind::Terminal,
219 payload_a: token.index() as u32,
220 ..NodeRecord::default()
221 })
222 }
223
224 pub(crate) fn error(&mut self, token: TokenId) -> NodeId {
225 self.push_node(NodeRecord {
226 kind: NodeKind::Error,
227 payload_a: token.index() as u32,
228 ..NodeRecord::default()
229 })
230 }
231
232 pub(crate) fn add_child(&mut self, context: &mut ParserRuleContext, child: NodeId) {
233 context.matched_child = true;
234 let link = self.child_links.len_u32("parse-tree scratch child links");
235 self.child_links.push(ChildLink {
236 node: child,
237 next: NONE,
238 });
239 if context.first_child == NONE {
240 context.first_child = link;
241 } else {
242 self.child_links[context.last_child as usize].next = link;
243 }
244 context.last_child = link;
245 context.child_count = context
246 .child_count
247 .checked_add(1)
248 .expect("rule child count exceeds u32");
249 }
250
251 pub(crate) fn finish_rule(&mut self, context: ParserRuleContext) -> NodeId {
252 let parent = NodeId(self.kinds.len_u32("parse-tree node pool"));
253 let child_start = self.children.len_u32("parse-tree child pool");
254 let mut link = context.first_child;
255 while link != NONE {
256 let child = &self.child_links[link as usize];
257 self.children.push(child.node);
258 self.parents[child.node.index()] = parent.0;
259 link = child.next;
260 }
261
262 let extra_id = if context.int_returns.is_empty()
263 && context.exception.is_none()
264 && context.attrs.is_none()
265 {
266 NONE
267 } else {
268 let id = self.extras.len_u32("parse-tree extra pool");
269 self.extras.push(ParseTreeExtra::Rule(RuleExtra {
270 int_returns: context.int_returns,
271 exception: context.exception,
272 attrs: context.attrs,
273 }));
274 id
275 };
276
277 self.push_node(NodeRecord {
278 kind: NodeKind::Rule,
279 child_start,
280 child_len: context.child_count,
281 payload_a: u32::try_from(context.rule_index).expect("rule index exceeds u32"),
282 payload_b: i32::try_from(context.invoking_state)
283 .expect("invoking state exceeds i32")
284 .cast_unsigned(),
285 start: context.start.map_or(NONE, |token| token.index() as u32),
286 stop: context.stop.map_or(NONE, |token| token.index() as u32),
287 alt_number: u32::try_from(context.alt_number).expect("alternative number exceeds u32"),
288 context_alt_number: u32::try_from(context.context_alt_number)
289 .expect("context alternative number exceeds u32"),
290 extra_id,
291 flags: (u8::from(context.matched_child) * FLAG_MATCHED_CHILD)
292 | (u8::from(context.start.is_some()) * FLAG_START_PRESENT)
293 | (u8::from(context.stop.is_some()) * FLAG_STOP_PRESENT),
294 })
295 }
296
297 fn push_node(&mut self, record: NodeRecord) -> NodeId {
298 let id = NodeId(self.kinds.len_u32("parse-tree node pool"));
299 self.kinds.push(record.kind);
300 self.child_starts.push(record.child_start);
301 self.child_lens.push(record.child_len);
302 self.payload_a.push(record.payload_a);
303 self.payload_b.push(record.payload_b);
304 self.starts.push(record.start);
305 self.stops.push(record.stop);
306 self.alt_numbers.push(record.alt_number);
307 if record.context_alt_number == 0 {
308 if !self.context_alt_numbers.is_empty() {
309 self.context_alt_numbers.push(0);
310 }
311 } else {
312 if self.context_alt_numbers.is_empty() {
313 self.context_alt_numbers.resize(id.index(), 0);
314 }
315 self.context_alt_numbers.push(record.context_alt_number);
316 }
317 self.extra_ids.push(record.extra_id);
318 self.parents.push(NONE);
319 self.flags.push(record.flags);
320 id
321 }
322
323 #[must_use]
324 pub fn node<'tree>(&'tree self, tokens: &'tree TokenStore, id: NodeId) -> Option<Node<'tree>> {
325 (id.index() < self.node_count()).then_some(Node {
326 storage: self,
327 tokens,
328 id,
329 })
330 }
331
332 fn kind(&self, id: NodeId) -> NodeKind {
333 self.kinds[id.index()]
334 }
335
336 fn child_ids(&self, id: NodeId) -> &[NodeId] {
337 let index = id.index();
338 let start = self.child_starts[index] as usize;
339 let len = self.child_lens[index] as usize;
340 &self.children[start..start + len]
341 }
342
343 const fn context_child_ids<'a>(
344 &'a self,
345 context: &'a ParserRuleContext,
346 ) -> ContextChildIds<'a> {
347 ContextChildIds {
348 storage: self,
349 next: context.first_child,
350 remaining: context.child_count as usize,
351 }
352 }
353
354 fn token_id(&self, id: NodeId) -> Option<TokenId> {
355 match self.kind(id) {
356 NodeKind::Terminal | NodeKind::Error => {
357 Some(stored_token_id(self.payload_a[id.index()]))
358 }
359 NodeKind::Rule => None,
360 }
361 }
362
363 fn rule_extra(&self, id: NodeId) -> Option<&RuleExtra> {
364 let extra = *self.extra_ids.get(id.index())?;
365 if extra == NONE {
366 return None;
367 }
368 match &self.extras[extra as usize] {
369 ParseTreeExtra::Rule(extra) => Some(extra),
370 }
371 }
372}
373
374#[derive(Clone, Copy)]
375struct NodeRecord {
376 kind: NodeKind,
377 child_start: u32,
378 child_len: u32,
379 payload_a: u32,
380 payload_b: u32,
381 start: u32,
382 stop: u32,
383 alt_number: u32,
384 context_alt_number: u32,
385 extra_id: u32,
386 flags: u8,
387}
388
389impl Default for NodeRecord {
390 fn default() -> Self {
391 Self {
392 kind: NodeKind::Rule,
393 child_start: 0,
394 child_len: 0,
395 payload_a: 0,
396 payload_b: 0,
397 start: NONE,
398 stop: NONE,
399 alt_number: 0,
400 context_alt_number: 0,
401 extra_id: NONE,
402 flags: 0,
403 }
404 }
405}
406
407trait LenU32 {
408 fn len_u32(&self, name: &str) -> u32;
409}
410
411impl<T> LenU32 for Vec<T> {
412 fn len_u32(&self, name: &str) -> u32 {
413 u32::try_from(self.len()).unwrap_or_else(|_| panic!("{name} exceeds u32"))
414 }
415}
416
417#[derive(Clone, Copy, Debug)]
418pub struct Node<'tree> {
419 storage: &'tree ParseTreeStorage,
420 tokens: &'tree TokenStore,
421 id: NodeId,
422}
423
424impl<'tree> Node<'tree> {
425 #[must_use]
426 pub const fn id(self) -> NodeId {
427 self.id
428 }
429
430 #[must_use]
431 pub fn kind(self) -> NodeKind {
432 self.storage.kind(self.id)
433 }
434
435 #[must_use]
436 pub fn as_rule(self) -> Option<RuleNodeView<'tree>> {
437 (self.kind() == NodeKind::Rule).then_some(RuleNodeView { node: self })
438 }
439
440 #[must_use]
441 pub fn as_terminal(self) -> Option<TerminalNodeView<'tree>> {
442 (self.kind() == NodeKind::Terminal).then_some(TerminalNodeView { node: self })
443 }
444
445 #[must_use]
446 pub fn as_error(self) -> Option<ErrorNodeView<'tree>> {
447 (self.kind() == NodeKind::Error).then_some(ErrorNodeView { node: self })
448 }
449
450 #[must_use]
451 pub fn children(self) -> NodeChildren<'tree> {
452 NodeChildren {
453 storage: self.storage,
454 tokens: self.tokens,
455 ids: self.storage.child_ids(self.id).iter(),
456 }
457 }
458
459 #[must_use]
460 pub fn parent(self) -> Option<Self> {
461 let parent = self.storage.parents[self.id.index()];
462 (parent != NONE)
463 .then(|| self.storage.node(self.tokens, NodeId(parent)))
464 .flatten()
465 }
466
467 #[must_use]
468 pub fn descendants(self) -> ParseTreeDescendants<'tree> {
469 ParseTreeDescendants {
470 storage: self.storage,
471 tokens: self.tokens,
472 stack: vec![self.id],
473 }
474 }
475
476 #[must_use]
477 pub fn pre_order(self) -> ParseTreeDescendants<'tree> {
478 self.descendants()
479 }
480
481 #[must_use]
482 pub fn text(self) -> String {
483 match self.kind() {
484 NodeKind::Terminal | NodeKind::Error => self
485 .storage
486 .token_id(self.id)
487 .and_then(|id| self.tokens.text(id))
488 .unwrap_or("")
489 .to_owned(),
490 NodeKind::Rule => {
491 let mut text = String::new();
492 let mut stack = self
493 .storage
494 .child_ids(self.id)
495 .iter()
496 .rev()
497 .copied()
498 .collect::<Vec<_>>();
499 while let Some(id) = stack.pop() {
500 match self.storage.kind(id) {
501 NodeKind::Rule => {
502 stack.extend(self.storage.child_ids(id).iter().rev().copied());
503 }
504 NodeKind::Terminal | NodeKind::Error => text.push_str(
505 self.storage
506 .token_id(id)
507 .and_then(|token| self.tokens.text(token))
508 .unwrap_or(""),
509 ),
510 }
511 }
512 text
513 }
514 }
515 }
516
517 #[must_use]
518 pub fn to_string_tree_with_names<S: AsRef<str>>(self, rule_names: &[S]) -> String {
519 match self.kind() {
520 NodeKind::Rule => self
521 .as_rule()
522 .expect("rule node kind checked")
523 .to_string_tree_with_names(rule_names),
524 NodeKind::Terminal | NodeKind::Error => escape_tree_text(
525 self.storage
526 .token_id(self.id)
527 .and_then(|id| self.tokens.text(id))
528 .unwrap_or(""),
529 ),
530 }
531 }
532
533 #[must_use]
534 pub fn to_string_tree<R: Recognizer>(
535 self,
536 recognizer: Option<&R>,
537 _tokens: &TokenStore,
538 ) -> String {
539 recognizer.map_or_else(
540 || self.to_string_tree_with_names::<&str>(&[]),
541 |recognizer| self.to_string_tree_with_names(recognizer.data().rule_names()),
542 )
543 }
544
545 #[must_use]
546 pub fn first_rule(self, rule_index: usize) -> Option<Self> {
547 self.descendants().find(|node| {
548 node.as_rule()
549 .is_some_and(|rule| rule.rule_index() == rule_index)
550 })
551 }
552
553 #[must_use]
554 pub fn first_rule_stop(self, rule_index: usize) -> Option<TokenView<'tree>> {
555 self.first_rule(rule_index)?.as_rule()?.stop()
556 }
557
558 #[must_use]
559 pub fn first_rule_int_return(self, rule_index: usize, name: &str) -> Option<i64> {
560 self.first_rule(rule_index)?.as_rule()?.int_return(name)
561 }
562
563 #[must_use]
564 pub fn rule_attrs<T: Any>(self) -> Option<&'tree T> {
565 self.as_rule()?.generated_attrs::<T>()
566 }
567
568 #[must_use]
569 pub fn first_error_token(self) -> Option<TokenView<'tree>> {
570 self.descendants()
571 .find_map(Node::as_error)
572 .map(ErrorNodeView::symbol)
573 }
574
575 #[must_use]
576 pub fn rule_invocation_stack<S: AsRef<str>>(
577 self,
578 rule_index: usize,
579 rule_names: &[S],
580 ) -> Option<Vec<String>> {
581 let mut stack = vec![(self.id, 0_usize)];
582 let mut names = Vec::new();
583 while let Some((id, child_index)) = stack.last_mut() {
584 if *child_index == 0 {
585 let Some(rule) = self.storage.node(self.tokens, *id).and_then(Node::as_rule) else {
586 stack.pop();
587 continue;
588 };
589 names.push(
590 rule_names
591 .get(rule.rule_index())
592 .map_or("<unknown>", |name| name.as_ref())
593 .to_owned(),
594 );
595 if rule.rule_index() == rule_index {
596 names.reverse();
597 return Some(names);
598 }
599 }
600 let children = self.storage.child_ids(*id);
601 let next = children.get(*child_index).copied();
602 *child_index += 1;
603 if let Some(child) = next {
604 if self.storage.kind(child) == NodeKind::Rule {
605 stack.push((child, 0));
606 }
607 } else {
608 stack.pop();
609 names.pop();
610 }
611 }
612 None
613 }
614}
615
616#[derive(Clone, Debug)]
617pub struct NodeChildren<'tree> {
618 storage: &'tree ParseTreeStorage,
619 tokens: &'tree TokenStore,
620 ids: std::slice::Iter<'tree, NodeId>,
621}
622
623impl<'tree> Iterator for NodeChildren<'tree> {
624 type Item = Node<'tree>;
625
626 fn next(&mut self) -> Option<Self::Item> {
627 self.ids
628 .next()
629 .and_then(|id| self.storage.node(self.tokens, *id))
630 }
631
632 fn size_hint(&self) -> (usize, Option<usize>) {
633 self.ids.size_hint()
634 }
635}
636
637impl DoubleEndedIterator for NodeChildren<'_> {
638 fn next_back(&mut self) -> Option<Self::Item> {
639 self.ids
640 .next_back()
641 .and_then(|id| self.storage.node(self.tokens, *id))
642 }
643}
644
645impl ExactSizeIterator for NodeChildren<'_> {}
646
647#[derive(Clone, Debug)]
648pub struct ParseTreeDescendants<'tree> {
649 storage: &'tree ParseTreeStorage,
650 tokens: &'tree TokenStore,
651 stack: Vec<NodeId>,
652}
653
654impl<'tree> Iterator for ParseTreeDescendants<'tree> {
655 type Item = Node<'tree>;
656
657 fn next(&mut self) -> Option<Self::Item> {
658 let id = self.stack.pop()?;
659 self.stack
660 .extend(self.storage.child_ids(id).iter().rev().copied());
661 Some(Node {
662 storage: self.storage,
663 tokens: self.tokens,
664 id,
665 })
666 }
667}
668
669#[derive(Clone, Copy, Debug)]
670pub struct RuleNodeView<'tree> {
671 node: Node<'tree>,
672}
673
674impl<'tree> RuleNodeView<'tree> {
675 #[must_use]
676 pub const fn node(self) -> Node<'tree> {
677 self.node
678 }
679
680 #[must_use]
681 pub fn rule_index(self) -> usize {
682 self.node.storage.payload_a[self.node.id.index()] as usize
683 }
684
685 #[must_use]
686 pub fn invoking_state(self) -> isize {
687 self.node.storage.payload_b[self.node.id.index()].cast_signed() as isize
688 }
689
690 #[must_use]
691 pub fn alt_number(self) -> usize {
692 self.node.storage.alt_numbers[self.node.id.index()] as usize
693 }
694
695 #[doc(hidden)]
696 #[must_use]
697 pub fn context_alt_number(self) -> usize {
698 self.node
699 .storage
700 .context_alt_numbers
701 .get(self.node.id.index())
702 .copied()
703 .unwrap_or_default() as usize
704 }
705
706 #[must_use]
707 pub fn start(self) -> Option<TokenView<'tree>> {
708 self.start_id().and_then(|id| self.node.tokens.view(id))
709 }
710
711 #[must_use]
712 pub fn start_id(self) -> Option<TokenId> {
713 let index = self.node.id.index();
714 (self.node.storage.flags[index] & FLAG_START_PRESENT != 0)
715 .then(|| stored_token_id(self.node.storage.starts[index]))
716 }
717
718 #[must_use]
719 pub fn stop(self) -> Option<TokenView<'tree>> {
720 self.stop_id().and_then(|id| self.node.tokens.view(id))
721 }
722
723 #[must_use]
724 pub fn stop_id(self) -> Option<TokenId> {
725 let index = self.node.id.index();
726 (self.node.storage.flags[index] & FLAG_STOP_PRESENT != 0)
727 .then(|| stored_token_id(self.node.storage.stops[index]))
728 }
729
730 #[must_use]
731 pub fn children(self) -> NodeChildren<'tree> {
732 self.node.children()
733 }
734
735 #[must_use]
736 pub fn child_count(self) -> usize {
737 self.node.storage.child_lens[self.node.id.index()] as usize
738 }
739
740 #[must_use]
741 pub fn child_rule(self, rule_index: usize) -> Option<Self> {
742 self.child_rules(rule_index).next()
743 }
744
745 pub fn child_rules(self, rule_index: usize) -> impl DoubleEndedIterator<Item = Self> + 'tree {
746 self.children().filter_map(move |child| {
747 let rule = child.as_rule()?;
748 (rule.rule_index() == rule_index).then_some(rule)
749 })
750 }
751
752 pub fn child_rule_trees(
753 self,
754 rule_index: usize,
755 ) -> impl DoubleEndedIterator<Item = Node<'tree>> + 'tree {
756 self.child_rules(rule_index).map(Self::node)
757 }
758
759 #[must_use]
760 pub fn child_token(self, token_type: i32) -> Option<TerminalNodeView<'tree>> {
761 self.child_tokens(token_type).next()
762 }
763
764 pub fn child_tokens(
765 self,
766 token_type: i32,
767 ) -> impl DoubleEndedIterator<Item = TerminalNodeView<'tree>> + 'tree {
768 self.children().filter_map(move |child| {
769 let terminal = match child.kind() {
770 NodeKind::Terminal => child.as_terminal(),
771 NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
772 NodeKind::Rule => None,
773 }?;
774 (terminal.symbol().token_type() == token_type).then_some(terminal)
775 })
776 }
777
778 pub fn terminal_children(
779 self,
780 ) -> impl DoubleEndedIterator<Item = TerminalNodeView<'tree>> + 'tree {
781 self.children().filter_map(|child| match child.kind() {
782 NodeKind::Terminal => child.as_terminal(),
783 NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
784 NodeKind::Rule => None,
785 })
786 }
787
788 #[must_use]
789 pub fn has_token(self, token_type: i32) -> bool {
790 self.child_token(token_type).is_some()
791 }
792
793 #[must_use]
794 pub fn text(self) -> String {
795 self.node.text()
796 }
797
798 #[must_use]
799 pub fn int_return(self, name: &str) -> Option<i64> {
800 self.node
801 .storage
802 .rule_extra(self.node.id)?
803 .int_returns
804 .get(name)
805 .copied()
806 }
807
808 #[must_use]
809 pub fn generated_attrs<T: Any>(self) -> Option<&'tree T> {
810 self.node
811 .storage
812 .rule_extra(self.node.id)?
813 .attrs
814 .as_ref()?
815 .downcast_ref::<T>()
816 }
817
818 #[must_use]
819 pub fn exception(self) -> Option<&'tree AntlrError> {
820 self.node
821 .storage
822 .rule_extra(self.node.id)?
823 .exception
824 .as_ref()
825 }
826
827 #[must_use]
828 pub fn downcast_ref<T: FromRuleNode<'tree>>(self) -> Option<T> {
829 T::from_rule_node(self)
830 }
831
832 pub fn invocation_states(self) -> impl Iterator<Item = isize> + 'tree {
833 std::iter::successors(Some(self), |rule| rule.node.parent()?.as_rule())
834 .take_while(|rule| rule.node.parent().is_some() && rule.invoking_state() >= 0)
835 .map(Self::invoking_state)
836 }
837
838 #[must_use]
839 pub fn to_string_tree_with_names<S: AsRef<str>>(self, rule_names: &[S]) -> String {
840 let name = rule_names
841 .get(self.rule_index())
842 .map_or("<unknown>", |name| name.as_ref());
843 let display_name = if self.alt_number() == 0 {
844 name.to_owned()
845 } else {
846 format!("{name}:{}", self.alt_number())
847 };
848 if self.child_count() == 0 {
849 return display_name;
850 }
851 let children = self
852 .children()
853 .map(|child| child.to_string_tree_with_names(rule_names))
854 .collect::<Vec<_>>()
855 .join(" ");
856 format!("({display_name} {children})")
857 }
858
859 #[must_use]
860 pub fn to_string_tree<R: Recognizer>(self, recognizer: Option<&R>) -> String {
861 recognizer.map_or_else(
862 || self.to_string_tree_with_names::<&str>(&[]),
863 |recognizer| self.to_string_tree_with_names(recognizer.data().rule_names()),
864 )
865 }
866}
867
868#[derive(Clone, Copy, Debug)]
869pub struct TerminalNodeView<'tree> {
870 node: Node<'tree>,
871}
872
873impl<'tree> TerminalNodeView<'tree> {
874 #[must_use]
875 pub const fn node(self) -> Node<'tree> {
876 self.node
877 }
878
879 #[must_use]
880 pub fn token_id(self) -> TokenId {
881 self.node
882 .storage
883 .token_id(self.node.id)
884 .expect("terminal node should contain a token ID")
885 }
886
887 #[must_use]
888 pub fn symbol(self) -> TokenView<'tree> {
889 self.node
890 .tokens
891 .view(self.token_id())
892 .expect("terminal node token ID should remain valid")
893 }
894
895 #[must_use]
896 pub fn text(self) -> &'tree str {
897 self.node.tokens.text(self.token_id()).unwrap_or("")
898 }
899}
900
901#[derive(Clone, Copy, Debug)]
902pub struct ErrorNodeView<'tree> {
903 node: Node<'tree>,
904}
905
906impl<'tree> ErrorNodeView<'tree> {
907 #[must_use]
908 pub const fn node(self) -> Node<'tree> {
909 self.node
910 }
911
912 #[must_use]
913 pub const fn terminal(self) -> TerminalNodeView<'tree> {
914 TerminalNodeView { node: self.node }
915 }
916
917 #[must_use]
918 pub fn token_id(self) -> TokenId {
919 self.terminal().token_id()
920 }
921
922 #[must_use]
923 pub fn symbol(self) -> TokenView<'tree> {
924 self.terminal().symbol()
925 }
926
927 #[must_use]
928 pub fn text(self) -> &'tree str {
929 self.terminal().text()
930 }
931}
932
933#[derive(Debug)]
934struct ContextChildIds<'a> {
935 storage: &'a ParseTreeStorage,
936 next: u32,
937 remaining: usize,
938}
939
940impl Iterator for ContextChildIds<'_> {
941 type Item = NodeId;
942
943 fn next(&mut self) -> Option<Self::Item> {
944 if self.next == NONE {
945 return None;
946 }
947 let link = &self.storage.child_links[self.next as usize];
948 self.next = link.next;
949 self.remaining -= 1;
950 Some(link.node)
951 }
952
953 fn size_hint(&self) -> (usize, Option<usize>) {
954 (self.remaining, Some(self.remaining))
955 }
956}
957
958impl ExactSizeIterator for ContextChildIds<'_> {}
959
960#[derive(Debug)]
966pub struct ParserRuleContext {
967 rule_index: usize,
968 invoking_state: isize,
969 alt_number: usize,
970 context_alt_number: usize,
971 start: Option<TokenId>,
972 stop: Option<TokenId>,
973 int_returns: BTreeMap<String, i64>,
974 first_child: u32,
975 last_child: u32,
976 child_count: u32,
977 matched_child: bool,
978 exception: Option<AntlrError>,
979 attrs: Option<GeneratedAttrs>,
980}
981
982impl ParserRuleContext {
983 #[must_use]
984 pub const fn new(rule_index: usize, invoking_state: isize) -> Self {
985 Self {
986 rule_index,
987 invoking_state,
988 alt_number: 0,
989 context_alt_number: 0,
990 start: None,
991 stop: None,
992 int_returns: BTreeMap::new(),
993 first_child: NONE,
994 last_child: NONE,
995 child_count: 0,
996 matched_child: false,
997 exception: None,
998 attrs: None,
999 }
1000 }
1001
1002 pub(crate) const fn with_child_capacity(
1003 rule_index: usize,
1004 invoking_state: isize,
1005 _capacity: usize,
1006 ) -> Self {
1007 Self::new(rule_index, invoking_state)
1008 }
1009
1010 #[must_use]
1011 pub const fn rule_index(&self) -> usize {
1012 self.rule_index
1013 }
1014
1015 #[must_use]
1016 pub const fn invoking_state(&self) -> isize {
1017 self.invoking_state
1018 }
1019
1020 #[must_use]
1021 pub const fn alt_number(&self) -> usize {
1022 self.alt_number
1023 }
1024
1025 pub const fn set_alt_number(&mut self, alt_number: usize) {
1026 self.alt_number = alt_number;
1027 }
1028
1029 #[doc(hidden)]
1030 #[must_use]
1031 pub const fn context_alt_number(&self) -> usize {
1032 self.context_alt_number
1033 }
1034
1035 #[doc(hidden)]
1036 pub const fn set_context_alt_number(&mut self, alt_number: usize) {
1037 self.context_alt_number = alt_number;
1038 }
1039
1040 pub fn start<'a>(&self, tokens: &'a TokenStore) -> Option<TokenView<'a>> {
1041 self.start.and_then(|id| tokens.view(id))
1042 }
1043
1044 pub(crate) const fn start_id(&self) -> Option<TokenId> {
1045 self.start
1046 }
1047
1048 pub fn stop<'a>(&self, tokens: &'a TokenStore) -> Option<TokenView<'a>> {
1049 self.stop.and_then(|id| tokens.view(id))
1050 }
1051
1052 pub(crate) const fn set_start_id(&mut self, token: TokenId) {
1053 self.start = Some(token);
1054 }
1055
1056 pub(crate) const fn set_stop_id(&mut self, token: TokenId) {
1057 self.stop = Some(token);
1058 }
1059
1060 pub(crate) const fn set_start_from_context(&mut self, other: &Self) {
1061 self.start = other.start;
1062 }
1063
1064 pub fn set_int_return(&mut self, name: impl Into<String>, value: i64) {
1065 self.int_returns.insert(name.into(), value);
1066 }
1067
1068 #[must_use]
1069 pub fn int_return(&self, name: &str) -> Option<i64> {
1070 self.int_returns.get(name).copied()
1071 }
1072
1073 pub fn set_generated_attrs(&mut self, attrs: GeneratedAttrs) {
1074 self.attrs = Some(attrs);
1075 }
1076
1077 #[must_use]
1078 pub fn generated_attrs<T: Any>(&self) -> Option<&T> {
1079 self.attrs.as_ref().and_then(GeneratedAttrs::downcast_ref)
1080 }
1081
1082 #[must_use]
1083 pub const fn exception(&self) -> Option<&AntlrError> {
1084 self.exception.as_ref()
1085 }
1086
1087 pub fn set_exception(&mut self, error: AntlrError) {
1088 self.exception = Some(error);
1089 }
1090
1091 #[must_use]
1092 pub const fn child_count(&self) -> usize {
1093 self.child_count as usize
1094 }
1095
1096 #[must_use]
1097 pub const fn has_matched_child(&self) -> bool {
1098 self.matched_child
1099 }
1100
1101 pub const fn note_matched_child(&mut self) {
1102 self.matched_child = true;
1103 }
1104
1105 pub fn child_nodes<'a>(
1106 &'a self,
1107 storage: &'a ParseTreeStorage,
1108 tokens: &'a TokenStore,
1109 ) -> impl Iterator<Item = Node<'a>> + 'a {
1110 storage
1111 .context_child_ids(self)
1112 .filter_map(move |id| storage.node(tokens, id))
1113 }
1114
1115 pub fn child_rules<'a>(
1116 &'a self,
1117 storage: &'a ParseTreeStorage,
1118 tokens: &'a TokenStore,
1119 rule_index: usize,
1120 ) -> impl Iterator<Item = RuleNodeView<'a>> + 'a {
1121 self.child_nodes(storage, tokens).filter_map(move |child| {
1122 let rule = child.as_rule()?;
1123 (rule.rule_index() == rule_index).then_some(rule)
1124 })
1125 }
1126
1127 pub fn child_rule_trees<'a>(
1128 &'a self,
1129 storage: &'a ParseTreeStorage,
1130 tokens: &'a TokenStore,
1131 rule_index: usize,
1132 ) -> impl Iterator<Item = Node<'a>> + 'a {
1133 self.child_rules(storage, tokens, rule_index)
1134 .map(RuleNodeView::node)
1135 }
1136
1137 pub fn child_tokens<'a>(
1138 &'a self,
1139 storage: &'a ParseTreeStorage,
1140 tokens: &'a TokenStore,
1141 token_type: i32,
1142 ) -> impl Iterator<Item = TerminalNodeView<'a>> + 'a {
1143 self.child_nodes(storage, tokens).filter_map(move |child| {
1144 let terminal = match child.kind() {
1145 NodeKind::Terminal => child.as_terminal(),
1146 NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
1147 NodeKind::Rule => None,
1148 }?;
1149 (terminal.symbol().token_type() == token_type).then_some(terminal)
1150 })
1151 }
1152
1153 pub fn terminal_children<'a>(
1154 &'a self,
1155 storage: &'a ParseTreeStorage,
1156 tokens: &'a TokenStore,
1157 ) -> impl Iterator<Item = TerminalNodeView<'a>> + 'a {
1158 self.child_nodes(storage, tokens)
1159 .filter_map(|child| match child.kind() {
1160 NodeKind::Terminal => child.as_terminal(),
1161 NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
1162 NodeKind::Rule => None,
1163 })
1164 }
1165
1166 #[must_use]
1167 pub fn text(&self, storage: &ParseTreeStorage, tokens: &TokenStore) -> String {
1168 self.child_nodes(storage, tokens).map(Node::text).collect()
1169 }
1170
1171 #[must_use]
1172 pub fn to_string_tree_with_names<S: AsRef<str>>(
1173 &self,
1174 storage: &ParseTreeStorage,
1175 tokens: &TokenStore,
1176 rule_names: &[S],
1177 ) -> String {
1178 let name = rule_names
1179 .get(self.rule_index)
1180 .map_or("<unknown>", |name| name.as_ref());
1181 let display_name = if self.alt_number == 0 {
1182 name.to_owned()
1183 } else {
1184 format!("{name}:{}", self.alt_number)
1185 };
1186 if self.child_count == 0 {
1187 return display_name;
1188 }
1189 let children = self
1190 .child_nodes(storage, tokens)
1191 .map(|child| child.to_string_tree_with_names(rule_names))
1192 .collect::<Vec<_>>()
1193 .join(" ");
1194 format!("({display_name} {children})")
1195 }
1196
1197 #[must_use]
1198 pub fn to_string_tree<R: Recognizer>(
1199 &self,
1200 recognizer: Option<&R>,
1201 storage: &ParseTreeStorage,
1202 tokens: &TokenStore,
1203 ) -> String {
1204 recognizer.map_or_else(
1205 || self.to_string_tree_with_names::<&str>(storage, tokens, &[]),
1206 |recognizer| {
1207 self.to_string_tree_with_names(storage, tokens, recognizer.data().rule_names())
1208 },
1209 )
1210 }
1211}
1212
1213pub struct GeneratedAttrs(Box<dyn Any>);
1215
1216impl GeneratedAttrs {
1217 #[must_use]
1218 pub fn new<T: Any>(attrs: T) -> Self {
1219 Self(Box::new(attrs))
1220 }
1221
1222 #[must_use]
1223 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
1224 self.0.downcast_ref::<T>()
1225 }
1226}
1227
1228impl fmt::Debug for GeneratedAttrs {
1229 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1230 f.write_str("GeneratedAttrs(..)")
1231 }
1232}
1233
1234pub trait FromRuleNode<'tree>: Sized {
1235 fn from_rule_node(node: RuleNodeView<'tree>) -> Option<Self>;
1236}
1237
1238pub trait AsRuleNode<'tree> {
1240 fn as_rule_node(&self) -> RuleNodeView<'tree>;
1241}
1242
1243impl<'tree> AsRuleNode<'tree> for RuleNodeView<'tree> {
1244 fn as_rule_node(&self) -> Self {
1245 *self
1246 }
1247}
1248
1249#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1251pub struct MissingChildError {
1252 context: &'static str,
1253 child: &'static str,
1254}
1255
1256impl MissingChildError {
1257 #[must_use]
1258 pub const fn new(context: &'static str, child: &'static str) -> Self {
1259 Self { context, child }
1260 }
1261
1262 #[must_use]
1263 pub const fn context(self) -> &'static str {
1264 self.context
1265 }
1266
1267 #[must_use]
1268 pub const fn child(self) -> &'static str {
1269 self.child
1270 }
1271}
1272
1273impl fmt::Display for MissingChildError {
1274 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1275 write!(
1276 f,
1277 "required child {} is missing from {}",
1278 self.child, self.context
1279 )
1280 }
1281}
1282
1283impl std::error::Error for MissingChildError {}
1284
1285pub trait ParseTreeListener {
1286 fn enter_every_rule(&mut self, _ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1287 Ok(())
1288 }
1289
1290 fn exit_every_rule(&mut self, _ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1291 Ok(())
1292 }
1293
1294 fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Result<(), AntlrError> {
1295 Ok(())
1296 }
1297
1298 fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Result<(), AntlrError> {
1299 Ok(())
1300 }
1301}
1302
1303pub trait ParseTreeVisitor {
1309 type Result;
1310
1311 fn default_result(&mut self) -> Self::Result;
1312
1313 fn visit(&mut self, tree: Node<'_>) -> Self::Result {
1314 match tree.kind() {
1315 NodeKind::Rule => self.visit_rule(tree.as_rule().expect("rule node kind checked")),
1316 NodeKind::Terminal => {
1317 self.visit_terminal(tree.as_terminal().expect("terminal node kind checked"))
1318 }
1319 NodeKind::Error => {
1320 self.visit_error_node(tree.as_error().expect("error node kind checked"))
1321 }
1322 }
1323 }
1324
1325 fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1326 self.visit_children(node)
1327 }
1328
1329 fn visit_children(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1330 stacker::maybe_grow(VISITOR_STACK_RED_ZONE, VISITOR_STACK_SIZE, || {
1331 let mut result = self.default_result();
1332 for child in node.children() {
1333 if !self.should_visit_next_child(node, &result) {
1334 break;
1335 }
1336 let child_result = self.visit(child);
1337 result = self.aggregate_result(result, child_result);
1338 }
1339 result
1340 })
1341 }
1342
1343 fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Self::Result {
1344 self.default_result()
1345 }
1346
1347 fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Self::Result {
1348 self.default_result()
1349 }
1350
1351 fn aggregate_result(
1352 &mut self,
1353 _aggregate: Self::Result,
1354 next_result: Self::Result,
1355 ) -> Self::Result {
1356 next_result
1357 }
1358
1359 fn should_visit_next_child(
1360 &mut self,
1361 _node: RuleNodeView<'_>,
1362 _current_result: &Self::Result,
1363 ) -> bool {
1364 true
1365 }
1366}
1367
1368#[derive(Debug, Default)]
1369pub struct ParseTreeWalker;
1370
1371impl ParseTreeWalker {
1372 pub fn walk<L: ParseTreeListener>(listener: &mut L, tree: Node<'_>) -> Result<(), AntlrError> {
1373 enum Event {
1374 Enter(NodeId),
1375 Exit(NodeId),
1376 }
1377
1378 let storage = tree.storage;
1379 let tokens = tree.tokens;
1380 let mut stack = vec![Event::Enter(tree.id)];
1381 while let Some(event) = stack.pop() {
1382 match event {
1383 Event::Enter(id) => {
1384 let node = storage
1385 .node(tokens, id)
1386 .expect("walker node ID should remain valid");
1387 match node.kind() {
1388 NodeKind::Rule => {
1389 let rule = node.as_rule().expect("rule node kind checked");
1390 listener.enter_every_rule(rule)?;
1391 stack.push(Event::Exit(id));
1392 stack.extend(
1393 storage
1394 .child_ids(id)
1395 .iter()
1396 .rev()
1397 .copied()
1398 .map(Event::Enter),
1399 );
1400 }
1401 NodeKind::Terminal => listener.visit_terminal(
1402 node.as_terminal().expect("terminal node kind checked"),
1403 )?,
1404 NodeKind::Error => {
1405 listener.visit_error_node(
1406 node.as_error().expect("error node kind checked"),
1407 )?;
1408 }
1409 }
1410 }
1411 Event::Exit(id) => {
1412 let rule = storage
1413 .node(tokens, id)
1414 .and_then(Node::as_rule)
1415 .expect("walker exit node should remain a rule");
1416 listener.exit_every_rule(rule)?;
1417 }
1418 }
1419 }
1420 Ok(())
1421 }
1422}
1423
1424#[derive(Debug)]
1425pub struct ParsedFile {
1426 tokens: TokenStore,
1427 tree: ParseTreeStorage,
1428 root: NodeId,
1429}
1430
1431impl ParsedFile {
1432 #[must_use]
1433 pub fn new(tokens: TokenStore, mut tree: ParseTreeStorage, root: NodeId) -> Self {
1434 tree.discard_scratch();
1435 Self { tokens, tree, root }
1436 }
1437
1438 #[must_use]
1439 pub const fn tokens(&self) -> &TokenStore {
1440 &self.tokens
1441 }
1442
1443 #[must_use]
1444 pub const fn storage(&self) -> &ParseTreeStorage {
1445 &self.tree
1446 }
1447
1448 #[must_use]
1449 pub const fn root_id(&self) -> NodeId {
1450 self.root
1451 }
1452
1453 #[must_use]
1454 pub fn tree(&self) -> Node<'_> {
1455 self.tree
1456 .node(&self.tokens, self.root)
1457 .expect("parsed file root ID should remain valid")
1458 }
1459
1460 #[must_use]
1461 pub fn node(&self, id: NodeId) -> Option<Node<'_>> {
1462 self.tree.node(&self.tokens, id)
1463 }
1464
1465 #[must_use]
1466 pub fn into_parts(self) -> (TokenStore, ParseTreeStorage, NodeId) {
1467 (self.tokens, self.tree, self.root)
1468 }
1469}
1470
1471fn escape_tree_text(text: &str) -> String {
1472 let mut escaped = String::with_capacity(text.len());
1473 for ch in text.chars() {
1474 match ch {
1475 '\n' => escaped.push_str("\\n"),
1476 '\r' => escaped.push_str("\\r"),
1477 '\t' => escaped.push_str("\\t"),
1478 _ => escaped.push(ch),
1479 }
1480 }
1481 escaped
1482}
1483
1484fn stored_token_id(raw: u32) -> TokenId {
1485 TokenId::try_from(raw as usize).expect("stored token ID should fit in u32")
1486}
1487
1488#[cfg(test)]
1489mod tests {
1490 use super::*;
1491 use crate::token::TokenSpec;
1492
1493 fn token(store: &mut TokenStore, token_type: i32, text: &str) -> TokenId {
1494 store
1495 .push(TokenSpec::explicit(token_type, text))
1496 .expect("test token should fit")
1497 }
1498
1499 #[test]
1500 fn stores_rule_children_in_one_pooled_range() {
1501 let mut tokens = TokenStore::new(None, "");
1502 let first = token(&mut tokens, 1, "a");
1503 let second = token(&mut tokens, 2, "b");
1504 let mut storage = ParseTreeStorage::new();
1505 let first = storage.terminal(first);
1506 let second = storage.error(second);
1507 let mut context = ParserRuleContext::new(0, -1);
1508 storage.add_child(&mut context, first);
1509 storage.add_child(&mut context, second);
1510 let root = storage.finish_rule(context);
1511 let parsed = ParsedFile::new(tokens, storage, root);
1512
1513 assert_eq!(parsed.tree().text(), "ab");
1514 assert_eq!(parsed.tree().children().count(), 2);
1515 assert_eq!(parsed.storage().stats().edges, 2);
1516 assert_eq!(parsed.storage().stats().scratch_links, 0);
1517 assert_eq!(
1518 parsed.tree().to_string_tree_with_names(&["root"]),
1519 "(root a b)"
1520 );
1521 }
1522
1523 #[test]
1524 fn context_alt_number_does_not_change_public_tree_rendering() {
1525 let tokens = TokenStore::new(None, "");
1526 let mut storage = ParseTreeStorage::new();
1527 let mut context = ParserRuleContext::new(0, -1);
1528 context.set_context_alt_number(2);
1529
1530 assert_eq!(context.alt_number(), 0);
1531 assert_eq!(context.context_alt_number(), 2);
1532 assert_eq!(
1533 context.to_string_tree_with_names(&storage, &tokens, &["root"]),
1534 "root"
1535 );
1536
1537 let root = storage.finish_rule(context);
1538 let parsed = ParsedFile::new(tokens, storage, root);
1539 let rule = parsed.tree().as_rule().expect("root rule");
1540 assert_eq!(rule.alt_number(), 0);
1541 assert_eq!(rule.context_alt_number(), 2);
1542 assert_eq!(parsed.tree().to_string_tree_with_names(&["root"]), "root");
1543 }
1544
1545 #[test]
1546 fn descendants_and_walker_preserve_antlr_order() {
1547 let mut tokens = TokenStore::new(None, "");
1548 let a = token(&mut tokens, 1, "a");
1549 let b = token(&mut tokens, 2, "b");
1550 let mut storage = ParseTreeStorage::new();
1551 let a = storage.terminal(a);
1552 let b = storage.terminal(b);
1553 let mut child = ParserRuleContext::new(1, 7);
1554 storage.add_child(&mut child, b);
1555 let child = storage.finish_rule(child);
1556 let mut root = ParserRuleContext::new(0, -1);
1557 storage.add_child(&mut root, a);
1558 storage.add_child(&mut root, child);
1559 let root = storage.finish_rule(root);
1560 let parsed = ParsedFile::new(tokens, storage, root);
1561
1562 let visited = parsed
1563 .tree()
1564 .descendants()
1565 .map(|node| match node.kind() {
1566 NodeKind::Rule => format!(
1567 "r{}",
1568 node.as_rule().expect("rule node kind checked").rule_index()
1569 ),
1570 NodeKind::Terminal => node
1571 .as_terminal()
1572 .expect("terminal node kind checked")
1573 .text()
1574 .to_owned(),
1575 NodeKind::Error => node
1576 .as_error()
1577 .expect("error node kind checked")
1578 .text()
1579 .to_owned(),
1580 })
1581 .collect::<Vec<_>>();
1582 assert_eq!(visited, ["r0", "a", "r1", "b"]);
1583
1584 #[derive(Default)]
1585 struct Listener(Vec<String>);
1586 impl ParseTreeListener for Listener {
1587 fn enter_every_rule(&mut self, ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1588 self.0.push(format!("enter{}", ctx.rule_index()));
1589 Ok(())
1590 }
1591
1592 fn exit_every_rule(&mut self, ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1593 self.0.push(format!("exit{}", ctx.rule_index()));
1594 Ok(())
1595 }
1596
1597 fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Result<(), AntlrError> {
1598 self.0.push(node.text().to_owned());
1599 Ok(())
1600 }
1601 }
1602 let mut listener = Listener::default();
1603 ParseTreeWalker::walk(&mut listener, parsed.tree())
1604 .expect("test listener should accept every node");
1605 assert_eq!(listener.0, ["enter0", "a", "enter1", "b", "exit1", "exit0"]);
1606 }
1607
1608 fn visitor_test_tree() -> ParsedFile {
1609 let mut tokens = TokenStore::new(None, "");
1610 let a = token(&mut tokens, 1, "a");
1611 let b = token(&mut tokens, 2, "b");
1612 let error = token(&mut tokens, 3, "!");
1613 let mut storage = ParseTreeStorage::new();
1614 let a = storage.terminal(a);
1615 let b = storage.terminal(b);
1616 let error = storage.error(error);
1617 let mut child = ParserRuleContext::new(1, 7);
1618 storage.add_child(&mut child, b);
1619 let child = storage.finish_rule(child);
1620 let mut root = ParserRuleContext::new(0, -1);
1621 storage.add_child(&mut root, a);
1622 storage.add_child(&mut root, child);
1623 storage.add_child(&mut root, error);
1624 let root = storage.finish_rule(root);
1625 ParsedFile::new(tokens, storage, root)
1626 }
1627
1628 #[test]
1629 fn visitor_dispatches_and_aggregates_all_node_kinds() {
1630 #[derive(Default)]
1631 struct Visitor(Vec<String>);
1632
1633 impl ParseTreeVisitor for Visitor {
1634 type Result = Vec<String>;
1635
1636 fn default_result(&mut self) -> Self::Result {
1637 Vec::new()
1638 }
1639
1640 fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1641 self.0.push(format!("rule{}", node.rule_index()));
1642 self.visit_children(node)
1643 }
1644
1645 fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Self::Result {
1646 vec![format!("terminal:{}", node.text())]
1647 }
1648
1649 fn visit_error_node(&mut self, node: ErrorNodeView<'_>) -> Self::Result {
1650 vec![format!("error:{}", node.text())]
1651 }
1652
1653 fn aggregate_result(
1654 &mut self,
1655 mut aggregate: Self::Result,
1656 next_result: Self::Result,
1657 ) -> Self::Result {
1658 aggregate.extend(next_result);
1659 aggregate
1660 }
1661 }
1662
1663 let parsed = visitor_test_tree();
1664 let mut visitor = Visitor::default();
1665 assert_eq!(
1666 visitor.visit(parsed.tree()),
1667 ["terminal:a", "terminal:b", "error:!"]
1668 );
1669 assert_eq!(visitor.0, ["rule0", "rule1"]);
1670 }
1671
1672 #[test]
1673 fn visitor_default_aggregation_returns_the_latest_child() {
1674 struct Visitor;
1675
1676 impl ParseTreeVisitor for Visitor {
1677 type Result = String;
1678
1679 fn default_result(&mut self) -> Self::Result {
1680 String::new()
1681 }
1682
1683 fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Self::Result {
1684 node.text().to_owned()
1685 }
1686
1687 fn visit_error_node(&mut self, node: ErrorNodeView<'_>) -> Self::Result {
1688 node.text().to_owned()
1689 }
1690 }
1691
1692 let parsed = visitor_test_tree();
1693 assert_eq!(Visitor.visit(parsed.tree()), "!");
1694 }
1695
1696 #[test]
1697 fn visitor_can_short_circuit_before_any_or_later_children() {
1698 struct Visitor {
1699 limit: usize,
1700 visited: usize,
1701 }
1702
1703 impl ParseTreeVisitor for Visitor {
1704 type Result = usize;
1705
1706 fn default_result(&mut self) -> Self::Result {
1707 0
1708 }
1709
1710 fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Self::Result {
1711 self.visited += 1;
1712 1
1713 }
1714
1715 fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Self::Result {
1716 self.visited += 1;
1717 1
1718 }
1719
1720 fn aggregate_result(
1721 &mut self,
1722 aggregate: Self::Result,
1723 next_result: Self::Result,
1724 ) -> Self::Result {
1725 aggregate + next_result
1726 }
1727
1728 fn should_visit_next_child(
1729 &mut self,
1730 _node: RuleNodeView<'_>,
1731 current_result: &Self::Result,
1732 ) -> bool {
1733 *current_result < self.limit
1734 }
1735 }
1736
1737 let parsed = visitor_test_tree();
1738 let mut none = Visitor {
1739 limit: 0,
1740 visited: 0,
1741 };
1742 assert_eq!(none.visit(parsed.tree()), 0);
1743 assert_eq!(none.visited, 0);
1744
1745 let mut one = Visitor {
1746 limit: 1,
1747 visited: 0,
1748 };
1749 assert_eq!(one.visit(parsed.tree()), 1);
1750 assert_eq!(one.visited, 1);
1751 }
1752
1753 #[test]
1754 fn visitor_grows_the_stack_for_deep_rule_trees() {
1755 const DEPTH: usize = 20_000;
1756 const STACK_SIZE: usize = 256 * 1024;
1757
1758 std::thread::Builder::new()
1759 .name("visitor-stack-growth".to_owned())
1760 .stack_size(STACK_SIZE)
1761 .spawn(|| {
1762 let tokens = TokenStore::new(None, "");
1763 let mut storage = ParseTreeStorage::new();
1764 let mut child = storage.finish_rule(ParserRuleContext::new(DEPTH, -1));
1765 for rule_index in (0..DEPTH).rev() {
1766 let mut parent = ParserRuleContext::new(rule_index, -1);
1767 storage.add_child(&mut parent, child);
1768 child = storage.finish_rule(parent);
1769 }
1770 let parsed = ParsedFile::new(tokens, storage, child);
1771
1772 struct Visitor;
1773 impl ParseTreeVisitor for Visitor {
1774 type Result = usize;
1775
1776 fn default_result(&mut self) -> Self::Result {
1777 0
1778 }
1779
1780 fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1781 self.visit_children(node) + 1
1782 }
1783 }
1784
1785 assert_eq!(Visitor.visit(parsed.tree()), DEPTH + 1);
1786 })
1787 .expect("small-stack thread should start")
1788 .join()
1789 .expect("visitor should not overflow its stack");
1790 }
1791
1792 #[test]
1793 fn invocation_states_exclude_a_nonnegative_root_frame() {
1794 let tokens = TokenStore::new(None, "");
1795 let mut storage = ParseTreeStorage::new();
1796 let grandchild = storage.finish_rule(ParserRuleContext::new(2, 13));
1797 let mut child = ParserRuleContext::new(1, 7);
1798 storage.add_child(&mut child, grandchild);
1799 let child = storage.finish_rule(child);
1800 let mut root = ParserRuleContext::new(0, 4);
1801 storage.add_child(&mut root, child);
1802 let root = storage.finish_rule(root);
1803 let parsed = ParsedFile::new(tokens, storage, root);
1804
1805 let root = parsed
1806 .node(root)
1807 .and_then(Node::as_rule)
1808 .expect("root rule should be stored");
1809 let child = parsed
1810 .node(child)
1811 .and_then(Node::as_rule)
1812 .expect("child rule should be stored");
1813 let grandchild = parsed
1814 .node(grandchild)
1815 .and_then(Node::as_rule)
1816 .expect("grandchild rule should be stored");
1817
1818 assert_eq!(root.invocation_states().collect::<Vec<_>>(), []);
1819 assert_eq!(child.invocation_states().collect::<Vec<_>>(), [7]);
1820 assert_eq!(grandchild.invocation_states().collect::<Vec<_>>(), [13, 7]);
1821 }
1822
1823 #[test]
1824 fn uncommon_rule_payloads_live_in_sparse_extras() {
1825 let tokens = TokenStore::new(None, "");
1826 let mut storage = ParseTreeStorage::new();
1827 let plain = storage.finish_rule(ParserRuleContext::new(0, -1));
1828 let mut rich = ParserRuleContext::new(1, 3);
1829 rich.set_int_return("value", 42);
1830 let rich = storage.finish_rule(rich);
1831 let parsed = ParsedFile::new(tokens, storage, rich);
1832
1833 assert_eq!(parsed.storage().extra_count(), 1);
1834 assert_eq!(
1835 parsed
1836 .node(rich)
1837 .expect("rich rule should be stored")
1838 .as_rule()
1839 .expect("rich node should be a rule")
1840 .int_return("value"),
1841 Some(42)
1842 );
1843 assert!(
1844 parsed
1845 .node(plain)
1846 .expect("plain rule should be stored")
1847 .as_rule()
1848 .expect("plain node should be a rule")
1849 .int_return("value")
1850 .is_none()
1851 );
1852 }
1853
1854 #[test]
1855 fn preserves_maximum_token_id_in_nodes_and_rule_spans() {
1856 let max = TokenId::try_from(u32::MAX as usize).expect("maximum token ID should fit");
1857 let tokens = TokenStore::new(None, "");
1858 let mut storage = ParseTreeStorage::new();
1859 let terminal = storage.terminal(max);
1860 assert_eq!(storage.token_id(terminal), Some(max));
1861
1862 let mut context = ParserRuleContext::new(0, -1);
1863 context.set_start_id(max);
1864 context.set_stop_id(max);
1865 let rule = storage.finish_rule(context);
1866 let rule = storage
1867 .node(&tokens, rule)
1868 .and_then(Node::as_rule)
1869 .expect("rule should be stored");
1870 assert_eq!(rule.start_id(), Some(max));
1871 assert_eq!(rule.stop_id(), Some(max));
1872 }
1873}