a 1 a i a n $ s m Ausgabe LR-Parser X m s m-1 X m Action Goto Compilerbau Bachelorstudiengang Informatik/IT-Sicherheit

Größe: px
Ab Seite anzeigen:

Download "a 1 a i a n $ s m Ausgabe LR-Parser X m s m-1 X m Action Goto Compilerbau Bachelorstudiengang Informatik/IT-Sicherheit"

Transkript

1 a 1 a i a n $ s m X m LR-Parser Ausgabe s m-1 X m-1... s 0 Action Goto Bachelorstudiengang Informatik/IT-Sicherheit Compilerbau Autoren: Dr. rer. nat. Werner Massonne Prof. Dr.-Ing. Felix C. Freiling Friedrich-Alexander-Universität Erlangen-Nürnberg

2

3 Compilerbau Studienbrief 1: Einführung Studienbrief 2: Lexikalische Analyse Studienbrief 3: Syntaktische Analyse Studienbrief 4: Semantische Analyse, Zwischencodeerzeugung Studienbrief 5: Codeerzeugung und Optimierung Autoren: Dr. rer. nat. Werner Massonne Prof. Dr.-Ing. Felix C. Freiling 1. Auflage Friedrich-Alexander-Universität Erlangen-Nürnberg

4 2015 Felix Freiling Friedrich-Alexander-Universität Erlangen-Nürnberg Department Informatik Martensstr Erlangen 1. Auflage (3. Dezember 2015) Didaktische und redaktionelle Bearbeitung: Bärbel Wolf-Gellatly Das Werk einschließlich seiner Teile ist urheberrechtlich geschützt. Jede Verwendung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung der Verfasser unzulässig und strafbar. Das gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen. Um die Lesbarkeit zu vereinfachen, wird auf die zusätzliche Formulierung der weiblichen Form bei Personenbezeichnungen verzichtet. Wir weisen deshalb darauf hin, dass die Verwendung der männlichen Form explizit als geschlechtsunabhängig verstanden werden soll. Das diesem Bericht zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung, und Forschung unter dem Förderkennzeichen 160H11068 gefördert. Die Verantwortung für den Inhalt dieser Veröffentlichung liegt beim Autor.

5 Inhaltsverzeichnis Seite 3 Inhaltsverzeichnis Einleitung zu den Studienbriefen 6 I. Abkürzungen der Randsymbole und Farbkodierungen II. Zu den Autoren III. Modullehrziele Studienbrief 1 Einführung Lernergebnisse Advance Organizer Anwendungsgebiete und Grobstruktur von Compilern Übersetzung von Programmiersprachen Datenbankanfragesprachen Dokumentbeschreibungssprachen Weitere Anwendungsgebiete Analyse- und Synthesephase Phasen der Kompilierung Lexikalische Analyse Syntaktische Analyse Semantische Analyse Erzeugung von Zwischencode Optimierung und Codeerzeugung Compiler für imperative Programmiersprachen Ausblick und Aufbau des Moduls Zusammenfassung Übungen Studienbrief 2 Lexikalische Analyse Lernergebnisse Advance Organizer Aufgaben der lexikalischen Analyse Formale Sprachen und reguläre Ausdrücke Von regulären Ausdrücken zu nichtdeterministischen Automaten Endliche Automaten NEA-Erzeugung aus regulären Ausdrücken Von nichtdeterministischen zu deterministischen Automaten Umwandlung eines NEAs in einen DEA Automatenminimierung Flex, ein Scannergenerator Aufbau einer Flex-Scannerbeschreibung Präambel Definitionen Regeln C-Funktionen Flex-Variablen Zusammenfassung Übungen Studienbrief 3 Syntaktische Analyse Lernergebnisse Advance Organizer Einführung und Grundlagen Theoretische Grundlagen Grundprinzip von Top-down-Analyse und Bottom-up-Analyse Top-down-Analyse Beseitigung von Linksrekursion

6 Seite 4 Inhaltsverzeichnis Vorausschauendes Parsen Grundlegender Aufbau eines rekursiven Abstiegsparsers Erstellung von Parsertabellen FIRST- und FOLLOW-Mengen Berechnung von FIRST- und FOLLOW-Mengen Konstruktion von Parsertabellen Zusammenfassung, Top-down-Parser als abstrakte Maschine Bottom-up-Analyse Motivation Kellerautomaten LR-Parser als Kellerautomaten Bestimmen von Handles LR(1)-Parser als abstrakte Maschine DEA zum Erkennen von Handles Konstruktion von ACTION- und GOTO-Tabelle Zusammenfassung LR(1)-Parser SLR(1) und LALR(1) Fehlerbehandlung Grundsätzliche Fehlerbehandlungsstrategien Fehlerbehandlung bei LL(1)-Parsern Fehlerbehandlung bei LR(1)-Parsern Zusammenfassung Übungen Studienbrief 4 Semantische Analyse, Zwischencodeerzeugung Lernergebnisse Advance Organizer Aufgaben der semantischen Analyse Syntaxgesteuerte Übersetzung Attributierte Grammatiken und syntaxgesteuerte Definitionen Synthetisierte und vererbte Attribute L-attributierte Definition, Übersetzungsschema Übersetzungsschemata in der Bottom-up-Übersetzung Die Symboltabelle Organisation von Symboltabellen Der Parsergenerator Bison Grundlegender Aufbau einer Bison-Spezifikation Deklarationen und Regeln Die Zusammenarbeit von Flex und Bison Ziele der semantischen Analyse am Beispiel imperativer Programmiersprachen Speicherorganisation und Laufzeitsystem Erzeugung von Zwischencode Adress-Code Übersetzung in 3-Adress-Code Symboltabellen Übersetzungsschemata für Jacqueline Zusammenfassung Übungen Studienbrief 5 Codeerzeugung und Optimierung Lernergebnisse Advance Organizer Übersicht Flussanalysen Kontrollflussanalyse Basic Blocks

7 Inhaltsverzeichnis Seite 5 Kontrollfluss Dominatoren Erkennung von Schleifen Datenflussanalyse Regionen Punkte und Spuren Globale Datenflussanalyse Maschinenunabhängige Optimierung Lokale Verfahren Schleifenoptimierungen Globale Verfahren Maschinenabhängige Optimierung Codeerzeugung Codeerzeugung für Basic Blocks Lebendigkeitsanalyse Registerzuordnung durch Graphfärbung Berechnung von Interferenzgraphen Graphfärbung durch Vereinfachung Zusammenfassung Übungen Liste der Lösungen zu den Kontrollaufgaben 187 Verzeichnisse 193 I. Abbildungen II. Definitionen III. Exkurse IV. Tabellen V. Literatur

8 Seite 6 Einleitung zu den Studienbriefen Einleitung zu den Studienbriefen I. Abkürzungen der Randsymbole und Farbkodierungen Definition Exkurs Merksatz Quelltext Übung D E M Q Ü

9 Zu den Autoren Seite 7 II. Zu den Autoren Felix Freiling ist seit Dezember 2010 Inhaber des Lehrstuhls für IT- Sicherheitsinfrastrukturen an der Friedrich-Alexander-Universität Erlangen- Nürnberg. Zuvor war er bereits als Professor für Informatik an der RWTH Aachen ( ) und der Universität Mannheim ( ) tätig. Schwerpunkte seiner Arbeitsgruppe in Forschung und Lehre sind offensive Methoden der IT-Sicherheit, technische Aspekte der Cyberkriminalität sowie digitale Forensik. In den Verfahren zur Online-Durchsuchung und zur Vorratsdatenspeicherung vor dem Bundesverfassungsgericht diente Felix Freiling als sachverständige Auskunftsperson. Werner Massonne erwarb sein Diplom in Informatik an der Universität des Saarlandes in Saarbrücken. Er promovierte anschließend im Bereich Rechnerarchitektur mit dem Thema Leistung und Güte von Datenflussrechnern. Nach einem längeren Abstecher in die freie Wirtschaft arbeitet er inzwischen als Postdoktorand bei Professor Freiling an der Friedrich-Alexander-Universität.

10 Seite 8 Einleitung zu den Studienbriefen III. Modullehrziele Ein Compiler C ist ein 7-Tupel C = (Q,Z,Σ,L r,s k, z,c o ), wobei Q eine Quellsprache, Z eine Zielsprache,... Nein, ganz so wollen wir es nicht machen! Compilerbau, also die Programmierung eines Compilers, wurzelt zwar tief in der theoretischen Informatik, insbesondere in der Theorie der formalen Sprachen und der Automatentheorie, aber dennoch gehört Compilerbau in den Bereich der praktischen Informatik. Compilerbau ist ein eigenständiges Gebiet der praktischen Informatik und gilt sogar als das älteste Gebiet der praktischen Informatik. Das liegt daran, dass Compiler so schön praktisch, also äußerst nützlich und heutzutage bspw. aus dem Bereich der Softwareentwicklung nicht mehr wegzudenken sind. Als erster Compiler überhaupt gilt der Compiler A-0, den die Mathematikerin Grace Hopper 1 im Jahr 1952 entwickelt hat. Als weitere Meilensteine gelten der 1957 entwickelte erste FORTRAN-Compiler und der 1960 entwickelte erste COBOL-Compiler. Durch die Entwicklung von Compilern für höhere Programmiersprachen trat die Programmentwicklung auf der Ebene von Maschinen- oder Assemblercode immer mehr in den Hintergrund, während gleichzeitig Effizienz und Geschwindigkeit der Softwareentwicklung stark anstiegen. Eine Kompilierung besteht grob aus zwei Phasen, einer Analysephase und einer Synthesephase, die jeweils wieder in mehrere Teilphasen untergliedert sind. Dieser Aufbau hat sich in der Geschichte des Compilerbaus entwickelt und etabliert. Durch ihn ist auch der Aufbau einer Lehrveranstaltung oder eines Lehrbuchs über Compilerbau strukturell vorgegeben. Auch dieses Modul richtet sich in seinem Aufbau nach dieser Grundstruktur. Die Analysephase ist im Gegensatz zur Synthesephase eher universell, d. h. die dort angewandten Verfahren sind quasi in allen Compilern zu finden. In der Synthesephase diversifizieren sich Compiler, d. h. hier unterscheiden sich Compiler für unterschiedliche Aufgaben sehr stark. Der Schwerpunkt dieses Moduls liegt in der Betrachtung der Analysephase. Es geht dabei darum, die theoretischen Hintergründe dieser Phase zu verstehen. Nur durch dieses Verstehen wird deutlich, was Compiler prinzipiell leisten können und was nicht. Nach dem einführenden Studienbrief 1 beschäftigen sich die Studienbriefe 2 und 3 ausschließlich mit der Analysephase. Darin wird auch so manches Tupel erscheinen, aber trotz aller notwendigen Theorie soll trotzdem der praktische Aspekt dieses Moduls im Vordergrund stehen, der im darauf folgenden Studienbrief deutlich wird. Studienbrief 4 bildet das Bindeglied zwischen Analyse- und Synthesephase. Die damit erworbenen Kenntnisse über Compilerbau reichen aus, um mittels geeigneter Tools einen Compiler für eine realistische Programmiersprache zu bauen. Um den praktischen Anspruch des Moduls zu unterstreichen, ist die Bearbeitung von zwei Übungen dieses Studienbriefs obligatorisch, denn jede Theorie ist rasch vergessen, wenn man sie nicht in die Praxis umsetzt. Die Betrachtung der Synthesephase führen wir nur ausschnitthaft am Beispiel von imperativen Programmiersprachen durch. Studienbrief 5 greift einige Themenfelder auf, die bereits im Modul Systemnahe Programmierung behandelt wurden. Hier sind insbesondere Ergänzungen und Vertiefungen von allgemeinen Prinzipien zu finden, die beim Compilerbau besonders berücksichtigt werden müssen. Viel Spaß und viel Erfolg! Noch zu tun: Flex-Abschnitt verifizieren; dazu die Übungen selber machen Bison-Abschnitt verifizieren und ggf. erweitern und ändern; dazu die Übungen selber machen Alle Übungen selber machen 1

