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 pub fn labeled_terminal_children<'a>(
1176 &'a self,
1177 storage: &'a ParseTreeStorage,
1178 tokens: &'a TokenStore,
1179 ) -> impl Iterator<Item = TerminalNodeView<'a>> + 'a {
1180 self.child_nodes(storage, tokens)
1181 .filter_map(|child| match child.kind() {
1182 NodeKind::Terminal => child.as_terminal(),
1183 NodeKind::Error => {
1184 let terminal = child.as_error().map(ErrorNodeView::terminal)?;
1185 let symbol = terminal.symbol();
1186 (symbol.start() == usize::MAX && symbol.stop() == usize::MAX)
1189 .then_some(terminal)
1190 }
1191 NodeKind::Rule => None,
1192 })
1193 }
1194
1195 #[must_use]
1196 pub fn text(&self, storage: &ParseTreeStorage, tokens: &TokenStore) -> String {
1197 self.child_nodes(storage, tokens).map(Node::text).collect()
1198 }
1199
1200 #[must_use]
1201 pub fn to_string_tree_with_names<S: AsRef<str>>(
1202 &self,
1203 storage: &ParseTreeStorage,
1204 tokens: &TokenStore,
1205 rule_names: &[S],
1206 ) -> String {
1207 let name = rule_names
1208 .get(self.rule_index)
1209 .map_or("<unknown>", |name| name.as_ref());
1210 let display_name = if self.alt_number == 0 {
1211 name.to_owned()
1212 } else {
1213 format!("{name}:{}", self.alt_number)
1214 };
1215 if self.child_count == 0 {
1216 return display_name;
1217 }
1218 let children = self
1219 .child_nodes(storage, tokens)
1220 .map(|child| child.to_string_tree_with_names(rule_names))
1221 .collect::<Vec<_>>()
1222 .join(" ");
1223 format!("({display_name} {children})")
1224 }
1225
1226 #[must_use]
1227 pub fn to_string_tree<R: Recognizer>(
1228 &self,
1229 recognizer: Option<&R>,
1230 storage: &ParseTreeStorage,
1231 tokens: &TokenStore,
1232 ) -> String {
1233 recognizer.map_or_else(
1234 || self.to_string_tree_with_names::<&str>(storage, tokens, &[]),
1235 |recognizer| {
1236 self.to_string_tree_with_names(storage, tokens, recognizer.data().rule_names())
1237 },
1238 )
1239 }
1240}
1241
1242pub struct GeneratedAttrs(Box<dyn Any>);
1244
1245impl GeneratedAttrs {
1246 #[must_use]
1247 pub fn new<T: Any>(attrs: T) -> Self {
1248 Self(Box::new(attrs))
1249 }
1250
1251 #[must_use]
1252 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
1253 self.0.downcast_ref::<T>()
1254 }
1255}
1256
1257impl fmt::Debug for GeneratedAttrs {
1258 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1259 f.write_str("GeneratedAttrs(..)")
1260 }
1261}
1262
1263pub trait FromRuleNode<'tree>: Sized {
1264 fn from_rule_node(node: RuleNodeView<'tree>) -> Option<Self>;
1265}
1266
1267pub trait AsRuleNode<'tree> {
1269 fn as_rule_node(&self) -> RuleNodeView<'tree>;
1270}
1271
1272impl<'tree> AsRuleNode<'tree> for RuleNodeView<'tree> {
1273 fn as_rule_node(&self) -> Self {
1274 *self
1275 }
1276}
1277
1278#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1280pub struct MissingChildError {
1281 context: &'static str,
1282 child: &'static str,
1283}
1284
1285impl MissingChildError {
1286 #[must_use]
1287 pub const fn new(context: &'static str, child: &'static str) -> Self {
1288 Self { context, child }
1289 }
1290
1291 #[must_use]
1292 pub const fn context(self) -> &'static str {
1293 self.context
1294 }
1295
1296 #[must_use]
1297 pub const fn child(self) -> &'static str {
1298 self.child
1299 }
1300}
1301
1302impl fmt::Display for MissingChildError {
1303 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1304 write!(
1305 f,
1306 "required child {} is missing from {}",
1307 self.child, self.context
1308 )
1309 }
1310}
1311
1312impl std::error::Error for MissingChildError {}
1313
1314pub trait ParseTreeListener {
1315 fn enter_every_rule(&mut self, _ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1316 Ok(())
1317 }
1318
1319 fn exit_every_rule(&mut self, _ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1320 Ok(())
1321 }
1322
1323 fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Result<(), AntlrError> {
1324 Ok(())
1325 }
1326
1327 fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Result<(), AntlrError> {
1328 Ok(())
1329 }
1330}
1331
1332pub trait ParseTreeVisitor {
1338 type Result;
1339
1340 fn default_result(&mut self) -> Self::Result;
1341
1342 fn visit(&mut self, tree: Node<'_>) -> Self::Result {
1343 match tree.kind() {
1344 NodeKind::Rule => self.visit_rule(tree.as_rule().expect("rule node kind checked")),
1345 NodeKind::Terminal => {
1346 self.visit_terminal(tree.as_terminal().expect("terminal node kind checked"))
1347 }
1348 NodeKind::Error => {
1349 self.visit_error_node(tree.as_error().expect("error node kind checked"))
1350 }
1351 }
1352 }
1353
1354 fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1355 self.visit_children(node)
1356 }
1357
1358 fn visit_children(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1359 stacker::maybe_grow(VISITOR_STACK_RED_ZONE, VISITOR_STACK_SIZE, || {
1360 let mut result = self.default_result();
1361 for child in node.children() {
1362 if !self.should_visit_next_child(node, &result) {
1363 break;
1364 }
1365 let child_result = self.visit(child);
1366 result = self.aggregate_result(result, child_result);
1367 }
1368 result
1369 })
1370 }
1371
1372 fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Self::Result {
1373 self.default_result()
1374 }
1375
1376 fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Self::Result {
1377 self.default_result()
1378 }
1379
1380 fn aggregate_result(
1381 &mut self,
1382 _aggregate: Self::Result,
1383 next_result: Self::Result,
1384 ) -> Self::Result {
1385 next_result
1386 }
1387
1388 fn should_visit_next_child(
1389 &mut self,
1390 _node: RuleNodeView<'_>,
1391 _current_result: &Self::Result,
1392 ) -> bool {
1393 true
1394 }
1395}
1396
1397#[derive(Debug, Default)]
1398pub struct ParseTreeWalker;
1399
1400impl ParseTreeWalker {
1401 pub fn walk<L: ParseTreeListener>(listener: &mut L, tree: Node<'_>) -> Result<(), AntlrError> {
1402 enum Event {
1403 Enter(NodeId),
1404 Exit(NodeId),
1405 }
1406
1407 let storage = tree.storage;
1408 let tokens = tree.tokens;
1409 let mut stack = vec![Event::Enter(tree.id)];
1410 while let Some(event) = stack.pop() {
1411 match event {
1412 Event::Enter(id) => {
1413 let node = storage
1414 .node(tokens, id)
1415 .expect("walker node ID should remain valid");
1416 match node.kind() {
1417 NodeKind::Rule => {
1418 let rule = node.as_rule().expect("rule node kind checked");
1419 listener.enter_every_rule(rule)?;
1420 stack.push(Event::Exit(id));
1421 stack.extend(
1422 storage
1423 .child_ids(id)
1424 .iter()
1425 .rev()
1426 .copied()
1427 .map(Event::Enter),
1428 );
1429 }
1430 NodeKind::Terminal => listener.visit_terminal(
1431 node.as_terminal().expect("terminal node kind checked"),
1432 )?,
1433 NodeKind::Error => {
1434 listener.visit_error_node(
1435 node.as_error().expect("error node kind checked"),
1436 )?;
1437 }
1438 }
1439 }
1440 Event::Exit(id) => {
1441 let rule = storage
1442 .node(tokens, id)
1443 .and_then(Node::as_rule)
1444 .expect("walker exit node should remain a rule");
1445 listener.exit_every_rule(rule)?;
1446 }
1447 }
1448 }
1449 Ok(())
1450 }
1451}
1452
1453#[derive(Debug)]
1454pub struct ParsedFile {
1455 tokens: TokenStore,
1456 tree: ParseTreeStorage,
1457 root: NodeId,
1458}
1459
1460impl ParsedFile {
1461 #[must_use]
1462 pub fn new(tokens: TokenStore, mut tree: ParseTreeStorage, root: NodeId) -> Self {
1463 tree.discard_scratch();
1464 Self { tokens, tree, root }
1465 }
1466
1467 #[must_use]
1468 pub const fn tokens(&self) -> &TokenStore {
1469 &self.tokens
1470 }
1471
1472 #[must_use]
1473 pub const fn storage(&self) -> &ParseTreeStorage {
1474 &self.tree
1475 }
1476
1477 #[must_use]
1478 pub const fn root_id(&self) -> NodeId {
1479 self.root
1480 }
1481
1482 #[must_use]
1483 pub fn tree(&self) -> Node<'_> {
1484 self.tree
1485 .node(&self.tokens, self.root)
1486 .expect("parsed file root ID should remain valid")
1487 }
1488
1489 #[must_use]
1490 pub fn node(&self, id: NodeId) -> Option<Node<'_>> {
1491 self.tree.node(&self.tokens, id)
1492 }
1493
1494 #[must_use]
1495 pub fn into_parts(self) -> (TokenStore, ParseTreeStorage, NodeId) {
1496 (self.tokens, self.tree, self.root)
1497 }
1498}
1499
1500fn escape_tree_text(text: &str) -> String {
1501 let mut escaped = String::with_capacity(text.len());
1502 for ch in text.chars() {
1503 match ch {
1504 '\n' => escaped.push_str("\\n"),
1505 '\r' => escaped.push_str("\\r"),
1506 '\t' => escaped.push_str("\\t"),
1507 _ => escaped.push(ch),
1508 }
1509 }
1510 escaped
1511}
1512
1513fn stored_token_id(raw: u32) -> TokenId {
1514 TokenId::try_from(raw as usize).expect("stored token ID should fit in u32")
1515}
1516
1517#[cfg(test)]
1518#[allow(clippy::disallowed_methods)] mod tests {
1520 use super::*;
1521 use crate::token::TokenSpec;
1522
1523 fn token(store: &mut TokenStore, token_type: i32, text: &str) -> TokenId {
1524 store
1525 .push(TokenSpec::explicit(token_type, text))
1526 .expect("test token should fit")
1527 }
1528
1529 #[test]
1530 fn stores_rule_children_in_one_pooled_range() {
1531 let mut tokens = TokenStore::new(None, "");
1532 let first = token(&mut tokens, 1, "a");
1533 let second = token(&mut tokens, 2, "b");
1534 let mut storage = ParseTreeStorage::new();
1535 let first = storage.terminal(first);
1536 let second = storage.error(second);
1537 let mut context = ParserRuleContext::new(0, -1);
1538 storage.add_child(&mut context, first);
1539 storage.add_child(&mut context, second);
1540 let root = storage.finish_rule(context);
1541 let parsed = ParsedFile::new(tokens, storage, root);
1542
1543 assert_eq!(parsed.tree().text(), "ab");
1544 assert_eq!(parsed.tree().children().count(), 2);
1545 assert_eq!(parsed.storage().stats().edges, 2);
1546 assert_eq!(parsed.storage().stats().scratch_links, 0);
1547 assert_eq!(
1548 parsed.tree().to_string_tree_with_names(&["root"]),
1549 "(root a b)"
1550 );
1551 }
1552
1553 #[test]
1554 fn labeled_terminal_children_keep_inserted_tokens_and_skip_deleted_ones() {
1555 let mut tokens = TokenStore::new(None, "");
1556 let deleted = token(&mut tokens, 1, "x");
1557 let inserted = tokens
1558 .push(
1559 TokenSpec::explicit(2, "<missing B>")
1560 .with_span(usize::MAX, usize::MAX)
1561 .with_byte_span(0, 0),
1562 )
1563 .expect("test token should fit");
1564 let kept = token(&mut tokens, 3, "c");
1565 let mut storage = ParseTreeStorage::new();
1566 let deleted = storage.error(deleted);
1567 let inserted = storage.error(inserted);
1568 let kept = storage.terminal(kept);
1569 let mut context = ParserRuleContext::new(0, -1);
1570 storage.add_child(&mut context, deleted);
1571 storage.add_child(&mut context, inserted);
1572 storage.add_child(&mut context, kept);
1573
1574 let raw = context
1577 .terminal_children(&storage, &tokens)
1578 .map(|terminal| terminal.text().to_owned())
1579 .collect::<Vec<_>>();
1580 let labeled = context
1581 .labeled_terminal_children(&storage, &tokens)
1582 .map(|terminal| terminal.text().to_owned())
1583 .collect::<Vec<_>>();
1584
1585 insta::assert_debug_snapshot!("terminal_children_raw_vs_labeled", (raw, labeled));
1586 }
1587
1588 #[test]
1589 fn context_alt_number_does_not_change_public_tree_rendering() {
1590 let tokens = TokenStore::new(None, "");
1591 let mut storage = ParseTreeStorage::new();
1592 let mut context = ParserRuleContext::new(0, -1);
1593 context.set_context_alt_number(2);
1594
1595 assert_eq!(context.alt_number(), 0);
1596 assert_eq!(context.context_alt_number(), 2);
1597 assert_eq!(
1598 context.to_string_tree_with_names(&storage, &tokens, &["root"]),
1599 "root"
1600 );
1601
1602 let root = storage.finish_rule(context);
1603 let parsed = ParsedFile::new(tokens, storage, root);
1604 let rule = parsed.tree().as_rule().expect("root rule");
1605 assert_eq!(rule.alt_number(), 0);
1606 assert_eq!(rule.context_alt_number(), 2);
1607 assert_eq!(parsed.tree().to_string_tree_with_names(&["root"]), "root");
1608 }
1609
1610 #[test]
1611 fn descendants_and_walker_preserve_antlr_order() {
1612 let mut tokens = TokenStore::new(None, "");
1613 let a = token(&mut tokens, 1, "a");
1614 let b = token(&mut tokens, 2, "b");
1615 let mut storage = ParseTreeStorage::new();
1616 let a = storage.terminal(a);
1617 let b = storage.terminal(b);
1618 let mut child = ParserRuleContext::new(1, 7);
1619 storage.add_child(&mut child, b);
1620 let child = storage.finish_rule(child);
1621 let mut root = ParserRuleContext::new(0, -1);
1622 storage.add_child(&mut root, a);
1623 storage.add_child(&mut root, child);
1624 let root = storage.finish_rule(root);
1625 let parsed = ParsedFile::new(tokens, storage, root);
1626
1627 let visited = parsed
1628 .tree()
1629 .descendants()
1630 .map(|node| match node.kind() {
1631 NodeKind::Rule => format!(
1632 "r{}",
1633 node.as_rule().expect("rule node kind checked").rule_index()
1634 ),
1635 NodeKind::Terminal => node
1636 .as_terminal()
1637 .expect("terminal node kind checked")
1638 .text()
1639 .to_owned(),
1640 NodeKind::Error => node
1641 .as_error()
1642 .expect("error node kind checked")
1643 .text()
1644 .to_owned(),
1645 })
1646 .collect::<Vec<_>>();
1647 assert_eq!(visited, ["r0", "a", "r1", "b"]);
1648
1649 #[derive(Default)]
1650 struct Listener(Vec<String>);
1651 impl ParseTreeListener for Listener {
1652 fn enter_every_rule(&mut self, ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1653 self.0.push(format!("enter{}", ctx.rule_index()));
1654 Ok(())
1655 }
1656
1657 fn exit_every_rule(&mut self, ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1658 self.0.push(format!("exit{}", ctx.rule_index()));
1659 Ok(())
1660 }
1661
1662 fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Result<(), AntlrError> {
1663 self.0.push(node.text().to_owned());
1664 Ok(())
1665 }
1666 }
1667 let mut listener = Listener::default();
1668 ParseTreeWalker::walk(&mut listener, parsed.tree())
1669 .expect("test listener should accept every node");
1670 assert_eq!(listener.0, ["enter0", "a", "enter1", "b", "exit1", "exit0"]);
1671 }
1672
1673 fn visitor_test_tree() -> ParsedFile {
1674 let mut tokens = TokenStore::new(None, "");
1675 let a = token(&mut tokens, 1, "a");
1676 let b = token(&mut tokens, 2, "b");
1677 let error = token(&mut tokens, 3, "!");
1678 let mut storage = ParseTreeStorage::new();
1679 let a = storage.terminal(a);
1680 let b = storage.terminal(b);
1681 let error = storage.error(error);
1682 let mut child = ParserRuleContext::new(1, 7);
1683 storage.add_child(&mut child, b);
1684 let child = storage.finish_rule(child);
1685 let mut root = ParserRuleContext::new(0, -1);
1686 storage.add_child(&mut root, a);
1687 storage.add_child(&mut root, child);
1688 storage.add_child(&mut root, error);
1689 let root = storage.finish_rule(root);
1690 ParsedFile::new(tokens, storage, root)
1691 }
1692
1693 #[test]
1694 fn visitor_dispatches_and_aggregates_all_node_kinds() {
1695 #[derive(Default)]
1696 struct Visitor(Vec<String>);
1697
1698 impl ParseTreeVisitor for Visitor {
1699 type Result = Vec<String>;
1700
1701 fn default_result(&mut self) -> Self::Result {
1702 Vec::new()
1703 }
1704
1705 fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1706 self.0.push(format!("rule{}", node.rule_index()));
1707 self.visit_children(node)
1708 }
1709
1710 fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Self::Result {
1711 vec![format!("terminal:{}", node.text())]
1712 }
1713
1714 fn visit_error_node(&mut self, node: ErrorNodeView<'_>) -> Self::Result {
1715 vec![format!("error:{}", node.text())]
1716 }
1717
1718 fn aggregate_result(
1719 &mut self,
1720 mut aggregate: Self::Result,
1721 next_result: Self::Result,
1722 ) -> Self::Result {
1723 aggregate.extend(next_result);
1724 aggregate
1725 }
1726 }
1727
1728 let parsed = visitor_test_tree();
1729 let mut visitor = Visitor::default();
1730 assert_eq!(
1731 visitor.visit(parsed.tree()),
1732 ["terminal:a", "terminal:b", "error:!"]
1733 );
1734 assert_eq!(visitor.0, ["rule0", "rule1"]);
1735 }
1736
1737 #[test]
1738 fn visitor_default_aggregation_returns_the_latest_child() {
1739 struct Visitor;
1740
1741 impl ParseTreeVisitor for Visitor {
1742 type Result = String;
1743
1744 fn default_result(&mut self) -> Self::Result {
1745 String::new()
1746 }
1747
1748 fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Self::Result {
1749 node.text().to_owned()
1750 }
1751
1752 fn visit_error_node(&mut self, node: ErrorNodeView<'_>) -> Self::Result {
1753 node.text().to_owned()
1754 }
1755 }
1756
1757 let parsed = visitor_test_tree();
1758 assert_eq!(Visitor.visit(parsed.tree()), "!");
1759 }
1760
1761 #[test]
1762 fn visitor_can_short_circuit_before_any_or_later_children() {
1763 struct Visitor {
1764 limit: usize,
1765 visited: usize,
1766 }
1767
1768 impl ParseTreeVisitor for Visitor {
1769 type Result = usize;
1770
1771 fn default_result(&mut self) -> Self::Result {
1772 0
1773 }
1774
1775 fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Self::Result {
1776 self.visited += 1;
1777 1
1778 }
1779
1780 fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Self::Result {
1781 self.visited += 1;
1782 1
1783 }
1784
1785 fn aggregate_result(
1786 &mut self,
1787 aggregate: Self::Result,
1788 next_result: Self::Result,
1789 ) -> Self::Result {
1790 aggregate + next_result
1791 }
1792
1793 fn should_visit_next_child(
1794 &mut self,
1795 _node: RuleNodeView<'_>,
1796 current_result: &Self::Result,
1797 ) -> bool {
1798 *current_result < self.limit
1799 }
1800 }
1801
1802 let parsed = visitor_test_tree();
1803 let mut none = Visitor {
1804 limit: 0,
1805 visited: 0,
1806 };
1807 assert_eq!(none.visit(parsed.tree()), 0);
1808 assert_eq!(none.visited, 0);
1809
1810 let mut one = Visitor {
1811 limit: 1,
1812 visited: 0,
1813 };
1814 assert_eq!(one.visit(parsed.tree()), 1);
1815 assert_eq!(one.visited, 1);
1816 }
1817
1818 #[test]
1819 fn visitor_grows_the_stack_for_deep_rule_trees() {
1820 const DEPTH: usize = 20_000;
1821 const STACK_SIZE: usize = 256 * 1024;
1822
1823 std::thread::Builder::new()
1824 .name("visitor-stack-growth".to_owned())
1825 .stack_size(STACK_SIZE)
1826 .spawn(|| {
1827 let tokens = TokenStore::new(None, "");
1828 let mut storage = ParseTreeStorage::new();
1829 let mut child = storage.finish_rule(ParserRuleContext::new(DEPTH, -1));
1830 for rule_index in (0..DEPTH).rev() {
1831 let mut parent = ParserRuleContext::new(rule_index, -1);
1832 storage.add_child(&mut parent, child);
1833 child = storage.finish_rule(parent);
1834 }
1835 let parsed = ParsedFile::new(tokens, storage, child);
1836
1837 struct Visitor;
1838 impl ParseTreeVisitor for Visitor {
1839 type Result = usize;
1840
1841 fn default_result(&mut self) -> Self::Result {
1842 0
1843 }
1844
1845 fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1846 self.visit_children(node) + 1
1847 }
1848 }
1849
1850 assert_eq!(Visitor.visit(parsed.tree()), DEPTH + 1);
1851 })
1852 .expect("small-stack thread should start")
1853 .join()
1854 .expect("visitor should not overflow its stack");
1855 }
1856
1857 #[test]
1858 fn invocation_states_exclude_a_nonnegative_root_frame() {
1859 let tokens = TokenStore::new(None, "");
1860 let mut storage = ParseTreeStorage::new();
1861 let grandchild = storage.finish_rule(ParserRuleContext::new(2, 13));
1862 let mut child = ParserRuleContext::new(1, 7);
1863 storage.add_child(&mut child, grandchild);
1864 let child = storage.finish_rule(child);
1865 let mut root = ParserRuleContext::new(0, 4);
1866 storage.add_child(&mut root, child);
1867 let root = storage.finish_rule(root);
1868 let parsed = ParsedFile::new(tokens, storage, root);
1869
1870 let root = parsed
1871 .node(root)
1872 .and_then(Node::as_rule)
1873 .expect("root rule should be stored");
1874 let child = parsed
1875 .node(child)
1876 .and_then(Node::as_rule)
1877 .expect("child rule should be stored");
1878 let grandchild = parsed
1879 .node(grandchild)
1880 .and_then(Node::as_rule)
1881 .expect("grandchild rule should be stored");
1882
1883 assert_eq!(root.invocation_states().collect::<Vec<_>>(), []);
1884 assert_eq!(child.invocation_states().collect::<Vec<_>>(), [7]);
1885 assert_eq!(grandchild.invocation_states().collect::<Vec<_>>(), [13, 7]);
1886 }
1887
1888 #[test]
1889 fn uncommon_rule_payloads_live_in_sparse_extras() {
1890 let tokens = TokenStore::new(None, "");
1891 let mut storage = ParseTreeStorage::new();
1892 let plain = storage.finish_rule(ParserRuleContext::new(0, -1));
1893 let mut rich = ParserRuleContext::new(1, 3);
1894 rich.set_int_return("value", 42);
1895 let rich = storage.finish_rule(rich);
1896 let parsed = ParsedFile::new(tokens, storage, rich);
1897
1898 assert_eq!(parsed.storage().extra_count(), 1);
1899 assert_eq!(
1900 parsed
1901 .node(rich)
1902 .expect("rich rule should be stored")
1903 .as_rule()
1904 .expect("rich node should be a rule")
1905 .int_return("value"),
1906 Some(42)
1907 );
1908 assert!(
1909 parsed
1910 .node(plain)
1911 .expect("plain rule should be stored")
1912 .as_rule()
1913 .expect("plain node should be a rule")
1914 .int_return("value")
1915 .is_none()
1916 );
1917 }
1918
1919 #[test]
1920 fn preserves_maximum_token_id_in_nodes_and_rule_spans() {
1921 let max = TokenId::try_from(u32::MAX as usize).expect("maximum token ID should fit");
1922 let tokens = TokenStore::new(None, "");
1923 let mut storage = ParseTreeStorage::new();
1924 let terminal = storage.terminal(max);
1925 assert_eq!(storage.token_id(terminal), Some(max));
1926
1927 let mut context = ParserRuleContext::new(0, -1);
1928 context.set_start_id(max);
1929 context.set_stop_id(max);
1930 let rule = storage.finish_rule(context);
1931 let rule = storage
1932 .node(&tokens, rule)
1933 .and_then(Node::as_rule)
1934 .expect("rule should be stored");
1935 assert_eq!(rule.start_id(), Some(max));
1936 assert_eq!(rule.stop_id(), Some(max));
1937 }
1938}