Implementierung Switch Compilerbau



  • Was haltet ihr von meiner IMplementierung eines Switch Knotens für die Erstellung eines abstrakten Syntaxbaums.

    public class SwitchKnoten extends Statement {
    	Expression switchExpression;
    	List<CaseKnoten> lstCaseKnoten;
    	Symboltable symTable;
    
    	public SwitchKnoten(Expression switchExpression,List<CaseKnoten> lstCaseKnoten)
    	{
    		//assign members
    		this.switchExpression = switchExpression;
    		this.lstCaseKnoten = lstCaseKnoten;
    
    		//set Parent Symboltable of members
    		switchExpression.setParentSymboltable(symTable);
    		for(CaseKnoten caseKnoten : lstCaseKnoten)
    		{
    			caseKnoten.setParentSymboltable(symTable);
    		}
    
    		//create new SymbolTable
    		symTable = new Symboltable(this.parentSymtable);
    	}
    
    	@Override
    	void sema1() throws SemanticError {
    		switchExpression.sema1();
    		for(CaseKnoten caseKnoten: lstCaseKnoten)
    
    		{
    			caseKnoten.sema1();
    		}
    
    	}
    
    	@Override
    	void sema2() throws SemanticError {
    		switchExpression.sema2();
    
    		//get Type of Expression
    		String typeSwitch;
    		typeSwitch = TypeInference.infer(switchExpression, symTable);
    
    		//check type
    		for(CaseKnoten caseKnoten : lstCaseKnoten)
    		{
    			String typeLabel = TypeInference.infer(caseKnoten.label, symTable);
    			if( typeSwitch!=  typeLabel)
    			{
    				throw new SemanticError("Type mismatch!");
    			}
    		}
    
    		//check if SwitchStatement other type than int,String or enum
    		if(typeSwitch != "String" || typeSwitch != "enum" || typeSwitch != "int")
    		{
    			throw new SemanticError("Only int,enum or double allowed in Switch !");
    		}
    
    		//check if label duplicate
    		for(int i = 0 ; i < lstCaseKnoten.size();i++)
    		{
    			for(int j = i +1; j < lstCaseKnoten.size()-1;j++)
    			{
    				int res1 = TypeInference.getResult(lstCaseKnoten.get(i).label);
    				int res2 = TypeInference.getResult(lstCaseKnoten.get(j).label);
    
    				if(res1 == res2)
    				{
    					throw new SemanticError("Duplicate label not allowed");
    				}
    			}
    
    		}
    		for(CaseKnoten caseKnoten: lstCaseKnoten)
    		{
    			caseKnoten.sema2();
    		}
    	}
    


  • Ninaner schrieb:

    Was haltet ihr von meiner IMplementierung eines Switch Knotens für die Erstellung eines abstrakten Syntaxbaums.

    In welcher Hinsicht? Denglisch find ich schon mal zum Kotzen. Namen wie sema1 und sema2 sehr sehr fragwürdig. Das führt normalerweise zu Code, den niemand mehr warten will. Hätte ich zumindest sowas gesehen, würde ich viel eher dazu tendieren, das neuzuschreiben, als mich da reinzudenken.

    Für Typen würde ich keine Strings nehmen, sondern Klassen (intern enum für eingebaute + Typverweis für benutzerdefinierte). Du läufst in sema2 drei mal über die Liste drüber, einmal sogar quadratisch, sicher nicht optimal.
    Ansonsten sieht man an dem Ausschnitt nicht genug, um den ganzen Aufbau beurteilen zu können. Was ich bisher gesehen habe, gefällt mir aber nicht so.



  • Ok danke. Ich hatte ursprümglich auch ein enum für bekannte Datentypen. Aber ich wußte halt nicht wie ich das mit benutzerdefinierten dann machen soll. Deswegen String für Typen.

    Und wie gesagt das ist der ASTKnoten für das Switch. Meine anderen ASTKnoten sind ähnlich.

    Was hast du gegen sema1 und sema1. Sema1 baut die Symboltabelle auf und Sema2 prüft dann ob die Typen stimmen.



  • Ninaner schrieb:

    Sema1 baut die Symboltabelle auf und Sema2 prüft dann ob die Typen stimmen.

    Und woher soll ich das wissen und warum schreibst du das nicht so hin? Es ist vom Namen her echt nicht klar, was sema1 genau macht, vor allem, wenn das nur über die anderen Knoten drüberläuft und wieder sema1 aufruft. Nenn das halt irgendwie buildSymbolTable und checkTypes, oder wie auch immer. Gute Namen sind wichtig.

    Das mit den Typen hätte ich wahrscheinlich als enum {Int, String, ..., Custom} gemacht und dann evtl. einen Verweis auf weitere Informationen (z.B. Klassendeklaration), je nachdem, was man braucht.

    Ninaner schrieb:

    Meine anderen ASTKnoten sind ähnlich.

    Was genau willst du dann über den Switch Knoten wissen? Wenn du die Typprüfung usw. in der Form aufgebaut hast, dann ist er wohl richtig. Hast du hier konkretere Fragen? Aus Performancesicht finde ich das wie gesagt nicht optimal.



  • Mechanics schrieb:

    intern enum für eingebaute + Typverweis für benutzerdefinierte

    Also bislang mach ich das ja so.

    String typ;
    

    Und du würdest jetzt für bekannte Datentypen ein enum verwenden und für benutzerdefinierte einen Verweis auf die Klasse oder ? Aber in meinem Variablenknoten brauch ich ja dann 2 member für den Typen ? Einmal enum und einmal Object ?



  • Eher sowas:

    class TypeInfo
    {
    public enum Type {Int, String, Custom};
    
    Type type;
    CustomTypeInfo info;
    }
    

    Dann hätte jedes Symbol im AST einen Verweis auf so eine Struktur.



  • Mechanics schrieb:

    Eher sowas:

    class TypeInfo
    {
    public enum Type {Int, String, Custom};
    
    Type type;
    CustomTypeInfo info;
    }
    

    Dann hätte jedes Symbol im AST einen Verweis auf so eine Struktur.

    Werd ich grad net schlau draus. CustomTypeInfo bleibt bei Standardtypen also immer leer bei der Implementierung oder. Bei

    MyOwnClass var = new MyOwnClass();
    

    würdest du MyOwnClass speichern in einer Klasse CustomTypeInfo ?



  • Ja, irgendwie so. Was man für benutzerdefinierte Typen speichern muss, kann ich dir so nicht sagen. Vielleicht den Namen der Klasse, wo sie deklariert wurde, wieviel Speicher eine Instanz braucht, eine Liste mit Membern usw...



  • Mechanics schrieb:

    Ja, irgendwie so. Was man für benutzerdefinierte Typen speichern muss, kann ich dir so nicht sagen. Vielleicht den Namen der Klasse, wo sie deklariert wurde, wieviel Speicher eine Instanz braucht, eine Liste mit Membern usw...

    Was du da beschreibst das kommt doch alles in die Symboltabelle. Da es nicht so einfach ist , hab ich es einfach als String gespeichert *gg*



  • Ok, man kann sich das auch so vorstellen, dass auch eine Klasse eine Symboltabelle hat oder ist. Ich würde aber hier aber auf jeden Fall weiter abstrahieren. Allein schon mit den Strings zu hantieren ist sehr unschön. Und später wirst du wahrscheinlich weitere Informationen brauchen, die du irgendwo speichern musst. Ich würde das gleich sauberer trennen.


Log in to reply