11 Studienbrief 1 Einführung Seite 9 Studienbrief 1 Einführung 1.1 Lernergebnisse Sie können einige Einsatzgebiete von Compilern und Compilerbautechniken benennen und erklären. Die Teilaufgaben eines Compilers und das dadurch entstehende Phasenmodell können Sie strukturiert darstellen. Die Funktionsprinzipien der einzelnen Kompilierungsphasen und die Schnittstellen zwischen diesen Phasen können Sie grob erläutern. Einige wichtige Anforderungen an Compiler für imperative Programmiersprachen und einige ihrer Abhängigkeiten können Sie benennen und erklären. 1.2 Advance Organizer Der Autor einer Abhandlung über Compilerbau hat es im Prinzip leicht. Der Aufbau eines Compilers ist sehr klar in einzelne, aufeinanderfolgende, Schritte oder Phasen gegliedert. An dieser Gliederung orientieren sich auch die allermeisten Lehrbücher bzw. Vorlesungen über Compilerbau. Wir beginnen in diesem Studienbrief mit einem Überblick über die Einsatzgebiete von Compilern, gefolgt von einer Vorstellung des Phasenmodells. Die Aufgaben der einzelnen Phasen werden dabei so weit skizziert, dass Sinnhaftigkeit und Abgrenzung der Phasen deutlich werden. In den nachfolgenden Studienbriefen werden diese Phasen detailliert besprochen, wobei neben den theoretischen Grundlagen jeweils auch praktische Implementierungsmethoden im Vordergrund stehen. 1.3 Anwendungsgebiete und Grobstruktur von Compilern In Wikipedia 1 findet sich die folgende Definition eines Compilers: Ein Compiler [...] ist ein Computerprogramm, das ein (anderes) Programm, das in einer bestimmten Programmiersprache geschrieben ist, in eine Form übersetzt, die von einem Computer ausgeführt werden kann. Diese Definition trifft zwar ganz gut unsere Vorstellung von dem, was ein Compiler tut, aber dennoch ist sie zu eng. Ein Compiler übersetzt zwar Programme im weitesten Sinne, aber nicht zwangsläufig in eine Form, die (direkt) von einem Computer ausgeführt werden kann. Ein Programm, das Java in C++ übersetzt, würde man auch als Compiler bezeichnen, obwohl das Ergebnis einer solchen Kompilierung keineswegs direkter auf einem Computer ausgeführt werden kann als das ursprüngliche Programm. Ein Compiler übersetzt allgemein ein Quellprogramm aus einer Sprache A in ein Zielprogramm in einer Sprache B (Abb. 1.1). Die Sprachen A und B sind dabei formale Sprachen, also Sprachen mit einer eindeutig definierten Syntax und Semantik. 2 Bei der Kompilierung eines Programms aus der Sprache A muss ein semantisch äquivalentes Zielprogramm in der Sprache B entstehen. Gelingt dies nicht, so muss der Compiler zumindest darauf hinweisen, dass ein Fehler aufgetreten ist. formale Sprachen Ein Übersetzer für natürliche Sprachen ist damit bspw. in unserem Sinne kein Compiler.

12 Seite 10 Studienbrief 1 Einführung Abb. 1.1: Compiler Quellprogramm in A Compiler Zielprogramm in B Fehlermeldungen Übersetzung von Programmiersprachen Das klassische Anwendungsgebiet von Compilern ist die Übersetzung von Programmen einer höheren Programmiersprache wie z. B. C oder Java. 3 Das Ergebnis einer solchen Kompilierung muss dabei nicht zwangsläufig ein auf einem Rechner direkt ausführbares Programm sein. Beispielsweise erzeugt ein Java-Compiler keine Maschinenprogramme, sondern maschinenunabhängigen Bytecode, der dann von einer virtuellen Maschine auf dem Zielrechner ausgeführt wird. In jedem Fall ist das Ergebnis einer Kompilierung Code, der bereits strukturell nahe an Maschinencode ist. Ob ein Compiler ein Assemblerprogramm erzeugt, Objektcode (verschiebbarer Maschinencode), Bytecode oder tatsächlich Maschinencode, ist aus unserer Sicht relativ belanglos, weil die Schritte vom Compilererzeugnis zum ausführbaren Programm weitgehend mechanisch und wenig akademisch anspruchsvoll durch Assembler, Linker usw. durchgeführt werden. In modernen Entwicklungsumgebungen wie z. B. Eclipse 4 arbeiten diese Komponenten unauffällig im Hintergrund (Abb. 1.2). Abb. 1.2: Zusammenspiel von Compiler, Assembler und Linker Compiler Quellcode Assemblercode Assembler Linker Objektcode Binärcode Interpreter Bezüglich des Zeitpunkts, zu dem die Übersetzung eines Hochsprachenprogramms in ausführbaren Code stattfindet, unterscheidet man klassisch die Begriffe Compiler und Interpreter, auch wenn eine genaue Abgrenzung wie z. B. bei Java nicht immer möglich ist. Demnach übersetzt ein Compiler ein Hochsprachenprogramm nur einmal in ein ausführbares Programm, während ein Interpreter dies bei jeder Ausführung des Hochsprachenprogramms tut. Da die Übersetzungstechniken in beiden Fällen weitgehend 5 identisch sind, wollen wir im Folgenden diese begrifflichen Unterschiede nicht mehr berücksichtigen. Compiler und Interpreter haben jeweils andere Vor- und Nachteile. Compilerbau beschäftigt sich mit allgemeinen Übersetzungstechniken. Diese sind gleichermaßen für klassische Compilersprachen wie z. B. C und für klassische Interpretersprachen wie z. B. BASIC anwendbar. 3 Dieses Themengebiet wurde bereits im Modul Systemnahe Programmierung eingehend behandelt. Dieser Abschnitt ist eine kurze Zusammenfassung aus der Sicht des Compilerbaus Manche Programmiersprachen machen es erforderlich, dass der Übersetzer den Quelltext mehrfach liest (x-pass-compiler), um ein Zielprogramm zu erzeugen. Diese Sprachen können logischerweise nicht interpretiert werden. So gesehen ist ein Compiler mächtiger als ein Interpreter.

13 1.3 Anwendungsgebiete und Grobstruktur von Compilern Seite 11 In die Klasse der Interpretersprachen fallen auch Skriptsprachen wie Python oder Perl Datenbankanfragesprachen Die Kommunikation mit Datenbanken findet in der Regel über Datenbankanfragesprachen wie SQL statt. Solche Anfragen müssen vom Datenbanksystem analysiert, eventuell optimiert und in elementare Rechenoperationen auf den Nutzdaten und Metadaten umgewandelt werden. Auch hierbei kommen die Techniken des Compilerbaus zur Anwendung. Beispiel 1.1: SQL-Anfrage an eine Datenbank Die folgende Anfrage liefert Name und Anschrift der Berliner Informatikstudenten im 5. Semester: B select Name, Anschrift from Studenten where Stadt = "Berlin" and Fach = "Informatik" and Semester = Dokumentbeschreibungssprachen In Dokumentbeschreibungssprachen wird das Erscheinungsbild eines Textdokumentes (z. B. Absätze, Überschriften, Aufzählungen, Bilder, Formeln, Schriftarten) in Textdateien beschrieben. Zur Strukturierung kommen Metaanweisungen zur Anwendung, die ganz ähnlich denen höherer Programmiersprachen sind. Zwei prominente Beispiele für Dokumentbeschreibungssprachen sind: 1. HTML: Web-Server liefern HTML-Dokumente an Browser, die diese dann analysieren und in eine graphische Darstellung im Browser-Fenster umwandeln. 2. LATEX(sprich: Latech) ist ein Textsatzsystem für wissenschaftliche Texte. Dieses Modul wurde in LATEXverfasst und ins pdf-format übersetzt. Der LATEX- Code zur Erzeugung des vorangegangenen Bildes sieht bspw. wie folgt aus: \begin{bild}[htbp] \centering \includegraphics[width=0.70\textwidth]{bilder/cal.pdf} \caption{zusammenspiel von Compiler, Assembler und Linker} \label{fig:cal} \end{bild} Weitere Anwendungsgebiete Es gibt viele weitere Anwendungsgebiete für Compiler, z. B. bei der Simulation integrierter Schaltungen. Design und Layout integrierter Schaltungen werden hierbei durch Hardwarebeschreibungssprachen (Hardware Description Language, HDL) spezifiziert. Bekannte Beispiele hierfür sind Verilog und VHDL. Auch Protokolle in verteilten Systemen benutzen Techniken des Compilerbaus. Die Struktur von Zeichenströmen gehorcht einer formalen Sprache, die von der Empfängerseite analysiert werden muss.

14 Seite 12 Studienbrief 1 Einführung Analyse- und Synthesephase Wir haben gesehen, dass Compilerbautechniken sehr wichtig sind und in vielen Anwendungsgebieten benötigt werden. Aus den bisherigen Ausführungen zeichnet sich bereits eine grobe, zweiteilige Struktur ab, die allen Compilern gemein ist. Analysephase Synthesephase 1. Vor der eigentlichen Übersetzung muss zunächst eine Analyse stattfinden, um zumindest die syntaktische Korrektheit des Quellprogramms sicherzustellen. In dieser Analysephase wird das Quellprogramm auch für die zweite Phase aufbereitet und strukturiert. Die Analysephase ist stark theoretisch untermauert und eines der am besten erforschten Gebiete der Informatik. Die theoretischen Grundlagen basieren auf der Theorie der formalen Sprachen. Die praktische Umsetzung bei der Konstruktion eines Compilers bedient sich der Automatentheorie: Formale Sprachen werden mit entsprechenden Automaten ausgewertet. Es hat sich gezeigt, dass alle gängigen Programmiersprachen in die Klasse der sogenannten LR(1)-Sprachen fallen. Diese Thematik wird in Studienbrief 3 sehr ausgiebig behandelt. 2. In der Synthesephase findet die eigentliche Übersetzung in die Zielsprache statt. Diese Phase ist stark vom jeweiligen Zielsystem abhängig. Beispielsweise muss bei der Übersetzung höherer Programmiersprachen in den Maschinencode eines Prozessors berücksichtigt werden, dass in den letzten Jahrzehnten Prozessoren immer komplexer und leistungsfähiger geworden sind. Die möglichst effiziente Ausnutzung prozessorspezifischer Eigenschaften ist daher sehr wichtig und damit ein Teil von Optimierungsverfahren, die während der Synthesephase zur Anwendung kommen. Auf dieses Thema werden wir in Studienbrief 5 zurückkommen. 1.4 Phasen der Kompilierung Abb. 1.3 zeigt die klassischen Phasen der Kompilierung (Compilerphasen) eines Hochsprachenprogramms. Bei Compilern für andere Anwendungsgebiete fallen ggf. einige dieser Phasen weg. Die Phasen der lexikalischen, syntaktischen und semantischen Analyse bilden zusammen die Analysephase, die übrigen die Synthesephase. Ein Quellprogramm wird von Phase zu Phase bis zur Erzeugung des Zielprogramms umgeformt. Die einzelnen Phasen entsprechen logischen Schritten, wobei in der Praxis die einzelnen Schritte nicht so klar voneinander getrennt sind, wie es das Bild zeigt. Insbesondere sind die Schritte der Synthesephase oft enger miteinander verzahnt. Fehlerbehandlung und Symboltabellenverwaltung sind keine Compilerphasen, sondern Datenstrukturen und Verfahren, die in allen Compilerphasen benötigt werden. In der Symboltabelle werden während der Kompilierung Datenstrukturen erzeugt, die in darauf folgenden Phasen benötigt werden. Die Fehlerbehandlung ist für Fehler zuständig, die während der unterschiedlichen Phasen auftreten können. Jede Phase benötigt unterschiedliche Fehlerbehandlungsverfahren. Die einzelnen Phasen werden im Folgenden etwas näher beschrieben. In den weiteren Studienbriefen werden die Compilerphasen dann detailliert erklärt und theoretisch untermauert. Token Lexikalische Analyse Während der lexikalischen Analyse wird der Quellcode eines Programms eingelesen und in eine Folge von Token umgewandelt (Abb. 1.4). Das Einlesen erfolgt zeichenweise, also als eine Folge von Buchstaben, Ziffern, Sonderzeichen usw. Die einzelnen Zeichen werden nach lexikalischen Regeln gruppiert, d. h. strukturiert zusammengefasst. Token repräsentieren Zeichenfolgen, die in der Quellsprache irgendeine Bedeutung haben, z. B. Bezeichner, Konstanten oder Schlüsselworte

