Mise en place formelle du visiteur et séparation de l'affichage d'un arbre syntaxique abstrait (AST).

This commit is contained in:
2024-05-03 08:03:05 +02:00
parent 66e4a515b3
commit 6e12be2d36
3 changed files with 75 additions and 38 deletions

42
src/astprinter.rs Normal file
View File

@@ -0,0 +1,42 @@
use crate::expr::{Binary, Expr, ExprVisitor, Grouping, Literal, Unary, VisitableExpr};
pub struct ASTPrinter;
impl ExprVisitor for ASTPrinter {
fn visit_binary(&self, b: &Binary) {
print!("( {}", b.operator.literal);
b.left.accept(self);
b.right.accept(self);
print!(")");
}
fn visit_grouping(&self, g: &Grouping) {
print!("( group ");
g.expression.accept(self);
print!(")");
}
fn visit_literal(&self, l: &Literal) {
match l {
Literal::LiteralNumber(i) => print!("{}", i),
Literal::LiteralString(s) => print!("{}", s),
Literal::LiteralBool(b) => print!("{}", b),
Literal::LiteralNil => print!("nil"),
}
}
fn visit_unary(&self, u: &Unary) {
print!("( {}", u.operator.literal);
u.right.accept(self);
print!(")");
}
fn visit_expr(&self, e: &Expr) {
match e {
Expr::BinaryExpr(b) => { b.accept(self); }
Expr::GroupingExpr(g) => { g.accept(self); }
Expr::LiteralExpr(l) => { l.accept(self); }
Expr::UnaryExpr(u) => { u.accept(self); }
}
}
}

View File

@@ -29,53 +29,44 @@ pub enum Expr {
UnaryExpr(Unary),
}
pub trait Visitable {
fn visit(&self);
pub trait ExprVisitor {
fn visit_binary(&self, b: &Binary);
fn visit_grouping(&self, g: &Grouping);
fn visit_literal(&self, l: &Literal);
fn visit_unary(&self, u: &Unary);
fn visit_expr(&self, e: &Expr);
}
impl Visitable for Binary {
fn visit(&self) {
print!("( {}",&self.operator.literal);
&self.left.visit();
&self.right.visit();
print!(")");
pub trait VisitableExpr {
fn accept(&self, visitor: &impl ExprVisitor);
}
impl VisitableExpr for Binary {
fn accept(&self, visitor: &impl ExprVisitor) {
visitor.visit_binary(self);
}
}
impl Visitable for Grouping {
fn visit(&self) {
print!("( group ");
&self.expression.visit();
print!(")");
impl VisitableExpr for Grouping {
fn accept(&self, visitor: &impl ExprVisitor) {
visitor.visit_grouping(self);
}
}
impl Visitable for Literal {
fn visit(&self) {
match &self {
Literal::LiteralNumber(i) => print!("{}", i),
Literal::LiteralString(s) => print!("{}", s),
Literal::LiteralBool(b) => print!("{}", b),
Literal::LiteralNil => print!("nil"),
}
}
}
impl Visitable for Unary {
fn visit(&self) {
print!("( {}",&self.operator.literal);
&self.right.visit();
print!(")");
impl VisitableExpr for Literal {
fn accept(&self, visitor: &impl ExprVisitor) {
visitor.visit_literal(self);
}
}
impl Visitable for Expr {
fn visit(&self) {
match &self {
Expr::BinaryExpr(b) => { b.visit(); }
Expr::GroupingExpr(g) => { g.visit(); }
Expr::LiteralExpr(l) => { l.visit(); }
Expr::UnaryExpr(u) => { u.visit(); }
impl VisitableExpr for Unary {
fn accept(&self, visitor: &impl ExprVisitor) {
visitor.visit_unary(self);
}
}
impl VisitableExpr for Expr {
fn accept(&self, visitor: &impl ExprVisitor) {
visitor.visit_expr(self);
}
}

View File

@@ -1,17 +1,20 @@
use std::env;
use std::process;
use crate::expr::{Binary, Expr, Grouping, Literal, Unary, Visitable};
use crate::expr::Expr::LiteralExpr;
mod rlox_interpreter;
mod scanner;
mod token;
mod token_type;
mod expr;
mod astprinter;
use crate::rlox_interpreter::RLoxInterpreter;
use crate::token::Token;
use crate::token_type::TokenType;
use crate::expr::{Binary, Expr, Grouping, Literal, Unary, VisitableExpr};
use crate::expr::Expr::LiteralExpr;
use crate::astprinter::ASTPrinter;
// Exit codes from #include <sysexits.h>
const EX_OK: i32 = 0;
@@ -44,7 +47,7 @@ fn essai_visitor() {
line: 0,
literal: String::from("-")
},
right: Box::new(Expr::LiteralExpr(Literal::LiteralNumber(123.0)))
right: Box::new(Expr::LiteralExpr(Literal::LiteralNumber(456.0)))
})),
operator: Token {
token_type: TokenType::Star,
@@ -57,7 +60,8 @@ fn essai_visitor() {
}))
});
expression.visit();
let a = ASTPrinter{};
expression.accept(&a);
}