EINFÜHRUNG UND ÜBERBLICK

Werbung
1. Kapitel
EINFÜHRUNG UND ÜBERBLICK Compilerbau Prof. Dr. Wolfgang Schramm Vorbemerkungen 1/4 1 o 
o 
o 
o 
o 
o 
o 
o 
Einführung in die Grundlagen und Techniken des Compilerbaus. Übersetzer transformieren Texte einer Quellsprache, deren Struktur durch eine formale GrammaOk beschrieben ist, in eine Zielsprache. Klassische Anwendung: Übersetzung höherer Programmiersprachen in Maschinensprache. Übersetzung von Programmiersprachen = grundlegendes Problem der InformaOk. Gut verstandene Theorie zu formalen Sprachen und Maschinen, die sie akzepOeren. Techniken der Syntaxanalyse und ihre Verbindungen mit Übersetzungs-­‐akOonen sind ausgefeilt. Klare Zerlegung der Gesamtaufgabe des Übersetzungsprozesses in Teilaufgaben. ImplemenOerung von Programmiersprachen = Allgemeinbildung eines InformaOkers. Vorbemerkungen 2/4 2 o 
Themengebiete des Compilerbau: ¤ 
¤ 
¤ 
¤ 
¤ 
Programmiersprachen Rechnerarchitektur Theorie (formaler) Sprachen Datenstrukturen und Algorithmen So^ware Engineering Vorbemerkungen 3/4 3 o 
Einsatzbereiche von Compilerbautechniken ¤ 
¤ 
¤ 
¤ 
¤ 
¤ 
¤ 
Dokumentstrukturen GrafikspezifikaOonssprachen Kommandosprachen von Betriebssystemen Hardware-­‐Beschreibungssprachen Anfragesprachen für Datenbanksysteme Protokolle in verteilten Systemen Formate für den Datenaustausch Vorbemerkungen 4/4 4 o 
Vorlesungsinhalte ¤ 
¤ 
¤ 
¤ 
Methoden des Übersetzerbaus (lexikalische Analyse, Syntaxanalyse, syntaxgesteuerte Übersetzung, Code-­‐OpOmierung). VielseiOgkeit der Anwendbarkeit der Techniken (Übersetzung einer Dokumentbeschreibungssprache nach LATEX = Beispiel für eine vollständige ÜbersetzerimplemenOerung) Einsatz von Werkzeugen (Scanner-­‐ und Parsergeneratoren; Lex/Flex und Yacc/-­‐Bison). Detaillierte Behandlung der ImplemenOerung eines Compilers für eine klassische imperaOve Programmiersprache auf der Basis einer abstrakten Maschine. Programmiersprachen -­‐ GeneraOonen 5 o 
Maschinensprachen (1. GeneraOon – seit 1945) ¤ 
¤ 
o 
Assemblersprachen (2. GeneraOon – seit 1950) ¤ 
¤ 
o 
¤ 
Loslösung von der Hardware à problemorienOert ImperaOve/prozedurale/objektorienOerte Sprachen Bsp.: Fortran, Cobol, C, Java 4GL (Sprachen der 4. GeneraOon -­‐ seit 1970) ¤ 
o 
Befehle maschinennah (mnemotechnisch) Programme sind schwer lesbar, wenig übersichtlich und fehleranfällig Höhere Programmiersprachen (3. GeneraOon – seit 1954) ¤ 
o 
Befehle in Binärform Programme sind (fast) unlesbar, unübersichtlich und fehleranfällig Sprachenfür besondere Anwendungen; Bsp. SQL, PostScript, Maple DeklaraOve Programmiersprachen (5. GeneraOon -­‐ seit 1980) ¤ 
¤ 
Nicht der Lösungsalgorithmus sondern die Problemformulierung mit Hilfe logischer Ausdrücke steht im Vordergrund Die Lösungsfindung ist weitgehend vom System vorgegeben. Bsp: Prolog Höhere Programmiersprachen 6 •  Fortran I – 2000
•  Common Lisp
•  Simula 67
•  Algol
•  Scheme
•  Smalltalk 80
•  PL/I
•  Haskell
•  CLOS (Common Lisp
Object System)
•  Cobol 68 - 02
•  Basic
•  Prolog
•  Pascal
•  ...
•  Oberon-2
•  C++
•  C
•  ObjectPascal
•  Modula-2
•  Delphi
•  ...
•  Ada
•  Eiffel
•  Java
•  C#
•  ...
Programmiersprachklassen 7 o 
ImperaOve Sprachen ¤ 
o 
FunkOonale Sprachen ¤ 
¤ 
o 
¤ 
Basieren auf der operaOonellen Sicht der Prädikatenlogik. Ausführungsmechanismus: ResoluOon. ObjektorienOerte Programmiersprachen ¤ 
¤ 
o 
Keine Trennung zwischen Anweisungen und Ausdrücken. Namen nur für FunkOonen und Ausdrücke nicht aber für Speicherzellen. Logische Programmiersprachen ¤ 
o 
Eng an Struktur des von-­‐Neumann-­‐Rechners orienOert. Im Kern imperaOv, ihre Typsysteme unterstützen DatenabstrakOon. Ermöglichen evoluOonäre So^wareentwicklung. Sprachen für spezielle Anwendungsgebiete Beispiele: ¤  Hardware-­‐Beschreibungssprachen. ¤  Kommandosprachen für Betriebssysteme. ¤  Text-­‐ und GrafikspezifikaOonssprachen. o 
Skriptsprachen ¤ 
¤ 
¤ 
InterpreOerte Sprachen mit Operatoren auf höherer Ebene, Kurze, sehr mächOge Befehle / Berechnungen = Skripts Beipiele: Awk, JavaScript. Perl, PHP, Python, Ruby, Tcl Abstammung von Programmiersprachen 8 1957
1960
Fortran I
Lisp
1965
Cobol
Algol 60
Fortran IV
PL/I
Algol-W
Basic
Algol 68
1970
Pascal
Simula 67
BCPL
C
1975
1980
1985
Fortran 77
Smalltalk 80
Common
Lisp
CLOS
1990
1995
Ada
Modula-2
ObjectPascal
Delphi
Oberon-2
C++
Ansi-C
Fortran 90
Java
Ada 9x
C#
Fortran 95
Aufgabe eines Compilers 9 Quellprogramm
in A
Compiler
Meldungen
Zielprogramm
in B
Grobmodell eines Compilers 10 Quellprogramm
Analyse
Zwischenprogramm
Synthese
Zielprogramm
Feinmodell eines Compilers 11 Quellprogramm
lexikalische Analyse
Analyse
Syntaxanalyse
semantische Analyse
Symboltabellenverwaltung
Zwischencodeerzeugung
Fehlerbehandlung
Codeoptimierung
Codergenerierung
Zielprogramm
Synthese
Symboltabelle 12 . . . enthält InformaOon über Bezeichner, die vom Programmierer eingeführt werden. Format: Bezeichner
Attribute
Beispiel: double r;
Attribute von r:
•  Typ: double
•  Relative Adresse innerhalb des umschließenden Unterprogramms / der
Klasse
•  Gültigkeitsbereich
Fehlerbehandlung 13 o 
Ziel der Fehlerbehandlung ¤ 
¤ 
¤ 
Entdeckung aller Fehler Beschreibung der Fehler Behebung der Fehler für eine Fortsetzung der Übersetzung Lexikalische Analyse 14 Eingabe
Ausgabe
Folge von einzelnen Zeichen
–  Buchstaben
–  Ziffern
–  Leerzeichen
–  Zeilenende
–  Operatorsymbole
–  Interpunktionszeichen
Gruppe zusammengehöriger Zeichen
–  Bezeichner
–  Schlüsselworte
–  Operatoren: = <= != . . .
–  Zahlen
–  Trennzeichen /* */
–  Zeichenketten “ . . . . . “
Aufgabe
Erkennen gewisser “Grundsymbole“ im Zeichenstrom
Zusätzliche Aktionen
– 
– 
– 
– 
Vorbereiten von Einträgen in die Symboltabelle
Entfernen von Kommentaren
Entfernen überflüssiger Leerzeichen (Blank Stripping)
Fehlerbehandlung
lexikalische Elemente,
Lexeme,
Token
SyntakOsche Analyse 1/2 15 Eingabe:
Folgen lexikalischer Elemente.
Aufgabe:
Erkennen hierarchischer Strukturen in Programmen.
Ausgabe:
Hierarchische Darstellung („Baum“) von Folgen lexikalischer Elemente
= Strukturbaum.
Beispiel:
mitte = (links + rechts) / 2;
assignment
identifier
=
Strukturbaum
expression
expression
identifier
+
/
identifier
number
SyntakOsche Analyse 2/2 16 Komprimierung des Strukturbaums
=
identifier
/
+
Syntaxbaum
identifier
Zusätzliche Aktionen
– 
– 
Ergänzungen in der Symboltabelle
Fehlerbehandlung
number
identifier
SemanOsche Analyse 1/2 17 Eingabe:
Hierarchische Darstellung des Quellprogramms Aufgabe: Überprüfung der Typverträglichkeiten Überprüfung von Aspekten, die nicht von der syntakOschen Analyse erfassbar sind, z.B.: n 
DeklaraOon / Verwendung von Bezeichnern. n 
ÜbereinsOmmung zwischen formalen und aktuellen Parametern. n 
ÜbereinsOmmung zwischen Dimension eines Feldes und Indizierung des Zugriffs. n 
Auflösen überladener oder polymorpher OperaOonen. Ausgabe: Geänderter Struktur-­‐ (oder Syntax-­‐) Baum SemanOsche Analyse 2/2 18 Beispiel:
mitte = (links + rechts) / 2;
Feststellen des Typs der Variablen links und rechts. Überprüfen, ob für die beiden Typen idenOsch sind. Sind beide beispielsweise vom Typ int, dann wird eine ganzzahlige AddiOon durchgeführt. Sind die beiden von unterschiedlichem Typ, wird, falls in der Programmiersprache zugelassen, zuerst eine TypkonverOerung durchgeführt. Dann wird analog weiter verfahren: Feststellen des Typs der AddiOon von links und rechts und von 2. Zwischencode Erzeugung 19 Eingabe:
Strukturbaum (Syntaxbaum) Aufgabe: Erzeugen eines “höheren Maschinencodes“ aus dem Syntaxbaum Ausgabe: Zwischencode Beispiel:
mitte = (links + rechts) / 2;
hilf_1 = links + rechts
hilf_2 = hilf_1 div 2
mitte
= hilf_2
3-Adress-Code
CodeopOmierung 20 Eingabe:
Zwischencode Aufgabe: Auffinden von Ineffizienzen im Zwischencode Ausgabe: (OpOmierter) Zwischencode Beispiel:
hilf_1 = links + rechts
hilf_2 = hilf_1 div 2
mitte
= hilf_2
hilf_1 = links + rechts
mitte
= hilf_1 div 2
Codeerzeugung 21 Eingabe:
OpOmierter Zwischencode Aufgabe: Erzeugen von Assembler-­‐ oder Maschinencode für die spezielle Zielmaschine Ausgabe: Maschinencode Beispiel:
hilf_1 = links + rechts
mitte
= hilf_1 div 2
LOAD
links
ADD
rechts
DIV
2
STORE
mitte
1-Registermaschine
“Akkumulator“
Die Systemumgebung des Compilers 22 Vorform des Quellprogramms Präprozessor Quellprogramm Compiler Zielprogramm in Assemblersprache Assembler Programm in verschiebbarem Maschinencode Lader/Binder Programm in absolutem Maschinencode Andere Programmteile, Pro-­‐
gramme aus Bibliotheken in verschiebbarem Maschinencode Aufgaben von Präprozessor, Assembler und Binder/Lader 23 o 
o 
o 
Präprozessor: Erzeugt aus der Vorform des Quellprogramms (enthält Spracherweiterungen wie z.B. Makros, Einbesung von Datenbank-­‐
anfragesprachen) die Eingabe für den Compiler. Assembler: Überführt ein Programm in Assemblersprache in ein „verschiebbares“ Programm in Maschinensprache. D.h. die im Maschinen-­‐
programm verwendeten Adressen sind relaOv zum Programmanfang. Binder und Lader: Bauen eine Menge von verschiebbaren Maschinenprogrammen aus unterschiedlichen Dateien zu einem einzigen ausführbaren Programm zusammen und laden es in den Hauptspeicher. Dabei werden externe Referenzen (links) aufgelöst (Binder) und es werden die relaOven Adressen entsprechend der LadeposiOon in absolute Adressen umgewandelt. Ablauf eines komplexen Übersetzungsvorgangs 24 Programmeinheit1
Assemblercode1
Programmeinheitn
Compiler
Assemblercoden
Assembler
relokatierbarer
Maschinencoden
relokatierbarer
Maschinencode1
Linker
relokatierbare Einheit
ausführbarer Maschinencode im
Hauptspeicher
Loader
Compiler und Interpreter 25 o 
o 
Compiler: Übersetzt ein Quellprogramm in ein Zielprogramm, das zu einem
beliebigen späteren Zeitpunkt ausgeführt wird.
Interpreter: Analysiert das Quellprogramm genauso wie der Compiler. Statt der
Überführung in ein Zielprogramm, wird das Quellprogramm direkt ausgeführt.
Ausführung von Compiler-­‐Sprachen 26 Programm
(höhere
Sprache)
1.Describe system
Set of Subsystems
Set of Interconnections
Compiler
1.Describe system
Set of Subsystems
Set of Interconnections
Programm
(Maschinensprache)
1.Describe system
Set of Subsystems
2.Describe subsystems
by their properties
2.Describe subsystems
by their properties
2.Describe subsystems
by their properties
Subsystems and
Properties
Subsystems and
Properties
Subsystems and
Properties
Set of Interconnections
3.Determine potential
mismatches
3.Determine potential
mismatches
List of Potential
Mismatches
List of Potential
Mismatches
3.Determine potential
mismatches
List of Potential
Mismatches
4.Determine
actual mismatches
4.Determine
actual mismatches
4.Determine
actual mismatches
List of Mismatches
List of Mismatches
List of Mismatches
Ausführung von Compiler-­‐Sprachen 27 Programm
(Maschinensprache)
1.Describe system
Set of Subsystems
Set of Interconnections
2.Describe subsystems
by their properties
Subsystems and
Properties
3.Determine potential
mismatches
List of Potential
Mismatches
4.Determine
actual mismatches
List of Mismatches
Ausführung von Interpreter-­‐Sprachen 28 Programm
(höhere
Sprache)
1.Describe system
Set of Subsystems
Set of Interconnections
2.Describe subsystems
by their properties
Subsystems and
Properties
3.Determine potential
mismatches
List of Potential
Mismatches
4.Determine
actual mismatches
List of Mismatches
Interpreter
InterpretaOon -­‐ Arbeitsweise 29 = direktes Ausführen der zu den Anweisungen der höheren Programmiersprache gehörenden AkOonen. 1
Lesen der nächsten Anweisung
2
Bestimmen der auszuführenden Aktion
3
Ausführen dieser Aktion
Vor-­‐ und Nachteile von Compilern und Interpretern 30 Compiler ¤ 
¤ 
¤ 
¤ 
¤ 
Compiler können das Programm bei der Übersetzung auf Syntax-­‐ und SemanOk-­‐
Fehler überprüfen, d.h. auf Schreibfehler und Widersprüche gegen die SprachdefiniOon. Anweisungen werden genau einmal (beim Übersetzen) geprü^ und beim Ablauf direkt vom Prozessor ausgeführt. Compiler zu erstellen ist schwierig. Treten zur Laufzeit Fehler auf (z.B. eine Division durch 0), sind diese meist schwer zu lokalisieren. Compiler erzeugen Code, der nur auf einem speziellen Prozessor läu^; Unterschiede z.B. in der Darstellung von Datentypen kann zu unterschiedlichen Ergebnissen des gleichen Programms führen. ¨ 
Interpreter ¤ 
¤ 
¤ 
¤ 
¤ 
SemanOk-­‐Fehler werden eventuell erst bei der Programmausführung bemerkt, ein Absturz kann die Folge sein. Anweisungen werden bei jedem Durchlauf erneut interpreOert, daher laufen interpreOerte Programme langsamer als übersetzte (Just-­‐In-­‐Time-­‐Compiler helfen). Interpreter sind einfacher und schneller zu entwickeln. Interpreter können genauere Fehlermeldungen geben als Compiler. Interpreter abstrahieren vom zugrundeliegenden Prozessor, Programme liefern auf jedem Rechner idenOsche Ergebnisse. Hybridcompiler 31 Quellprogramm
Java-Sprachprozessoren
Übersetzer
Zwischenprogramm
Eingabe
Virtuelle
Maschine
Ausgabe
Zusammenspiel von Compiler und Interpreter 32 Quellsprache A
Compiler
Zielsprache B
Quellsprache B
Interpreter
Abstrakte Maschine für B
Maschinensprache X
Maschinensprache X
Reale Maschine für X
Hardware
Werkzeuge für den Compilerbau 33 Werkzeuge für die verschiedenen Teilaufgaben: o 
Scannergenerator (Bsp.: Lex, Flex, JFlex) o 
Parsergeneratoren (Bsp.: Yacc, Bison, JavaCC, SableCC) o 
Generator für abstrakte Syntaxbäume o 
Generator für Asributauswerter o 
TransformaOon abstrakter Syntaxbäume o 
Generator für Codegeneratoren Vorlesungsgliederung 34 OrienOert an den Phasen des Compilers: • 
• 
• 
• 
Lexikalische Analyse SyntakOsche Analyse SemanOsche Analyse – Syntax gesteuerte Übersetzung (Zwischen)code Erzeugung und CodeopOmierung Literaturempfehlungen – eine kleine Auswahl 1/2 35 o 
A. Aho, M. Lam, R. Sethi, J. Ullman: Compilers – Principles, Techniques and Tools 2nd EdiOon, Pearson InternaOonal 2007; Paperback (Englisch) 83,45 €
Deutsche Übersetzung Pearson Verlag 2008 69,95 € Das Standardwerk des Compilerbaus. Hat (in seiner Erstausgabe) gewissermaßen alle weiteren Bücher zum Compilerbau beeinflusst. Sehr umfassend (Theorie + Praxis) und anschaulich, gut verständlich. o 
o 
R. GüOng, M. Erwig: Übersetzerbau – Techniken, Werkzeuge, Anwendungen, Springer Verlag 1999, 32,95 € Verständlich geschriebenes, kompaktes Buch, ideal für den Einsatz der Compilerbautechniken in der Praxis. Buch mit dem geringsten Theorieanteil aber mit schönen Beispielen. N. Wirth: Grundlagen und Techniken des Compilerbaus 2. Auflage, Oldenbourg Verlag, München, 2008, 24,80 € Sehr kompaktes Buch. Die Theorie wird sehr knapp behandelt. Schwerpunkt liegt auf der prakOschen Umsetzung, d.h. der ImplemenOerung eines Compilers (mit konkreten Codefragmenten) für eine Teilmenge von Oberon. Literaturempfehlungen – eine kleine Auswahl 2/2 36 o 
R. Wilhelm, D. Maurer: Übersetzerbau – Theorie, KonstrukOon, Generierung 2. Auflage, Springer Verlag 1997, 32,95 €
Gutes Buch mit anderem (ungewöhnlichem) Auyau. Auyau orienOert an den 4 Typen von Programmiersprachen. Behandelt auch die Übersetzung funkOonaler, logischer und objektorienOerter Sprachen. DidakOsch anders mit Theorieanteil, der nicht ganz einfach zu verstehen ist. o 
O. Mayer: Syntaxanalyse, BI 1978 Ein umfassendes Buch mit hohem Theorieanteil zum Thema Syntaxanalyse. o 
J. Levine, T. Mason, D. Brown: „ lex & yacc“. O‘Reilly 1995. 29 €. Gute, einfache Einführung in lex und yacc. Geht auch auf die unterschiedlichen „lexe“ und „yaccs“ ein. o 
Herold: „ lex & yacc. Die Profitools zur lexikalischen und syntakOschen Textanalyse“. Addison-­‐Wesley 2003. 24,95 €. Gute, einfache Einführung in lex und yacc. Wie das Buch von Levine mit etwas zu vielen Redundanzen. 
Zugehörige Unterlagen
Herunterladen