15 1.4 Phasen der Kompilierung Seite 13 Quellprogramm Abb. 1.3: Phasen der Kompilierung [Aho et al., 1999] Lexikalische Analyse Syntakische Analyse Semantische Analyse Erzeugungbvonb Zwischencode Codeerzeugung Symboltabellenverwaltung Fehlerbehandlung Optimierung Zielprogramm bei Programmiersprachen. Das Erkennen basiert auf der Definition regulärer Ausdrücke. Ein regulärer Ausdruck für einen Bezeichner (z. B. Variablenname) könnte bspw. < letter > (< letter > < digit >) lauten. Dies besagt, dass ein Variablenname immer mit einem Buchstaben (letter) beginnen muss, dem in beliebiger Anordnung beliebig viele weitere Buchstaben oder Ziffern (digit) folgen können. Lexikalische Analyse Quellcode Token- Folge Abb. 1.4: Lexikalische Analyse Der Teil des Compilers, der die lexikalische Analyse vornimmt, wird als Scanner bezeichnet. Der Scanner liefert eine Token-Folge, in der eine Klassifizierung enthalten ist. Für jedes Token steht bspw. fest, ob es sich um eine Integer-Konstante, einen Bezeichner oder um ein Schlüsselwort handelt. Viele unterschiedliche Bezeichner können bspw. der Klasse Bezeichner angehören. Diese Klassifizierung ist von Vorteil, weil es bei der nachfolgenden syntaktischen Analyse unwichtig ist, welcher konkrete Bezeichner gemeint ist. Die Details der Bezeichner werden allerdings in der Symboltabelle abgelegt, weil sie in späteren Compilerphasen benötigt werden. Scanner Beispiel 1.2 Abb. 1.5 zeigt das mögliche Ergebnis der lexikalischen Analyse einer Programmzeile if b >= 10 then a := 1 end. if, then, end und := sind Schlüsselworte. a und b sind Bezeichner der Klasse id (identifier). cop B

16 Seite 14 Studienbrief 1 Einführung repräsentiert die Klasse der Vergleichsoperatoren. Die beiden Konstanten gehören zur Klasse const. Die in der Ausgabe fett gedruckten Teile zeigen Schlüsselworte und Klassen an. In eckigen Klammern stehen hinter den Klassen die Details der Symbole. Bei den beiden Konstanten und dem Vergleichsoperator sind dies die Werte der Konstanten bzw. der Operator selbst, bei den Bezeichnern fortlaufend vergebene Indizes, die auf die Symboltabelle verweisen. Für die syntaktische Analyse werden nur die Klassenzugehörigkeiten benötigt. Das Beispiel wird in den weiteren Abschnitten dieser Einführung weitergeführt. 6 Abb. 1.5: Lexikalische Analyse if b>=10 then a:=1 end Lexikalische Analyse if id[1] cop[ ] const[10] then id[2] := const[1] end In den Scanner können weitere Aufgaben integriert sein, wie z. B. die Entfernung von Kommentaren, die Ausführung von Compilerdirektiven, die Umwandlung von Ziffernfolgen in eine interne Zahlendarstellung usw. Da es sich hierbei allerdings eher um Implementierungsdetails handelt, wollen wir im Folgenden nicht näher auf diese Punkte eingehen. K Kontrollaufgabe 1.1 Welcher lexikalische Fehler ist in der Programmzeile if b >= 10 then then a := 1 end zu erkennen? Parser Syntaktische Analyse Die syntaktische Analyse wird von einem sogenannten Parser vorgenommen. Der Parser entscheidet, ob eine Token-Folge den syntaktischen Regeln der Quellsprache entspricht. Die syntaktischen Regeln werden in Form einer kontextfreien Grammatik formuliert. Der Parser prüft dabei, ob eine Token-Folge aus einer gegebenen kontextfreien Grammatik schrittweise ableitbar ist. Der Parser liefert als Ergebnis einen Ableitungsbaum, der auch Syntaxbaum genannt wird (Abb. 1.6). Abb. 1.6: Syntaktische Analyse Lexikalische Analyse Quellcode Token- Folge Syntaktische Analyse Syntaxbaum Syntaxbaum Der Syntaxbaum ist die baumförmige Darstellung der Token-Folge eines Quellcodes anhand der Regeln, die während einer Ableitung benutzt wurden. Syntaktische 6 Das Beispiel ist [Güting and Erwig, 1998] entnommen.

17 1.4 Phasen der Kompilierung Seite 15 Regeln können hierarchisch, also rekursiv sein. 7 Rekursive Regeln erlauben die Formulierung von Verschachtelungen, wie sie in höheren Programmiersprachen üblich sind. Beispiel 1.3 Für eine Programmiersprache, in der unsere Beispielprogrammzeile formuliert ist, könnten die folgenden syntaktischen Regeln gelten: B stmt assignment cond cond if boolexpr then stmt end Eine Anweisung (stmt) ist demnach eine Zuweisung (assignment) oder eine bedingte Anweisung (cond). Eine bedingte Anweisung besteht aus den Schlüsselworten if, then und end, aus einer Bedingung (boolexpr) und wieder aus einer Anweisung. Abb. 1.7 zeigt den Syntaxbaum für die bereits bekannte Token-Folge. Die syntaktischen Regeln für assignment und boolexpr sind im Syntaxbaum ebenfalls enthalten und sollten leicht verständlich sein. Der Saum des Syntaxbaums, gemeint ist damit die Auflistung der Blätter von links nach rechts, ergibt die Token-Folge der Eingabe. if id[1] cop[ ] const[10] then id[2] := const[1] end Abb. 1.7: Syntaktische Analyse Syntaktische Analyse stmt cond if boolexpr then stmt end numexpr cop numexpr assignment id const id := expr numexpr const Wenn wir davon ausgehen, dass die wenigsten Programme auf Anhieb korrekt sind, wird klar, dass die Fehlerbehandlung gerade bei der syntaktischen Analyse sehr wichtig ist. Die meisten Fehler bei der Programmentwicklung sind zunächst syntaktischer Natur. Dass ein Parser diese Syntaxfehler finden muss, ist selbstverständlich. Der Parser sollte Fehler aber auch möglichst genau lokalisieren und Fehlerbehandlung 7 Dies hat zur Folge, dass reguläre Ausdrücke, wie sie bei der lexikalischen Analyse verwendet werden, nicht zur Formulierung syntaktischer Regeln ausreichen.

18 Seite 16 Studienbrief 1 Einführung Lösungshinweise anbieten. Eine Aussage der Art Ihr Programm ist fehlerhaft hilft einem Programmierer nicht wirklich weiter. K Kontrollaufgabe 1.2 Was ist in der Programmzeile if b >= 10 then a <= 1 end syntaktisch falsch, wenn die syntaktischen Regeln des vorangegangenen Beispiels gelten? K Kontrollaufgabe 1.3 Ist in der Programmzeile if x >= 1.34 then a := 1 end ein syntaktischer Fehler zu erkennen ( x ist eine Zeichenkonstante)? Semantische Analyse Während der semantischen Analyse wird all das geprüft, was die syntaktische Analyse nicht leisten kann 8. Bei Programmiersprachen besteht die semantische Analyse insbesondere aus: Namensanalyse: Überprüfung von Gültigkeits- und Sichtbarkeitsbereichen von Variablen Typanalyse: Überprüfung der Typkonsistenz von Ausdrücken Allgemein werden während der semantischen Analyse Informationen gesammelt und ausgewertet, die Korrektheitsaspekte betreffen oder für die folgende Codeerzeugung wichtig sind. Diese Informationen werden in den Datenstrukturen der Symboltabelle abgelegt. Die Knoten des Syntaxbaums verweisen auf diese Informationen, die auch Attribute genannt werden. Demnach ist das Ergebnis der semantischen Analyse ein mit Attributen dekorierter Syntaxbaum (Abb. 1.8). Abb. 1.8: Semantische Analyse Lexikalische Analyse Quellcode Token- Folge Syntaktische Analyse Syntaxbaum Semantische Analyse "dekorierter" Syntaxbaum synthetisierte und vererbte Attribute Manche Attribute berechnen sich im Syntaxbaum von den Blättern zur Wurzel, andere von der Wurzel zu den Blättern. Erstere werden synthetisierte Attribute genannt, die Zweiten vererbte Attribute. Die vollständige Berechnung der Attribute und die Auswertung von Fehlern, wenn diese nicht gelingt, ist eine Hauptaufgabe der semantischen Analyse. 8 In der Programmiersprache C fällt auch die Konvention, dass bei verschachtelten if-else-anweisungen ein else (ohne explizite Blockklammerung) immer zum letzten if gehört, in den Bereich der semantischen Regeln. Die Syntax von C bildet dies nicht ab.

