Mise en place formelle du visiteur et séparation de l'affichage d'un arbre syntaxique abstrait (AST).
This commit is contained in:
42
src/astprinter.rs
Normal file
42
src/astprinter.rs
Normal 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); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
59
src/expr.rs
59
src/expr.rs
@@ -29,53 +29,44 @@ pub enum Expr {
|
|||||||
UnaryExpr(Unary),
|
UnaryExpr(Unary),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Visitable {
|
pub trait ExprVisitor {
|
||||||
fn visit(&self);
|
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 {
|
pub trait VisitableExpr {
|
||||||
fn visit(&self) {
|
fn accept(&self, visitor: &impl ExprVisitor);
|
||||||
print!("( {}",&self.operator.literal);
|
}
|
||||||
&self.left.visit();
|
|
||||||
&self.right.visit();
|
impl VisitableExpr for Binary {
|
||||||
print!(")");
|
fn accept(&self, visitor: &impl ExprVisitor) {
|
||||||
|
visitor.visit_binary(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitable for Grouping {
|
impl VisitableExpr for Grouping {
|
||||||
fn visit(&self) {
|
fn accept(&self, visitor: &impl ExprVisitor) {
|
||||||
print!("( group ");
|
visitor.visit_grouping(self);
|
||||||
&self.expression.visit();
|
|
||||||
print!(")");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitable for Literal {
|
impl VisitableExpr for Literal {
|
||||||
fn visit(&self) {
|
fn accept(&self, visitor: &impl ExprVisitor) {
|
||||||
match &self {
|
visitor.visit_literal(self);
|
||||||
Literal::LiteralNumber(i) => print!("{}", i),
|
|
||||||
Literal::LiteralString(s) => print!("{}", s),
|
|
||||||
Literal::LiteralBool(b) => print!("{}", b),
|
|
||||||
Literal::LiteralNil => print!("nil"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitable for Unary {
|
impl VisitableExpr for Unary {
|
||||||
fn visit(&self) {
|
fn accept(&self, visitor: &impl ExprVisitor) {
|
||||||
print!("( {}",&self.operator.literal);
|
visitor.visit_unary(self);
|
||||||
&self.right.visit();
|
|
||||||
print!(")");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitable for Expr {
|
impl VisitableExpr for Expr {
|
||||||
fn visit(&self) {
|
fn accept(&self, visitor: &impl ExprVisitor) {
|
||||||
match &self {
|
visitor.visit_expr(self);
|
||||||
Expr::BinaryExpr(b) => { b.visit(); }
|
|
||||||
Expr::GroupingExpr(g) => { g.visit(); }
|
|
||||||
Expr::LiteralExpr(l) => { l.visit(); }
|
|
||||||
Expr::UnaryExpr(u) => { u.visit(); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/main.rs
12
src/main.rs
@@ -1,17 +1,20 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::process;
|
use std::process;
|
||||||
use crate::expr::{Binary, Expr, Grouping, Literal, Unary, Visitable};
|
|
||||||
use crate::expr::Expr::LiteralExpr;
|
|
||||||
|
|
||||||
mod rlox_interpreter;
|
mod rlox_interpreter;
|
||||||
|
|
||||||
mod scanner;
|
mod scanner;
|
||||||
mod token;
|
mod token;
|
||||||
mod token_type;
|
mod token_type;
|
||||||
mod expr;
|
mod expr;
|
||||||
|
mod astprinter;
|
||||||
|
|
||||||
use crate::rlox_interpreter::RLoxInterpreter;
|
use crate::rlox_interpreter::RLoxInterpreter;
|
||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
use crate::token_type::TokenType;
|
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>
|
// Exit codes from #include <sysexits.h>
|
||||||
const EX_OK: i32 = 0;
|
const EX_OK: i32 = 0;
|
||||||
@@ -44,7 +47,7 @@ fn essai_visitor() {
|
|||||||
line: 0,
|
line: 0,
|
||||||
literal: String::from("-")
|
literal: String::from("-")
|
||||||
},
|
},
|
||||||
right: Box::new(Expr::LiteralExpr(Literal::LiteralNumber(123.0)))
|
right: Box::new(Expr::LiteralExpr(Literal::LiteralNumber(456.0)))
|
||||||
})),
|
})),
|
||||||
operator: Token {
|
operator: Token {
|
||||||
token_type: TokenType::Star,
|
token_type: TokenType::Star,
|
||||||
@@ -57,7 +60,8 @@ fn essai_visitor() {
|
|||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.visit();
|
let a = ASTPrinter{};
|
||||||
|
expression.accept(&a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user