1use 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::char_stream::InputData;
12use crate::int_stream::EOF;
13use crate::interval_set::Interval;
14use crate::parser::ParserNodeType;
15use crate::parser_rule_context::ParserRuleContext;
16use crate::recognizer::Recognizer;
17use crate::rule_context::{CustomRuleContext, RuleContext};
18use crate::token::Token;
19use crate::token_factory::TokenFactory;
20use crate::{interval_set, trees, CoerceTo};
21use std::mem;
22
23#[allow(missing_docs)]
25pub trait Tree<'input>: RuleContext<'input> {
26 fn get_parent(&self) -> Option<Rc<<Self::Ctx as ParserNodeType<'input>>::Type>> {
27 None
28 }
29 fn has_parent(&self) -> bool {
30 false
31 }
32 fn get_payload(&self) -> Box<dyn Any> {
33 unimplemented!()
34 }
35 fn get_child(&self, _i: usize) -> Option<Rc<<Self::Ctx as ParserNodeType<'input>>::Type>> {
36 None
37 }
38 fn get_child_count(&self) -> usize {
39 0
40 }
41 fn get_children<'a>(
42 &'a self,
43 ) -> Box<dyn Iterator<Item = Rc<<Self::Ctx as ParserNodeType<'input>>::Type>> + 'a>
44 where
45 'input: 'a,
46 {
47 let mut index = 0;
48 let iter = from_fn(move || {
49 if index < self.get_child_count() {
50 index += 1;
51 self.get_child(index - 1)
52 } else {
53 None
54 }
55 });
56
57 Box::new(iter)
58 }
59 }
61
62pub trait ParseTree<'input>: Tree<'input> {
64 fn get_source_interval(&self) -> Interval {
69 interval_set::INVALID
70 }
71
72 fn get_text(&self) -> String {
80 String::new()
81 }
82
83 fn to_string_tree(
87 &self,
88 r: &dyn Recognizer<'input, TF = Self::TF, Node = Self::Ctx>,
89 ) -> String {
90 trees::string_tree(self, r.get_rule_names())
91 }
92}
93
94#[doc(hidden)]
117#[derive(Debug)]
118pub struct NoError;
119
120#[doc(hidden)]
121#[derive(Debug)]
122pub struct IsError;
123
124pub struct LeafNode<'input, Node: ParserNodeType<'input>, T: 'static> {
126 pub symbol: <Node::TF as TokenFactory<'input>>::Tok,
128 iserror: PhantomData<T>,
129}
130better_any::tid! { impl <'input, Node, T:'static> TidAble<'input> for LeafNode<'input, Node, T> where Node:ParserNodeType<'input> }
131
132impl<'input, Node: ParserNodeType<'input>, T: 'static> CustomRuleContext<'input>
133 for LeafNode<'input, Node, T>
134{
135 type TF = Node::TF;
136 type Ctx = Node;
137
138 fn get_rule_index(&self) -> usize {
139 usize::max_value()
140 }
141
142 fn get_node_text(&self, rule_names: &[&str]) -> String {
143 self.symbol.borrow().get_text().to_display()
144 }
145}
146
147impl<'input, Node: ParserNodeType<'input>, T: 'static> ParserRuleContext<'input>
148 for LeafNode<'input, Node, T>
149{
150}
151
152impl<'input, Node: ParserNodeType<'input>, T: 'static> Tree<'input> for LeafNode<'input, Node, T> {}
153
154impl<'input, Node: ParserNodeType<'input>, T: 'static> RuleContext<'input>
155 for LeafNode<'input, Node, T>
156{
157}
158
159impl<'input, Node: ParserNodeType<'input>, T: 'static> ParseTree<'input>
166 for LeafNode<'input, Node, T>
167{
168 fn get_source_interval(&self) -> Interval {
169 let i = self.symbol.borrow().get_token_index();
170 Interval { a: i, b: i }
171 }
172
173 fn get_text(&self) -> String {
174 self.symbol.borrow().get_text().to_display()
175 }
176}
177
178impl<'input, Node: ParserNodeType<'input>, T: 'static> Debug for LeafNode<'input, Node, T> {
179 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
180 if self.symbol.borrow().get_token_type() == EOF {
181 f.write_str("<EOF>")
182 } else {
183 let a = self.symbol.borrow().get_text().to_display();
184 f.write_str(&a)
185 }
186 }
187}
188
189impl<'input, Node: ParserNodeType<'input>, T: 'static> LeafNode<'input, Node, T> {
190 pub fn new(symbol: <Node::TF as TokenFactory<'input>>::Tok) -> Self {
192 Self {
193 symbol,
194 iserror: Default::default(),
195 }
196 }
197}
198
199pub type TerminalNode<'input, NodeType> = LeafNode<'input, NodeType, NoError>;
201
202impl<'input, Node: ParserNodeType<'input>, Listener: ParseTreeListener<'input, Node> + ?Sized>
203 Listenable<Listener> for TerminalNode<'input, Node>
204{
205 fn enter(&self, listener: &mut Listener) {
206 listener.visit_terminal(self)
207 }
208
209 fn exit(&self, _listener: &mut Listener) {
210 }
212}
213
214impl<'input, Node: ParserNodeType<'input>, Visitor: ParseTreeVisitor<'input, Node> + ?Sized>
215 Visitable<Visitor> for TerminalNode<'input, Node>
216{
217 fn accept(&self, visitor: &mut Visitor) {
218 visitor.visit_terminal(self)
219 }
220}
221
222pub type ErrorNode<'input, NodeType> = LeafNode<'input, NodeType, IsError>;
225
226impl<'input, Node: ParserNodeType<'input>, Listener: ParseTreeListener<'input, Node> + ?Sized>
227 Listenable<Listener> for ErrorNode<'input, Node>
228{
229 fn enter(&self, listener: &mut Listener) {
230 listener.visit_error_node(self)
231 }
232
233 fn exit(&self, _listener: &mut Listener) {
234 }
236}
237
238impl<'input, Node: ParserNodeType<'input>, Visitor: ParseTreeVisitor<'input, Node> + ?Sized>
239 Visitable<Visitor> for ErrorNode<'input, Node>
240{
241 fn accept(&self, visitor: &mut Visitor) {
242 visitor.visit_error_node(self)
243 }
244}
245
246pub trait ParseTreeVisitorCompat<'input>: VisitChildren<'input, Self::Node> {
247 type Node: ParserNodeType<'input>;
248 type Return: Default;
249
250 fn temp_result(&mut self) -> &mut Self::Return;
261
262 fn visit(&mut self, node: &<Self::Node as ParserNodeType<'input>>::Type) -> Self::Return {
263 self.visit_node(node);
264 mem::take(self.temp_result())
265 }
266
267 fn visit_terminal(&mut self, _node: &TerminalNode<'input, Self::Node>) -> Self::Return {
269 Self::Return::default()
270 }
271 fn visit_error_node(&mut self, _node: &ErrorNode<'input, Self::Node>) -> Self::Return {
273 Self::Return::default()
274 }
275
276 fn visit_children(
277 &mut self,
278 node: &<Self::Node as ParserNodeType<'input>>::Type,
279 ) -> Self::Return {
280 let mut result = Self::Return::default();
281 for node in node.get_children() {
282 if !self.should_visit_next_child(&node, &result) {
283 break;
284 }
285
286 let child_result = self.visit(&node);
287 result = self.aggregate_results(result, child_result);
288 }
289 result
290 }
291
292 fn aggregate_results(&self, aggregate: Self::Return, next: Self::Return) -> Self::Return {
293 next
294 }
295
296 fn should_visit_next_child(
297 &self,
298 node: &<Self::Node as ParserNodeType<'input>>::Type,
299 current: &Self::Return,
300 ) -> bool {
301 true
302 }
303}
304
305impl<'input, Node, T> ParseTreeVisitor<'input, Node> for T
312where
313 Node: ParserNodeType<'input>,
314 Node::Type: VisitableDyn<Self>,
315 T: ParseTreeVisitorCompat<'input, Node = Node>,
316{
317 fn visit_terminal(&mut self, node: &TerminalNode<'input, Node>) {
318 let result = <Self as ParseTreeVisitorCompat>::visit_terminal(self, node);
319 *<Self as ParseTreeVisitorCompat>::temp_result(self) = result;
320 }
321
322 fn visit_error_node(&mut self, node: &ErrorNode<'input, Node>) {
323 let result = <Self as ParseTreeVisitorCompat>::visit_error_node(self, node);
324 *<Self as ParseTreeVisitorCompat>::temp_result(self) = result;
325 }
326
327 fn visit_children(&mut self, node: &Node::Type) {
328 let result = <Self as ParseTreeVisitorCompat>::visit_children(self, node);
329 *<Self as ParseTreeVisitorCompat>::temp_result(self) = result;
330 }
331}
332
333pub trait ParseTreeVisitor<'input, Node: ParserNodeType<'input>>:
335 VisitChildren<'input, Node>
336{
337 fn visit_terminal(&mut self, _node: &TerminalNode<'input, Node>) {}
342 fn visit_error_node(&mut self, _node: &ErrorNode<'input, Node>) {}
344 fn visit_children(&mut self, node: &Node::Type) {
346 node.get_children()
347 .for_each(|child| self.visit_node(&child))
348 }
349}
350
351pub trait VisitChildren<'input, Node: ParserNodeType<'input>> {
356 fn visit_node(&mut self, node: &Node::Type);
358}
359
360impl<'input, Node, T> VisitChildren<'input, Node> for T
361where
362 Node: ParserNodeType<'input>,
363 T: ParseTreeVisitor<'input, Node> + ?Sized,
364 Node::Type: VisitableDyn<T>,
366{
367 fn visit_node(&mut self, node: &Node::Type) {
374 node.accept_dyn(self)
375 }
376}
377
378pub trait Visitable<Vis: ?Sized> {
381 fn accept(&self, _visitor: &mut Vis) {
383 unreachable!("should have been properly implemented by generated context when reachable")
384 }
385}
386
387#[doc(hidden)]
389pub trait VisitableDyn<Vis: ?Sized> {
390 fn accept_dyn(&self, _visitor: &mut Vis) {
391 unreachable!("should have been properly implemented by generated context when reachable")
392 }
393}
394
395pub trait ParseTreeListener<'input, Node: ParserNodeType<'input>> {
397 fn visit_terminal(&mut self, _node: &TerminalNode<'input, Node>) {}
399 fn visit_error_node(&mut self, _node: &ErrorNode<'input, Node>) {}
401 fn enter_every_rule(&mut self, _ctx: &Node::Type) {}
403 fn exit_every_rule(&mut self, _ctx: &Node::Type) {}
405}
406
407pub trait Listenable<T: ?Sized> {
410 fn enter(&self, _listener: &mut T) {}
412 fn exit(&self, _listener: &mut T) {}
414}
415
416#[derive(Debug)]
424pub struct ParseTreeWalker<'input, 'a, Node, T = dyn ParseTreeListener<'input, Node> + 'a>(
425 PhantomData<fn(&'a T) -> &'input Node::Type>,
426)
427where
428 Node: ParserNodeType<'input>,
429 T: ParseTreeListener<'input, Node> + ?Sized;
430
431impl<'input, 'a, Node, T> ParseTreeWalker<'input, 'a, Node, T>
432where
433 Node: ParserNodeType<'input>,
434 T: ParseTreeListener<'input, Node> + 'a + ?Sized,
435 Node::Type: Listenable<T>,
436{
437 pub fn walk<Listener, Ctx>(mut listener: Box<Listener>, t: &Ctx) -> Box<Listener>
439 where
440 Listener: CoerceTo<T>,
443 Ctx: CoerceTo<Node::Type>,
444 {
445 Self::walk_inner(listener.as_mut().coerce_mut_to(), t.coerce_ref_to());
447
448 listener
451 }
452
453 fn walk_inner(listener: &mut T, t: &Node::Type) {
454 t.enter(listener);
455
456 for child in t.get_children() {
457 Self::walk_inner(listener, child.deref())
458 }
459
460 t.exit(listener);
461 }
462}