19 1.4 Phasen der Kompilierung Seite 17 Beispiel 1.4 In der Programmzeile if b >= 10 then a :=1 end könnte bspw. entdeckt werden, dass b eine Zeigervariable ist, die nicht sinnvoll mit einer Integer- Konstanten verglichen werden kann. Auch könnte Variable a nicht im Sichtbarkeitsbereich der Programmzeile liegen. Es ist eine Aufgabe der semantischen Analyse, solche Fehler aufzudecken. B Erzeugung von Zwischencode Mit der Erzeugung von Zwischencode beginnt die Synthesephase. Der dekorierte Syntaxbaum wird in eine Zwischendarstellung umgewandelt, die eventuell der Zielsprache schon recht nahe kommen kann. Die sinnvolle Art dieser Zwischendarstellung hängt bereits stark vom Verwendungszweck des Compilers ab und kann sehr abstrakt eher in der Nähe des dekorierten Syntaxbaums aber auch sehr konkret in der Nähe der Zielsprache liegen. In der Realität ist die Erzeugung von Zwischencode oft ein Bestandteil der semantischen Analyse. Hier ist der Zwischencode dann Schnittstelle zwischen Frontend und Backend eines Compilers. Dies macht insbesondere bei Compilersystemen Sinn, die mehrere Frontends (für unterschiedliche höhere Programmiersprachen) und mehrere Backends (für unterschiedliche Zielarchitekturen) aufweisen. Bei Compilern für Programmiersprachen wird oft der sogenannte 3-Adress-Code als Zwischencode eingesetzt. 3-Adress-Code besteht aus wenigen Befehlstypen, die schon stark an Assembler-Befehle erinnern. Allerdings abstrahiert 3-Adress-Code von den Gegebenheiten einer realen Architektur, insbesondere von den Registern einer realen CPU. 3-Adress-Code kann mit Hilfe sogenannter Übersetzungsschemata aus einem dekorierten Syntaxbaum erzeugt werden. Darauf werden wir in Studienbrief 4 detailliert eingehen. 3-Adress-Code Beispiel 1.5 Abb. 1.9 zeigt den aus unserer Programmzeile generierten 3-Adress-Code. Die Befehle können jeweils maximal drei Argumente (Adressen) enthalten. Zwischenergebnisse werden in fortlaufend durchnummerierten Zwischenspeichern (t1 bis t3) gehalten. Insbesondere lassen sich Operatorbaumstrukturen (hierarchische arithmetische Ausdrücke mit Variablen und Operatoren) sehr leicht in 3-Adress-Code umwandeln. B Optimierung und Codeerzeugung Wenngleich die Optimierung in Abb. 1.3 als eigenständige Phase bei der Kompilierung dargestellt ist, erstreckt sie sich in Wahrheit über mehrere Phasen hinweg. So

20 Seite 18 Studienbrief 1 Einführung Abb. 1.9: Erzeugung von Zwischencode stmt cond if boolexpr then stmt end numexpr cop numexpr assignment id const id := expr numexpr const Erzeugung von Zwischencode t1 := b t2 := 10 if t1 < t2 goto label t3 := 1 a := t3 label: können Optimierungen bereits bei der Erzeugung eines Zwischencodes, auf dem Zwischencode und bei der Erzeugung des Zielprogramms angewandt werden. B Beispiel 1.6 Abb zeigt eine offensichtliche Optimierung auf dem aus unserer Programmzeile erzeugten Zwischencode. Da die Teilausdrücke trivial sind, können einige Zwischenspeicher eingespart werden. Der Zwischencode wurde stur nach einem Schema erzeugt, das auch komplexere, d. h. rekursive Teilausdrücke berücksichtigen kann. Abb. 1.10: Optimierung t1 := b t2 := 10 if t1 < t2 goto label t3 := 1 a := t3 label: Optimierung if b < 10 goto label a := 1 label: maschinenunabhängige Optimierung Generell ist zwischen maschinenunabhängigen und maschinenabhängigen Optimierungen zu unterscheiden. Bei der Kompilierung von Hochsprachenprogrammen kommen bei der maschinenunabhängigen Optimierung insbesondere

21 1.5 Compiler für imperative Programmiersprachen Seite 19 Kontroll- und Datenflussanalysen zur Anwendung, die bspw. folgende Ziele haben: Erkennung von unerreichbarem Code Erkennung gemeinsamer Teilausdrücke Konstantenpropagierung Erkennen von Schleifeninvarianten, d. h. von Berechnungen, die in allen Schleifendurchläufen mit identischen Daten arbeiten, und daher aus der Schleife herausgezogen werden können. Sehr eng mit der eigentlichen Codeerzeugung verknüpft sind die Verfahren der maschinenabhängigen Optimierung. Dazu zählen bspw. die Registerzuordnung und die Befehlsanordnung. Register sind bei einem realen Prozessor meist nur in geringer Anzahl vorhanden und sollten möglichst optimal eingesetzt werden. Die Befehlsanordnung ist insbesondere wegen der Pipelinestrukturen moderner Prozessoren sehr wichtig. maschinenabhängige Optimierung Beispiel 1.7 Um unser fortlaufendes Beispiel abzuschließen, sei hier noch ein möglicher (Assembler-)Code einer finalen Codeerzeugung für Intel IA-32 angegeben: B mov ebx,b cmp ebx,10 jl label1 mov a,1 label1:... Die Codeoptimierung nimmt bei Compilern für Hochsprachenprogrammen Änderungen vor, die einen Code verbessern sollen. Es ist offensichtlich, dass diese Codeänderungen wieder zu korrektem Code führen müssen. Bisher gingen wir bei den Verbesserungen immer stillschweigend davon aus, dass damit eine schnellere Laufzeit des erzeugten Codes gemeint ist, also eine Steigerung der Laufzeiteffizienz. Das ist jedoch nur eine mögliche Zielfunktion von Optimierungen. Man sollte im Hinterkopf behalten, dass Compiler eventuell auch möglichst optimalen Code unter ganz anderen Zielfunktionen generieren müssen. Beispiele dafür sind: Optimierungsziele Geringe Codegröße Maximale Parallelisierung Echtzeitfähigkeit Geringer Energieverbrauch 1.5 Compiler für imperative Programmiersprachen Jeder Compiler muss gewisse Anforderungen erfüllen und Abhängigkeiten nach außen beachten. Die primäre Anforderung an einen Compiler ist natürlich die, dass er korrekt arbeitet. Eine weitere Anforderung ist die Geschwindigkeit des Compilers, d. h. seine effiziente Implementierung. Ein Compiler, der für die Übersetzung eines Programms Ewigkeiten braucht, wird sicher von einem Benutzer wenig akzeptiert. Es kann durchaus sein, dass die Geschwindigkeit eines Compilers für wichtiger eingeschätzt wird als die Qualität seines Erzeugnisses. Insbesondere Anforderungen an Compiler

22 Seite 20 Studienbrief 1 Einführung Optimierungen können sehr rechenzeitintensiv sein, d. h. eine Kompilierung kann sehr lange dauern, wenn versucht wird, ein fast optimales Ergebnis zu erzielen. 9 In anderen Szenarien kann jedoch die Qualität des Erzeugnisses Priorität vor der Laufzeit des Compilers haben. Ein Beispiel hierfür wäre ein Compiler, der Programme für eingebettete System erzeugt, deren Ressourcen an Speicherplatz und Geschwindigkeit stark beschränkt sind. Abhängigkeiten von Compilern Speicherorganisation Wir betrachten in diesem Modul neben den allgemeinen theoretischen Grundlagen meist Compiler für imperative Programmiersprachen. Es ist offensichtlich, dass für die Entwicklung solcher Compiler Kenntnisse über die Zielarchitektur vorausgesetzt werden. Etwas abstrakter ausgedrückt, benötigen wir ein Maschinenmodell, in dessen Sprache ein Compiler Programme übersetzt. Glücklicherweise entspricht das Maschinenmodell von Compilern für imperative Programmiersprachen im Wesentlichen dem Von-Neumann-Modell und damit der Architektur normal üblicher Prozessoren. Wir brauchen also gar nicht so genau zwischen Maschinenmodell und Zielarchitektur zu unterscheiden. Compiler für funktionale oder logische Programmiersprachen benutzten Maschinenmodelle, die i. Allg. keine direkte Entsprechung in der Realität haben. Dies macht insbesondere die Phase der Codeerzeugung schwieriger, weil zusätzlich noch eine Umsetzung des Maschinenmodells auf reale Hardware erforderlich wird. Maschinenmodelle und Übersetzungsschemata für Programmiersprachen der beiden genannten Klassen werden bspw. in [Wilhelm and Seidl, 2007] ausführlich beschrieben. In imperativen Programmiersprachen gibt es Datentypen, die in die Datentypen der Zielarchitektur überführt werden müssen. Bei einfachen Datentypen wie z. B. int, char oder float in der Programmiersprache C ist dies meist 1 : 1 möglich. Zusammengesetzte Datentypen wie Felder oder Strukturen müssen in einen zusammenhängenden Speicherbereich der Zielarchitektur abgebildet werden. Des Weiteren benötigen wir einen Speicherbereich für dynamisch erzeugte Datenstrukturen, einen Heap. Schließlich müssen wir noch die Lebensdauer und die Sichtbarkeit von Datenstrukturen berücksichtigen, wenn in der höheren Programmiersprache Funktionen definiert werden dürfen, die eventuell auch noch verschachtelt sind und rekursiv aufgerufen werden können. Die Verwaltung solcher Daten erfolgt über einen Stack. In den Speicher muss natürlich auch noch das Programm selbst abgelegt werden. Eine solche Speicherorganisation mit Codebereich, statischem Speicher, Heap und Stack zeigt Abb Das Programmiermodell (Speicherorganisation, Register, Befehlssatz) solcher Von-Neumann-Architekturen ist in diesem Modul unser Maschinenmodell zur Übersetzung imperativer Programmiersprachen. Auf die Mechanismen dieses Modells werden wir hier nicht mehr weiter eingehen; uns werden mehr die Datenstrukturen und Verfahren interessieren, die ein Compiler benutzt, um Code für dieses Architekturmodell zu erzeugen. Abb. 1.11: Grundprinzip der Speicherorganisation Code statischer Speicher Stack Heap Laufzeitumgebung Ein Compiler muss schließlich die Laufzeitumgebung berücksichtigen, in dem sein Erzeugnis ausgeführt werden soll. Gemeint ist damit letztendlich das Betriebssystem des Zielrechners. Das Programmformat (z. B. PE-Format für Windows) und die Programmierschnittstellen (API) müssen zum verwendeten Betriebssystem passen. 9 Die Erzeugung eines optimalen Ergebnisses ist aus theoretischen Gründen i. Allg. ohnehin nicht möglich. 10 Eine solche Speicherorganisation haben wir bereits im Modul Systemnahe Programmierung intensiv kennengelernt. Auch die grundsätzliche Codeerzeugung für Maschinen mit diesem Speichermodell wurde dort detailliert anhand von IA-32 erklärt.

