2

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?

Antwort

1

Der Wert der Symbole in der Symboltabelle (zum Beispiel der Wert von Variablen oder der Rückgabewert einer Funktion) muss jedoch, soweit ich weiß, auch in der Symboltabelle vorhanden sein.

Die Lage der Symbole in der Symboltabelle muss vorhanden, dort sein - klassisch in Form eines Stapels versetzt sind. Die tatsächlichen Werte sind in der Regel zur Kompilierzeit unbekannt.

Für ein Beispiel, denken Sie an etwas wie x = y. Der Zweck der Symboltabelle besteht darin, dem Compiler zu ermöglichen, die Typen x und y für die Typprüfung (in den entsprechenden Sprachen) zu kennen und die Adressoperanden der Befehle "Laden" und "Speichern" zu kennen. Aber es kann den Ausgabecode gut erzeugen, ohne zu wissen, was der tatsächliche Wert ist, der in x gespeichert wird.

+0

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

+0

@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

+0

Okay, gut danke, ich denke ich verstehe jetzt besser. – Chraebe