Aufgabe - Technische Universität Braunschweig

Werbung
TECHNISCHE UNIVERSITÄT CAROLO-WILHELMINA ZU BRAUNSCHWEIG
Institut für Programmierung und Reaktive Systeme
Prof. Dr. Ursula Goltz
[email protected]
Dipl.-Inform. Malte Lochau
[email protected]
19. April
Sommersemester 2012
Compiler I
1. Übungsblatt
Compiler Grundlagen,
Reguläre Ausdrücke und Endliche Automaten,
Lexikalische Analyse
Aufgabe 1: Grundlagen eines Compilers
a) Nennen Sie die Phasen eines Compilers. Beschreiben Sie diese jeweils mit Hilfe
der folgenden Eigenschaften:
ˆ Programmteil des Compilers, der die Phase implementiert
ˆ Aufgabe(n) der Phase
ˆ Erwartete Darstellungsform des zu verarbeitenden Programms (Eingabe
der Phase)
ˆ Erzeugte Darstellungsform des zu verarbeitenden Programms (Ausgabe
der Phase)
b) Was bezeichnet das Frontend und das Backend eines Compilers? Welche Phasen sind dem Frontend, welche dem Backend zuzuordnen?
c) Vergleichen Sie die Funktionsweise eines Interpreters und eines Compilers anhand der Verarbeitung und Ausführung von Eingabeprogrammen der Sprache
L. Ist Java eine interpretierte oder kompilierte Sprache?
Aufgabe 2: Bootstrapping
Es wurde ein Compiler für die neue Programmiersprache Java+ entwickelt. Dieser Compiler kompiliert in den Java Bytecode und wurde in Java geschrieben. Aus
Gründen der Performanz besteht der Wunsch, dass dieser Compiler in Maschinensprache geschrieben ist und in Maschinensprache kompiliert.
Zur Umsetzung dieser Aufgabe stehen noch weitere Compiler zur Verfügung:
ˆ Ein Java Compiler im Java Bytecode, der Java Bytecode erzeugt,
ˆ ein Compiler, der Java Bytecode in Maschinensprache übersetzt und der in C
geschrieben ist,
ˆ und ein C-Compiler in Maschinensprache, der in Maschinensprache übersetzt.
Auÿerdem gibt es auf dem Rechner, auf dem der Compiler erzeugt werden soll, eine
Java Virtual Machine (JVM), mit der sich Java Bytecode ausführen lässt. Denieren
Sie die Entwicklungsschritte (Bootstrap) zur Erzeugung des gewünschten Compilers
für Java+ durch Kombination der gegebenen Komponenten. Stellen Sie diese in
Form von T-Diagrammen wie folgt dar:
Q
Z
I
wobei Q für die Quellsprache, Z für die Zielsprache und I für die Implementierungssprache des Compilers steht.
Aufgabe 3: Reguläre Ausdrücke und Endliche Automaten
Zeigen oder widerlegen Sie die folgenden Aussagen:
a) Für alle regulären Ausdrücke r und s gilt (r∗ s∗ )∗ = (r|s)∗
b) Für alle regulären Ausdrücke r und s gilt r∗ |s∗ = (r|s)∗
Aufgabe 4: Reguläre Ausdrücke und Endliche Automaten
Geben Sie reguläre Ausdrücke an, die die folgenden Sprachen beschreiben:
a) Die Menge aller Wörter w ∈ {a, b}∗ , in denen jedem a direkt zwei b's vorangehen.
b) Die Menge aller Wörter w ∈ {a, b}∗ , die nicht das Teilwort bab enthalten.
c) Die Menge der DecimalIntegerLiterals in Java bestehen aus beliebig vielen
Ziern ohne führende Null, optional abgeschlossen durch ein Sux L oder l,
falls das Literal vom Typ long ist.
Aufgabe 5: Reguläre Ausdrücke und Endliche Automaten
Konstruieren Sie nichtdeterministische endliche Automaten, die die folgenden Sprachen erkennen:
a) Die Menge aller Wörter w ∈ {a, b, c}∗ , die mindestens ein a und ein b enthalten.
b) Die Menge aller Wörter w ∈ {a, b, c}∗ , die eine gerade Anzahl a's, eine ungerade Anzahl b's und beliebig viele c's enthalten.
c) Die Menge der DocumentationComments (Javadoc-Kommentare) in Java mit
der Form:
2
/**
* documentation text <LineTerminator>
* documentation text <LineTerminator>
* ...
*/
Für diese Art Kommentare gilt:
ˆ Die Kommentarblöcke beginnen mit /** und werden abgeschlossen durch
*/.
ˆ Kommentare können sich über mehrere Zeilen erstrecken, die jeweils mit
einem * beginnen.
ˆ Das Auftreten von / im Kommentartext ohne vorherigen * ist zulässig
und wird ignoriert.
Aufgabe 6: Reguläre Ausdrücke und Endliche Automaten
Aus jedem regulären Ausdruck r kann schrittweise ein minimaler deterministischer
Automat konstruiert werden, der die von r beschriebene reguläre Sprache L(r) erkennt. Führen Sie diese Konstruktion für den regulären Ausdruck r = b(a|b)∗ bc
durch.
a) Regulärer Ausdruck ⇒ NEA: Konstruieren Sie einen nichtdeterministischen
endlichen Automaten M1 , der die von r beschriebene Sprache akzeptiert.
b) NEA ⇒ DEA: Konstruieren Sie aus M1 einen deterministischen Automaten
M2 , der dieselbe Sprache wie M1 akzeptiert.
c) DEA ⇒ minimaler DEA: Konstruieren Sie aus M2 einen DEA M3 , der dieselbe
Sprache wie M2 akzeptiert und eine minimale Zustandsmenge besitzt.
Geben Sie auch die jeweiligen Zwischenschritte an. Enthält der Automat unproduktive oder unerreichbare Zustände?
Aufgabe 7: Lexikalische Analyse
Der aus einem regulären Ausdruck konstruierte (minimale) deterministische endliche
Automat kann zur Implementierung eines Scanners, der die durch den Ausdruck beschriebene Sprache erkennt, verwendet werden. Der Scanner wird so implementiert,
dass er den endlichen Automaten simuliert, also die Zustände geeignet codiert und
die Zustandsübergänge auf der Zustandsmenge ausführt. Eine Möglichkeit besteht
darin, den Automaten direkt mittels geschachtelter if und switch Anweisungen
zu implementieren. Schreiben Sie eine Java-Methode scan(), die diese Umsetzung
eines Parsers für die Sprache von r = b(a|b)∗ bc auf Grundlage des Automaten M3
aus Aufgabe 6 realisiert. Dabei können Sie von folgenden Vorgaben ausgehen
ˆ Es existiert bereits eine Methode char nextChar(), die jeweils das nächste
Eingabezeichen liefert.
3
ˆ Ist das Dateiende erreicht, liefert nextChar das Zeichen '!'.
ˆ Das Eingabealphabet des Scanners umfasst also die Zeichen a, b, c und !.
Aufgabe 8: Lexikalische Analyse
a) Nennen Sie die sieben lexikalischen Grundeinheiten der Sprache Java und geben Sie jeweils zu jeder Einheit ein Beispiel an.
b) Welche dieser Einheiten sind
weitergegeben?
Token
und werden vom Scanner an den Parser
c) Erläutern sie an diesem Beispiel die Aufgaben eines Siebers.
4
Herunterladen