23 1.6 Ausblick und Aufbau des Moduls Seite 21 So muss bspw. klar geregelt sein, wer die Speicherverwaltung für dynamische Datenstrukturen übernimmt, und welche Bibliotheken vorhanden und wie sie zu benutzen sind. Diese Aufgaben erledigt der Compiler zusammen mit dem Linker und dem Loader des Betriebssystems. Diese Aufgaben stehen allerdings außerhalb der Betrachtungen dieses Moduls. 1.6 Ausblick und Aufbau des Moduls Der Aufbau dieses Moduls orientiert sich an den Phasen der Kompilierung, wie sie in diesem Studienbrief vorgestellt wurden. Der Schwerpunkt liegt dabei in der Analysephase, da die dort verwendeten Techniken und Verfahren im Compilerbau allgemeingültigen Charakter haben. Die Synthesephase wird mit zunehmender Nähe zur Zielsprache immer abhängiger von dieser und immer spezieller. Hierfür werden wir eher allgemeine Verfahren vorstellen als die Programmsynthese für spezielle Zielsysteme. In der Synthesephase beziehen wir uns stark auf imperative Programmiersprachen wie C. Die Analysephase ist sehr stark theoretisch untermauert. Das Verständnis dieses theoretischen Unterbaus muss der Kern eines Moduls Compilerbau sein, weil sich daraus verschiedene Aspekte und Erkenntnisse fast automatisch ergeben. Wir werden es aber nicht bei der Theorie belassen. Es gibt sehr mächtige Werkzeuge, welche die theoretischen Grundlagen automatisiert umsetzen. Wir werden die Benutzung dieser Werkzeuge anhand von Flex und Bison erlernen. Flex und Bison sind die wohl gebräuchlichsten Werkzeuge dieser Art. Flex ist ein Programm, das nach Vorgabe lexikalischer Regeln automatisch einen passenden Scanner generiert. Bison ist ein Parsergenerator. Diesem werden die syntaktischen Regeln einer Sprache übergeben, aus denen Bison einen Parser für diese Sprache generiert. Zu den syntaktischen Regeln können zusätzlich semantische Aktionen definiert werden, sodass man im Zusammenspiel mit Flex selbst einen Compiler erzeugen kann. Um einschätzen zu können, wie Flex und Bison funktionieren, und was sie zu leisten imstande sind, ist es sehr wichtig die Theorie dahinter verstanden zu haben. Flex und Bison 1.7 Zusammenfassung Wir haben gesehen, dass Compiler in vielen, ganz unterschiedlichen Einsatzgebieten zur Anwendung kommen. Aber abgesehen vom jeweiligen Einsatzgebiet ist der interne Aufbau eines Compilers prinzipiell immer ähnlich. Grob durchläuft eine Kompilierung zwei Phasen, eine Analysephase und eine Synthesephase. Die Analysephase besteht aus einer lexikalischen, einer syntaktischen und einer semantischen Analyse und arbeitet nach Prinzipien, die in weiten Teilen unabhängig von der konkreten Verwendung eines Compilers sind. Während der Analysephase werden auch alle Informationen gesammelt, die in der nachfolgenden Synthesephase benötigt werden. Die Synthesephase besteht im Kern aus der Codeerzeugung und der Codeoptimierung und unterscheidet sich von Compiler zu Compiler mitunter sehr stark. Als Zwischenglied zwischen Analyse- und Synthesephase dient meist die Erzeugung eines Zwischencodes. Die Erzeugung von Zwischencode gehört zwar logisch zur Synthesephase, ist aber in Realität meist in die semantischen Analyse integriert. 1.8 Übungen

24 Seite 22 Studienbrief 1 Einführung Ü Übung 1.1 Benennen Sie einige Vor- und Nachteile von Compiler und Interpreter. Wo sehen Sie die Hauptunterschiede bei der Implementierung beider Übersetzertypen? Ü Übung 1.2 Nennen Sie Beispiele für Compiler und Einsatzgebiete von Compilerbautechniken, die in diesem Studienbrief nicht erwähnt wurden. Ü Übung 1.3 Erzeugen Sie die Token-Folge für den folgenden Programmausschnitt: if a >= 1 then if a < 10 then b := 0 end b := 1 end Ü Übung 1.4 Erzeugen Sie den Syntaxbaum für den Programmausschnitt der vorangegangenen Übung. Ü Übung 1.5 Übersetzen Sie den Programmausschnitt aus Übung 1.3 in 3-Adress-Code. Ü Übung 1.6 Optimieren Sie den 3-Adress-Code, den Sie in der vorangegangenen Übung erzeugt haben.

25

26 Liste der Lösungen zu den Kontrollaufgaben Seite 187 Liste der Lösungen zu den Kontrollaufgaben Lösung zu Kontrollaufgabe 1.1 auf Seite 14 Hier handelt es sich nicht um einen lexikalischen Fehler. Die (wahrscheinlich) sinnlose Verdopplung des Schlüsselwortes then muss während der syntaktischen Analyse erkannt werden. Lösung zu Kontrollaufgabe 1.2 auf Seite 16 Hinter then steht ein boolescher Ausdruck (boolexpr). Die zweite syntaktische Regel fordert hier aber eine Anweisung (stmt). Eine Anweisung ist eine Zuweisung oder eine bedingte Anweisung (erste syntaktische Regel) und niemals ein boolescher Ausdruck. Lösung zu Kontrollaufgabe 1.3 auf Seite 16 Nein, der boolesche Ausdruck ist syntaktisch korrekt, weil zwei Werte (numexpr) miteinander verglichen werden. Ob der Vergleich hier sinnvoll bzw. erlaubt ist, muss die semantische Analyse entscheiden.

27

28 Verzeichnisse Seite 189 Verzeichnisse I. Abbildungen Abb. 1.1: Compiler Abb. 1.2: Zusammenspiel von Compiler, Assembler und Linker Abb. 1.3: Phasen der Kompilierung [Aho et al., 1999] Abb. 1.4: Lexikalische Analyse Abb. 1.5: Lexikalische Analyse Abb. 1.6: Syntaktische Analyse Abb. 1.7: Syntaktische Analyse Abb. 1.8: Semantische Analyse Abb. 1.9: Erzeugung von Zwischencode Abb. 1.10: Optimierung Abb. 1.11: Grundprinzip der Speicherorganisation Abb. 2.1: Lexikalische Analyse Abb. 2.2: Verarbeitungsschritt eines NEAs Abb. 2.3: NEA als Übergangsdiagramm Abb. 2.4: NEA für Integer- und Fließkommakonstanten Abb. 2.5: Initialisierung Abb. 2.6: Schrittweise Verfeinerung Abb. 2.7: Entwicklung des Übergangsdiagramms zum regulären Ausdruck ZZ Abb. 2.8: NEA zum regulären Ausdruck a(a 0) Abb. 2.9: DEA zum regulären Ausdruck a(a 0) Abb. 2.10: Äquivalenz von Zuständen Abb. 2.11: Die Rolle eines Scanner-Generators Abb. 3.1: Syntaktische Analyse Abb. 3.2: Syntaxbaum Abb. 3.3: Alternativer Syntaxbaum zu id := id * id + id Abb. 3.4: Zusammenhang zwischen Rechts- und Linksableitung [Wilhelm et al., 2012] Abb. 3.5: Syntaxbaum zu id := id - num * id Abb. 3.6: Verhältnis von FIRST- und FOLLOW-Mengen Abb. 3.7: Vorausschauender Top-down-Parser als Kellerautomat Abb. 3.8: Initialisierung eines Kellerautomaten Abb. 3.9: Verarbeitungsschritt eines Kellerautomaten Abb. 3.10: Benutzte Handles bei den Reduce-Schritten Abb. 3.11: LR(1)-Parser als abstrakte Maschine Abb. 3.12: DEA aus ACTION- und GOTO-Tabelle Abb. 3.13: Ableitungsbaum von id+id*id bei Schritt Abb. 3.14: Teil-DEA nach 1. Iteration Abb. 4.1: Semantische Analyse Abb. 4.2: Synthetisierung des Attributs val Abb. 4.3: Berechnung des Attributs type Abb. 4.4: Syntaxbaum zur Eingabe Abb. 4.5: Stack Frames zur Laufzeitsituation main-p-p Abb. 4.6: Grundprinzip der Speicherorganisation Abb. 4.7: Struktur eines Stack Frame Abb. 4.8: Sprünge bei while- und if-then-else-anweisungen Abb. 4.9: Auswerteschema boolescher Operationen Abb. 5.1: Flussanalyse Abb. 5.2: Programmstruktur und Basic Blocks Abb. 5.3: Leader Instructions Abb. 5.4: Basic Blocks mit Kontrollfluss Abb. 5.5: Dominatoren Abb. 5.6: Schleife im CFG Abb. 5.7: Knoten 2 und 3: Eine Schleife?

Definition Compiler. Bekannte Compiler

Definition Compiler. Bekannte Compiler Compiler Inhalt: Definition Compiler / bekannte Compiler Klassifikationen von Compilern Analyse-Synthese-Modell der Kompilierung Analyse des Quellprogramms Synthesephase Die Phasen eines Compilers Symboltabellenverwaltung

Mehr

Compilerbau für die Common Language Run-Time

Compilerbau für die Common Language Run-Time Compilerbau für die Common Language Run-Time Syntax und Semantik von Programmiersprachen 2 Compilerbau Sprachbeschreibung vs. Implementierung Beschreibung: formale oder informale (engl.) Lexik, Syntax,

Mehr

Grundlagen der Programmierung 3 A

Grundlagen der Programmierung 3 A Grundlagen der Programmierung 3 A Compiler A: Phasen Lexikalische Analyse; Scanner Prof. Dr. Manfred Schmidt-Schauß Sommersemester 2018 Compiler; Übersetzungsprogramme Ein Übersetzer (Compiler) ist ein

Mehr

Programmiersprachen und Übersetzer

Programmiersprachen und Übersetzer Programmiersprachen und Übersetzer Sommersemester 2009 5. April 2009 Vorteile bei der Verwendung höherer Programmiersprachen Vorteile bei der Verwendung höherer Programmiersprachen 1. Einfache Notation

Mehr

Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen

Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen 16OH21005 gefördert. Die Verantwortung für den Inhalt dieser

Mehr

Übungs- und Praktikumsaufgaben zur Systemprogrammierung Dipl.-Ing. H. Büchter (Lehrbeauftragter) FH-Dortmund WS 2001/2002 / SS 2002

Übungs- und Praktikumsaufgaben zur Systemprogrammierung Dipl.-Ing. H. Büchter (Lehrbeauftragter) FH-Dortmund WS 2001/2002 / SS 2002 1. Stellen Sie die schrittweise Verbesserung eines Compilers durch das Bootstrap- Verfahren mit Hilfe von T-Diagrammen dar. Gegeben ist ein auf der Maschine M lauffähiger Compiler C 1, der in S geschrieben

Mehr

Einführung. (Compiler) Prof. Dr. Oliver Braun. Letzte Änderung: :49. Einführung 1/26

Einführung. (Compiler) Prof. Dr. Oliver Braun. Letzte Änderung: :49. Einführung 1/26 Einführung (Compiler) Prof. Dr. Oliver Braun Letzte Änderung: 10.05.2017 15:49 Einführung 1/26 Ein Compiler ist ein Computerprogramm das ein Programm geschrieben in einer Sprache in ein Programm übersetzt

Mehr

Compiler. Einführung. Prof. Dr. Oliver Braun. Fakultät für Informatik und Mathematik Hochschule München. Letzte Änderung:

Compiler. Einführung. Prof. Dr. Oliver Braun. Fakultät für Informatik und Mathematik Hochschule München. Letzte Änderung: Compiler Einführung Fakultät für Informatik und Mathematik Hochschule München Letzte Änderung: 10.05.2017 15:49 Inhaltsverzeichnis Ein Compiler................................... 2 Ein Compiler...................................

Mehr

Compiler: Einführung

Compiler: Einführung Fakultät für Informatik und Mathematik Hochschule München Letzte Änderung: 10.05.2017 15:49 Inhaltsverzeichnis Ein Compiler................................... 2 Ein Compiler...................................

Mehr

Informatik II SS Der Kompilationsprozess (-phasen) Schreiben des Programms. Die Organisation eines typischen Compilers

Informatik II SS Der Kompilationsprozess (-phasen) Schreiben des Programms. Die Organisation eines typischen Compilers Der Kompilationsprozess (-phasen) Informatik II SS 2004 Teil 6: Sprachen, Compiler und Theorie 7 Prof. Dr. Dieter Hogrefe Dipl.-Inform. Michael Ebner Lehrstuhl für Telematik Institut für Informatik Scanner

Mehr

Grundlagen der Programmierung 3 A

Grundlagen der Programmierung 3 A Grundlagen der Programmierung 3 A Compiler A: Phasen; Scanner Prof. Dr. Manfred Schmidt-Schauß Sommersemester 2017 Compiler; Übersetzungsprogramme Ein Übersetzer (Compiler) ist ein Programm, das ein Wort

