En fait lors d'un calcul sur un arbre, on va non seulement avoir des valeurs de retour
mais aussi passer des paramètres, donc l'interface d'un visteur devrait plutôt être
celle-ci
public interface ExprVisitor<P, R> {
public R visitValue(Value value, P param);
public R visitBinOp(BinOp binOp, P param);
}
avec P representant le type d'un objet contenant tous les arguments si il y en a plusieurs
ou le type de l'argument si il n'y en a qu'un seul.
Revenons sur ce qu'est un visteur, un visteur est un objet qui associe à
une classe (
Value ou
BinOp) à un code à exécuter.
Il peut donc est implanter avec une table de hachage qui associe à une classe
(un objet de type
java.lang.Class) une lambda contenant le code
à exécuter.
On se propose d'écrire la classe
ExprVisitor de tel sorte à ce que
le code suivant fonctionne
ExprVisitor<Void, Integer> evalVisitor = new ExprVisitor<>();
evalVisitor
.when(Value.class, (value, unused) -> {
...
})
.when(BinOp.class, (binOp, unused) -> {
...
});
evalVisitor.visit(expr, null);