parser: Visitor trait for traversal

This commit is contained in:
Ryan Chandler 2022-08-22 19:05:06 +01:00
parent 241eca2fb4
commit aa2a6c8507
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
2 changed files with 48 additions and 1 deletions

View File

@ -1,5 +1,7 @@
mod ast;
mod parser;
mod traverser;
pub use ast::{Statement, Expression, Program, Block, Param, Identifier, Type, InfixOp, MatchArm, Catch, Case};
pub use parser::{Parser, ParseError};
pub use parser::{Parser, ParseError};
pub use traverser::*;

View File

@ -0,0 +1,45 @@
use crate::{Statement, Program};
pub trait Visitor {
fn visit(&mut self, statement: &Statement);
fn traverse(&mut self, ast: Program) {
for statement in &ast {
self.visit(statement);
}
}
}
#[cfg(test)]
mod tests {
use crate::{Parser, Program, Visitor};
use trunk_lexer::Lexer;
struct CountVisitor {
count: usize,
}
impl Visitor for CountVisitor {
fn visit(&mut self, statement: &crate::Statement) {
self.count += 1;
}
}
#[test]
fn it_can_walk_an_ast() {
let ast = get_ast("<?php foo();");
let mut visitor = CountVisitor { count: 0 };
visitor.traverse(ast);
assert_eq!(visitor.count, 1);
}
fn get_ast(source: &str) -> Program {
let mut lexer = Lexer::new(None);
let tokens = lexer.tokenize(source).unwrap();
let mut parser = Parser::new(None);
let ast = parser.parse(tokens).unwrap();
ast
}
}