Mehr

Definitionen/Vorarbeit zum Thema Java

Definitionen/Vorarbeit zum Thema Java Definitionen/Vorarbeit zum Thema Java Programmiersprachen: System von Wörtern und Symbolen, die zur Formulierung von Programmen für die elektronische Datenverarbeitung verwendet werden. Arten: z.b. Javascript

Mehr

Grundlagen der Programmierung 2 (Comp-A)

Grundlagen der Programmierung 2 (Comp-A) Grundlagen der Programmierung 2 (Comp-A) Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 23. Mai 2007 Compiler; Übersetzungprogramme Ein Übersetzer (Compiler) ist ein Programm,

Mehr

EIGENSCHAFTEN VON SPRACHEN

EIGENSCHAFTEN VON SPRACHEN Vorlesung und Übung Universität Paderborn Wintersemester 2016/2017 Dr. Peter Pfahler EIGENSCHAFTEN VON SPRACHEN EWS, WS 2016/17, Pfahler C-1 Einführung Sprachen in der Informatik werden für bestimmte Zwecke

Mehr

Lexikalische Programmanalyse der Scanner

Lexikalische Programmanalyse der Scanner Der Scanner führt die lexikalische Analyse des Programms durch Er sammelt (scanned) Zeichen für Zeichen und baut logisch zusammengehörige Zeichenketten (Tokens) aus diesen Zeichen Zur formalen Beschreibung

Mehr

9.4 Grundlagen des Compilerbaus

9.4 Grundlagen des Compilerbaus Kap09.fm Seite 717 Dienstag, 7. September 2010 2:06 14 9.4 Grundlagen des Compilerbaus 717 so dass die Benutzung dieser Regeln zum Aufbau eines + -Knotens bzw. eines Negations- Knotens im abstrakten Syntaxbaum

Mehr

Compiler; Übersetzungsprogramme. Grundlagen der Programmierung 3 A. Compiler für Programmiersprachen. Phasen eines Compilers

Compiler; Übersetzungsprogramme. Grundlagen der Programmierung 3 A. Compiler für Programmiersprachen. Phasen eines Compilers ompiler; Übersetzungsprogramme Grundlagen der Programmierung 3 A ompiler A: Phasen; Scanner Prof. Dr. Manfred Schmidt-Schauß Sommersemester 2017 Ein Übersetzer (ompiler) ist ein Programm, das ein Wort

Mehr

1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen - 1 -

1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen - 1 - 1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen I.2. I.2. Grundlagen von von Programmiersprachen. - 1 - 1. Der Begriff Informatik "Informatik" = Kunstwort aus Information und Mathematik

Mehr

1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen - 1 -

1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen - 1 - 1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen I.2. I.2. Grundlagen von von Programmiersprachen. - 1 - 1. Der Begriff Informatik "Informatik" = Kunstwort aus Information und Mathematik

Mehr

Grundlagen der Programmierung 2 (Comp-A)

Grundlagen der Programmierung 2 (Comp-A) Grundlagen der Programmierung 2 (Comp-A) Prof. Dr. Manfred Schmidt-Schauß Künstliche Intelligenz und Softwaretechnologie 16. Juni 2011 Compiler; Übersetzungsprogramme Ein Übersetzer (Compiler) ist ein

Mehr

Zuerst wird die Bedingung ausgewertet. Ist sie erfüllt, wird der Rumpf des while-statements ausgeführt. Nach Ausführung des Rumpfs wird das gesamte

Zuerst wird die Bedingung ausgewertet. Ist sie erfüllt, wird der Rumpf des while-statements ausgeführt. Nach Ausführung des Rumpfs wird das gesamte Zuerst wird die Bedingung ausgewertet. Ist sie erfüllt, wird der Rumpf des while-statements ausgeführt. Nach Ausführung des Rumpfs wird das gesamte while-statement erneut ausgeführt. Ist die Bedingung

Mehr

3.1 Reservierte Wörter

3.1 Reservierte Wörter 3.1 Reservierte Wörter int Bezeichner für Basis-Typen; if, else, while Schlüsselwörter aus Programm-Konstrukten; (,), ",, {,},,,; Sonderzeichen. 62 3.2 Was ist ein erlaubter Name? Schritt 1: Angabe der

Mehr

Zwischencode-Erzeugung. 2. Juni 2009

Zwischencode-Erzeugung. 2. Juni 2009 Zwischencode-Erzeugung im Rahmen des Seminars "Übersetzung von künstlichen Sprachen" Sebastian Hanneken 2. Juni 2009 1 / 32 1 Einleitung Einordnung Funktion von Zwischencode 3-Adresscode (3AC) 2 Erzeugung

Mehr

3 Syntax von Programmiersprachen

3 Syntax von Programmiersprachen 3 Syntax von Programmiersprachen Syntax ( Lehre vom Satzbau ) formale Beschreibung des Aufbaus der Worte und Sätze, die zu einer Sprache gehören; im Falle einer Programmiersprache Festlegung, wie Programme

Mehr

Implementierung eines LR-Parser-Generators mit syntaktischen Prädikaten

Implementierung eines LR-Parser-Generators mit syntaktischen Prädikaten Implementierung eines LR-Parser-Generators mit syntaktischen Prädikaten Aufgabenbeschreibung 29. Juli 2011 1 Einleitung und Motivation Der Parser-Generator Antlr [Par07] bietet die Möglichkeit, die Auswahl

Mehr

Grundlagen der Informatik III Wintersemester 2010/ Vorlesung Dr.-Ing. Wolfgang Heenes

Grundlagen der Informatik III Wintersemester 2010/ Vorlesung Dr.-Ing. Wolfgang Heenes Grundlagen der Informatik III Wintersemester 2010/2011 20. Vorlesung Dr.-Ing. Wolfgang Heenes int main() { printf("hello, world!"); return 0; } msg: main:.data.asciiz "Hello, world!".text.globl main la

Mehr

Inhaltsverzeichnis. Inhalt. Bemerkung... 9 Vorwort Programme und Programmiersprachen

Inhaltsverzeichnis. Inhalt. Bemerkung... 9 Vorwort Programme und Programmiersprachen Inhalt 3 Bemerkung... 9 Vorwort... 10 1 Programme und Programmiersprachen 1.1 Assembler... 13 1.2 Höhere Programmiersprachen... 15 1.2.1 Interpreter... 16 1.2.2 Compiler... 17 1.2.3 Zwischencode... 18

Mehr

Einführung in die Informatik I (autip)

Einführung in die Informatik I (autip) Einführung in die Informatik I (autip) Dr. Stefan Lewandowski Fakultät 5: Informatik, Elektrotechnik und Informationstechnik Abteilung Formale Konzepte Universität Stuttgart 24. Oktober 2007 Was Sie bis

Mehr

Programmieren in C. Eine Einführung in die Programmiersprache C. Prof. Dr. Nikolaus Wulff

Programmieren in C. Eine Einführung in die Programmiersprache C. Prof. Dr. Nikolaus Wulff Programmieren in C Eine Einführung in die Programmiersprache C Prof. Dr. Nikolaus Wulff Agenda Elementare Einführung C Programm Syntax Datentypen, Variablen und Konstanten Operatoren und Ausdrücke Kontrollstrukturen

Mehr

Stratego/XT und ASF+SDF Meta-Environment. Paul Weder Seminar Transformationen Datum:

