use std::any::Any;
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
use crate::char_stream::InputData;
use crate::errors::ANTLRError;
use crate::int_stream::EOF;
use crate::interval_set::Interval;
use crate::parser_rule_context::ParserRuleContext;
use crate::rule_context::RuleContext;
use crate::token::Token;
use crate::{interval_set, token_factory, Arena};
#[allow(missing_docs)]
pub trait Tree<'arena>: Sized {
fn get_parent(&self) -> Option<&'arena Self>;
fn has_parent(&self) -> bool;
fn get_payload(&self) -> Box<dyn Any> {
unimplemented!()
}
fn get_child(&self, _i: usize) -> Option<&'arena Self> {
None
}
fn get_child_count(&self) -> usize {
0
}
fn get_children<'a>(&'a self) -> Box<dyn Iterator<Item = &'arena Self> + 'a>;
}
pub trait ParseTree<'input, 'arena>: Tree<'arena> {
fn get_source_interval(&self) -> Interval {
interval_set::INVALID
}
fn get_text(&self) -> String {
String::new()
}
}
pub trait RuleNode<'input, 'arena>:
ParseTree<'input, 'arena>
+ ParserRuleContext<'input, 'arena>
+ From<TerminalNode<'input, 'arena>>
+ From<ErrorNode<'input, 'arena>>
where
'input: 'arena,
Self: 'arena,
{
type Listener: ParseTreeListener<'input, 'arena, Self> + ?Sized;
fn get_rule_context(&self) -> &dyn ParserRuleContext<'input, 'arena> {
self
}
fn get_rule_context_mut(&mut self) -> &mut dyn ParserRuleContext<'input, 'arena> {
self
}
fn as_rule_context<T>(&self) -> Option<&T>
where
T: ParserRuleContext<'input, 'arena> + NodeInner<'input, 'arena, Self>,
{
T::cast_from(self)
}
fn as_rule_context_mut<T>(&mut self) -> Option<&mut T>
where
T: ParserRuleContext<'input, 'arena> + NodeInner<'input, 'arena, Self>,
{
T::cast_from_mut(self)
}
fn as_terminal_node(&self) -> Option<&TerminalNode<'input, 'arena>>;
fn as_terminal_node_mut(&mut self) -> Option<&mut TerminalNode<'input, 'arena>>;
fn as_error_node(&self) -> Option<&ErrorNode<'input, 'arena>>;
fn as_error_node_mut(&mut self) -> Option<&mut ErrorNode<'input, 'arena>>;
fn set_exception(&self, _e: ANTLRError, arena: &'arena Arena);
fn set_invoking_state(&mut self, _t: i32);
fn set_alt_number(&mut self, _alt_number: i32);
fn set_start(&mut self, _t: Option<&'arena dyn Token>);
fn set_stop(&mut self, _t: Option<&'arena dyn Token>);
fn remove_last_child(&mut self);
fn add_child(&mut self, _child: &'arena Self);
fn set_parent(&mut self, _parent: Option<&'arena Self>);
unsafe fn set_self_ref(&mut self, _self_ref: *const Self);
fn enter_rule(&self, listener: &mut Self::Listener) -> Result<(), ANTLRError>;
fn exit_rule(&self, listener: &mut Self::Listener) -> Result<(), ANTLRError>;
}
pub trait NodeInner<'input, 'arena, Node>
where
'input: 'arena,
Node: RuleNode<'input, 'arena>,
{
fn cast_from(node: &Node) -> Option<&Self>
where
Self: Sized;
fn cast_from_mut(node: &mut Node) -> Option<&mut Self>
where
Self: Sized;
fn try_as_node(&'arena self) -> Option<&'arena Node>;
fn iter_child_nodes<'a>(&'a self) -> Box<dyn Iterator<Item = &'arena Node> + 'a>;
}
#[doc(hidden)]
#[derive(Debug)]
pub struct NoError;
#[doc(hidden)]
#[derive(Debug)]
pub struct IsError;
pub struct LeafNode<'input, 'arena, E>
where
'input: 'arena,
E: 'static,
{
pub symbol: &'arena (dyn Token + 'input),
iserror: PhantomData<E>,
}
impl<'input, 'arena, E> RuleContext<'arena> for LeafNode<'input, 'arena, E>
where
'input: 'arena,
E: 'static,
{
fn get_rule_index(&self) -> usize {
usize::MAX
}
fn get_alt_number(&self) -> i32 {
crate::atn::INVALID_ALT
}
fn get_node_text(&self, _rule_names: &[&str]) -> String {
self.symbol.get_text().to_display()
}
fn get_invoking_state(&self) -> i32 {
-1
}
fn get_parent_ctx(&self) -> Option<&'arena dyn RuleContext<'arena>> {
None
}
}
impl<'input, 'arena, E> ParserRuleContext<'input, 'arena> for LeafNode<'input, 'arena, E>
where
'input: 'arena,
E: 'static,
{
fn get_text(&self) -> String {
self.symbol.get_text().to_display()
}
fn get_child_count(&self) -> usize {
0
}
}
impl<'input, 'arena, Node> NodeInner<'input, 'arena, Node> for LeafNode<'input, 'arena, NoError>
where
'input: 'arena,
Node: RuleNode<'input, 'arena>,
{
fn cast_from(node: &Node) -> Option<&Self>
where
Self: Sized,
{
node.as_terminal_node()
}
fn cast_from_mut(node: &mut Node) -> Option<&mut Self>
where
Self: Sized,
{
node.as_terminal_node_mut()
}
fn iter_child_nodes<'a>(&'a self) -> Box<dyn Iterator<Item = &'arena Node> + 'a> {
Box::new(std::iter::empty())
}
fn try_as_node(&'arena self) -> Option<&'arena Node> {
None
}
}
impl<'input, 'arena, Node> NodeInner<'input, 'arena, Node> for LeafNode<'input, 'arena, IsError>
where
'input: 'arena,
Node: RuleNode<'input, 'arena>,
{
fn cast_from(node: &Node) -> Option<&Self>
where
Self: Sized,
{
node.as_error_node()
}
fn cast_from_mut(node: &mut Node) -> Option<&mut Self>
where
Self: Sized,
{
node.as_error_node_mut()
}
fn iter_child_nodes<'a>(&'a self) -> Box<dyn Iterator<Item = &'arena Node> + 'a> {
Box::new(std::iter::empty())
}
fn try_as_node(&'arena self) -> Option<&'arena Node> {
None
}
}
impl<'input, 'arena, E> Default for LeafNode<'input, 'arena, E>
where
'input: 'arena,
E: 'static,
{
fn default() -> Self {
Self::new(token_factory::invalid())
}
}
impl<'input, 'arena, E> Debug for LeafNode<'input, 'arena, E>
where
E: 'static,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if self.symbol.get_token_type() == EOF {
f.write_str("<EOF>")
} else {
let a = self.symbol.get_text().to_display();
f.write_str(&a)
}
}
}
impl<'input, 'arena, E> LeafNode<'input, 'arena, E>
where
'input: 'arena,
E: 'static,
{
pub fn new(symbol: &'arena (dyn Token + 'input)) -> Self {
Self {
symbol,
iserror: Default::default(),
}
}
}
pub type TerminalNode<'input, 'arena> = LeafNode<'input, 'arena, NoError>;
pub type ErrorNode<'input, 'arena> = LeafNode<'input, 'arena, IsError>;
pub trait ParseTreeVisitor<'input, 'arena, Node>
where
'input: 'arena,
Node: RuleNode<'input, 'arena>,
{
type Return: Default;
fn visit(&mut self, node: &Node) -> Result<Self::Return, ANTLRError>;
fn visit_terminal(
&mut self,
_node: &TerminalNode<'input, 'arena>,
) -> Result<Self::Return, ANTLRError> {
Ok(Self::Return::default())
}
fn visit_error_node(
&mut self,
_node: &ErrorNode<'input, 'arena>,
) -> Result<Self::Return, ANTLRError> {
Ok(Self::Return::default())
}
fn visit_children(
&mut self,
node: &dyn NodeInner<'input, 'arena, Node>,
) -> Result<Self::Return, ANTLRError> {
let mut result = Self::Return::default();
for child in node.iter_child_nodes() {
if !self.should_visit_next_child(child, &result) {
break;
}
let child_result = self.visit(child)?;
result = self.aggregate_results(result, child_result)?;
}
Ok(result)
}
fn aggregate_results(
&self,
_aggregate: Self::Return,
next: Self::Return,
) -> Result<Self::Return, ANTLRError> {
Ok(next)
}
fn should_visit_next_child(&self, _node: &Node, _current: &Self::Return) -> bool {
true
}
}
pub trait ParseTreeListener<'input, 'arena, Node>
where
'input: 'arena,
Node: RuleNode<'input, 'arena>,
{
fn visit_terminal(&mut self, _node: &TerminalNode<'input, 'arena>) -> Result<(), ANTLRError> {
Ok(())
}
fn visit_error_node(&mut self, _node: &ErrorNode<'input, 'arena>) -> Result<(), ANTLRError> {
Ok(())
}
fn enter_every_rule(&mut self, _ctx: &Node) -> Result<(), ANTLRError> {
Ok(())
}
fn exit_every_rule(&mut self, _ctx: &Node) -> Result<(), ANTLRError> {
Ok(())
}
}
#[derive(Debug)]
pub struct ParseTreeWalker;
impl ParseTreeWalker {
pub fn walk<'input, 'arena, Node>(
mut listener: Box<Node::Listener>,
t: &Node,
) -> Result<Box<Node::Listener>, ANTLRError>
where
'input: 'arena,
Node: RuleNode<'input, 'arena>,
{
if let Some(terminal) = t.as_terminal_node() {
listener.visit_terminal(terminal)?;
return Ok(listener);
}
if let Some(error) = t.as_error_node() {
listener.visit_error_node(error)?;
return Ok(listener);
}
Self::enter_rule(&mut *listener, t)?;
for child in t.get_children() {
listener = Self::walk(listener, child)?;
}
Self::exit_rule(&mut *listener, t)?;
Ok(listener)
}
fn enter_rule<'input, 'arena, Node>(
listener: &mut Node::Listener,
t: &Node,
) -> Result<(), ANTLRError>
where
'input: 'arena,
Node: RuleNode<'input, 'arena>,
{
listener.enter_every_rule(t)?;
t.enter_rule(listener)
}
fn exit_rule<'input, 'arena, Node>(
listener: &mut Node::Listener,
t: &Node,
) -> Result<(), ANTLRError>
where
'input: 'arena,
Node: RuleNode<'input, 'arena>,
{
t.exit_rule(listener)?;
listener.exit_every_rule(t)
}
}