Folienkopien zur Vorlesung Übersetzung objektorientierter

Werbung
Folienkopien
zur
Vorlesung
1
Einleitung
1.1 Ein Blick auf den Übersetzungsprozeß
1.2 Aufgaben eines Compilers
Übersetzung
objektorientierter Sprachen
1.3 Aufgaben eines Compilerbauers
1.4 Struktur eines Compilers
1.5 T-Diagramme
1.6 Grobe Historie des Compilerbaus
Martin Lehmann
Wintersemester 2007/2008
1.7 Zusammenfassung
Beispiel einer Übersetzung:
Zielarchitektur: Einfache Registermaschine
Aufgabe: Berechnung des größten gemeinsamen Teilers
zweier natürlicher Zahlen.
Seien a, b ∈ N :
Register
R0
R1
R2
M
Hauptspeicher
0
1
2
..
.
..
.
falls a = b
⎧ a,
⎪
ggT(a, b ) = ⎨ ggT(a − b, b ), falls a > b
⎪ ggT(a, b − a ), falls a < b
⎩
Formulierung in einer algorithmischen Sprache:
a
b
..
.
ggT (a, b: natural) =
begin
while a ≠ b do
if a > b then
a := a – b
else
b := b – a;
return a
end;
Programm
..
.
Schritte bei der Übersetzung der Schleife:
1.
2.
Bildung des Strukturbaums:
Bildung der Lexeme
hier: nur für den Schleifenkörper
Symbol
Klasse
while
a
≠
b
do
if
a
>
b
then
a
:=
a
–
b
else
b
:=
b
–
a
;
Schlüsselwort
Bezeichner
Vergleichsoperator
Bezeichner
Schlüsselwort
Schlüsselwort
Bezeichner
Vergleichsoperator
Bezeichner
Schlüsselwort
Bezeichner
Zuweisungsoperator
Bezeichner
Additionsoperator
Bezeichner
Schlüsselwort
Bezeichner
Zuweisungsoperator
Bezeichner
Additionsoperator
Bezeichner
Trennsymbol
Bemerkung: Formatierungszeichen wurden entfernt.
Grammatikfragment für Quellsprache:
..
.
Anweisung
::= "while" Ausdruck "do" Anweisung
| "if" Ausdruck "then" Anweisung
| "if" Ausdruck "then" Anweisung
"else" Anweisung
| Zuweisung
| ...
Ausdruck
::= Ausdruck Operator Ausdruck
| Variable
| Konstante
| ...
Operator
::=
|
|
|
Additionsoperator
Multiplikationsoperator
Vergleichsoperator
...
Vergleichsoperator
..
.
::= "=" | "≠" | "<" | "≤"
| ">" | "≥"
Ausschnitt aus Strukturbaum:
3.
Transformation des Strukturbaums, Attributierung:
while : Schleife, Ende
Anweisung
Vergleich : ≠
while
do
Ausdruck
Anweisung
...
Ausdruck
Operator
if : Else, Ifende
Variable
: a
Variable
: b
Ausdruck
Vergleich : >
Zuweisung
Zuweisung
..
.
Variable
a
Vergleichsoperator
Variable
≠
b
Variable
: a
Variable
: b
Variable
: a
Variable
: a
Summe
: –
Variable
: b
4.
Einfache schablonengesteuerte Codeerzeugung:
Erzeugter Code:
Codeerzeugung mittels Schablonensatz:
Schleife:
Vergleich: ≠
A
load
sub
jnpos
R1, a
R1, b
Else
load
sub
store
jump
R1, a
R1, b
R1, a
Ifende
Else:
load
sub
store
R1, b
R1, a
R1, b
Ifende:
jump
Schleife
R?, A
R?, B
M?
Load
Sub
jnpos
R?, A
R?, B
M?
B
M
Summe: +
A
R1, a
R1, b
Ende
B
Vergleich: <
A
Load
Sub
jzero
load
sub
jzero
Load
Add
R?, A
R?, B
; jump on not positive
Ende:
B
Bemerkung: Es wird angenommen, daß das
analysierte Programm korrekt ist,
daher keine Berücksichtigung möglicher
Fehlrechnungen.
Bemerkung: In der Regel werden Codeschablonen umgebungsunabhängig eingesetzt. Der erzeugte
Code bedarf daher der nachträglichen
Glättung.
5a. Codeoptimierung, hier: Gucklochoptimierung:
5b. Codeoptimierung, hier: Flußgraphbetrachtung:
Ersetzen von Befehlen und Befehlsfolgen durch vermutlich
aufwandsärmere:
Schleife:
Else:
Ifende:
Ende:
load
sub
jzero
R1, a
R1, b
Ende
load
sub
jnpos
R1, a
R1, b
Else
; Berechnung schon
; erfolgt
load
sub
store
jump
R1, a
R1, b
R1, a
Ifende
; Berechnung schon
; erfolgt
jump
Schleife
load
sub
R1, b
R1, a
store
R1, b
jump
Schleife
load
sub
store
R1, a
R1, b
R1, a
; Vermeidung von
; Sprungkaskaden
;
;
;
;
;
Ersetzen dieser
zwei Befehle durch
neg R1
liegt außerhalb der
Gucklochoptimierung
load
sub
store
; Marke wird nicht
; mehr benötigt.
Problem: Lohnt der Aufwand?
R2, b
R2, a
R2, b
Zielcode für die Schleife auf einer Mehrregistermaschine:
Schleife:
load
sub
jzero
R1, a
R1, b
Ende
jnpos
Else
Aufgaben eines Compilers:
Fehlerangaben
Quelltext
Else:
store
jump
R1, a
Schleife
load
sub
store
R2, b
R2, a
R2, b
jump
Schleife
Ende:
(ii)
Verletzungen von
Implementationsgrenzen
Zielcode
Eigenschaften des Zielcodes:
Bemerkungen:
(i)
Compiler
Die algorithmische Formulierung zur Berechnung des größten gemeinsamen Teilers ist
nicht vorbildlich.
Der erzeugte Code ist nicht optimal.
1.
Bedeutungstreue Realisierung des Quelltextes.
2.
Ökonomische Nutzung der Ressourcen des
Zielrechners.
Eigenschaft der Beanstandungen:
Genaue Angabe, in welchen Teilen der Quelltext
die Sprachdefinition oder die Implementationsbeschränkungen verletzt.
Aufgaben eines Compilerbauers:
Aufgabenunterteilung:
Compiler
⇓
1.
Erstellung von Compilern.
Analyse
2.
Verbesserung von Compilern.
3.
Verbesserung der Erstellung von Compilern.
4.
Beschreibung von Compilern.
5.
Entwurf von Programmiersprachen.
6.
Entwurf von Rechnern.
Synthese
⇓
Analyse
der Form
Analyse
des Inhalts
Synthese
⇓
Lexikalische
Aufbereitung
Syntaxanalyse
Semantikanalyse
Codeerzeugung
⇓
Bemerkung: Gegeben seien eine Beschreibung der
Quellsprache S, eine Beschreibung der
Zielsprache T und Randbedingungen;
wieweit darf die in einem Compiler
implementierte Sprache S' von der
Originalsprache S abweichen?
Aufbereitung der Eingabe
Lexikalische Analyse
Syntaxanalyse
Analyse der statischen Semantik
Speicherplatz-Zuweisung
Erzeugung eines Universalcodes
Verbesserung des Universalcodes
Erzeugung zielnahen Codes
Verbesserung des zielnahen Codes
Aufbereitung der Ausgabe
Abstraktes Compilermodell:
Zweiteilung eines Compilers:
Quelltext
Lexikalische Analyse
Code
für
abstrakte
Maschine
Quelltext
Zwischentext-1
Zielcode
Syntaktische Analyse
Zwischentext-2
Semantische Analyse
sprachabhängiger
Teil
maschinenabhängiger
Teil
Zwischentext-3
Optimierung
Analyse:
Hauptaufgabe
Analyse:
trivial
Zwischentext-4
Codeerzeugung
Zieltext
Codeerzeugung:
trivial
Codeerzeugung:
Beschreibung mittels
eines kleinen
Schablonensatzes
Das n Sprachen, m Maschinen Problem,
auch UNCOL – Problem:
Front-ends
Back-ends
Sprache
1
Maschine
1
Sprache
2
Sprache
3
..
.
Sprache
n
Beispiele zur Struktur von Compilern:
Maschine
2
Darstellung
des
semantischen
Inhalts
..
.
Maschine
m–1
Maschine
m
Bemerkung: Bisher ist jeder Versuch einer allgemeinen
Lösung gescheitert.
(i)
Phasen des Gier-Algol-Compilers:
1
Übertragung in Hardware-Repräsentation
2
Ersetzung der Bezeichner durch Zahlen
3
Syntaxanalyse
4
Aufbau der Symboltabelle
5
Speicherzuweisung für Variable
6
Typprüfung und Überführung in
Polnische Notation
7
Codeerzeugung
8
Endgültige Adreßfestlegung
9
Umordnung der Programmteile auf
Trommel
(ii)
Aufbau des Fortran-Übersetzers von Backus
und Mitarbeitern:
(iii)
Gliederung des York Ada-Compilers
Zeilen Quellcode
(C-Code)
Phasengröße
Phasenaufgabe
5500 Instr.
Klassifizierung der Anweisungen,
Übersetzung arithmetischer
Formeln, Teilausgabe nach Datei 1.
6000 Instr.
Übersetzung von Indizes
innerhalb von Schleifen,
Ausgabe nach Datei 2.
2500 Instr.
Zusammenführen von Datei 1
und Datei 2.
3000 Instr.
Flußanalyse.
5000 Instr.
Abbildung des übersetzten
Textes auf Maschine mit
3 Indexregistern (IBM 704).
2000 Instr.
Endbehandlung.
Lexikalische und
syntaktische Analyse
davon lexikalische Analyse
Analyse der statischen
Semantik
davon
Deklarationsbearbeitung
Ausdrucksbearbeitung
Codeerzeugung
davon
maschinenunabhängig
maschinenabhängig
Laufzeitunterstützung
davon
allgemein
Bibliothekscode
5.221
461
40.178
10.835
14.831
31.248
24.319
5.376
17.813
3.514
14.399
Darstellung von Compilern als T-Diagramme:
Die Erstellung eines Compilers für die Sprache S läßt sich
als iterativer Vorgang betrachten.
Name
Zielsprache
Quellsprache
1.
Definiere Folge von Teilsprachen.
S 0 < S1 < S
Implementationssprache
2.
Schreibe Übersetzer.
S
3
S1
Einsatz:
Quellprogramm
S
Z
S1
2
S0
N
Z
Q
I
Zielprogramm
Z
S0
4
Z
Z
1
Z
Z
Um den gewünschten Übersetzer 4 zu erhalten,
sind 1, 2 und 3 zu schreiben.
Situation des eigenständigen "bootstrap":
Drei Perioden des Compilerbaus:
Periode 1: 1945 – 1960
Gegeben:
Hauptaugenmerk: Codeerzeugung.
1
Q
Q
ZC
Q
2
ZC
3
ZC
ZC
Q
Interpreter für
Zwischencode
Es galt für einfache syntaktische und semantische
Konstrukte hervorragenden Zielcode zu erzeugen. Es
galt zu demonstrieren, daß übersetzte Hochsprachenprogramme bezüglich Speicherplatz und Laufzeit den
Assemblerprogrammen ebenbürtig sind. Das leuchtende Beispiel für exzellenten Code ist der frühe
Fortran-Compiler (1954).
Periode 2: 1960 – 1975
Vorgehen:
Hauptaugenmerk: Syntaxanalyse.
Q
Q
1a
Q
Manuelle
Anpassung
M
Q
1a
Q
2
comp
Q
M
cpz
Q
ZC
M
ZC
ZC
3a
ZC
3a
ZC
M
M
M
M
gewünschter
Compiler
Diese Zeit war geprägt von dem Wissen, daß die
Leistungsfähigkeit von Rechnern exponentiell
zunimmt. Daher galt es, programmierfreundliche
mächtige Notationen automatisch zu analysieren. Die
Güte des erzeugten Codes wurde als zweitrangig
betrachtet. Wichtig war die Produktivität des
Programmierers.
Periode 3: 1975 – heute
Hauptaugenmerk: Codeoptimierung.
Die Zahl der strukturunterschiedlichen Rechner
reduziert sich erheblich. Die Investitionen in
Codeverbesserungen sind daher dauerhaft.
Beispiel zur Codeoptimierung:
Übersetzung als allgemeine Texttransformation:
Umbenennung der Register:
ursprünglich:
mov
mul
mov
mov
add
mov
[mem01], R2
R2, "6", R2
R2, [mem02]
[mem03], R2
R2, "7", R2
R2, [mem04]
Text Q
in
Quellsprache
Text Z
in
Zielsprache
Compiler
Beispiele:
Pascal
Intel 8086-Code
C
Assemblercode
Fortran
Fortran
Pascal
C
Postscript
Druckseite
HTML
Webseite
geändert:
mov
mul
mov
mov
add
mov
{mov
[mem01], T1
T1, "6", T1
T1, [mem02]
[mem03], T2
T2, "7", T2
T2, [mem04]
T2, R2} // eventuell ?
Bemerkung: Diese Art der Codeverbesserung wird
heutzutage von der Hardware ausgeführt,
Ti sind verborgene Hardware-Register.
Übersetzerarten:
Assembler
Zur Interpretation:
Quellcode
Makro-Assembler
Compiler
Präprozessor
Disassembler
Decompiler
Zwischencode
Interpretation
Objektcode
Ausführung
Interpreter
Bemerkung: Ein Decompiler wird eingesetzt, um aus
Objektcode einen Hochsprachentext zu
gewinnen, der den compilierten Algorithmus beschreibt. Dies kann sinnvoll sein,
um verloren gegangene Quelltexte zu
rekonstruieren oder um Malware zu
analysieren. Der Einsatz eines Decompilers
ist eine Form des Reverse Engineering.
Automatisierung der Compilererstellung:
Beschreibung
der
Quellsprache
Q
Beschreibung
der
Zielsprache
Z
Beschreibung
der
Implementationssprache
I
C
O
M
P
I
L
E
R
–
G
E
N
E
R
A
T
O
R
Q
→
I
Bemerkung: Für die einzelnen Teile eines
Compilers kennt man zugkräftige
Beschreibungsmittel.
Z
Herunterladen