Ich erstelle einen Compiler für meine eigene Programmiersprache zur Erstellung von Bots in Minecraft als Semesterprojekt an meiner Universität. Bisher habe ich erfolgreich einen Parser mit ANTLR erstellt, meine eigene Abstract Syntax Tree-Struktur erstellt und ANTLR-Besucher verwendet, um den AST zu erstellen. Ich bin in der kontextuellen Analysephase, und ich erstelle derzeit Symboltabellen und habe die Struktur unter Kontrolle. Meine SymbolTable-Klasse sieht so aus:Unbekannte Variablenwerte zur Kompilierzeit bei der Erstellung einer Symboltabelle in Java berücksichtigen
public class SymbolTable {
private HashMap<String, Symbol> ST = new HashMap<>();
public SymbolTable parent;
public LinkedList<SymbolTable> children = new LinkedList<>();
public String kind;
public String id;
public SymbolTable(String kind, String id){
this.kind = kind;
this.id = id;
}
public void put(String id, Symbol val){
ST.put(id, val);
}
public Symbol get(String id){
if(ST.containsKey(id)) {
return ST.get(id);
}
else{
try {
return parent.get(id);
}
catch(NullPointerException e){
return null;
}
}
}
public boolean contains(String id){
if(ST.containsKey(id)) {
return true;
}
else{
if(parent == null){
return false;
}
return parent.contains(id);
}
}
public String prettyPrint(){
String st = "(TABLE " + this.kind + " " + this.id + " " + ST.toString();
for(SymbolTable nst : children){
st = st.concat(" " + nst.prettyPrint());
}
st = st.concat(")");
return st;
}
public boolean isFunction(){
if(this.kind == "fun"){
return true;
}
else if(!(this.parent == null)){
return this.parent.isFunction();
}
else{
return false;
}
}
}
Das Einfügen von Variablen und Funktionen in die Symboltabelle ist kein Problem; Ich benutze meine Besucher Methoden dafür, wie folgt aus:
@Override
public Symbol visitStrVarCond(StrVarCondNode node){ return new StringSymbol("var", "string", node.val); }
jedoch, soweit ich verstehe, ist der Wert der Symbole in der Symboltabelle (zum Beispiel der Wert der Variablen oder der Rückgabewert einer Funktion) muss auch in der Symboltabelle vorhanden sein. Das ist auch kein Problem, und das kann ich schon machen. obwohl
Mein Problem, ist:
Einige der Werte könnte der Programmierer verwenden, ist nicht bekannt, zur Compile-Zeit. Sie sind nur zur Laufzeit eines bestimmten Programms bekannt. Zum Beispiel: Die aktuelle Position des Spielers, der bestimmte Gegenstand in einem Inventar-Slot usw. Meine Sprache hat Ereignisse, also wenn ein Programmierer den Bot zum Beispiel so lange braucht, bis ein bestimmter Block entdeckt wird, könnte er es so schreiben:
Dieses spezielle Ereignis, das Blockereignis, enthält Variablen für die Position des Blocks. Dies ist jedoch zur Kompilierzeit nicht bekannt. Wie berücksichtige ich solche Dinge beim Einfügen von Werten in die Symboltabellen?
Wäre dies in Form eines tatsächlichen Stack-Pointer, und nur eine "Länge", wie viele Bytes sie im Stapel benötigen (zum Beispiel für einen 32-Bit-IEEE-Gleitkomma wäre dies 4 (32 Bits))? – Chraebe
@Chraebe es ist in der Regel als stack * offset * - d. H. Wie viele Bytes vom Anfang des aktuellen Stack-Frame, bis wo der Wert gespeichert ist. Aber es hängt wirklich von der Zielsprache ab - wenn Sie zum Beispiel auf Java-Bytecode abzielen, stelle ich mir vor, es wäre der LVA-Index. – Oak
Okay, gut danke, ich denke ich verstehe jetzt besser. – Chraebe