Stratego/XT und ASF+SDF Meta-Environment. Paul Weder Seminar Transformationen Datum: Stratego/XT und ASF+SDF Meta-Environment Paul Weder Seminar Transformationen Datum: 20.01.2006 Gliederung Allgemeines ASF+SDF Meta-Environment Stratego/XT Zusammenfassung/Vergleich SDF (Syntax Definition

Mehr

Berichte aus der Informatik. Dieter Pawelczak. Start in die C-Programmierung

Berichte aus der Informatik. Dieter Pawelczak. Start in die C-Programmierung Berichte aus der Informatik Dieter Pawelczak Start in die C-Programmierung Shaker Verlag Aachen 2012 Inhaltsverzeichnis Inhaltsverzeichnis i 1 Einleitung 1 1.1 Umfeld und Aufbau des Buches 1 Die Programmiersprache

Mehr

Definition von LR(k)-Grammatiken

Definition von LR(k)-Grammatiken Definition von LR(k)-Grammatiken Ziel: Ein Lookahead von k soll ausreichen um entscheiden zu können, welche Regel angewendet werden muss. Definition: FIRST k (w 1 w n ):= w 1 w k, falls n k, w 1 w n, sonst.

Mehr

3 Syntax von Programmiersprachen

3 Syntax von Programmiersprachen 3 Syntax von Programmiersprachen Syntax ( Lehre vom Satzbau ) formale Beschreibung des Aufbaus der Worte und Sätze, die zu einer Sprache gehören; im Falle einer Programmiersprache Festlegung, wie Programme

Mehr

Die Klasse MiniJava ist in der Datei MiniJava.java definiert:

Die Klasse MiniJava ist in der Datei MiniJava.java definiert: Die Klasse MiniJava ist in der Datei MiniJava.java definiert: import javax.swing.joptionpane; import javax.swing.jframe; public class MiniJava { public static int read () { JFrame f = new JFrame (); String

Mehr

Inhalt. Einführung in die Strukturierte Programmierung 15

Inhalt. Einführung in die Strukturierte Programmierung 15 Inhalt Einführung in die Strukturierte Programmierung 15 1.1 Was bedeutet Programmieren? 17 1.2 Was bedeutet Strukturierte Programmierung? 18 1.3 Was ist Pascal? 19 1.4 Was ist PS/k? 20 1.5 Warum wird

Mehr

Springer-Verlag Berlin Heidelberg GmbH

Springer-Verlag Berlin Heidelberg GmbH Springer-Lehrbuch Springer-Verlag Berlin Heidelberg GmbH Ralf Hartmut Güting Martin Erwig Ü bersetzerba u Techniken, Werkzeuge, Anwendungen Mit 103 Abbildungen Springer Prof. Dr. Ralf HartmutGüting Dr.

Mehr

Einführung in die Informatik. Programming Languages

Einführung in die Informatik. Programming Languages Einführung in die Informatik Programming Languages Beschreibung von Programmiersprachen Wolfram Burgard Motivation und Einleitung Wir haben in den vorangehenden Kapiteln meistens vollständige Java- Programme

Mehr

Übersetzergenerierung mit lex und yacc

Übersetzergenerierung mit lex und yacc Übersetzergenerierung mit lex und yacc 0. Überblick und Organisatorisches Jan Bredereke WiSe 2006/07, Universität Bremen otivation Übersetzer: Grundlegende Werkzeuge welche Fehler kann er finden? Konstrukt

Mehr

Varianten endlicher Automaten

Varianten endlicher Automaten Varianten endlicher Automaten Varianten endlicher Automaten 2 Endliche Automaten mit λ-übergängen können aktuellen Zustand wechseln, ohne ein Zeichen zu lesen; sind praktisch (vereinfachen oft die Modellierung

Mehr

Programmierung 2. Übersetzer: Das Frontend. Sebastian Hack. Klaas Boesche. Sommersemester

Programmierung 2. Übersetzer: Das Frontend. Sebastian Hack. Klaas Boesche. Sommersemester 1 Programmierung 2 Übersetzer: Das Frontend Sebastian Hack hack@cs.uni-saarland.de Klaas Boesche boesche@cs.uni-saarland.de Sommersemester 2012 Vom Programm zur Maschine Was passiert eigentlich mit unseren

Mehr

Javakurs für Anfänger

Javakurs für Anfänger Javakurs für Anfänger Einheit 06: Einführung in Kontrollstrukturen Lorenz Schauer Lehrstuhl für Mobile und Verteilte Systeme Heutige Agenda 1. Teil: Einführung in Kontrollstrukturen 3 Grundstrukturen von

Mehr

Werkzeuge zur Programmentwicklung

Werkzeuge zur Programmentwicklung Werkzeuge zur Programmentwicklung B-15 Bibliothek Modulschnittstellen vorübersetzte Module Eingabe Editor Übersetzer (Compiler) Binder (Linker) Rechner mit Systemsoftware Quellmodul (Source) Zielmodul

Mehr

Pumping-Lemma 2 Pumping-Lemma Sei L eine von einem endlichen Automaten erkannte Sprache. Dann existiert eine natürliche Zahl p N derart, dass jedes Wo

Pumping-Lemma 2 Pumping-Lemma Sei L eine von einem endlichen Automaten erkannte Sprache. Dann existiert eine natürliche Zahl p N derart, dass jedes Wo 1 Endliche Automaten Modellierungskonzept mit vielen brauchbaren Eigenschaften schnelle Spracherkennung graphisch-visuelle Beschreibung automatische Korrektheitsbeweise gute Kompositionalitätseigenschaften

Mehr

Lexikalische Analyse, Tokenizer, Scanner

Lexikalische Analyse, Tokenizer, Scanner Lexikalische Analyse, Tokenizer, Scanner Frühe Phase des Übersetzers Aufgabenteilung: Scanner (lokale) Zeichen (Symbol-)Analyse Parser Syntax-Analyse Aufgabe des Scanners: Erkennung von: Zahlen, Bezeichner,

Mehr

n 1. Der Begriff Informatik n 2. Syntax und Semantik von Programmiersprachen - 1 -

n 1. Der Begriff Informatik n 2. Syntax und Semantik von Programmiersprachen - 1 - n 1. Der Begriff Informatik n 2. Syntax und Semantik von Programmiersprachen I.2. I.2. Grundlagen von von Programmiersprachen. - 1 - 1. Der Begriff Informatik n "Informatik" = Kunstwort aus Information

Mehr

5. Syntaxanalyse und der Parser-Generator yacc. 5.5 Aufsteigende Analyse. Absteigende Analyse versus aufsteigende Analyse. 5.5 Aufsteigende Analyse

5. Syntaxanalyse und der Parser-Generator yacc. 5.5 Aufsteigende Analyse. Absteigende Analyse versus aufsteigende Analyse. 5.5 Aufsteigende Analyse 5. Syntaxanalyse und der Parser-Generator yacc 5.1 Einleitung 5.2 Kontextfreie Grammatiken 5.3 Grundlagen von yacc 5.4 Absteigende Analyse Übersetzergenerierung Syntaxanalyse und yacc (2) Jan Bredereke,

Mehr

Programmieren lernen mit Perl

Programmieren lernen mit Perl Xpert.press Programmieren lernen mit Perl Bearbeitet von Joachim Ziegler 1. Auflage 2002. Buch. XIV, 400 S. Hardcover ISBN 978 3 540 42685 1 Format (B x L): 15,5 x 23,5 cm Gewicht: 783 g Weitere Fachgebiete

Mehr

2.2 Syntax, Semantik und Simulation

2.2 Syntax, Semantik und Simulation 2.2 Syntax, Semantik und Simulation Ein Java Programm ist eine Folge von Buchstaben. Nicht jede Folge von Buchstaben ist ein korrektes Java Programm! Wie kann man alle korrekten Java Programme beschreiben?

Mehr

Praktikum Compilerbau Sitzung 4 Abstrakter Syntaxbaum

Praktikum Compilerbau Sitzung 4 Abstrakter Syntaxbaum Praktikum Compilerbau Sitzung 4 Abstrakter Syntaxbaum Prof. Dr.-Ing. Gregor Sneltg Andreas Zwkau IPD Sneltg, Lehrstuhl für Programmierparadigmen KIT Universität des Landes Baden-Württemberg und nationales

Mehr

Einführung in die Computerlinguistik Einführung in Perl (1)

Einführung in die Computerlinguistik Einführung in Perl (1) Einführung in die Computerlinguistik Einführung in Perl (1) Dozentin: Wiebke Petersen 26.11.2009 Wiebke Petersen Einführung CL (WiSe 09/10) 1 Compiler Ein Compiler (auch Übersetzer oder Kompilierer genannt)

Mehr

3.4 Struktur von Programmen

3.4 Struktur von Programmen 3.4 Struktur von Programmen Programme sind hierarchisch aus Komponenten aufgebaut. Für jede Komponente geben wir Regeln an, wie sie aus anderen Komponenten zusammengesetzt sein können. program ::= decl*

Mehr

Syntax von Programmiersprachen

Syntax von Programmiersprachen Syntax von Programmiersprachen SEP 209 Programmiersprachen Sprache = Menge von Wörtern, typischerweise unendlich Programmiersprache: Wörter repräsentieren Programme Programm kann auf einem Computer evtl.

Mehr

2. Programmierung in C

2. Programmierung in C 2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten, Operatoren und Ausdrücke Anweisungen und Kontrollstrukturen (Steuerfluss)

Mehr

Es gibt keinen Algorithmus zum Schreiben eines Programms bzw. Algorithmus.

Es gibt keinen Algorithmus zum Schreiben eines Programms bzw. Algorithmus. 1 Einführung Programmiersprachen: Ermöglichen formale Beschreibung von Problemlösungsverfahren, die auf einem Computer oder Computersystemen ausführbar sind. Bilden die Basis zur Entwicklung von Software

Mehr

2. Programmierung in C

2. Programmierung in C 2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten, Operatoren und Ausdrücke Anweisungen und Kontrollstrukturen (Steuerfluss)

Mehr

Inhalt Kapitel 11: Formale Syntax und Semantik

Inhalt Kapitel 11: Formale Syntax und Semantik Inhalt Kapitel 11: Formale Syntax und Semantik 1 Abstrakte und konkrete Syntax 2 Lexikalische Analyse 3 Formale Sprachen, Grammatiken, BNF 4 Syntaxanalyse konkret 266 Abstrakte und konkrete Syntax Abstrakte

Mehr

Intensivübung zu Algorithmen und Datenstrukturen

Intensivübung zu Algorithmen und Datenstrukturen Intensivübung zu Algorithmen und Datenstrukturen Silvia Schreier Informatik 2 Programmiersysteme Martensstraße 3 91058 Erlangen Übersicht Programmierung Fallunterscheidung Flussdiagramm Bedingungen Boolesche

Mehr

Grammatiken. Grammatiken sind regelbasierte Kalküle zur Konstruktion von Systemen und Sprachen Überprüfung von Systemen und Sprachen

Grammatiken. Grammatiken sind regelbasierte Kalküle zur Konstruktion von Systemen und Sprachen Überprüfung von Systemen und Sprachen Grammatiken Grammatiken sind regelbasierte Kalküle zur Konstruktion von Systemen und Sprachen Überprüfung von Systemen und Sprachen Grammatiken eignen sich besonders zur Modellierung beliebig tief geschachtelter,

Mehr

Interpreter - Gliederung

Interpreter - Gliederung Institut für Informatik Ludwig-Maximilian Universität Interpreter - Gliederung Programmiersprache Syntax Konkrete Syntax Abstrakter Syntax Baum (Abstrakte Syntax) Parser Syntaktische Struktur einer Sprache

Mehr

Compilerbau + Virtuelle Maschinen

Compilerbau + Virtuelle Maschinen Helmut Seidl Compilerbau + Virtuelle Maschinen München Sommersemester 2009 1 Organisatorisches Der erste Abschnitt Die Übersetzung von C ist den Vorlesungen Compilerbau und Virtuelle Maschinen gemeinsam

Mehr

2 Eine einfache Programmiersprache

2 Eine einfache Programmiersprache 2 Eine einfache Programmiersprache Eine Programmiersprache soll Datenstrukturen anbieten Operationen auf Daten erlauben Kontrollstrukturen zur Ablaufsteuerung bereitstellen Als Beispiel betrachten wir

Mehr

Institut für Computational Science Prof. Dr. H. Hinterberger. Praxismodul 1. Einführung in die Programmierung Erste Programme

Institut für Computational Science Prof. Dr. H. Hinterberger. Praxismodul 1. Einführung in die Programmierung Erste Programme Institut für Computational Science Prof. Dr. H. Hinterberger Praxismodul 1 Einführung in die Programmierung Erste Programme Einführung in die Programmierung 2 Institut für Computational Science, ETH Zürich,

Mehr

Konzepte der Programmiersprachen

Konzepte der Programmiersprachen Konzepte der Programmiersprachen Lehrstuhl Prof. Plödereder Eduard Wiebe Institut für Softwaretechnologie Abteilung Programmiersprachen und Übersetzerbau Sommersemester 2007 Programm-Ausführung Programmiersprachen

Mehr

2 Eine einfache Programmiersprache. Variablen. Operationen Zuweisung. Variablen

2 Eine einfache Programmiersprache. Variablen. Operationen Zuweisung. Variablen Variablen Eine Programmiersprache soll Datenstrukturen anbieten Operationen auf Daten erlauben Kontrollstrukturen zur Ablaufsteuerung bereitstellen Variablen dienen zur Speicherung von Daten. Um Variablen

Mehr

Praktische Informatik I

Praktische Informatik I Praktische Informatik I WS 2005/2005 Prof. Dr. Wolfgang Effelsberg Lehrstuhl für Praktische Informatik IV Universität Mannheim 1. Einführung 1-1 Inhaltsverzeichnis (1) 1. Einführung 1.1 Was ist Informatik?

Mehr

Alfred V. Aho Monica S. Lam Ravi Sethi Jeffrey D. Ullman. Compiler. informatik. Prinzipien, Techniken und Werkzeuge. 2., aktualisierte Auflage

Alfred V. Aho Monica S. Lam Ravi Sethi Jeffrey D. Ullman. Compiler. informatik. Prinzipien, Techniken und Werkzeuge. 2., aktualisierte Auflage Alfred V. Aho Monica S. Lam Ravi Sethi Jeffrey D. Ullman it informatik Compiler Prinzipien, Techniken und Werkzeuge 2., aktualisierte Auflage Inhaltsverzeichnis Vorwort... XXIX Zur deutschen Ausgabe...XXXIII

Mehr

Theoretische Informatik I

Theoretische Informatik I Theoretische nformatik inheit 3 Kontextfreie Sprachen 1. Kontextfreie Grammatiken 2. Pushdown Automaten 3. igenschaften kontextfreier Sprachen Verarbeitung von Programmiersprachen Was ist das einfachste

Mehr

Inhaltsverzeichnis. Grundlagen und Einführung (1. Band) 1

Inhaltsverzeichnis. Grundlagen und Einführung (1. Band) 1 Inhaltsverzeichnis Grundlagen und Einführung (1. Band) 1 1 Einleitung und Vorwort 1 1.1 Vorwort zur 13. Auflage....................... 1 1.2 Vorwort zur 10. Auflage....................... 1 1.3 Voraussetzungen...........................

Mehr

Programmiersprache. Emily & rica

Programmiersprache. Emily & rica Programmiersprache Emily & rica inhaltsangabe Programmiersprache Def inition/funktion Arten Gängige Algorithmus/Syntax Compiler, Interpreter Def inition Unterscheidung Vor- und Nachteile Compiler/ Interpreter

Mehr

Compilerbau. Wintersemester 2009 / Dr. Heiko Falk

Compilerbau. Wintersemester 2009 / Dr. Heiko Falk Compilerbau Wintersemester 2009 / 2010 Dr. Heiko Falk Technische Universität Dortmund Lehrstuhl Informatik 12 Entwurfsautomatisierung für Eingebettete Systeme Kapitel 2 Interner Aufbau von Compilern Folie

Mehr

Grundlagen der Informatik I (Studiengang Medieninformatik)

Grundlagen der Informatik I (Studiengang Medieninformatik) Grundlagen der Informatik I (Studiengang Medieninformatik) Thema: 3. Datentypen, Datenstrukturen und imperative Programme Prof. Dr. S. Kühn Fachbereich Informatik/Mathematik Email: skuehn@informatik.htw-dresden.de

Mehr

Übersicht Formale Semantik. Übersicht Axiomatische Semantik. Inhaltsübersicht HPS WS 2003/04. Vorlesung Höhere Programmiersprachen,

Übersicht Formale Semantik. Übersicht Axiomatische Semantik. Inhaltsübersicht HPS WS 2003/04. Vorlesung Höhere Programmiersprachen, Vorlesung Höhere Programmiersprachen, WS 2003/04 Teil 2: Formale Semantik Axiomatische Semantik Inhaltsübersicht - Grundlagen (1,2) - Konzepte imperativer Programmiersprachen (2,3) - Deklarative Programmiersprachen

Mehr

Objektorientierte Programmierung. Kapitel 3: Syntaxdiagramme

Objektorientierte Programmierung. Kapitel 3: Syntaxdiagramme Stefan Brass: OOP (Java), 3. 1/31 Objektorientierte Programmierung Kapitel 3: Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester 2014/15 http://www.informatik.uni-halle.de/ brass/oop14/

Mehr

Algorithmen und Datenstrukturen (für ET/IT)

Algorithmen und Datenstrukturen (für ET/IT) Algorithmen und Datenstrukturen (für ET/IT) Sommersemester 2016 Dr. Tobias Lasser Computer Aided Medical Procedures Technische Universität München Programm heute 1 Einführung 2 Grundlagen von Algorithmen

Mehr

Theoretische Informatik I

Theoretische Informatik I Theoretische Informatik I Einheit 2.5 Grammatiken 1. Arbeitsweise 2. Klassifizierung 3. Beziehung zu Automaten Beschreibung des Aufbaus von Sprachen Mathematische Mengennotation Beschreibung durch Eigenschaften

Mehr

III.1 Prinzipien der funktionalen Programmierung - 1 -

III.1 Prinzipien der funktionalen Programmierung - 1 - 1. Prinzipien der funktionalen Programmierung 2. Deklarationen 3. Ausdrücke 4. Muster (Patterns) 5. Typen und Datenstrukturen 6. Funktionale Programmiertechniken III.1 Prinzipien der funktionalen Programmierung

Mehr

FACHHOCHSCHULE AUGSBURG Hochschule für Technik, Wirtschaft und Gestaltung

FACHHOCHSCHULE AUGSBURG Hochschule für Technik, Wirtschaft und Gestaltung C Sprachelemente für Übung 2 Typumwandlungen (type casts) Bei Ausdrücken, in denen Operanden mit unterschiedlichem Typ vorkommen, werden diese vom Compiler vor der Ausführung automatisch in einen gemeinsamen

Mehr

Kapitel 1: Informationsverarbeitung durch Programme

Kapitel 1: Informationsverarbeitung durch Programme LUDWIG- MAXIMILIANS- UNIVERSITY MUNICH DEPARTMENT INSTITUTE FOR INFORMATICS Skript zur Vorlesung: Einführung in die Informatik: Systeme und Anwendungen Sommersemester 2009 Kapitel 1: Informationsverarbeitung

Mehr

ECDL MODUL COMPUTING. Syllabus Version 1.0

ECDL MODUL COMPUTING. Syllabus Version 1.0 ECDL MODUL COMPUTING Syllabus Version 1.0 DLGI Dienstleistungsgesellschaft für Informatik Am Bonner Bogen 6 53227 Bonn Tel.: 0228-688-448-0 Fax: 0228-688-448-99 E-Mail: info@dlgi.de, URL: www.dlgi.de In

Mehr

Gliederung. n Teil I: Einleitung und Grundbegriffe. n Teil II: Imperative und objektorientierte Programmierung

Gliederung. n Teil I: Einleitung und Grundbegriffe. n Teil II: Imperative und objektorientierte Programmierung Gliederung n Teil I: Einleitung und Grundbegriffe l 1. Organisatorisches l 2. Grundlagen von Programmiersprachen n Teil II: Imperative und objektorientierte Programmierung l 1. Grundelemente der Programmierung

Mehr

Programm heute. Algorithmen und Datenstrukturen (für ET/IT) Definition Algorithmus. Wie beschreibt man Algorithmen?

Programm heute. Algorithmen und Datenstrukturen (für ET/IT) Definition Algorithmus. Wie beschreibt man Algorithmen? Programm heute Algorithmen und Datenstrukturen (für ET/IT) Sommersemester 2015 1 Einführung Dr. Tobias Lasser Computer Aided Medical Procedures Technische Universität München 2 Grundlagen von Algorithmen

Mehr

Compilerbau. Wintersemester 2010 / Dr. Heiko Falk

Compilerbau. Wintersemester 2010 / Dr. Heiko Falk Compilerbau Wintersemester 2010 / 2011 Dr. Heiko Falk Technische Universität Dortmund Lehrstuhl Informatik 12 Entwurfsautomatisierung für Eingebettete Systeme Organisatorisches (1) Vorlesung (2V) Montags,

Mehr

7. Optimierung. Verschiedene Hilfsmittel zur Entscheidung der Optimierungsfrage:

7. Optimierung. Verschiedene Hilfsmittel zur Entscheidung der Optimierungsfrage: Verschiedene Hilfsmittel zur Entscheidung der Optimierungsfrage: abstrakte Interpretation Datenflußanalysen wie: lebendige Variablen ankommende Definitionen verfügbare Ausdrücke wichtige Ausdrücke Beispiel

Mehr

Von der Grammatik zum AST

Von der Grammatik zum AST Von der Grammatik zum AST Welche Eigenschaften soll ein Parser haben? Wann ist eine Grammatik eindeutig? Wie sollte eine Grammatik aussehen? Theoretischer Hin tergrund: FIRST, FOLLOW Einschränkungen von

Mehr

Stackmaschine; Speicheradressierung

Stackmaschine; Speicheradressierung Stackmaschine; Speicheradressierung Erweiterung um globalen Speicher (Heap, Halde) pro Speicherplatz eine Zahl. Notation ist als Array SP [0..]. Zugriff mittels Adresse (Index): eine Zahl i.a.: Zahlen

Mehr

Lösungshinweise/-vorschläge zum Übungsblatt 2: Grundlagen der Programmierung (WS 2018/19)

Lösungshinweise/-vorschläge zum Übungsblatt 2: Grundlagen der Programmierung (WS 2018/19) Prof. Dr. Ralf Hinze Sebastian Schweizer, M.Sc. Peter Zeller, M. Sc. TU Kaiserslautern Fachbereich Informatik AG Programmiersprachen Lösungshinweise/-vorschläge zum Übungsblatt 2: Grundlagen der Programmierung

Mehr

Struktur und Implementierung von Programmiersprachen II. (Compilerbau) WS 2006/2007

Struktur und Implementierung von Programmiersprachen II. (Compilerbau) WS 2006/2007 Struktur und Implementierung von Programmiersprachen II (Compilerbau) WS 2006/2007 Vorlesung und Übung: Dr. Christoph Herrmann http://infosun.fmi.uni passau.de /cl/lehre/sips2 ws0607/index.html 1/1 Einordnung

Mehr

Anwenundg regulärer Sprachen und endlicher Automaten

Anwenundg regulärer Sprachen und endlicher Automaten Proseminar Theoretische Informatik Dozent: Prof. Helmut Alt Anwenundg regulärer Sprachen und endlicher Automaten Madlen Thaleiser 30. Oktober 2012 Reguläre Sprachen Regulärer Ausdruck definiert über einem

Mehr

C-Grundlagen. Einführung von Tronje Krabbe 1/21

C-Grundlagen. Einführung von Tronje Krabbe 1/21 C-Grundlagen Einführung von Tronje Krabbe 1/21 Gliederung Hintergrund Geschichte Nutzungsgebiete C-Derivate Syntax Compiler Beispielcode 2/21 Was ist C? C ist eine imperative, kompilierte Programmiersprache

Mehr

Was ist ein Compiler?

Was ist ein Compiler? Was ist ein Compiler? Was ist ein Compiler und worum geht es? Wie ist ein Compiler aufgebaut? Warum beschäftigen wir uns mit Compilerbau? Wie ist die Veranstaltung organisiert? Was interessiert Sie besonders?

Mehr

30. Parser-Generatoren

30. Parser-Generatoren 30. Parser-Generatoren Prof. Dr. rer. nat. Uwe Aßmann Institut für Software- und Multimediatechnik Lehrstuhl Softwaretechnologie Fakultät für Informatik TU Dresden http://st.inf.tu-dresden.de Version 11-0.1,

Mehr

2 Eine einfache Programmiersprache

2 Eine einfache Programmiersprache 2 Eine einfache Programmiersprache Eine Programmiersprache soll Datenstrukturen anbieten Operationen auf Daten erlauben Kontrollstrukturen zur Ablaufsteuerung bereitstellen Als Beispiel betrachten wir

Mehr

Unterrichtsmaterialien in digitaler und in gedruckter Form. Auszug aus: Formale Sprachen und endliche Automaten - Schülerband

Unterrichtsmaterialien in digitaler und in gedruckter Form. Auszug aus: Formale Sprachen und endliche Automaten - Schülerband Unterrichtsmaterialien in digitaler und in gedruckter Form Auszug aus: Formale Sprachen und endliche Automaten - Schülerband Das komplette Material finden Sie hier: School-Scout.de Dr. D. Appel Formale

Mehr

Einführung in die Informatik. Programming Languages

Einführung in die Informatik. Programming Languages Einführung in die Informatik Programming Languages Beschreibung von Programmiersprachen Wolfram Burgard Cyrill Stachniss 1/15 Motivation und Einleitung Wir haben in den vorangehenden Kapiteln meistens

Mehr

Sprechen Sie Java? Hanspeter Mössenböck. Tm\ dpunkt.verlag. Eine Einführung in das systematische Programmieren

Sprechen Sie Java? Hanspeter Mössenböck. Tm\ dpunkt.verlag. Eine Einführung in das systematische Programmieren Hanspeter Mössenböck Sprechen Sie Java? Eine Einführung in das systematische Programmieren 3., überarbeitete und erweiterte Auflage Tm\ dpunkt.verlag 1 Grundlagen 1 1.1 Daten und Befehle 2 1.2 Algorithmen

Mehr

Funktionale Programmiersprachen

Funktionale Programmiersprachen Funktionale Programmiersprachen An den Beispielen Haskell und Erlang Übersicht Programmiersprachen λ-kalkül Syntax, Definitionen Besonderheiten von funktionalen Programmiersprache, bzw. Haskell Objektorientierte

Mehr