Grundlagen der Programmierung 2 (Comp-A)

Werbung
Grundlagen der Programmierung 2
(Comp-A)
Prof. Dr. Manfred Schmidt-Schauß
Künstliche Intelligenz und Softwaretechnologie
16. Mai 2012
Compiler; Übersetzungsprogramme
Ein Übersetzer (Compiler) ist ein Programm, das
ein Wort einer formalen Sprache S1 (den Quelltext)
in ein Wort einer anderen formalen Sprache S2 (den Zieltext)
umwandelt,
wobei die Semantik erhalten bleibt.
Beispiele: Programme in Haskell, Java, Python, oder PASCAL,
werden in Maschinenkode, C, Assembler, oder Bytecode übersetzt.
LaTex-Eingaben werden in eine PDF-Datei (bzw. ps-Datei) übersetzt
Grundlagen der Programmierung 2 (Comp-A)
- 1 -
Compiler für Programmiersprachen
Ein Compiler ist ein Programm, das
ein S1-Programm (das Quellprogramm)
in ein S2-Programm (das Zielprogramm) umwandelt,
wobei die (operationale) Semantik erhalten bleibt
Grundlagen der Programmierung 2 (Comp-A)
- 2 -
T-Diagramme nach N. Wirth
S1
→
S2
S3
S1
→
S2
S3
S3 Intp
Übersetzung von S1 nach S2
Programm ist geschrieben in S3
Im rechten Diagramm: ein Interpreter für S3 ist vorhanden.
⇒ Compiler kann ausgeführt werden.
Grundlagen der Programmierung 2 (Comp-A)
- 3 -
Zusammensetzen von Compilern:
S1
→
S2
→
S2
S4
S5
S4 Intp
S5 Intp
S3
Hintereinanderausführung:
übersetzt S1 → S3,
falls S4 und S5-Interpreter vorhanden sind.
Grundlagen der Programmierung 2 (Comp-A)
- 4 -
Zusammensetzen von Compilern:
S1
→
S2
S4
S4
→
S6
S1
→
S5
S5
S2
S5 Intp
S6 Intp
das rechteste (blaue) T-Diagramm steht für den resultierenden Compiler
Konstruierbar:
lauffähiger Übersetzer von S1 nach S2
der nur einen S5-Interpreter benötigt
Grundlagen der Programmierung 2 (Comp-A)
- 5 -
T-Diagramme; Anwendung: Bootstrapping
Konstruktion eines Compilers für Programmiersprache Pneu
möglichst viel bereits in Pneu geschrieben.
1.
2.
3.
PL
Pneu ,Core -Compiler für einen kleinen Ausschnitt
Pneu,L-Übersetzer nach Pneu ,Core , geschrieben in Pneu ,Core
Pneu,L- Compiler zusammensetzen ; (Resultat: blau)
→ PCore
PCore PCore →
PL
→ PCore PCore →
C
C
C
C
C Intp
C Intp
C Intp
C
PL
→
C
C Intp
Grundlagen der Programmierung 2 (Comp-A)
- 6 -
C
Anwendung der T-Diagramme: Bootstrapping
Darauf aufbauend, kann man weiter konstruieren, Resultat dunkelblau
PXXL →
PL
PL
PL
PXXL →
→
C
PL
PL
→
C
PXXL →
C
C
C
C Intp
C Intp
C Intp
C
C Intp
Resultat:
Ein Compiler, der die volle Sprache PXXL übersetzt.
und bei dem ein großer Teil in PL geschrieben ist.
Grundlagen der Programmierung 2 (Comp-A)
- 7 -
C
Phasen eines Compilers
Lexikalische Analyse (Scanning): Text des Programms wird in Tokenstrom umgewandelt
Syntaxanalyse (Parsing): Tokenstrom wird entsprechend der Grammatik in einen Syntaxbaum transformiert
Semantische Analyse: Typcheck, Scope von Variablen, . . .
Zwischencode-Erzeugung: Generierung von Code für eine abstrakte
Maschine
Codeoptimierung: Verbesserung des Zwischencodes
Code-Erzeugung: Erzeugung des Ausgabe-Programms (z.B. in C,
Assembler)
Grundlagen der Programmierung 2 (Comp-A)
- 8 -
Beispiele zu den Phasen
Lexikalische Analyse
Z.B. IF 13 == X1 THEN A “ wird zu:
”
(’IF’, 13, ==, ’X1’, ’THEN’,’A’)
Syntaxanalyse (Parsing): Test, ob das Programm der Grammatik
entspricht. Umwandlung in Herleitungsbaum, dann in Syntaxbaum:
Z.B. (’IF’, 13, ==, ’X1’, ’THEN’, ’A’) wird zu:
ii
iiitittt
i
i
i
iiii tttt
iiii
i
i
tt
i
tii
ytt
II
uu
II
uu
II
u
u
II
uu
I$
u
zu
0 IF0
•
13
==
IFTHEN
NNN
ooo
N
• LULULULULUUUUU
0 X10
LLL UUUUUU
UUUU
L&
UUUU
UU*
0 THEN0
0 A0
oo
ooo
o
o
o
w oo
o
OOO
OOO
OOO
OOO
O'
NNN
NNN
NN&
==
ww
13
ww
ww
w
{w
w
0 A0
0 X10
Semantische Analyse
Typüberprüfungen : Z.B. 1 + ’a’ wird zurückgewiesen.
Sind Variablen / Funktionen / Klassen an der richtigen Stelle deklariert ?
Grundlagen der Programmierung 2 (Comp-A)
- 9 -
Weitere Komponenten
Symboltabelle speichert wesentliche Attribute (Typ, Gültigkeitsbereich, etc.) der Bezeichner des Quellprogramms
Fehlerbehandlung Analyse der Fehler, Lokalisierung,
Meldung an den Benutzer
Evtl. automatische Behebung des Fehlers und Fortsetzung der
Übersetzung
Grundlagen der Programmierung 2 (Comp-A)
- 10 -
Weitere mögliche Phasen
Einleseroutine; Zeichenbehandlung abhängig vom Prozessor bzw.
Betriebssystem
I.a. Standard-Routinen (Einlesen, Zeichenkodierung)
Präprozessor Vorverarbeitung des Quellprogramms
(i.a. Makro-Expansion)
Assembler übersetzt das Assemblerprogramm in Objektcode.
Binder/Lader Umsetzung in ausführbaren Maschinenkode plus Hinzunahme von anderem Objektcode z.B. aus Bibliothek
Grundlagen der Programmierung 2 (Comp-A)
- 11 -
Front-End und Back-End
Aufteilung des Compilers:
Front-End: maschinenunabhängiger Teil
(z.B. Syntaxanalyse, lexikalische Analyse, Typüberprüfung,
Zwischencode-Erzeugung, Zwischencode-Optimierung).
Back-End: maschinenspezifischer Teil
(z. B. I/O, Codegenerierung)
Grundlagen der Programmierung 2 (Comp-A)
- 12 -
Worte, Zeichenketten, formale Sprachen
Gegeben: ein Alphabet Σ
Definitionen:
• Eine Zeichenkette (String) ist endliche Folge von Σ-Symbolen
• ε
bezeichnet den leeren String
• Σ∗: die Menge aller Worte über Σ
• formale Sprache über Σ: Teilmenge von Σ∗
Beispiele
Σ = {a, b, c},
ac, aaaabcc sind Strings über Σ.
Grundlagen der Programmierung 2 (Comp-A)
- 13 -
Beispiele
• Σ = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}:
Die Ziffernrepräsentationen aller natürlichen Zahlen
ist eine formale Sprache über Σ.
Z.B. 111, 7, 3210999, ...
• Σ = {A, . . . , Z, a, . . . , z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ), (, . . .}.
Alle möglichen Haskell-Programme (als Strings) sind eine formale
Sprache über Σ.
Z.B.
main = map quadrat []
Grundlagen der Programmierung 2 (Comp-A)
- 14 -
Kontextfreie Grammatik
Kontextfreie Grammatik: ein Formalismus zum Erzeugen von Mengen
von Worten über einem Alphabet
Bestandteile einer kontextfreien Grammatik:
Nichtterminale
N
Terminale (bzw. Alphabet) T
(Σ)
Produktionen (Regeln)
P
Startsymbol
S
Regeln haben die Form N ::= w,
w ist ein Wort aus Nichtterminalen und Terminalen.
Die Sprache der Grammatik besteht aus allen vom Startsymbol S aus
erreichbaren Worten, die nur aus T -Symbolen bestehen.
Grundlagen der Programmierung 2 (Comp-A)
- 15 -
Grammatik Beispiele
Grammatik zur Erzeugung aller Klammerausdrücke aus + und x:
S ::= x | (S) | (S + S)
erzeugte Worte; Beispiele:
x“
”
(x)“
”
((x))“
”
...
(x+x)“
”
(x+(x))“
”
(x+((x)))“
”
((((x)))+(x))“
”
(((x+(x))+x)+((((x)))))“
”
...
Grundlagen der Programmierung 2 (Comp-A)
- 16 -
Reguläre formale Sprachen: Formalismen
Beschreibungsmöglichkeiten
für reguläre formale Sprachen:
•
reguläre Ausdrücke
•
(rechts- bzw. links-)reguläre Grammatik
•
DEA (deterministischer endlicher Automat): akzeptierte Sprache
•
NEA (nicht-deterministischer endlicher Automat): akzeptierte Sprache
(sind alle äquivalent in folgendem Sinn:
die gleichen formalen Sprachen sind damit definierbar)
Grundlagen der Programmierung 2 (Comp-A)
- 17 -
Reguläre Ausdrücke
Σ sei das Alphabet.
R
::=
a
(R)
ε
RR
R + R
R∗
für a ∈ Σ
Leeres Wort
Konkatinierte Ausdrücke
Auswahl bzw. Vereinigung
beliebige Anzahl Konkatinierungen
Grundlagen der Programmierung 2 (Comp-A)
- 18 -
Reguläre Ausdrücke: Beispiele
0+(1+2+3+4+5+6+7+8+9)(0+1+2+3+4+5+6+7+8+9)∗
positive ganze Zahlen (als Text)
(A + ... + Z)(A + ... + Z + a + ... + z)∗
Worte, die mit Großbuchstaben beginnen
(A + ... + Z)(A + ... + Z + a + ... + z)(A + ... + Z + a + ... + z)
Worte aus drei Buchstaben, die mit Großbuchstaben beginnen
Grundlagen der Programmierung 2 (Comp-A)
- 19 -
Lexikalische Analyse (Tokenizer, Scanner)
Aufgabenteilung:
Zuerst
Dann
Scanner
Parser
(lokale) Zeichen (Symbol-)Analyse
Syntax-Analyse
Aufgaben des Scanners:
•
•
•
Erkennung von: Zahlen, Bezeichner, Namen, Schlüsselworte, Strings
d.h. reguläre Ausdrücke
Aufbau der Symboltabelle
Zeichenstrom → Tokenstrom und Weitergabe an den Parser
Es gibt Scanner-Generatoren (Z.B. lex).
Allerdings ist es oft einfacher, einen Scanner selbst zu schreiben.
Z.B. unter Benutzung endlicher Automaten.
Grundlagen der Programmierung 2 (Comp-A)
- 20 -
Scanner: Etwas genauer
•
•
•
•
Einlesen des Programmtexts als lineare Zeichenkette
Beseitigung von Kommentaren, Leer- und Tabulatorzeichen.
Zusammenfassen von Teilstrings
(Schlüsselworte, Bezeichner, Zahlenwerte, u ä)
Ergebnis: Strom von Token
Ein Token kann bestehen aus:
Markierung:
Attribute:
Üblich:
Art des Tokens
wie String, Zahlwert, Position im Eingabefile.
Eigenes Endetoken für Eingabestrom.
Grundlagen der Programmierung 2 (Comp-A)
- 21 -
Beispiel für Tokens
Eingabe
if
123
x1
∗
<=
Tokenmarkierung
Keyword
Num
Id
Mult
Relop
Grundlagen der Programmierung 2 (Comp-A)
Attribut
if
123
’x1’
Code(∗)
Code(<=)
Position in der Eingabe
113
500
1001
2000
(501,30)
- 22 -
Grammatik-Zerlegung:
Tokenizer


