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