Compilerbau Teil 6: Abstrakter...

46
23.07.20 1 Compilerbau – SS 2020 – Teil 6/AST Compilerbau Teil 6: Abstrakter Syntaxbaum Version 2

Transcript of Compilerbau Teil 6: Abstrakter...

Page 1: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

23.07.20 1Compilerbau – SS 2020 – Teil 6/AST

Compilerbau

Teil 6: Abstrakter Syntaxbaum

Version 2

Page 2: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

2Compilerbau – SS 2020 – Teil 6/AST

Überblick

� Syntaxbäume

� Serialisieren und Deserialisieren eines Syntaxbaums

� Vererbungshierarchie

� Realisierung in Strukturen bzw. Klassen

Page 3: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

3Compilerbau – SS 2020 – Teil 6/AST

Wo sind wir?

Makro-Prozessor

Scanner Parser Semantik

Optimierung

Code-Generierung

Optimierung

Symbol-Tabelle

Page 4: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

4Compilerbau – SS 2020 – Teil 6/AST

Compiler

� Scanner = Teil eines Compilers, der die lexikalische Analyse durchführt

� Parser = Teil des Compilers, der eine Sequenz von Token auf syntaktische Korrektheit prüft und bei Korrektheit in einen abstrakten Syntaxbaum transformiert

Scanner

Parser

Erster Teileines Compilers

Tokenstrom

Abstrakter Syntaxbaum

Datei(en)

Page 5: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

5Compilerbau – SS 2020 – Teil 6/AST

Definition und weitere Schnittstelle

� Abstrakter Syntax Baum = Abstract Syntax tree = AST = auf die Semantik der Sprachkonstrukte reduzierter Ableitungsbaum

� Im folgenden wird statt AST nur noch einfach vom Syntaxbaum gesprochen.

� Das Generieren des AST ist die letzte Aktion des Parsers.� Damit ist der Parser von den danach folgenden Phasen

entkoppelt.� Es besteht die Möglichkeit, dass der AST serialisiert

abgespeichert wird, so dass die folgenden Phasen lediglich dies einzulesen brauchen (wird aber selten gemacht).

� Bei einige Compilern werden die folgenden Phasen mit dem Parser gemischt, z.B. bei 1-Pass-Compilern (Pascal-Dialekte).

� In diesem Kurs werden die Phasen klar getrennt.

Page 6: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

6Compilerbau – SS 2020 – Teil 6/AST

Beispiel I - Zuweisung

� Es handelt sich um einen n-ären Baum.

� Die Semantik eines Knotens k ist die Semantik der Unterknoten verknüpft durch die Operation des betreffenden Knotens k.

� Häufig werden diese Bäume mit depth-first (Tiefensuche) in Postorder-Reihenfolge traversiert.

a:= 3*(b+a);:=

a

3 +

b a

*

Page 7: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

7Compilerbau – SS 2020 – Teil 6/AST

Beispiel II – Reihenfolge des Traversierens

� Preorder = Knoten, linker Unterbaum, rechter UnterbaumIm Beispiel: :=, a, *, 3, +, b, a Dies wird polnische Notation genannt.

� Postorder = linker Unterbaum, rechter Unterbaum, KnotenIm Beispiel: a, 3, b, a, +, *, := Dies wird umgekehrte Polnische Notation genannt.

� Inorder = linker Unterbaum, Knoten, rechter UnterbaumIm Beispiel: a, :=, 3, *, b, +, a Dies ist die übliche Infix-Schreibweise für arithmetische Ausdrücke. Hier sind Klammern zur Darstellung der Bindungsstärken erforderlich.

� https://de.wikipedia.org/wiki/Polnische_Notation

� https://de.wikipedia.org/wiki/Umgekehrte_polnische_Notation

� https://www.fmi.uni-jena.de/fmimedia/Fakultaet/Institute+und+Abteilungen/Abteilung+f%C3%BCr+Didaktik/Ressourcen/GE_If/InfixPostfixPrefix.pdf

Siehe

Page 8: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

8Compilerbau – SS 2020 – Teil 6/AST

Traversieren von binären Bäumen

proc Preorder(Node root) { if root<>nil { ...root.data... Preorder(root.left); Preorder(root.right); }}

