do_not_use_antlr_rust/
tree.rs

1//! General AST
2use std::any::Any;
3use std::borrow::Borrow;
4
5use std::fmt::{Debug, Formatter};
6use std::iter::from_fn;
7use std::marker::PhantomData;
8use std::ops::Deref;
9use std::rc::Rc;
10
11use crate::atn::INVALID_ALT;
12use crate::char_stream::InputData;
13use crate::int_stream::EOF;
14use crate::interval_set::Interval;
15use crate::parser::ParserNodeType;
16use crate::parser_rule_context::{ParserRuleContext, RuleContextExt};
17use crate::recognizer::Recognizer;
18use crate::rule_context::{CustomRuleContext, RuleContext};
19use crate::token::Token;
20use crate::token_factory::TokenFactory;
21use crate::{interval_set, trees, CoerceTo};
22use better_any::{Tid, TidAble};
23use std::mem;
24
25//todo try to make in more generic
26#[allow(missing_docs)]
27pub trait Tree<'input>: RuleContext<'input> {
28    fn get_parent(&self) -> Option<Rc<<Self::Ctx as ParserNodeType<'input>>::Type>> { None }
29    fn has_parent(&self) -> bool { false }
30    fn get_payload(&self) -> Box<dyn Any> { unimplemented!() }
31    fn get_child(&self, _i: usize) -> Option<Rc<<Self::Ctx as ParserNodeType<'input>>::Type>> {
32        None
33    }
34    fn get_child_count(&self) -> usize { 0 }
35    fn get_children<'a>(
36        &'a self,
37    ) -> Box<dyn Iterator<Item = Rc<<Self::Ctx as ParserNodeType<'input>>::Type>> + 'a>
38    where
39        'input: 'a,
40    {
41        let mut index = 0;
42        let iter = from_fn(move || {
43            if index < self.get_child_count() {
44                index += 1;
45                self.get_child(index - 1)
46            } else {
47                None
48            }
49        });
50
51        Box::new(iter)
52    }
53    // fn get_children_full(&self) -> &RefCell<Vec<Rc<<Self::Ctx as ParserNodeType<'input, Self::TF>>::Type>>> { unimplemented!() }
54}
55
56/// Tree that knows about underlying text
57pub trait ParseTree<'input>: Tree<'input> {
58    /// Return an {@link Interval} indicating the index in the
59    /// {@link TokenStream} of the first and last token associated with this
60    /// subtree. If this node is a leaf, then the interval represents a single
61    /// token and has interval i..i for token index i.
62    fn get_source_interval(&self) -> Interval { interval_set::INVALID }
63
64    /// Return combined text of this AST node.
65    /// To create resulting string it does traverse whole subtree,
66    /// also it includes only tokens added to the parse tree
67    ///
68    /// Since tokens on hidden channels (e.g. whitespace or comments) are not
69    ///	added to the parse trees, they will not appear in the output of this
70    ///	method.
71    fn get_text(&self) -> String { String::new() }
72
73    /// Print out a whole tree, not just a node, in LISP format
74    /// (root child1 .. childN). Print just a node if this is a leaf.
75    /// We have to know the recognizer so we can get rule names.
76    fn to_string_tree(
77        &self,
78        r: &dyn Recognizer<'input, TF = Self::TF, Node = Self::Ctx>,
79    ) -> String {
80        trees::string_tree(self, r.get_rule_names())
81    }
82}
83
84/// text of the node.
85/// Already implemented for all rule contexts
86// pub trait NodeText {
87//     fn get_node_text(&self, rule_names: &[&str]) -> String;
88// }
89//
90// impl<T> NodeText for T {
91//     default fn get_node_text(&self, _rule_names: &[&str]) -> String { "<unknown>".to_owned() }
92// }
93//
94// impl<'input, T: CustomRuleContext<'input>> NodeText for T {
95//     default fn get_node_text(&self, rule_names: &[&str]) -> String {
96//         let rule_index = self.get_rule_index();
97//         let rule_name = rule_names[rule_index];
98//         let alt_number = self.get_alt_number();
99//         if alt_number != INVALID_ALT {
100//             return format!("{}:{}", rule_name, alt_number);
101//         }
102//         return rule_name.to_owned();
103//     }
104// }
105
106#[doc(hidden)]
107#[derive(Debug)]
108pub struct NoError;
109
110#[doc(hidden)]
111#[derive(Debug)]
112pub struct IsError;
113
114/// Generic leaf AST node
115pub struct LeafNode<'input, Node: ParserNodeType<'input>, T: 'static> {
116    /// Token, this leaf consist of
117    pub symbol: <Node::TF as TokenFactory<'input>>::Tok,
118    iserror: PhantomData<T>,
119}
120better_any::tid! { impl <'input, Node, T:'static> TidAble<'input> for LeafNode<'input, Node, T> where Node:ParserNodeType<'input> }
121
122impl<'input, Node: ParserNodeType<'input>, T: 'static> CustomRuleContext<'input>
123    for LeafNode<'input, Node, T>
124{
125    type TF = Node::TF;
126    type Ctx = Node;
127
128    fn get_rule_index(&self) -> usize { usize::max_value() }
129
130    fn get_node_text(&self, rule_names: &[&str]) -> String {
131        self.symbol.borrow().get_text().to_display()
132    }
133}
134
135impl<'input, Node: ParserNodeType<'input>, T: 'static> ParserRuleContext<'input>
136    for LeafNode<'input, Node, T>
137{
138}
139
140impl<'input, Node: ParserNodeType<'input>, T: 'static> Tree<'input> for LeafNode<'input, Node, T> {}
141
142impl<'input, Node: ParserNodeType<'input>, T: 'static> RuleContext<'input>
143    for LeafNode<'input, Node, T>
144{
145}
146
147// impl<'input, Node: ParserNodeType<'input>, T: 'static> NodeText for LeafNode<'input, Node, T> {
148//     fn get_node_text(&self, _rule_names: &[&str]) -> String {
149//         self.symbol.borrow().get_text().to_display()
150//     }
151// }
152
153impl<'input, Node: ParserNodeType<'input>, T: 'static> ParseTree<'input>
154    for LeafNode<'input, Node, T>
155{
156    fn get_source_interval(&self) -> Interval {
157        let i = self.symbol.borrow().get_token_index();
158        Interval { a: i, b: i }
159    }
160
161    fn get_text(&self) -> String { self.symbol.borrow().get_text().to_display() }
162}
163
164impl<'input, Node: ParserNodeType<'input>, T: 'static> Debug for LeafNode<'input, Node, T> {
165    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
166        if self.symbol.borrow().get_token_type() == EOF {
167            f.write_str("<EOF>")
168        } else {
169            let a = self.symbol.borrow().get_text().to_display();
170            f.write_str(&a)
171        }
172    }
173}
174
175impl<'input, Node: ParserNodeType<'input>, T: 'static> LeafNode<'input, Node, T> {
176    /// creates new leaf node
177    pub fn new(symbol: <Node::TF as TokenFactory<'input>>::Tok) -> Self {
178        Self {
179            symbol,
180            iserror: Default::default(),
181        }
182    }
183}
184
185/// non-error AST leaf node
186pub type TerminalNode<'input, NodeType> = LeafNode<'input, NodeType, NoError>;
187
188impl<'input, Node: ParserNodeType<'input>, Listener: ParseTreeListener<'input, Node> + ?Sized>
189    Listenable<Listener> for TerminalNode<'input, Node>
190{
191    fn enter(&self, listener: &mut Listener) { listener.visit_terminal(self) }
192
193    fn exit(&self, _listener: &mut Listener) {
194        // do nothing
195    }
196}
197
198impl<'input, Node: ParserNodeType<'input>, Visitor: ParseTreeVisitor<'input, Node> + ?Sized>
199    Visitable<Visitor> for TerminalNode<'input, Node>
200{
201    fn accept(&self, visitor: &mut Visitor) { visitor.visit_terminal(self) }
202}
203
204/// # Error Leaf
205/// Created for each token created or consumed during recovery
206pub type ErrorNode<'input, NodeType> = LeafNode<'input, NodeType, IsError>;
207
208impl<'input, Node: ParserNodeType<'input>, Listener: ParseTreeListener<'input, Node> + ?Sized>
209    Listenable<Listener> for ErrorNode<'input, Node>
210{
211    fn enter(&self, listener: &mut Listener) { listener.visit_error_node(self) }
212
213    fn exit(&self, _listener: &mut Listener) {
214        // do nothing
215    }
216}
217
218impl<'input, Node: ParserNodeType<'input>, Visitor: ParseTreeVisitor<'input, Node> + ?Sized>
219    Visitable<Visitor> for ErrorNode<'input, Node>
220{
221    fn accept(&self, visitor: &mut Visitor) { visitor.visit_error_node(self) }
222}
223
224pub trait ParseTreeVisitorCompat<'input>: VisitChildren<'input, Self::Node> {
225    type Node: ParserNodeType<'input>;
226    type Return: Default;
227
228    /// Temporary storage for `ParseTreeVisitor` blanket implementation to work
229    fn temp_result(&mut self) -> &mut Self::Return;
230
231    fn visit(&mut self, node: &<Self::Node as ParserNodeType<'input>>::Type) -> Self::Return {
232        self.visit_node(&node);
233        mem::take(self.temp_result())
234    }
235
236    /// Called on terminal(leaf) node
237    fn visit_terminal(&mut self, _node: &TerminalNode<'input, Self::Node>) -> Self::Return {
238        Self::Return::default()
239    }
240    /// Called on error node
241    fn visit_error_node(&mut self, _node: &ErrorNode<'input, Self::Node>) -> Self::Return {
242        Self::Return::default()
243    }
244
245    fn visit_children(
246        &mut self,
247        node: &<Self::Node as ParserNodeType<'input>>::Type,
248    ) -> Self::Return {
249        let mut result = Self::Return::default();
250        for node in node.get_children() {
251            if !self.should_visit_next_child(&node, &result) {
252                break;
253            }
254
255            let child_result = self.visit(&node);
256            result = self.aggregate_results(result, child_result);
257        }
258        return result;
259    }
260
261    fn aggregate_results(&self, aggregate: Self::Return, next: Self::Return) -> Self::Return {
262        next
263    }
264
265    fn should_visit_next_child(
266        &self,
267        node: &<Self::Node as ParserNodeType<'input>>::Type,
268        current: &Self::Return,
269    ) -> bool {
270        true
271    }
272}
273
274// struct VisitorAdapter<'input, T: ParseTreeVisitorCompat<'input>> {
275//     visitor: T,
276//     pub curr_value: T::Return,
277//     _pd: PhantomData<&'input str>,
278// }
279
280impl<'input, Node, T> ParseTreeVisitor<'input, Node> for T
281where
282    Node: ParserNodeType<'input>,
283    Node::Type: VisitableDyn<Self>,
284    T: ParseTreeVisitorCompat<'input, Node = Node>,
285{
286    fn visit_terminal(&mut self, node: &TerminalNode<'input, Node>) {
287        let result = <Self as ParseTreeVisitorCompat>::visit_terminal(self, node);
288        *<Self as ParseTreeVisitorCompat>::temp_result(self) = result;
289    }
290
291    fn visit_error_node(&mut self, node: &ErrorNode<'input, Node>) {
292        let result = <Self as ParseTreeVisitorCompat>::visit_error_node(self, node);
293        *<Self as ParseTreeVisitorCompat>::temp_result(self) = result;
294    }
295
296    fn visit_children(&mut self, node: &Node::Type) {
297        let result = <Self as ParseTreeVisitorCompat>::visit_children(self, node);
298        *<Self as ParseTreeVisitorCompat>::temp_result(self) = result;
299    }
300}
301
302/// Base interface for visiting over syntax tree
303pub trait ParseTreeVisitor<'input, Node: ParserNodeType<'input>>:
304    VisitChildren<'input, Node>
305{
306    /// Basically alias for `node.accept(self)` in visitor implementation
307    /// just to make api closer to java
308
309    /// Called on terminal(leaf) node
310    fn visit_terminal(&mut self, _node: &TerminalNode<'input, Node>) {}
311    /// Called on error node
312    fn visit_error_node(&mut self, _node: &ErrorNode<'input, Node>) {}
313    /// Implement this only if you want to change children visiting algorithm
314    fn visit_children(&mut self, node: &Node::Type) {
315        node.get_children()
316            .for_each(|child| self.visit_node(&child))
317    }
318}
319
320/// Workaround for default recursive children visiting
321///
322/// Already blanket implemented for all visitors.
323/// To override it you would need to implement `ParseTreeVisitor::visit_children`
324pub trait VisitChildren<'input, Node: ParserNodeType<'input>> {
325    // fn visit_children_inner(&mut self, node: &Node::Type);
326    fn visit_node(&mut self, node: &Node::Type);
327}
328
329impl<'input, Node, T> VisitChildren<'input, Node> for T
330where
331    Node: ParserNodeType<'input>,
332    T: ParseTreeVisitor<'input, Node> + ?Sized,
333    // for<'a> &'a mut Self: CoerceUnsized<&'a mut Node::Visitor>,
334    Node::Type: VisitableDyn<T>,
335{
336    // #[inline(always)]
337    // fn visit_children_inner(&mut self, node: &Node::Type) {
338    //     // node.accept_children(self)
339    //
340    // }
341
342    fn visit_node(&mut self, node: &Node::Type) { node.accept_dyn(self) }
343}
344
345/// Types that can accept particular visitor
346/// ** Usually implemented only in generated parser **
347pub trait Visitable<Vis: ?Sized> {
348    /// Calls corresponding visit callback on visitor`Vis`
349    fn accept(&self, _visitor: &mut Vis) {
350        unreachable!("should have been properly implemented by generated context when reachable")
351    }
352}
353
354// workaround trait for accepting sized visitor on rule context trait object
355#[doc(hidden)]
356pub trait VisitableDyn<Vis: ?Sized> {
357    fn accept_dyn(&self, _visitor: &mut Vis) {
358        unreachable!("should have been properly implemented by generated context when reachable")
359    }
360}
361
362/// Base parse listener interface
363pub trait ParseTreeListener<'input, Node: ParserNodeType<'input>> {
364    /// Called when parser creates terminal node
365    fn visit_terminal(&mut self, _node: &TerminalNode<'input, Node>) {}
366    /// Called when parser creates error node
367    fn visit_error_node(&mut self, _node: &ErrorNode<'input, Node>) {}
368    /// Called when parser enters any rule node
369    fn enter_every_rule(&mut self, _ctx: &Node::Type) {}
370    /// Called when parser exits any rule node
371    fn exit_every_rule(&mut self, _ctx: &Node::Type) {}
372}
373
374/// Types that can accept particular listener
375/// ** Usually implemented only in generated parser **
376pub trait Listenable<T: ?Sized> {
377    /// Calls corresponding enter callback on listener `T`
378    fn enter(&self, _listener: &mut T) {}
379    /// Calls corresponding exit callback on listener `T`
380    fn exit(&self, _listener: &mut T) {}
381}
382
383// #[inline]
384// pub fn temp_to_trait<Z,TraitObject>(mut input: Z, f:impl FnOnce(&mut TraitObject)) -> Z where &mut Z:CoerceUnsized<&mut TraitObject>{
385//     let a = &mut input as &mut TraitObject;
386//     f(a)
387// }
388
389/// Helper struct to accept parse listener on already generated tree
390#[derive(Debug)]
391pub struct ParseTreeWalker<'input, 'a, Node, T = dyn ParseTreeListener<'input, Node> + 'a>(
392    PhantomData<fn(&'a T) -> &'input Node::Type>,
393)
394where
395    Node: ParserNodeType<'input>,
396    T: ParseTreeListener<'input, Node> + ?Sized;
397
398impl<'input, 'a, Node, T> ParseTreeWalker<'input, 'a, Node, T>
399where
400    Node: ParserNodeType<'input>,
401    T: ParseTreeListener<'input, Node> + 'a + ?Sized,
402    Node::Type: Listenable<T>,
403{
404    /// Walks recursively over tree `t` with `listener`
405    pub fn walk<Listener, Ctx>(mut listener: Box<Listener>, t: &Ctx) -> Box<Listener>
406    where
407        // for<'x> &'x mut Listener: CoerceUnsized<&'x mut T>,
408        // for<'x> &'x Ctx: CoerceUnsized<&'x Node::Type>,
409        Listener: CoerceTo<T>,
410        Ctx: CoerceTo<Node::Type>,
411    {
412        // let mut listener = listener as Box<T>;
413        Self::walk_inner(listener.as_mut().coerce_mut_to(), t.coerce_ref_to());
414
415        // just cast back
416        // unsafe { Box::<Listener>::from_raw(Box::into_raw(listener) as *mut _) }
417        listener
418    }
419
420    fn walk_inner(listener: &mut T, t: &Node::Type) {
421        t.enter(listener);
422
423        for child in t.get_children() {
424            Self::walk_inner(listener, child.deref())
425        }
426
427        t.exit(listener);
428    }
429}