Diciamo, ipoteticamente, che sto scrivendo un compilatore Java. E supponiamo che nel mio caso una classe non possa essere compilata fino a quando non saranno note tutte le firme delle dipendenze (importazioni e altre classi utilizzate). Poiché non desidero mantenere contemporaneamente il codice sorgente e AST di tutte le classi in memoria, ho bisogno di un algoritmo per gestire tali dipendenze e elaborarle tutte nell'ordine corretto.
Quale sarebbe un buon algoritmo per ordinare tutte le dipendenze? Quella:
- non è ricorsivo
- non conserva tutti i codici sorgente e / o gli ast nodi in memoria
- è lineare sia nello spazio che nel tempo
- può gestire le dipendenze cicliche
O forse più generale, come si fa normalmente?
Il mio approccio è il seguente:
abstract class Compiler {
TypeSystem ts;
Type compile(String className) {
if (ts.containsType(className)) {
return ts.getType(className);
}
// Create skeleton type for this class:
Type type = ts.createType(className);
// Parse the class file:
Node ast = parse(className);
// Create signature:
for (Node attribute : ast.findAll("AttributeDeclaration")) {
// Get the text value of the name of the attribute:
String attributeName = attribute.find("Identifier").text();
// Get the text value of the type of the attribute:
String attributeTypeName = attribute.find("Type").text();
// Call compile recursive!
Type attributeType = compile(attributeTypeName);
type.createAttribute(attributeName, attributeType);
}
return type;
}
abstract Node parse(String className); // This method can find the file by class name.
}
Per semplicità, questo codice elabora solo attributi e semplici strutture. Nota che questo algoritmo è ricorsivo!