proc Postorder(Node root) { if root<>nil { Postorder(root.left); Postorder(root.right); ...root.data... }}

proc Inorder(Node root) { if root<>nil { Inorder(root.left); ...root.data... Inorder(root.right); }}

Das Traversieren in der Postorder- Reihenfolge ist die Basis der Code- generierung für Stack-Maschinen.

Page 9: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

9Compilerbau – SS 2020 – Teil 6/AST

Beispiel III – Reihenfolge des Traversierens

proc Postorder(Node root) { if root<>nil { Postorder(root.left); Postorder(root.right); if terminal(root.data) { emit("push "+data); else emit(data); } }}

push apush 3push bpush aaddmulassign

Generierte Sequenz mitsymbolischen Operationen

Page 10: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

10Compilerbau – SS 2020 – Teil 6/AST

Aufbau eines Syntaxbaumes (Beispiel) I

class Node { enum type; ref Node left; ref Node right; Node(type,left,right) { Konstruktor... }}

Klasse für binäre Bäume

+

b a

p1:= new Node(ID,nil,nil); // bp2:= new Node(ID,nil,nil); // aroot:= new Node(plus,p1,p2);

� Aufbau erfolgt Bottom-Up: erst die Blätter, dann die Unterbäume, dann der Baum

� Verknüpft wird das Ganze im übergeordneten Knoten.

� In dem Beispiel werden die Namen der beiden IDs ("a" und "b") nicht abgespeichert; dazu ist eine Symboltabelle nötig.

Page 11: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

11Compilerbau – SS 2020 – Teil 6/AST

Aufbau eines Syntaxbaumes (Beispiel) II

� Damit lässt sich explizit programmiert ein Baum aufbauen.

� Aber wie soll dies Daten-gesteuert gehen?

� Dazu wird ein kleine Aufbausprache entworfen, die durch die Postordner-Traversierung generiert wird.

� Diese Sprache wird dann zum späteren Aufbau des Baums interpretiert.

� Beispiel: push apush 3push bpush aaddmulassign

Page 12: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

12Compilerbau – SS 2020 – Teil 6/AST

Aufbau eines Syntaxbaumes (Beispiel) III

� Das ist hier nun das Skelett eines Interpreters.

� Am Ende liegt auf dem Stack die Adresse der Wurzel des Baums.

push apush 3push bpush aaddmulassign

