1use crate::errors::AntlrError;
2use crate::recognizer::Recognizer;
3use std::any::Any;
4use std::fmt;
5use std::rc::Rc;
6
7use crate::token::{CommonToken, Token, TokenRef};
8use std::collections::BTreeMap;
9
10#[derive(Clone, Debug, Eq, PartialEq)]
11pub enum ParseTree {
12 Rule(RuleNode),
13 Terminal(TerminalNode),
14 Error(ErrorNode),
15}
16
17impl ParseTree {
18 pub fn children(&self) -> &[Self] {
24 match self {
25 Self::Rule(rule) => rule.context().children(),
26 Self::Terminal(_) | Self::Error(_) => &[],
27 }
28 }
29
30 pub fn descendants(&self) -> ParseTreeDescendants<'_> {
32 ParseTreeDescendants { stack: vec![self] }
33 }
34
35 pub fn pre_order(&self) -> ParseTreeDescendants<'_> {
40 self.descendants()
41 }
42
43 pub fn text(&self) -> String {
44 match self {
45 Self::Rule(rule) => rule.text(),
46 Self::Terminal(node) => node.text(),
47 Self::Error(node) => node.text(),
48 }
49 }
50
51 pub fn to_string_tree_with_names<S: AsRef<str>>(&self, rule_names: &[S]) -> String {
52 match self {
53 Self::Rule(rule) => rule.to_string_tree_with_names(rule_names),
54 Self::Terminal(node) => escape_tree_text(&node.text()),
55 Self::Error(node) => escape_tree_text(&node.text()),
56 }
57 }
58
59 pub fn to_string_tree<R: Recognizer>(&self, recognizer: Option<&R>) -> String {
63 recognizer.map_or_else(
64 || self.to_string_tree_with_names::<&str>(&[]),
65 |recognizer| self.to_string_tree_with_names(recognizer.data().rule_names()),
66 )
67 }
68
69 pub fn first_rule(&self, rule_index: usize) -> Option<&Self> {
71 match self {
72 Self::Rule(rule) => {
73 if rule.context().rule_index() == rule_index {
74 return Some(self);
75 }
76 rule.context()
77 .children()
78 .iter()
79 .find_map(|child| child.first_rule(rule_index))
80 }
81 Self::Terminal(_) | Self::Error(_) => None,
82 }
83 }
84
85 pub fn first_rule_stop(&self, rule_index: usize) -> Option<&CommonToken> {
87 let Self::Rule(rule) = self else {
88 return None;
89 };
90 if rule.context().rule_index() == rule_index {
91 return rule.context().stop();
92 }
93 rule.context()
94 .children()
95 .iter()
96 .find_map(|child| child.first_rule_stop(rule_index))
97 }
98
99 pub fn first_rule_int_return(&self, rule_index: usize, name: &str) -> Option<i64> {
103 let Self::Rule(rule) = self else {
104 return None;
105 };
106 if rule.context().rule_index() == rule_index {
107 return rule.context().int_return(name);
108 }
109 rule.context()
110 .children()
111 .iter()
112 .find_map(|child| child.first_rule_int_return(rule_index, name))
113 }
114
115 pub fn rule_attrs<T: Any>(&self) -> Option<&T> {
120 let Self::Rule(rule) = self else {
121 return None;
122 };
123 rule.context().generated_attrs::<T>()
124 }
125
126 pub fn first_error_token(&self) -> Option<&CommonToken> {
128 match self {
129 Self::Rule(rule) => rule
130 .context()
131 .children()
132 .iter()
133 .find_map(Self::first_error_token),
134 Self::Terminal(_) => None,
135 Self::Error(node) => Some(node.symbol()),
136 }
137 }
138
139 pub fn rule_invocation_stack<S: AsRef<str>>(
142 &self,
143 rule_index: usize,
144 rule_names: &[S],
145 ) -> Option<Vec<String>> {
146 let mut stack = Vec::new();
147 if self.find_rule_path(rule_index, rule_names, &mut stack) {
148 stack.reverse();
149 return Some(stack);
150 }
151 None
152 }
153
154 fn find_rule_path<S: AsRef<str>>(
155 &self,
156 rule_index: usize,
157 rule_names: &[S],
158 stack: &mut Vec<String>,
159 ) -> bool {
160 let Self::Rule(rule) = self else {
161 return false;
162 };
163 let current_index = rule.context().rule_index();
164 stack.push(
165 rule_names
166 .get(current_index)
167 .map_or("<unknown>", |name| name.as_ref())
168 .to_owned(),
169 );
170 if current_index == rule_index
171 || rule
172 .context()
173 .children()
174 .iter()
175 .any(|child| child.find_rule_path(rule_index, rule_names, stack))
176 {
177 return true;
178 }
179 stack.pop();
180 false
181 }
182}
183
184#[derive(Clone, Debug)]
185pub struct ParseTreeDescendants<'a> {
186 stack: Vec<&'a ParseTree>,
187}
188
189impl<'a> Iterator for ParseTreeDescendants<'a> {
190 type Item = &'a ParseTree;
191
192 fn next(&mut self) -> Option<Self::Item> {
193 let tree = self.stack.pop()?;
194 self.stack.extend(tree.children().iter().rev());
195 Some(tree)
196 }
197}
198
199fn escape_tree_text(text: &str) -> String {
200 let mut escaped = String::with_capacity(text.len());
201 for ch in text.chars() {
202 match ch {
203 '\n' => escaped.push_str("\\n"),
204 '\r' => escaped.push_str("\\r"),
205 '\t' => escaped.push_str("\\t"),
206 _ => escaped.push(ch),
207 }
208 }
209 escaped
210}
211
212#[derive(Clone, Debug, Eq, PartialEq)]
213pub struct RuleNode {
214 context: ParserRuleContext,
215}
216
217impl RuleNode {
218 pub const fn new(context: ParserRuleContext) -> Self {
219 Self { context }
220 }
221
222 pub const fn context(&self) -> &ParserRuleContext {
223 &self.context
224 }
225
226 pub const fn context_mut(&mut self) -> &mut ParserRuleContext {
227 &mut self.context
228 }
229
230 pub fn text(&self) -> String {
231 self.context.text()
232 }
233
234 pub fn to_string_tree_with_names<S: AsRef<str>>(&self, rule_names: &[S]) -> String {
235 self.context.to_string_tree_with_names(rule_names)
236 }
237}
238
239#[derive(Clone, Debug, Eq, PartialEq)]
240pub struct ParserRuleContext {
241 rule_index: usize,
242 invoking_state: isize,
243 alt_number: usize,
244 start: Option<TokenRef>,
245 stop: Option<TokenRef>,
246 int_returns: Option<Box<IntReturns>>,
247 children: Vec<ParseTree>,
248 matched_child: bool,
254 exception: Option<Box<AntlrError>>,
258 attrs: Option<GeneratedAttrs>,
260}
261
262#[derive(Clone, Debug, Default, Eq, PartialEq)]
263struct IntReturns(BTreeMap<String, i64>);
264
265#[derive(Clone)]
273pub struct GeneratedAttrs(Rc<dyn Any>);
274
275impl GeneratedAttrs {
276 pub fn new<T: Any>(attrs: T) -> Self {
277 Self(Rc::new(attrs))
278 }
279
280 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
281 self.0.downcast_ref::<T>()
282 }
283}
284
285impl fmt::Debug for GeneratedAttrs {
286 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287 f.write_str("GeneratedAttrs(..)")
288 }
289}
290
291impl PartialEq for GeneratedAttrs {
294 fn eq(&self, other: &Self) -> bool {
295 Rc::ptr_eq(&self.0, &other.0)
296 }
297}
298
299impl Eq for GeneratedAttrs {}
300
301impl ParserRuleContext {
302 pub const fn new(rule_index: usize, invoking_state: isize) -> Self {
303 Self {
304 rule_index,
305 invoking_state,
306 alt_number: 0,
307 start: None,
308 stop: None,
309 int_returns: None,
310 children: Vec::new(),
311 matched_child: false,
312 exception: None,
313 attrs: None,
314 }
315 }
316
317 pub(crate) fn with_child_capacity(
318 rule_index: usize,
319 invoking_state: isize,
320 capacity: usize,
321 ) -> Self {
322 Self {
323 rule_index,
324 invoking_state,
325 alt_number: 0,
326 start: None,
327 stop: None,
328 int_returns: None,
329 children: Vec::with_capacity(capacity),
330 matched_child: false,
331 exception: None,
332 attrs: None,
333 }
334 }
335
336 pub const fn rule_index(&self) -> usize {
337 self.rule_index
338 }
339
340 pub const fn invoking_state(&self) -> isize {
341 self.invoking_state
342 }
343
344 pub const fn alt_number(&self) -> usize {
345 self.alt_number
346 }
347
348 pub const fn set_alt_number(&mut self, alt_number: usize) {
349 self.alt_number = alt_number;
350 }
351
352 pub fn start(&self) -> Option<&CommonToken> {
353 self.start.as_deref()
354 }
355
356 pub(crate) fn start_ref(&self) -> Option<TokenRef> {
357 self.start.as_ref().map(Rc::clone)
358 }
359
360 pub fn stop(&self) -> Option<&CommonToken> {
361 self.stop.as_deref()
362 }
363
364 pub fn set_start(&mut self, token: CommonToken) {
365 self.start = Some(Rc::new(token));
366 }
367
368 pub(crate) fn set_start_ref(&mut self, token: TokenRef) {
369 self.start = Some(token);
370 }
371
372 pub fn set_stop(&mut self, token: CommonToken) {
373 self.stop = Some(Rc::new(token));
374 }
375
376 pub(crate) fn set_stop_ref(&mut self, token: TokenRef) {
377 self.stop = Some(token);
378 }
379
380 pub fn set_int_return(&mut self, name: impl Into<String>, value: i64) {
382 self.int_returns
383 .get_or_insert_with(Box::default)
384 .0
385 .insert(name.into(), value);
386 }
387
388 pub fn int_return(&self, name: &str) -> Option<i64> {
390 self.int_returns
391 .as_ref()
392 .and_then(|values| values.0.get(name).copied())
393 }
394
395 pub fn set_generated_attrs(&mut self, attrs: GeneratedAttrs) {
397 self.attrs = Some(attrs);
398 }
399
400 pub fn generated_attrs<T: Any>(&self) -> Option<&T> {
402 self.attrs.as_ref().and_then(GeneratedAttrs::downcast_ref)
403 }
404
405 pub fn exception(&self) -> Option<&AntlrError> {
406 self.exception.as_deref()
407 }
408
409 pub fn set_exception(&mut self, error: AntlrError) {
410 self.exception = Some(Box::new(error));
411 }
412
413 pub fn children(&self) -> &[ParseTree] {
414 &self.children
415 }
416
417 pub const fn child_count(&self) -> usize {
419 self.children.len()
420 }
421
422 pub fn child_rule(&self, rule_index: usize) -> Option<&Self> {
424 self.child_rules(rule_index).next()
425 }
426
427 pub fn child_rules(&self, rule_index: usize) -> impl Iterator<Item = &Self> + '_ {
429 self.children.iter().filter_map(move |child| match child {
430 ParseTree::Rule(rule) if rule.context().rule_index() == rule_index => {
431 Some(rule.context())
432 }
433 _ => None,
434 })
435 }
436
437 pub fn child_token(&self, token_type: i32) -> Option<&TerminalNode> {
442 self.child_tokens(token_type).next()
443 }
444
445 pub fn child_rule_trees(&self, rule_index: usize) -> impl Iterator<Item = &ParseTree> + '_ {
451 self.children.iter().filter(move |child| match child {
452 ParseTree::Rule(rule) => rule.context().rule_index() == rule_index,
453 ParseTree::Terminal(_) | ParseTree::Error(_) => false,
454 })
455 }
456
457 pub fn child_tokens(&self, token_type: i32) -> impl Iterator<Item = &TerminalNode> + '_ {
460 self.children.iter().filter_map(move |child| match child {
461 ParseTree::Terminal(node) if node.symbol().token_type() == token_type => Some(node),
462 ParseTree::Error(node) if node.symbol().token_type() == token_type => {
463 Some(node.terminal())
464 }
465 _ => None,
466 })
467 }
468
469 pub fn terminal_children(&self) -> impl Iterator<Item = &TerminalNode> + '_ {
471 self.children.iter().filter_map(|child| match child {
472 ParseTree::Terminal(node) => Some(node),
473 ParseTree::Error(node) => Some(node.terminal()),
474 ParseTree::Rule(_) => None,
475 })
476 }
477
478 pub fn downcast_ref<T: FromRuleContext>(&self) -> Option<T> {
484 T::from_rule_context(self)
485 }
486
487 pub fn has_token(&self, token_type: i32) -> bool {
489 self.child_token(token_type).is_some()
490 }
491
492 pub fn add_child(&mut self, child: ParseTree) {
493 self.matched_child = true;
494 self.children.push(child);
495 }
496
497 pub const fn note_matched_child(&mut self) {
501 self.matched_child = true;
502 }
503
504 pub const fn has_matched_child(&self) -> bool {
507 self.matched_child
508 }
509
510 pub fn text(&self) -> String {
511 self.children.iter().map(ParseTree::text).collect()
512 }
513
514 pub fn to_string_tree_with_names<S: AsRef<str>>(&self, rule_names: &[S]) -> String {
515 let name = rule_names
516 .get(self.rule_index)
517 .map_or("<unknown>", |name| name.as_ref());
518 let display_name = if self.alt_number == 0 {
519 name.to_owned()
520 } else {
521 format!("{name}:{}", self.alt_number)
522 };
523 if self.children.is_empty() {
524 return display_name;
525 }
526 let children = self
527 .children
528 .iter()
529 .map(|child| child.to_string_tree_with_names(rule_names))
530 .collect::<Vec<_>>()
531 .join(" ");
532 format!("({display_name} {children})")
533 }
534
535 pub fn to_string_tree<R: Recognizer>(&self, recognizer: Option<&R>) -> String {
539 recognizer.map_or_else(
540 || self.to_string_tree_with_names::<&str>(&[]),
541 |recognizer| self.to_string_tree_with_names(recognizer.data().rule_names()),
542 )
543 }
544}
545
546#[derive(Clone, Debug, Eq, PartialEq)]
547pub struct TerminalNode {
548 token: TokenRef,
549}
550
551impl TerminalNode {
552 pub fn new(token: CommonToken) -> Self {
553 Self {
554 token: Rc::new(token),
555 }
556 }
557
558 pub(crate) const fn from_ref(token: TokenRef) -> Self {
559 Self { token }
560 }
561
562 pub fn symbol(&self) -> &CommonToken {
563 self.token.as_ref()
564 }
565
566 pub fn text(&self) -> String {
567 self.token.text().to_owned()
568 }
569}
570
571impl fmt::Display for TerminalNode {
574 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
575 f.write_str(self.token.text())
576 }
577}
578
579#[derive(Clone, Debug, Eq, PartialEq)]
580pub struct ErrorNode {
581 terminal: TerminalNode,
582}
583
584impl ErrorNode {
585 pub fn new(token: CommonToken) -> Self {
586 Self {
587 terminal: TerminalNode::new(token),
588 }
589 }
590
591 pub(crate) const fn from_ref(token: TokenRef) -> Self {
592 Self {
593 terminal: TerminalNode::from_ref(token),
594 }
595 }
596
597 const fn terminal(&self) -> &TerminalNode {
598 &self.terminal
599 }
600
601 pub fn symbol(&self) -> &CommonToken {
602 self.terminal.symbol()
603 }
604
605 pub fn text(&self) -> String {
606 self.terminal.text()
607 }
608}
609
610pub trait FromRuleContext: Sized {
617 fn from_rule_context(context: &ParserRuleContext) -> Option<Self>;
618}
619
620pub trait ParseTreeListener {
621 fn enter_every_rule(&mut self, _ctx: &ParserRuleContext) -> Result<(), AntlrError> {
622 Ok(())
623 }
624
625 fn exit_every_rule(&mut self, _ctx: &ParserRuleContext) -> Result<(), AntlrError> {
626 Ok(())
627 }
628
629 fn visit_terminal(&mut self, _node: &TerminalNode) -> Result<(), AntlrError> {
630 Ok(())
631 }
632
633 fn visit_error_node(&mut self, _node: &ErrorNode) -> Result<(), AntlrError> {
634 Ok(())
635 }
636}
637
638#[derive(Debug, Default)]
639pub struct ParseTreeWalker;
640
641impl ParseTreeWalker {
642 pub fn walk<L: ParseTreeListener>(
645 listener: &mut L,
646 tree: &ParseTree,
647 ) -> Result<(), AntlrError> {
648 match tree {
649 ParseTree::Rule(rule) => {
650 listener.enter_every_rule(rule.context())?;
651 for child in rule.context().children() {
652 Self::walk(listener, child)?;
653 }
654 listener.exit_every_rule(rule.context())
655 }
656 ParseTree::Terminal(node) => listener.visit_terminal(node),
657 ParseTree::Error(node) => listener.visit_error_node(node),
658 }
659 }
660}
661
662#[cfg(test)]
663mod tests {
664 use super::*;
665 use crate::token::CommonToken;
666
667 #[test]
668 fn renders_rule_tree() {
669 let mut ctx = ParserRuleContext::new(0, -1);
670 ctx.add_child(ParseTree::Terminal(TerminalNode::new(
671 CommonToken::new(1).with_text("x"),
672 )));
673 let tree = ParseTree::Rule(RuleNode::new(ctx));
674 assert_eq!(tree.to_string_tree_with_names(&["expr"]), "(expr x)");
675 }
676
677 #[test]
678 fn finds_first_rule_depth_first() {
679 let mut nested = ParserRuleContext::new(1, -1);
680 nested.add_child(ParseTree::Terminal(TerminalNode::new(
681 CommonToken::new(1).with_text("x"),
682 )));
683
684 let mut root = ParserRuleContext::new(0, -1);
685 root.add_child(ParseTree::Rule(RuleNode::new(nested)));
686 let tree = ParseTree::Rule(RuleNode::new(root));
687
688 let rule = tree.first_rule(1).expect("nested rule should be found");
689 assert_eq!(
690 rule.to_string_tree_with_names(&["root".to_owned(), "child".to_owned()]),
691 "(child x)"
692 );
693 assert!(tree.first_rule(2).is_none());
694 }
695
696 #[test]
697 fn reports_rule_invocation_stack_from_leaf_to_root() {
698 let mut nested = ParserRuleContext::new(1, -1);
699 nested.add_child(ParseTree::Terminal(TerminalNode::new(
700 CommonToken::new(1).with_text("x"),
701 )));
702
703 let mut root = ParserRuleContext::new(0, -1);
704 root.add_child(ParseTree::Rule(RuleNode::new(nested)));
705 let tree = ParseTree::Rule(RuleNode::new(root));
706
707 assert_eq!(
708 tree.rule_invocation_stack(1, &["s", "a"]),
709 Some(vec!["a".to_owned(), "s".to_owned()])
710 );
711 }
712
713 #[test]
714 fn parse_tree_children_returns_rule_children_and_empty_leaf_slices() {
715 let terminal =
716 ParseTree::Terminal(TerminalNode::new(CommonToken::new(1).with_text("terminal")));
717 let error = ParseTree::Error(ErrorNode::new(CommonToken::new(2).with_text("error")));
718
719 let mut root = ParserRuleContext::new(0, -1);
720 root.add_child(terminal);
721 root.add_child(error);
722 let tree = ParseTree::Rule(RuleNode::new(root));
723
724 let children = tree.children();
725 let [first, second] = children else {
726 panic!("expected exactly 2 children");
727 };
728 assert_eq!(first.text(), "terminal");
729 assert_eq!(second.text(), "error");
730 assert!(first.children().is_empty());
731 assert!(second.children().is_empty());
732 }
733
734 #[test]
735 fn iterates_descendants_in_pre_order() {
736 let mut nested = ParserRuleContext::new(1, -1);
737 nested.add_child(ParseTree::Terminal(TerminalNode::new(
738 CommonToken::new(10).with_text("child"),
739 )));
740
741 let mut root = ParserRuleContext::new(0, -1);
742 root.add_child(ParseTree::Terminal(TerminalNode::new(
743 CommonToken::new(11).with_text("prefix"),
744 )));
745 root.add_child(ParseTree::Rule(RuleNode::new(nested)));
746 root.add_child(ParseTree::Error(ErrorNode::new(
747 CommonToken::new(12).with_text("error"),
748 )));
749 let tree = ParseTree::Rule(RuleNode::new(root));
750
751 let visited = tree
752 .descendants()
753 .map(|node| match node {
754 ParseTree::Rule(rule) => format!("rule:{}", rule.context().rule_index()),
755 ParseTree::Terminal(terminal) => format!("terminal:{}", terminal.text()),
756 ParseTree::Error(error) => format!("error:{}", error.text()),
757 })
758 .collect::<Vec<_>>();
759
760 assert_eq!(
761 visited,
762 vec![
763 "rule:0".to_owned(),
764 "terminal:prefix".to_owned(),
765 "rule:1".to_owned(),
766 "terminal:child".to_owned(),
767 "error:error".to_owned(),
768 ]
769 );
770
771 let preorder = tree.pre_order().map(ParseTree::text).collect::<Vec<_>>();
772 assert_eq!(
773 preorder,
774 vec!["prefixchilderror", "prefix", "child", "child", "error"]
775 );
776 }
777
778 #[test]
779 fn finds_direct_child_rules_by_index() {
780 let mut direct = ParserRuleContext::new(1, -1);
781 direct.add_child(ParseTree::Terminal(TerminalNode::new(
782 CommonToken::new(10).with_text("direct"),
783 )));
784
785 let mut nested_match = ParserRuleContext::new(1, -1);
786 nested_match.add_child(ParseTree::Terminal(TerminalNode::new(
787 CommonToken::new(11).with_text("nested"),
788 )));
789 let mut wrapper = ParserRuleContext::new(2, -1);
790 wrapper.add_child(ParseTree::Rule(RuleNode::new(nested_match)));
791
792 let mut root = ParserRuleContext::new(0, -1);
793 root.add_child(ParseTree::Terminal(TerminalNode::new(
794 CommonToken::new(12).with_text("prefix"),
795 )));
796 root.add_child(ParseTree::Rule(RuleNode::new(direct)));
797 root.add_child(ParseTree::Rule(RuleNode::new(wrapper)));
798
799 assert_eq!(root.child_count(), 3);
800 assert_eq!(root.child_rules(1).count(), 1);
801 assert_eq!(
802 root.child_rule(1).map(ParserRuleContext::text),
803 Some("direct".to_owned())
804 );
805 assert_eq!(
806 root.child_rule(2).map(ParserRuleContext::rule_index),
807 Some(2)
808 );
809 assert!(root.child_rule(3).is_none());
810 }
811
812 #[test]
813 fn finds_direct_terminal_children_by_token_type() {
814 let mut nested = ParserRuleContext::new(1, -1);
815 nested.add_child(ParseTree::Terminal(TerminalNode::new(
816 CommonToken::new(13).with_text("nested"),
817 )));
818
819 let mut root = ParserRuleContext::new(0, -1);
820 root.add_child(ParseTree::Error(ErrorNode::new(
821 CommonToken::new(12).with_text("error"),
822 )));
823 root.add_child(ParseTree::Terminal(TerminalNode::new(
824 CommonToken::new(10).with_text("direct"),
825 )));
826 root.add_child(ParseTree::Terminal(TerminalNode::new(
827 CommonToken::new(11).with_text("other"),
828 )));
829 root.add_child(ParseTree::Rule(RuleNode::new(nested)));
830
831 assert_eq!(root.child_count(), 4);
832 assert!(root.has_token(10));
833 assert!(root.has_token(12));
834 assert_eq!(
835 root.child_token(10).map(TerminalNode::text),
836 Some("direct".to_owned())
837 );
838 assert_eq!(
839 root.child_token(11).map(TerminalNode::text),
840 Some("other".to_owned())
841 );
842 assert_eq!(
843 root.child_token(12).map(TerminalNode::text),
844 Some("error".to_owned())
845 );
846 assert!(root.child_token(13).is_none());
847 }
848}