Compiler-CampusMinden / CB-Vorlesung-Bachelor

Lecture "Compilerbau" (B.Sc.)
https://www.hsbi.de/elearning/goto.php?target=crs_1089779&client_id=FH-Bielefeld
Creative Commons Attribution Share Alike 4.0 International
1 stars 0 forks source link

lecture: fix resolving in classes #234

Closed cagix closed 9 months ago

cagix commented 9 months ago

Das Auflösen von Namen bei Klassen funktioniert nicht korrekt: Wenn es eine Elternklasse gab, wurde nur dort nachgeschaut - auch, wenn das Symbol dort nicht gefunden werden konnte.

Siehe Diskussion in https://github.com/Compiler-CampusMinden/CB-Vorlesung-Master/issues/140:

  1. Wenn ich Funktionen betrachte:
class Y {}

class X extends Y {
    int f(int z) { return z; }
}

class Z {
    int f(int z) { return z; }

    class W extends X {
        int f(int z) { return z; }

        void foo() {
            f(34);
        }
    }
}

Beim Aufruf von f(34) in void foo() versuche ich, die Funktion in der Klasse (also Z.W) aufzulösen. Wenn ich sie dort nicht finde, gehe ich in die Elternklasse von W, also X (und so weiter). Erst wenn ich die Funktion auf diesem Wege nicht finden kann, suche ich im enclosing scope der Klasse W, also in Z.

  1. Wenn ich Attribute/Variablen betrachte:
class Y {}

class X extends Y {
    int x = 1;
}

class Z {
    int x = 3;

    class W extends X {
        int x = 2;

        void foo() {
            System.out.println(x);
        }
    }
}

Auch hier würde ich im System.out.println(x) zunächst im enclosing scope suchen, also in der Klasse W. Wenn ich dort nicht fündig werde, gehe ich zur Elternklasse (X) ... Danach suche ich dann im enclosing scope der Klasse W, also in Z weiter.

Insofern ist der Code-Schnipsel im Skript nicht ganz korrekt, jedenfalls nicht in Bezug auf die Semantik in Java :) Dein Code-Vorschlag löst das ein wenig besser auf, aber am Ende gibt es ja eine Exception, wenn das Element nicht gefunden wird - ich glaube, wir brauchen einfach nur eine doppelte try/catch-Struktur?

    # NEW: if not here, check any parent class ...
    if parentClazz and parentClazz.resolve(name): return parentClazz.resolve(name)
    else: 
        # ... or enclosing scope if base class
        if enclosingScope: return enclosingScope.resolve(name)
        else: return None     # not found

fixes https://github.com/Compiler-CampusMinden/CB-Vorlesung-Master/issues/140