Skip to main content

antlr4_runtime/
tree.rs

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