Zahl


 Ziffer

Bezeichner



Alphanum
Parser


 E
T

 F
::=
::=
::=
::=
::=
::=
::=
Ziffer | ZifferZahl
0|1|2|3|4|5|6|7|8|9
Char | Char Alphanum
Ziffer | Char
E + T | T
T ∗ F | F
(E) | Zahl | Bezeichner
Parseralphabet = {Tokenmarkierungen}
Parseralphabet im Beispiel: {+,*,Zahl, Bezeichner,),( }
Der Parser behandelt alle Bezeichner als ein einziges Terminal
Grundlagen der Programmierung 2 (Comp-A)
- 23 -
Compiler-Phasen: Struktur und Typen
Typen, in Haskell-Notation:
Scanner:
String -> [Token]
det. Teil-Parser:
[Token] -> ([Token], Syntaxbaum)
Teil-Parser mit Backtracking
[Token] -> [([Token], Syntaxbaum)]
Gesamt-Parser:
[Token] -> Syntaxbaum
Grundlagen der Programmierung 2 (Comp-A)
- 24 -
Fehlererkennung des Scanners
•
•
•
•
falsche Zahlen Z.B. 123.a
falsche Escape-Folgen in Strings
ein fehlendes String-Endezeichen,
oder evtl. Längenüberschreitungen.
Bezeichner, die nicht der Konvention entsprechen
Ungültige Symbole in bestimmten Kontexten
Nicht erkennbar für den Scanner:
• Klammerfehler,
• Klammerfehler bzgl. (tief) geschachtelter Kommentare
• falsche Schlüsselworte.
Grundlagen der Programmierung 2 (Comp-A)
- 25 -
Scannen von Kommentaren und Strings
String im Eingabestrom:
= Unterstring mit linkem und rechtem Begrenzungssymbol ”.
Bekannte Problematik: String im String?
Beachte: ” trennt, erzeugt aber keine Klammerstruktur
sinnvolle Lösungsalternativen:
• Escape-symbol \ als Kommando:
\” im String → ”
\\ im String → \
• Verdopplung: ”” im String → ”
Nachteil: Exponentiell große Strings könnten
in der Eingabe erforderlich sein
abhängig von der Tiefe bzw. der
Anzahl Scanner-Durchgänge.
Der Scanner darf keine Leerzeichen in Strings entfernen
Grundlagen der Programmierung 2 (Comp-A)
- 26 -
Scannen von Kommentaren:
Zeilenkommentare
Anfangssymbol
z.B. * oder ; oder % oder −− oder //.
geklammerte
Kommentare
Kommentar-Begrenzer:
Z.B. Anfang: /∗ , Ende: ∗/.
Aktuelle Programmiersprachen:
nur eine Klammerebene;
Echte Kommentar-Schachtelung
muss vom Parser erkannt werden.
Beachte Zeilenkommentar im String sind Stringzeichen.
Grundlagen der Programmierung 2 (Comp-A)
- 27 -
Zugehörige Unterlagen
Herunterladen