(01) while not eof {(02) cmd:= read(); // Scanner vereinfacht(03) switch(cmd) {(04) case push: push(new Node(Operand));(05) case add: op1:= pop();(06) op2:= pop();(07) push(new Node(add,op1,op2));(08) case mul: op1:= pop(); (09) op2:= pop();(10) push(new Node(mul,op1,op2));(11) case assign: op1:= pop(); (12) op2:= pop();(13) push(new Node(assign,op1,op2));(14) }(15) }

Page 13: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

13Compilerbau – SS 2020 – Teil 6/AST

AST und rekursiver Abstieg I

expr

expr

id

term

factor

id id+ *

term

factor

term

factor

+

id

*id

id

Abstrakter SyntaxbaumParsebaum mit allen beteiligten Regeln

� Jeder Knoten entspricht (fast immer) einer Regel.

� Ausnahmen: Regeln haben keine terminalen Kinder, die den Operationen entsprechen.

Page 14: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

14Compilerbau – SS 2020 – Teil 6/AST

Eine Entscheidung

� Es wird statt der Adresse des Unterbaums ein NULL/NIL geliefert.

� Der Unterbaum wird verworfen; stattdessen wird ein Error-Knoten mit Diagnose-Information geliefert.

Wie werden syntaktische Fehler behandelt?

� Error sei eine Klasse, deren Objekte jeweils einen Fehler beschreiben.

� Diese Objekte können anstelle jeden Knotens geliefert werden, d.h. sie werden gestreut in den Syntaxbaum eingebaut.

� Über eine globale Variable gesteuert wird später der Baum verworfen.

Page 15: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

15Compilerbau – SS 2020 – Teil 6/AST

AST und rekursiver Abstieg II

func ref node rule1() { if(token in FIRST(rule1) { ref Node left:= rule2(); if token="+" { eat("+"); else return Error("+ missing"); } ref Node right:= rule3(); return new node("+",left,right); else return Error("FIRST(rule1) missing"); }}

rule1= rule2, "+", rule3;

Es wird in der eigenenRegel auf die korrektenFirst-Token geprüft.

Auch wird dort, wo derFehler festgestellt wird,die Fehlerbehandlungdurchgeführt.

Die Adressen der Unter-bäume werden hier nichtals Parameter sondernals Funktionsresultategeliefert.

Page 16: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

16Compilerbau – SS 2020 – Teil 6/AST

AST und rekursiver Abstieg III - Verkürzungen

� Die Fehlerbehandlung error() gibt hier lediglich eine Meldung aus. Diese wird noch mit lexikalischer Information (Dateiname, Zeile, Spalte) ergänzt.

� Besser ist es, wenn eine "Stop-Menge" von Token als Parameter mit gegeben werden. Im Fehlerfall werden dann alle folgenden Token überlesen bis eines aus dieser Menge gefunden wird.

func bool eat(Token tk) { if token=tk { getNextToken(); return true; else return false; }}

Class Error(String s) ... { ... process error ... print(s); return this;}

proc error(String s) { ... process error ... print(tk+" missing"); return nil;}

Page 17: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

17Compilerbau – SS 2020 – Teil 6/AST

AST und rekursiver Abstieg IV - Verkürzungen

rule1= rule2, "+", rule3;

Schon etwaskürzer undüberschaubarer.

func ref node rule1() { if(token in FIRST(rule1) { ref Node left:= rule2(); if not eat("+") { return Error("+ missing"); } ref Node right:= rule3(); return new node("+",left,right); else return Error("FIRST(rule1) missing"); }}

Page 18: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

18Compilerbau – SS 2020 – Teil 6/AST

Behandlung von Fehlern I

� Im Fall1 sollte alles bis zum "then" überlesen werden; sollte dies auch fehlen, dann bis zum "fi".Die Stop-Menge ist hier: ["then","fi"], wobei die vorderen Elemente Priorität gegenüber den hinteren haben.Das Überlesen erfolgt in der If-Regel so, dass halbwegs sinnvoll weiter gemacht werden kann.

� Im Fall2 sollte bis zum ";" überlesen werden. Hier wird die Assignment-Regel beendet, so dass sinnvoll vom Aufrufer her weiter gemacht werden sollte, z.B. mit einer anderen Alternative.Die Stop-Menge ist hier: [";","if","while","od","fi","end"],

... if a+<10 then a:= b+c;fi

... a:= (b+c)*c);

Fall1 Fall2

Page 19: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

19Compilerbau – SS 2020 – Teil 6/AST

Behandlung von Fehlern II

� Die Bestimmung der Stop-Menge hängt stark von den Regeln und deren verschachtelte Aufrufen ab.

� Häufig ist auch noch eine Skip-Menge erforderlich: Solange ein Element aus dieser Menge gefunden wird, dann wird weiter überlesen.

� Bitte beachten, dass die vorhandene Aufrufschachtelung nach dem Überlesen abgebaut sein muss. Das ist nicht einfach zu lösen, da dann ein „schneller return-Durchlauf“ bis zu einem Wiederaufsetzpunkt realisiert werden muss.

� Exceptions sollten nur dann benutzt werden, wenn der Parser interne Fehler hat, z.B. zu wenig Speicher.

� Auf der anderen Seite werden durch Exceptions viele If-Abfragen gespart.

Page 20: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

20Compilerbau – SS 2020 – Teil 6/AST

AST und rekursiver Abstieg V - Hinweise

� Immer wenn ein Token verarbeitet ist, wird um 1 Token weiter geschaltet (eat()).

� In der Regel-Funktion wird die Rechtmäßigkeit des Aufrufes geprüft.– Weniger, einfacher Code

– Schlechte Fehlerbehandlung

� Aber:Es sollten nie Funktionen mit Seiteneffekten programmiert werden – hier geht das nicht anders.

Page 21: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

21Compilerbau – SS 2020 – Teil 6/AST

AST und rekursiver Abstieg VI - Hinweise

� Es besteht auch die Möglichkeit Daten von oben nach unten zu transportieren: per Parameter.

� Da komplexere Konstrukte, wie z.B. Prozeduren oder Klassen, über mehrere syntaktische Regeln aufgeteilt definiert werden, bedeutet dies aber, dass nicht zu jeder dieser "Hilfsregeln" ein eigener Knoten erzeugt wird.

� Es gibt dann die Möglichkeit, dass ein Knoten von der umfassenden Regelfunktion, z.B. Funktion, erzeugt und unvollständig als Parameter an anderen Routinen gegeben wird, die die fehlenden Teile ergänzen.

� Der Parameter ist dann der Kontext.

ParameterReferenz aufUnterbaumoder Error

Page 22: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

22Compilerbau – SS 2020 – Teil 6/AST

Implementierungshinweise (primär für Java)

� Die Tokentypen werden durch eine enum-Klasse definiert.

� Bei den Mengenabfragen ("token in FIRST(T)") werden konstante Set-Objekte vom Typ EnumSet benutzt (Singletons).

� Aus Gründen der Verständlichkeit sollten alle Mengenabfragen in Methoden gekapselt werden:boolean isRuleXYZ().

� Das gilt auch für die Stop-Mengen.

� Wenn die Methoden genauso wie die Regeln heißen würden, kann es Konflikte mit Bibliotheksroutinen geben. Daher wird "rule" vor den Namen der Regel gesetzt: z.B. ruleStatement.

Wenn Generatoren wie Coco/R benutzt werden, sind das allesProbleme der Implementierer dieser Generatoren.

Page 23: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

23Compilerbau – SS 2020 – Teil 6/AST

Knoten des Syntaxbaumes I

� Es besteht die Möglichkeit, n-äre Knoten als Listen von binären darzustellen, z.B. für Ketten von Statements.

� Dies hat den Vorteil, dass die Liste innerhalb des Knotens stückweise aufgebaut werden kann, anstatt zum Beginn ein Array mit einer geschätzten Größe anzulegen.

k

a dcb

k1 k

2k3

k4

a dcb

Page 24: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

24Compilerbau – SS 2020 – Teil 6/AST

Knoten des Syntaxbaumes II

class PlusOp { type t= plusOp; ref Node left; ref Node right;}

class IfStatm { type t= IfStatm; ref Node expression; ref Node thenPart; ref Node elsePart;}

Zwei Beispielefür Knotentypen

struct node { type t; union { struct { struct *node left, struct *node right } PlusOp; struct { struct *node expression, struct *node thenPart struct *node elsePart } IfStatm; };};

Eine möglicheRealisierung in C/C++

Dies ist nichttypsicher.

Page 25: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

25Compilerbau – SS 2020 – Teil 6/AST

Knoten des Syntaxbaumes III

type node = record t : typ; case nt : typ of PlusOp: ( left : node; right : node; ) IfStatm: ( expression : node; thenPart : node; elsePart : node; ) end;

Eine möglicheRealisierung in Pascal

� Dies ist auch nicht typsicher, aber es gibt immerhin einen Deskriptor, der zur Laufzeit bei Zugriffen geprüft werden könnte: nt.

� Wird dies immer getan, wie z.B. in Ada, dann sind diese Konstruktionen typsicher.

Page 26: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

26Compilerbau – SS 2020 – Teil 6/AST

AST für Plong I - Vorgehen

� Anhand der Grammatik wird der AST entworfen.

� Durch Spezialisierung wird ein Klassenmodell entwickelt; dies gilt für Programmiersprachen mit Vererbung.

� Für Sprachen ohne Vererbung werden Strukturen mit Unions benutzt.

Page 27: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

27Compilerbau – SS 2020 – Teil 6/AST

AST für Plong II - Deklarationen

AbstrakteMutterklasse Klasse für

alle Deklarationen

Aufzählung derbeiden Typenint und StringVererbungshierarchie für Deklarationen.

Page 28: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

28Compilerbau – SS 2020 – Teil 6/AST

Bemerkungen I

� Eine Kette von Deklarationen wird durch eine lineare Liste dargestellt. In jedem Element wird eine Variable deklariert.

� DeclType wird der Datentyp – hier in Plong: int und String – dargestellt. Dies wird durch einen Aufzählungstyp erreicht.

� DeclID repräsentiert den Namen als terminales Symbol.

int a, b, c;

DeclVar

DeclType ID

int a

DeclVar

DeclType ID

int b

DeclVar

DeclType ID

int c

Beispiel

Page 29: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

29Compilerbau – SS 2020 – Teil 6/AST

Bemerkungen II – Deklaration von Prozeduren

� Beachten Sie, dass es lokale Prozeduren oder Funktionen gibt.

� Die drei Punkte deuten eine Liste wie bei den Parametern an.

DeclProc

ID

Name

DeclParam

DeclType ID

Typ Parameter

DeclParam

DeclType ID

ParameterTyp

...

DeclVar DeclProc DeclFunc... ...

proc Name(Param, Param) … begin … end

Stmt ...

Prozeduren undFunktionen werdengemischt in derDeklarationsreihen-folge dargestellt.

Page 30: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

30Compilerbau – SS 2020 – Teil 6/AST

Bemerkungen III – Deklaration von Funktionen

� Eine Funktion sieht genauso aus wie eine Prozedur, nur das ein Typ für den Rückgabewert angegeben wird.

DeclFunc

ID

Name

DeclParam

DeclVar DeclProc DeclFunc... ...

DeclType

Typ

Stmt ...

func typ Name(Param, Param) … begin … end

DeclType ID

ParameterTyp

DeclParam

DeclType ID

ParameterTyp

...

Page 31: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

31Compilerbau – SS 2020 – Teil 6/AST

Bemerkungen IV - Program

� Das gesamte Programm sieht wie eine parameterlose Prozedur aus.

� Es ist erkennbar, wie sich die Struktur der Grammatikregeln sich in der Struktur des Ableitungsbaums niederschlägt.

ID

Name

DeclVar DeclProc DeclFunc... ...

program Name() … begin … end

Stmt ...

DeclProgram

Page 32: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

32Compilerbau – SS 2020 – Teil 6/AST

AST für Plong III - Statements

Vererbungshierarchie für Statements.

Page 33: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

33Compilerbau – SS 2020 – Teil 6/AST

Bemerkungen I

StmtAssign

DeclID

Variable

ID Expr

Variable := Expression;

Expression

StmtReturn

Expr

return Expression;

Expression

Page 34: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

34Compilerbau – SS 2020 – Teil 6/AST

Bemerkungen II

� Ein Block von Statements wird durch eine Liste von Stmt-Knoten definiert.

� Analog bildet eine Liste von Expressions die Parameterliste einer aufgerufenen Routine.

call Name(Expr, Expr, ...);

StmtCall

DeclID

Name

ID ExprParam

Expression

...

if Expr then Statem1 else Statem2 fi

Expr

Expression

...Stmt

StmtIf

...Stmt

Statem1 Statem2

Page 35: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

35Compilerbau – SS 2020 – Teil 6/AST

Bemerkungen III

while Expr do Statements od

Expr

Expression

...Stmt

StmtWhile

Statements

Page 36: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

36Compilerbau – SS 2020 – Teil 6/AST

AST für Plong IV - Ausdrücke

Page 37: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

37Compilerbau – SS 2020 – Teil 6/AST

Bemerkungen I - Blätter

� Es gibt keinen Unterschied zwischen ExprID und DeclID, außer dass es einen anderen Kontext gibt.

� Aber: es kann sein, dass eine benutzte Variable (ExprID) nicht deklariert ist (DeclID).

� ExprInt beinhaltet den Integerwert selbst, genauso wie ExprString den String selbst beinhaltet.

Variable

Variable

ID

Integer String

Value

ExprInt

Value

ExprString

Page 38: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

38Compilerbau – SS 2020 – Teil 6/AST

Bemerkungen II

� Die Typanpassungsfunktionen (Coercions) werden wie vorher deklarierte Funktionsaufrufe behandelt.

� Auf dieselbe Weise werden auch die anderen vordefinierten Routinen behandelt: writeln(), readln()

Name(Expr, Expr, ...);

ExprFunc

DeclID

Name

ID ExprParam

Expression

...

int string2int(String);String int2string(int);

ExprFunc

DeclID

string2intint2string

ID ExprParam

Expression

Page 39: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

39Compilerbau – SS 2020 – Teil 6/AST

Typanpassungen allgemein I

� Coercion = (Hier:) Funktion, die einen Typ in einen anderen durch Berechnung zur Laufzeit konvertiert.

� Cast = (Hier:) Anweisung an den Compiler ein bestehendes Bitmuster (Variablenwert) als einen bestimmten Typ anzusehen, d.h. keine "aktiven" Umrechnungen

� In anderen Programmiersprachen wird dies anders definiert.

� Siehe– https://en.wikipedia.org/wiki/Type_conversion

– https://de.wikipedia.org/wiki/Typumwandlung

Page 40: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

40Compilerbau – SS 2020 – Teil 6/AST

Typanpassungen allgemein II

� Typerweiterungen = type promotion = Wert eines Typs als Wert eines umfassenden Typs ansehen bzw. dorthin konvertieren

� Typeinschränkung = type demotion = Wert eines Typs als Wert eines verkleinerten Typs ansehen bzw. dorthin konvertieren

Typeinschränkung

int i = 42;byte b = (byte) i;

float f = 3.0;int j = f;

Typerweiterung

byte b = 42;int i = (int) b;

int j = 42;float f = j;

Normalerweise kein Genauigkeitsverlust

Eventuell ein Genauigkeitsverlust

Was wäre, wennhier 3.141stehen würde?

Page 41: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

41Compilerbau – SS 2020 – Teil 6/AST

Bibliotheksroutinen - Übersicht

Signatur Erläuterung

int string2int(String); String int2string(int);

Konvertierungsroutinen

String stringConcat(String,String) Realisierung der String-Addition

proc write(String s)proc writeln(String s)

Ausgaberoutinen

int readInt()String readString()proc readln()

Einleseroutinen

bool notEOF() Anzeige des EOF/EOI-Status

Page 42: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

42Compilerbau – SS 2020 – Teil 6/AST

Bemerkungen III - Arithmetik

Expr, "+", Expr ;

ExprDyadic

DeclID

Left

Expr Expr

Right

ExprMonadic

Expr

Expression

"+", Expr ;

enum MonadicOp { plus, // + minus, // -}

enum DyadicOp { plus, // + minus, // - mul, // * div, // /

eq, // = ne, // <> ge, // >= gt, // > le, // <= lt, // <}

Page 43: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

43Compilerbau – SS 2020 – Teil 6/AST

Grundsätzliche Ergänzung I

� Damit der AST später nicht rekursiv traversiert werden muss, erhalten alle Knoten in der abstrakten Klasse AST einen Zeiger zum Elternknoten, also hin zur Wurzel.

� Bei der Wurzel ist dieser Zeiger immer null.

� Hinweis: Wenn ein Zeiger zurück zum Elternknoten existiert, reicht eine einfache Schleife zum Traversieren des Baums.

Page 44: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

44Compilerbau – SS 2020 – Teil 6/AST

Grundsätzliche Ergänzung II - Beispiel

program = "program", id, "(", ")", body ;procDecl = "proc", id, "(", [paramDecls], ")", body ;funcDecl = "func", ( "int" | "String" ), id, "(", ..., ")", body ;body = { varDecl }, { subDecl }, "begin", { ... }, "end" ;

DeclID

DeclVar DeclProc DeclFunc... ... ...

Stmt ...

DeclProgram

body

Diesen Knoten gibt es nicht im Syntaxbaum.

Page 45: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

45Compilerbau – SS 2020 – Teil 6/AST

Grundsätzliche Ergänzung III - Beispiel

� Wenn also mehrere Aufrufe von verschiedenen Routinen erst den gesamten Knoten erzeugen, dann werden die teilweise gesetzten Knoten per Parameter zur Weiterverarbeitung den anderen Routinen übergeben.

� Dann entsteht die richtige Struktur:

DeclID DeclVar DeclProc DeclFunc... ...

program Name() … begin … end

Stmt ...

DeclProgram

Page 46: Compilerbau Teil 6: Abstrakter Syntaxbaumwi.f4.htw-berlin.de/users/messer/LV/AI-Compilerbau-SS20/...Compilerbau – SS 2020 – Teil 6/AST 6 Beispiel I - Zuweisung Es handelt sich

46Compilerbau – SS 2020 – Teil 6/AST

Nach dieser Anstrengung etwas Entspannung...