Skip to main content

dbt_antlr4/
tree.rs

1//! General AST
2use std::any::Any;
3
4use std::fmt::{Debug, Formatter};
5use std::marker::PhantomData;
6
7use crate::char_stream::InputData;
8use crate::errors::ANTLRError;
9use crate::int_stream::EOF;
10use crate::interval_set::Interval;
11use crate::parser_rule_context::ParserRuleContext;
12use crate::rule_context::RuleContext;
13use crate::token::{CommonToken, Token};
14use crate::{cast_unchecked, token_factory, Arena};
15
16#[allow(missing_docs)]
17pub trait Tree<'arena>: Sized {
18    fn get_parent(&self) -> Option<&'arena Self>;
19
20    fn has_parent(&self) -> bool;
21
22    fn get_payload(&self) -> Box<dyn Any> {
23        unimplemented!()
24    }
25
26    fn get_child(&self, _i: usize) -> Option<&'arena Self>;
27
28    fn get_child_count(&self) -> usize;
29
30    fn get_children<'a>(&'a self) -> Box<dyn Iterator<Item = &'arena Self> + 'a>;
31}
32
33/// Tree that knows about underlying text
34pub trait ParseTree<'input, 'arena>: Tree<'arena> {
35    /// Return an {@link Interval} indicating the index in the
36    /// {@link TokenStream} of the first and last token associated with this
37    /// subtree. If this node is a leaf, then the interval represents a single
38    /// token and has interval i..i for token index i.
39    fn get_source_interval(&self) -> Interval;
40
41    /// Return combined text of this AST node.
42    /// To create resulting string it does traverse whole subtree,
43    /// also it includes only tokens added to the parse tree
44    ///
45    /// Since tokens on hidden channels (e.g. whitespace or comments) are not
46    /// added to the parse trees, they will not appear in the output of this
47    /// method.
48    fn get_text(&self) -> String;
49}
50
51/// Helper trait, implemented for all rule context types that can be wrapped
52/// inside [TreeNode].
53pub trait NodeInner<'input, 'arena, Node, Tok = CommonToken<'input>>
54where
55    'input: 'arena,
56    Node: NodeKindType<'arena, Tok>,
57    Tok: Token + 'input,
58{
59    /// Extract a reference to self from a reference to [TreeNode].
60    ///
61    /// Used for safe downcasting.
62    fn cast_from<'a>(node: &'a TreeNode<'input, 'arena, Node, Tok>) -> Option<&'a Self>
63    where
64        Self: Sized;
65
66    /// Extract a mutable reference to self from a mutable reference to
67    /// [TreeNode].
68    ///
69    /// Used for safe downcasting.
70    fn cast_from_mut<'a>(node: &'a mut TreeNode<'input, 'arena, Node, Tok>) -> Option<&'a mut Self>
71    where
72        Self: Sized;
73
74    /// Upcast &self back to a `&'arena Node`.
75    fn as_node(&self) -> &TreeNode<'input, 'arena, Node, Tok>;
76
77    fn as_node_mut(&mut self) -> &mut TreeNode<'input, 'arena, Node, Tok>;
78
79    /// Iterate over children as [TreeNode]s
80    fn iter_child_nodes<'a>(
81        &'a self,
82    ) -> Box<dyn Iterator<Item = &'arena TreeNode<'input, 'arena, Node, Tok>> + 'a>;
83}
84
85pub type CtxPtr<'input, 'arena> = *mut (&'input (), *mut &'arena ());
86
87pub trait NodeKindType<'arena, Tok = CommonToken<'arena>>:
88    Copy + Debug + PartialEq + Eq + 'static
89where
90    Tok: Token + 'arena,
91{
92    type Listener: ParseTreeListener<'arena, Self, Tok> + ?Sized;
93
94    fn cast_to_ctx<'n, 'input: 'arena>(
95        node: &'n TreeNode<'input, 'arena, Self, Tok>,
96    ) -> &'n dyn ParserRuleContext<'input, 'arena>;
97
98    fn cast_to_ctx_mut<'n, 'input: 'arena>(
99        node: &'n mut TreeNode<'input, 'arena, Self, Tok>,
100    ) -> &'n mut dyn ParserRuleContext<'input, 'arena>;
101
102    fn set_alt_number<'input: 'arena>(
103        node: &mut TreeNode<'input, 'arena, Self, Tok>,
104        alt_number: i32,
105    );
106
107    fn get_rule_index<'input: 'arena>(node: &TreeNode<'input, 'arena, Self, Tok>) -> usize;
108
109    fn get_alt_number<'input: 'arena>(node: &TreeNode<'input, 'arena, Self, Tok>) -> i32;
110
111    fn terminal() -> Self;
112
113    fn error() -> Self;
114
115    fn is_context(&self) -> bool;
116
117    fn enter_rule<'input: 'arena>(
118        node: &TreeNode<'input, 'arena, Self, Tok>,
119        listener: &mut Self::Listener,
120    ) -> Result<(), ANTLRError>;
121
122    fn exit_rule<'input: 'arena>(
123        node: &TreeNode<'input, 'arena, Self, Tok>,
124        listener: &mut Self::Listener,
125    ) -> Result<(), ANTLRError>;
126
127    #[inline]
128    fn is_terminal(&self) -> bool {
129        *self == Self::terminal()
130    }
131
132    #[inline]
133    fn is_error(&self) -> bool {
134        *self == Self::error()
135    }
136}
137#[repr(C, align(8))]
138struct ParserRuleContextCommonLayout<'input, 'arena, Node, Tok = CommonToken<'input>>
139where
140    'input: 'arena,
141    Node: NodeKindType<'arena, Tok>,
142    Tok: Token + 'input,
143{
144    // --- BaseParserRuleContext fields ---
145    start: Option<&'arena Tok>,
146    stop: Option<&'arena Tok>,
147    children: bumpalo::collections::Vec<'arena, &'arena TreeNode<'input, 'arena, Node, Tok>>,
148    // --- BaseRuleContext fields ---
149    parent: Option<&'arena TreeNode<'input, 'arena, Node, Tok>>,
150}
151
152#[derive(Debug)]
153#[repr(C, align(8))]
154pub struct TreeNode<'input, 'arena, NodeKind, Tok = CommonToken<'input>>
155where
156    'input: 'arena,
157    NodeKind: NodeKindType<'arena, Tok>,
158    Tok: Token + 'input,
159{
160    pub(crate) label_tag: u16,
161    pub node_tag: NodeKind,
162    invoking_state: i32,
163    body: (),
164
165    _mark: PhantomData<(&'input Tok, *mut &'arena ())>,
166}
167
168impl<'input, 'arena, NodeKind, Tok> TreeNode<'input, 'arena, NodeKind, Tok>
169where
170    'input: 'arena,
171    NodeKind: NodeKindType<'arena, Tok>,
172    Tok: Token + 'input,
173{
174    pub fn create_token_node(arena: &'arena Arena, symbol: &'arena Tok) -> *mut Self {
175        let header = TreeNode {
176            node_tag: NodeKind::terminal(),
177            label_tag: 0,
178            invoking_state: -1,
179            body: (),
180            _mark: PhantomData,
181        };
182        let leaf = TerminalNode::new(symbol);
183        arena.alloc_node(header, leaf)
184    }
185
186    pub fn create_error_node(arena: &'arena Arena, symbol: &'arena Tok) -> *mut Self {
187        let header = TreeNode {
188            node_tag: NodeKind::error(),
189            label_tag: 0,
190            invoking_state: -1,
191            body: (),
192            _mark: PhantomData,
193        };
194        let leaf = ErrorNode::new(symbol);
195        arena.alloc_node(header, leaf)
196    }
197
198    #[inline]
199    pub fn node_tag(&self) -> NodeKind {
200        self.node_tag
201    }
202
203    /// Return the [ParserRuleContext] object associated with this rule node.
204    pub fn get_rule_context(&self) -> &dyn ParserRuleContext<'input, 'arena> {
205        NodeKind::cast_to_ctx(self)
206    }
207
208    /// Return mutable reference to the [ParserRuleContext] object associated
209    /// with this rule node.
210    pub fn get_rule_context_mut(&mut self) -> &mut dyn ParserRuleContext<'input, 'arena> {
211        NodeKind::cast_to_ctx_mut(self)
212    }
213
214    #[inline]
215    pub fn ctx_ptr(&self) -> CtxPtr<'input, 'arena> {
216        &self.body as *const _ as *mut (&'input (), *mut &'arena ())
217    }
218
219    pub(crate) fn get_start_token(&self) -> Option<&'arena Tok> {
220        self.as_rule_context_common().and_then(|ctx| ctx.start)
221    }
222
223    #[allow(dead_code)]
224    pub(crate) fn get_stop_token(&self) -> Option<&'arena Tok> {
225        self.as_rule_context_common().and_then(|ctx| ctx.stop)
226    }
227
228    /// # Safety
229    /// Caller must ensure that the provided pointer is a valid pointer to a
230    /// properly instantiated [NodeInner] object:
231    /// - For leaf nodes, it must be created via [TreeNode::create_token_node]
232    ///   or [TreeNode::create_error_node];
233    /// - For rule context nodes, it must be created via
234    ///   [BaseParserRuleContext::create].
235    #[inline]
236    pub(crate) unsafe fn from_ctx_ptr(ctx_ptr: CtxPtr<'input, 'arena>) -> &'arena Self {
237        &*((ctx_ptr as *const u8).sub(std::mem::offset_of!(Self, body)) as *const Self)
238    }
239
240    /// # Safety
241    /// Caller must ensure that the provided pointer is a valid pointer to a
242    /// properly instantiated [NodeInner] object:
243    /// - For leaf nodes, it must be created via [TreeNode::create_token_node]
244    ///   or [TreeNode::create_error_node];
245    /// - For rule context nodes, it must be created via
246    ///   [BaseParserRuleContext::create].
247    #[inline]
248    pub(crate) unsafe fn from_ctx_ptr_mut(ctx_ptr: CtxPtr<'input, 'arena>) -> &'arena mut Self {
249        &mut *((ctx_ptr as *const u8).sub(std::mem::offset_of!(Self, body)) as *mut Self)
250    }
251
252    #[inline]
253    fn as_rule_context_common(
254        &self,
255    ) -> Option<&ParserRuleContextCommonLayout<'input, 'arena, NodeKind, Tok>> {
256        if self.node_tag.is_context() {
257            Some(
258                cast_unchecked!(self.ctx_ptr() => ParserRuleContextCommonLayout<'input, 'arena, NodeKind, Tok>),
259            )
260        } else {
261            None
262        }
263    }
264
265    #[inline]
266    fn as_rule_context_common_mut(
267        &mut self,
268    ) -> Option<&mut ParserRuleContextCommonLayout<'input, 'arena, NodeKind, Tok>> {
269        if self.node_tag.is_context() {
270            Some(
271                cast_unchecked!(self.ctx_ptr() => mut ParserRuleContextCommonLayout<'input, 'arena, NodeKind, Tok>),
272            )
273        } else {
274            None
275        }
276    }
277
278    /// Attempt to downcast this node to specific [ParserRuleContext] type
279    pub fn as_rule_context<T>(&self) -> Option<&T>
280    where
281        T: ParserRuleContext<'input, 'arena> + NodeInner<'input, 'arena, NodeKind, Tok>,
282    {
283        T::cast_from(self)
284    }
285
286    /// Attempt to downcast this node to specific [ParserRuleContext] type
287    pub fn as_rule_context_mut<T>(&mut self) -> Option<&mut T>
288    where
289        T: ParserRuleContext<'input, 'arena> + NodeInner<'input, 'arena, NodeKind, Tok>,
290    {
291        T::cast_from_mut(self)
292    }
293
294    /// Downcast this node to terminal node, if the associated context is a
295    /// terminal node
296    pub fn as_terminal_node(&self) -> Option<&TerminalNode<'input, 'arena, Tok>> {
297        TerminalNode::cast_from(self)
298    }
299
300    /// Downcast this node to terminal node, if the associated context is a
301    /// terminal node
302    pub fn as_terminal_node_mut(&mut self) -> Option<&mut TerminalNode<'input, 'arena, Tok>> {
303        TerminalNode::cast_from_mut(self)
304    }
305
306    /// Downcast this node to error node, if the associated context is an error
307    /// node
308    pub fn as_error_node(&self) -> Option<&ErrorNode<'input, 'arena, Tok>> {
309        ErrorNode::cast_from(self)
310    }
311
312    /// Downcast this node to error node, if the associated context is an error
313    /// node
314    pub fn as_error_node_mut(&mut self) -> Option<&mut ErrorNode<'input, 'arena, Tok>> {
315        ErrorNode::cast_from_mut(self)
316    }
317
318    // pub fn add_token_node(&self, token: TerminalNode<'input, Self::TF>) { }
319    // pub fn add_error_node(&self, bad_token: ErrorNode<'input, Self::TF>) { }
320
321    pub fn set_exception(&self, _e: ANTLRError, _arena: &'arena Arena) {}
322
323    /// Sets internal parser state
324    pub fn set_invoking_state(&mut self, s: i32) {
325        self.invoking_state = s;
326    }
327
328    pub fn set_alt_number(&mut self, _alt_number: i32) {
329        NodeKind::set_alt_number(self, _alt_number);
330    }
331
332    pub fn set_start(&mut self, t: Option<&'arena Tok>) {
333        let Some(ctx) = self.as_rule_context_common_mut() else {
334            return;
335        };
336
337        ctx.start = t;
338    }
339
340    pub fn set_stop(&mut self, t: Option<&'arena Tok>) {
341        let Some(ctx) = self.as_rule_context_common_mut() else {
342            return;
343        };
344
345        ctx.stop = t;
346    }
347
348    pub fn remove_last_child(&mut self) {
349        let Some(ctx) = self.as_rule_context_common_mut() else {
350            return;
351        };
352        ctx.children.pop();
353    }
354
355    pub fn add_child(&mut self, _child: &'arena Self) {
356        let Some(ctx) = self.as_rule_context_common_mut() else {
357            return;
358        };
359        ctx.children.push(_child);
360    }
361
362    pub fn set_parent(&mut self, parent: Option<&'arena Self>) {
363        let Some(ctx) = self.as_rule_context_common_mut() else {
364            return;
365        };
366        ctx.parent = parent;
367    }
368
369    pub fn enter_rule(&self, listener: &mut NodeKind::Listener) -> Result<(), ANTLRError> {
370        NodeKind::enter_rule(self, listener)
371    }
372
373    pub fn exit_rule(&self, listener: &mut NodeKind::Listener) -> Result<(), ANTLRError> {
374        NodeKind::exit_rule(self, listener)
375    }
376}
377
378impl<'input, 'arena, NodeKind, Tok> Tree<'arena> for TreeNode<'input, 'arena, NodeKind, Tok>
379where
380    'input: 'arena,
381    NodeKind: NodeKindType<'arena, Tok>,
382    Tok: Token + 'input,
383{
384    #[inline]
385    fn get_parent(&self) -> Option<&'arena Self> {
386        self.as_rule_context_common().and_then(|ctx| ctx.parent)
387    }
388
389    fn has_parent(&self) -> bool {
390        self.get_parent().is_some()
391    }
392
393    fn get_child(&self, i: usize) -> Option<&'arena Self> {
394        self.as_rule_context_common()
395            .and_then(|ctx| ctx.children.get(i).copied())
396    }
397
398    #[inline]
399    fn get_child_count(&self) -> usize {
400        self.as_rule_context_common()
401            .map_or(0, |ctx| ctx.children.len())
402    }
403
404    #[inline]
405    fn get_children<'a>(&'a self) -> Box<dyn Iterator<Item = &'arena Self> + 'a> {
406        if let Some(ctx) = self.as_rule_context_common() {
407            Box::new(ctx.children.iter().copied())
408        } else {
409            Box::new(std::iter::empty())
410        }
411    }
412}
413
414impl<'input, 'arena, Node, Tok> ParseTree<'input, 'arena> for TreeNode<'input, 'arena, Node, Tok>
415where
416    'input: 'arena,
417    Node: NodeKindType<'arena, Tok>,
418    Tok: Token,
419{
420    fn get_source_interval(&self) -> Interval {
421        if let Some(terminal) = self.as_terminal_node() {
422            Interval::new(
423                terminal.symbol.get_start_index() as i32,
424                terminal.symbol.get_stop_index() as i32,
425            )
426        } else if let Some(error) = self.as_error_node() {
427            Interval::new(
428                error.symbol.get_start_index() as i32,
429                error.symbol.get_stop_index() as i32,
430            )
431        } else {
432            let ctx = self
433                .as_rule_context_common()
434                .expect("Can only be rule context at this point");
435            match (ctx.start, ctx.stop) {
436                (Some(start), Some(stop)) => {
437                    Interval::new(start.get_start_index() as i32, stop.get_stop_index() as i32)
438                }
439                _ => Interval::invalid(),
440            }
441        }
442    }
443
444    fn get_text(&self) -> String {
445        if let Some(terminal) = self.as_terminal_node() {
446            return terminal.get_text();
447        } else if let Some(error) = self.as_error_node() {
448            return error.get_text();
449        }
450
451        let mut result = String::new();
452        for child in self.get_children() {
453            result.push_str(&ParseTree::get_text(child));
454        }
455        result
456    }
457}
458
459impl<'input, 'arena, NodeKind, Tok> RuleContext<'arena> for TreeNode<'input, 'arena, NodeKind, Tok>
460where
461    'input: 'arena,
462    NodeKind: NodeKindType<'arena, Tok>,
463    Tok: Token,
464{
465    fn get_rule_index(&self) -> usize {
466        NodeKind::get_rule_index(self)
467    }
468
469    fn get_alt_number(&self) -> i32 {
470        NodeKind::get_alt_number(self)
471    }
472
473    #[inline]
474    fn get_invoking_state(&self) -> i32 {
475        self.invoking_state
476    }
477
478    fn get_parent_ctx(&self) -> Option<&'arena dyn RuleContext<'arena>> {
479        self.get_parent()
480            .map(|p| p as &'arena dyn RuleContext<'arena>)
481    }
482
483    fn get_node_text(&self, rule_names: &[&str]) -> String {
484        NodeKind::cast_to_ctx(self).get_node_text(rule_names)
485    }
486}
487
488impl<'input, 'arena, Node, Tok> ParserRuleContext<'input, 'arena>
489    for TreeNode<'input, 'arena, Node, Tok>
490where
491    'input: 'arena,
492    Node: NodeKindType<'arena, Tok>,
493    Tok: Token,
494{
495    fn get_text(&self) -> String {
496        ParseTree::get_text(self)
497    }
498
499    fn get_child_count(&self) -> usize {
500        Tree::get_child_count(self)
501    }
502
503    fn start(&self) -> &'arena dyn Token {
504        if let Some(terminal) = self.as_terminal_node() {
505            return terminal.symbol;
506        } else if let Some(error) = self.as_error_node() {
507            return error.symbol;
508        }
509        let ctx = self
510            .as_rule_context_common()
511            .expect("Can only be rule context at this point");
512        ctx.start.map_or_else(
513            || token_factory::invalid() as &dyn Token,
514            |t| t as &dyn Token,
515        )
516    }
517
518    fn stop(&self) -> &'arena dyn Token {
519        if let Some(terminal) = self.as_terminal_node() {
520            return terminal.symbol;
521        } else if let Some(error) = self.as_error_node() {
522            return error.symbol;
523        }
524        let ctx = self
525            .as_rule_context_common()
526            .expect("Can only be rule context at this point");
527        ctx.stop.map_or_else(
528            || token_factory::invalid() as &dyn Token,
529            |t| t as &dyn Token,
530        )
531    }
532
533    fn get_parent_ctx(&self) -> Option<&'arena dyn ParserRuleContext<'input, 'arena>> {
534        self.get_parent()
535            .map(|p| p as &'arena dyn ParserRuleContext<'input, 'arena>)
536    }
537
538    fn get_child_ctx(&self, i: usize) -> Option<&'arena dyn ParserRuleContext<'input, 'arena>> {
539        self.get_child(i)
540            .map(|child| child.get_rule_context() as &dyn ParserRuleContext<'input, 'arena>)
541    }
542
543    fn iter_children<'a>(
544        &'a self,
545    ) -> Box<dyn Iterator<Item = &'arena dyn ParserRuleContext<'input, 'arena>> + 'a>
546    where
547        'input: 'a,
548        'arena: 'a,
549    {
550        let Some(ctx) = self.as_rule_context_common() else {
551            return Box::new(std::iter::empty());
552        };
553        Box::new(
554            ctx.children
555                .iter()
556                .map(|child| child.get_rule_context() as &dyn ParserRuleContext<'input, 'arena>),
557        )
558    }
559
560    fn get_token(&self, _ttype: i32, _pos: usize) -> Option<&dyn Token> {
561        let ctx = self.as_rule_context_common()?;
562        ctx.children
563            .iter()
564            .filter_map(|child| child.as_terminal_node())
565            .filter(|t| t.symbol.get_token_type() == _ttype)
566            .nth(_pos)
567            .map(|t| t.symbol as &dyn Token)
568    }
569
570    fn get_tokens(&self, _ttype: i32) -> Vec<&dyn Token> {
571        let Some(ctx) = self.as_rule_context_common() else {
572            return vec![];
573        };
574        ctx.children
575            .iter()
576            .filter_map(|child| child.as_terminal_node())
577            .filter(|t| t.symbol.get_token_type() == _ttype)
578            .map(|t| t.symbol as &dyn Token)
579            .collect()
580    }
581
582    fn to_string_tree(&self, rule_names: &[&str]) -> String {
583        crate::trees::string_tree(self, rule_names)
584    }
585}
586
587#[doc(hidden)]
588#[derive(Debug)]
589pub struct NoError;
590
591#[doc(hidden)]
592#[derive(Debug)]
593pub struct IsError;
594
595/// Generic leaf AST node
596pub struct LeafNodeInner<'input, 'arena, E, Tok>
597where
598    'input: 'arena,
599    Tok: Token + 'input,
600    E: 'static,
601{
602    /// Token, this leaf consist of
603    pub symbol: &'arena Tok,
604    iserror: PhantomData<(E, &'input ())>,
605}
606
607impl<'input, 'arena, E, Tok> RuleContext<'arena> for LeafNodeInner<'input, 'arena, E, Tok>
608where
609    'input: 'arena,
610    E: 'static,
611    Tok: Token + 'input,
612{
613    fn get_rule_index(&self) -> usize {
614        usize::MAX
615    }
616
617    fn get_alt_number(&self) -> i32 {
618        crate::atn::INVALID_ALT
619    }
620
621    fn get_node_text(&self, _rule_names: &[&str]) -> String {
622        self.symbol.get_text().to_display()
623    }
624
625    fn get_invoking_state(&self) -> i32 {
626        -1
627    }
628
629    fn get_parent_ctx(&self) -> Option<&'arena dyn RuleContext<'arena>> {
630        None
631    }
632}
633
634impl<'input, 'arena, E, Tok> ParserRuleContext<'input, 'arena>
635    for LeafNodeInner<'input, 'arena, E, Tok>
636where
637    'input: 'arena,
638    E: 'static,
639    Tok: Token + 'input,
640{
641    fn get_text(&self) -> String {
642        self.symbol.get_text().to_display()
643    }
644
645    fn get_child_count(&self) -> usize {
646        0
647    }
648
649    fn iter_children<'a>(
650        &'a self,
651    ) -> Box<dyn Iterator<Item = &'arena dyn ParserRuleContext<'input, 'arena>> + 'a>
652    where
653        'input: 'a,
654        'arena: 'a,
655    {
656        Box::new(std::iter::empty())
657    }
658
659    fn get_token(&self, _ttype: i32, _pos: usize) -> Option<&dyn Token> {
660        None
661    }
662
663    fn get_tokens(&self, _ttype: i32) -> Vec<&dyn Token> {
664        vec![]
665    }
666}
667
668impl<'input, 'arena, Node, Tok> NodeInner<'input, 'arena, Node, Tok>
669    for LeafNodeInner<'input, 'arena, NoError, Tok>
670where
671    'input: 'arena,
672    Node: NodeKindType<'arena, Tok>,
673    Tok: Token + 'input,
674{
675    fn cast_from<'a>(node: &'a TreeNode<'input, 'arena, Node, Tok>) -> Option<&'a Self>
676    where
677        Self: Sized,
678    {
679        if node.node_tag.is_terminal() {
680            Some(unsafe { &*(node.ctx_ptr() as *const Self) })
681        } else {
682            None
683        }
684    }
685
686    fn cast_from_mut<'a>(node: &'a mut TreeNode<'input, 'arena, Node, Tok>) -> Option<&'a mut Self>
687    where
688        Self: Sized,
689    {
690        if node.node_tag.is_terminal() {
691            Some(unsafe { &mut *(node.ctx_ptr() as *mut Self) })
692        } else {
693            None
694        }
695    }
696
697    fn as_node(&self) -> &TreeNode<'input, 'arena, Node, Tok> {
698        // SAFETY: All [NodeInner] instances are allocated by
699        // [Arena::alloc_node] with a valid [RuleNodeImpl] header
700        unsafe { TreeNode::from_ctx_ptr(self as *const Self as CtxPtr<'input, 'arena>) }
701    }
702
703    fn as_node_mut(&mut self) -> &mut TreeNode<'input, 'arena, Node, Tok> {
704        // SAFETY: All [NodeInner] instances are allocated by
705        // [Arena::alloc_node] with a valid [RuleNodeImpl] header
706        unsafe { TreeNode::from_ctx_ptr_mut(self as *mut Self as CtxPtr<'input, 'arena>) }
707    }
708
709    fn iter_child_nodes<'a>(
710        &'a self,
711    ) -> Box<dyn Iterator<Item = &'arena TreeNode<'input, 'arena, Node, Tok>> + 'a> {
712        Box::new(std::iter::empty())
713    }
714}
715
716impl<'input, 'arena, Node, Tok> NodeInner<'input, 'arena, Node, Tok>
717    for LeafNodeInner<'input, 'arena, IsError, Tok>
718where
719    'input: 'arena,
720    Node: NodeKindType<'arena, Tok>,
721    Tok: Token + 'input,
722{
723    fn cast_from<'a>(node: &'a TreeNode<'input, 'arena, Node, Tok>) -> Option<&'a Self>
724    where
725        Self: Sized,
726    {
727        if node.node_tag.is_error() {
728            Some(unsafe { &*(node.ctx_ptr() as *const Self) })
729        } else {
730            None
731        }
732    }
733
734    fn cast_from_mut<'a>(node: &'a mut TreeNode<'input, 'arena, Node, Tok>) -> Option<&'a mut Self>
735    where
736        Self: Sized,
737    {
738        if node.node_tag.is_error() {
739            Some(unsafe { &mut *(node.ctx_ptr() as *mut Self) })
740        } else {
741            None
742        }
743    }
744
745    fn as_node(&self) -> &TreeNode<'input, 'arena, Node, Tok> {
746        // SAFETY: All [NodeInner] instances are allocated by
747        // [Arena::alloc_node] with a valid [RuleNodeImpl] header
748        unsafe { TreeNode::from_ctx_ptr(self as *const Self as CtxPtr<'input, 'arena>) }
749    }
750
751    fn as_node_mut(&mut self) -> &mut TreeNode<'input, 'arena, Node, Tok> {
752        // SAFETY: All [NodeInner] instances are allocated by
753        // [Arena::alloc_node] with a valid [RuleNodeImpl] header
754        unsafe { TreeNode::from_ctx_ptr_mut(self as *mut Self as CtxPtr<'input, 'arena>) }
755    }
756
757    fn iter_child_nodes<'a>(
758        &'a self,
759    ) -> Box<dyn Iterator<Item = &'arena TreeNode<'input, 'arena, Node, Tok>> + 'a> {
760        Box::new(std::iter::empty())
761    }
762}
763
764impl<'input, 'arena, E, Tok> Debug for LeafNodeInner<'input, 'arena, E, Tok>
765where
766    E: 'static,
767    Tok: Token + 'input,
768{
769    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
770        if self.symbol.get_token_type() == EOF {
771            f.write_str("<EOF>")
772        } else {
773            let a = self.symbol.get_text().to_display();
774            f.write_str(&a)
775        }
776    }
777}
778
779impl<'input, 'arena, E, Tok> LeafNodeInner<'input, 'arena, E, Tok>
780where
781    'input: 'arena,
782    E: 'static,
783    Tok: Token + 'input,
784{
785    /// Creates new leaf node
786    ///
787    /// Note: [LeafNodeInner] can not exist as a standalone entity, this
788    /// constructor can only be called from [RuleNodeImpl::create_token_node] or
789    /// [RuleNodeImpl::create_error_node]
790    fn new(symbol: &'arena Tok) -> Self {
791        Self {
792            symbol,
793            iserror: Default::default(),
794        }
795    }
796}
797
798/// non-error AST leaf node
799pub type TerminalNode<'input, 'arena, Tok = CommonToken<'input>> =
800    LeafNodeInner<'input, 'arena, NoError, Tok>;
801
802/// # Error Leaf
803/// Created for each token created or consumed during recovery
804pub type ErrorNode<'input, 'arena, Tok = CommonToken<'input>> =
805    LeafNodeInner<'input, 'arena, IsError, Tok>;
806
807pub trait ParseTreeVisitor<'input, 'arena, Node, Tok>
808where
809    'input: 'arena,
810    Node: NodeKindType<'arena, Tok>,
811    Tok: Token + 'input,
812{
813    type Return: Default;
814
815    fn visit(
816        &mut self,
817        node: &TreeNode<'input, 'arena, Node, Tok>,
818    ) -> Result<Self::Return, ANTLRError>;
819
820    /// Called on terminal(leaf) node
821    fn visit_terminal(
822        &mut self,
823        _node: &TerminalNode<'input, 'arena, Tok>,
824    ) -> Result<Self::Return, ANTLRError> {
825        Ok(Self::Return::default())
826    }
827
828    /// Called on error node
829    fn visit_error_node(
830        &mut self,
831        _node: &ErrorNode<'input, 'arena, Tok>,
832    ) -> Result<Self::Return, ANTLRError> {
833        Ok(Self::Return::default())
834    }
835
836    fn visit_children(
837        &mut self,
838        node: &dyn NodeInner<'input, 'arena, Node, Tok>,
839    ) -> Result<Self::Return, ANTLRError> {
840        let mut result = Self::Return::default();
841        for child in node.iter_child_nodes() {
842            if !self.should_visit_next_child(child, &result) {
843                break;
844            }
845
846            let child_result = self.visit(child)?;
847            result = self.aggregate_results(result, child_result)?;
848        }
849        Ok(result)
850    }
851
852    fn aggregate_results(
853        &self,
854        _aggregate: Self::Return,
855        next: Self::Return,
856    ) -> Result<Self::Return, ANTLRError> {
857        Ok(next)
858    }
859
860    fn should_visit_next_child(
861        &self,
862        _node: &TreeNode<'input, 'arena, Node, Tok>,
863        _current: &Self::Return,
864    ) -> bool {
865        true
866    }
867}
868
869/// Base parse listener interface
870pub trait ParseTreeListener<'arena, Node, Tok>
871where
872    Node: NodeKindType<'arena, Tok>,
873    Tok: Token + 'arena,
874{
875    /// Called when parser creates terminal node
876    fn visit_terminal(&mut self, _node: &TerminalNode<'_, 'arena, Tok>) -> Result<(), ANTLRError> {
877        Ok(())
878    }
879
880    /// Called when parser creates error node
881    fn visit_error_node(&mut self, _node: &ErrorNode<'_, 'arena, Tok>) -> Result<(), ANTLRError> {
882        Ok(())
883    }
884
885    /// Called when parser enters any rule node
886    fn enter_every_rule(
887        &mut self,
888        _ctx: &TreeNode<'_, 'arena, Node, Tok>,
889    ) -> Result<(), ANTLRError> {
890        Ok(())
891    }
892
893    /// Called when parser exits any rule node
894    fn exit_every_rule(
895        &mut self,
896        _ctx: &TreeNode<'_, 'arena, Node, Tok>,
897    ) -> Result<(), ANTLRError> {
898        Ok(())
899    }
900}
901
902/// Helper struct to accept parse listener on already generated tree
903#[derive(Debug)]
904pub struct ParseTreeWalker;
905
906impl ParseTreeWalker {
907    /// Walks recursively over tree `t` with `listener`
908    pub fn walk<'input, 'arena, Node, Tok>(
909        mut listener: Box<Node::Listener>,
910        t: &TreeNode<'input, 'arena, Node, Tok>,
911    ) -> Result<Box<Node::Listener>, ANTLRError>
912    where
913        'input: 'arena,
914        Node: NodeKindType<'arena, Tok>,
915        Tok: Token + 'input,
916    {
917        if let Some(terminal) = t.as_terminal_node() {
918            listener.visit_terminal(terminal)?;
919            return Ok(listener);
920        }
921        if let Some(error) = t.as_error_node() {
922            listener.visit_error_node(error)?;
923            return Ok(listener);
924        }
925
926        Self::enter_rule(&mut *listener, t)?;
927        for child in t.get_children() {
928            listener = Self::walk(listener, child)?;
929        }
930        Self::exit_rule(&mut *listener, t)?;
931
932        Ok(listener)
933    }
934
935    fn enter_rule<'input, 'arena, Node, Tok>(
936        listener: &mut Node::Listener,
937        t: &TreeNode<'input, 'arena, Node, Tok>,
938    ) -> Result<(), ANTLRError>
939    where
940        'input: 'arena,
941        Node: NodeKindType<'arena, Tok>,
942        Tok: Token + 'input,
943    {
944        listener.enter_every_rule(t)?;
945        t.enter_rule(listener)
946    }
947
948    fn exit_rule<'input, 'arena, Node, Tok>(
949        listener: &mut Node::Listener,
950        t: &TreeNode<'input, 'arena, Node, Tok>,
951    ) -> Result<(), ANTLRError>
952    where
953        'input: 'arena,
954        Node: NodeKindType<'arena, Tok>,
955        Tok: Token + 'input,
956    {
957        t.exit_rule(listener)?;
958        listener.exit_every_rule(t)
959    }
960}