use crate::parser::{
AltExpr, AnonymousNode, CapturedExpr, Def, Expr, FieldExpr, NamedNode, QuantifiedExpr, Ref,
Root, SeqExpr,
};
pub trait Visitor: Sized {
fn visit(&mut self, ast: &Root) {
walk(self, ast);
}
fn visit_def(&mut self, def: &Def) {
walk_def(self, def);
}
fn visit_expr(&mut self, expr: &Expr) {
walk_expr(self, expr);
}
fn visit_named_node(&mut self, node: &NamedNode) {
walk_named_node(self, node);
}
fn visit_anonymous_node(&mut self, _node: &AnonymousNode) {}
fn visit_ref(&mut self, _ref: &Ref) {}
fn visit_alt_expr(&mut self, alt: &AltExpr) {
walk_alt_expr(self, alt);
}
fn visit_seq_expr(&mut self, seq: &SeqExpr) {
walk_seq_expr(self, seq);
}
fn visit_captured_expr(&mut self, cap: &CapturedExpr) {
walk_captured_expr(self, cap);
}
fn visit_quantified_expr(&mut self, quant: &QuantifiedExpr) {
walk_quantified_expr(self, quant);
}
fn visit_field_expr(&mut self, field: &FieldExpr) {
walk_field_expr(self, field);
}
}
pub fn walk<V: Visitor>(visitor: &mut V, ast: &Root) {
for def in ast.defs() {
visitor.visit_def(&def);
}
}
pub fn walk_def<V: Visitor>(visitor: &mut V, def: &Def) {
if let Some(body) = def.body() {
visitor.visit_expr(&body);
}
}
pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr) {
match expr {
Expr::NamedNode(n) => visitor.visit_named_node(n),
Expr::AnonymousNode(n) => visitor.visit_anonymous_node(n),
Expr::Ref(r) => visitor.visit_ref(r),
Expr::AltExpr(a) => visitor.visit_alt_expr(a),
Expr::SeqExpr(s) => visitor.visit_seq_expr(s),
Expr::CapturedExpr(c) => visitor.visit_captured_expr(c),
Expr::QuantifiedExpr(q) => visitor.visit_quantified_expr(q),
Expr::FieldExpr(f) => visitor.visit_field_expr(f),
}
}
pub fn walk_named_node<V: Visitor>(visitor: &mut V, node: &NamedNode) {
for child in node.children() {
visitor.visit_expr(&child);
}
}
pub fn walk_alt_expr<V: Visitor>(visitor: &mut V, alt: &AltExpr) {
for branch in alt.branches() {
if let Some(body) = branch.body() {
visitor.visit_expr(&body);
}
}
for expr in alt.exprs() {
visitor.visit_expr(&expr);
}
}
pub fn walk_seq_expr<V: Visitor>(visitor: &mut V, seq: &SeqExpr) {
for child in seq.children() {
visitor.visit_expr(&child);
}
}
pub fn walk_captured_expr<V: Visitor>(visitor: &mut V, cap: &CapturedExpr) {
if let Some(inner) = cap.inner() {
visitor.visit_expr(&inner);
}
}
pub fn walk_quantified_expr<V: Visitor>(visitor: &mut V, quant: &QuantifiedExpr) {
if let Some(inner) = quant.inner() {
visitor.visit_expr(&inner);
}
}
pub fn walk_field_expr<V: Visitor>(visitor: &mut V, field: &FieldExpr) {
if let Some(val) = field.value() {
visitor.visit_expr(&val);
}
}