Rispetto al C/Yacc, l'accoppiata Java/JavaCup offre molti vantaggi, in particolare
una maggiore chiarezza del meccanismo. In particolare l'uso di oggetti si
sposa molto bene con la struttura a regole del riconoscimento grammaticale,
quindi è facile e naturale costruire gli alberi sintattici.
La cosa interessante è che, una volta costruito l'albero, utilizzarlo (in
questo caso valutarlo) è di solito una questione di aggiungere metodi ai
nodi. Vediamo come risolviamo in breve il problema di valutare l'espressione:
class ASTNodeN {
…
public double eval() {
double a=0, b=0;
boolean binary = sons.size() == 2;
a = ((ASTNode)sons.elementAt(0)).eval();
if(binary)
b = ((ASTNode)sons.elementAt(0)).eval();
switch(value.charAt(0)) {
case '+':
return a+b;
case '-':
return binary ? a-b : -a;
case '*':
return a * b;
case '/':
return a / b;
case '%':
return a % b;
default:
return 0;
}
}
}
class ASTLeaf {
…
double value;
public double eval() {
return value;
}
}
Nel nostro caso si poteva valutare direttamente l'espressione mentre si
esaminava il testo senza avere necessità di costruire l'albero di sintassi
astratta, ma nella maggior parte dei casi occorre costruire l'AST e manipolarlo
prima di utilizzarlo, in particolare quando occorre effettuare compilazioni,
per cui abbiamo preferito descrivere in dettaglio la costruzione dell'AST.
|