abstract class Expr { public abstract E accept(Visitor v); /* NOTA: il tutto si basa sull'overloading del metodo visit. Se si scrive qui la seguente implementazione di accept: { v.visit(this); } e non la si scrive nelle sottoclassi, il meccanismo non funziona. Infatti, i metodi accept delle sottoclassi, anche se apparentemente uguali, chiamano metodi visit differenti (il tipo dell'argomento fornito cambia). */ } class PiuExpr extends Expr { private Expr sx, dx; public PiuExpr(Expr sx, Expr dx) { this.sx = sx; this.dx = dx; } public E accept(Visitor v) { return v.visit(this); } public Expr getSx() { return sx; } public Expr getDx() { return dx; } } class MenoExpr extends Expr { private Expr sx, dx; public MenoExpr(Expr sx, Expr dx) { this.sx = sx; this.dx = dx; } public E accept(Visitor v) { return v.visit(this); } public Expr getSx() { return sx; } public Expr getDx() { return dx; } } class PerExpr extends Expr { private Expr sx, dx; public PerExpr(Expr sx, Expr dx) { this.sx = sx; this.dx = dx; } public E accept(Visitor v) { return v.visit(this); } public Expr getSx() { return sx; } public Expr getDx() { return dx; } } class DivisoExpr extends Expr { private Expr sx, dx; public DivisoExpr(Expr sx, Expr dx) { this.sx = sx; this.dx = dx; } public E accept(Visitor v) { return v.visit(this); } public Expr getSx() { return sx; } public Expr getDx() { return dx; } } class UnMenoExpr extends Expr { private Expr e; public UnMenoExpr(Expr e) { this.e = e; } public E accept(Visitor v) { return v.visit(this); } public Expr getE() { return e; } } class UnPiuExpr extends Expr { private Expr e; public UnPiuExpr(Expr e) { this.e = e; } public E accept(Visitor v) { return v.visit(this); } public Expr getE() { return e; } } class NumExpr extends Expr { private Integer num; public NumExpr(Integer num) { this.num = num; } public E accept(Visitor v) { return v.visit(this); } public Integer getValue() { return num; } } class IdExpr extends Expr { private String id; public IdExpr(String id) { this.id = id; } public E accept(Visitor v) { return v.visit(this); } public String toString() { return id; } }