Grundlagen der Programmierung 2 Aufgabenblatt Nr. 7 Aufgabe 1

Werbung
Prof. Dr. Manfred Schmidt-Schauß
Künstliche Intelligenz/Softwaretechnologie
Fachbereich Informatik und Mathematik/ Institut für Informatik
Goethe-Universität Frankfurt am Main
Grundlagen der Programmierung 2
Sommersemester 2014
Aufgabenblatt Nr. 7
Abgabe: Mittwoch 04. Juni 2014 vor! der Vorlesung
Aufgabe 1 (60 Punkte)
Wie in der Vorlesung und im Skript erläutert, kann die Auswertung einer Stackmaschine mit den
Befehlen pop, pushK, push, slide, branchz, jump und mit arithmetischen Operationen +, − und ∗
sowie Marken wie folgt als Funktion I definiert werden:
I
I
I
I
I
I
I
I
I
I
Programm
[]
(pop : prest)
((pushK k) : prest)
((push i) : prest)
(+ : prest)
(− : prest)
(∗ : prest)
((slide m n) : prest)
(marke : prest)
((branchz marke) : prest)
I (jump marke) : prest)
Stack
stack
(a : srest)
stack
stack
(a : b : srest)
(a : b : srest)
(a : b : srest)
stack
stack
(a : srest)
Kopie
prg
prg
prg
prg
prg
prg
prg
prg
prg
prg
−→
−→
−→
−→
−→
−→
−→
−→
−→
−→
stack
prg
−→
Nächster Aufruf (Resultat)
stack
I prest srest prg
I prest (k : stack ) prg
I prest ((stack !!i) : stack ) prg
I prest (b + a : srest) prg
I prest (b − a : srest) prg
I prest (b ∗ a : srest) prg
I prest (take m stack ++ (drop (n + m) stack )) prg
I prest stack prg
if (0 == a) then
I (dropWhile (marke /=) prg) srest prg
else I prest srest prg
I (dropWhile (marke /=) prg) stack prg
a) Führen Sie das Stackmaschinenprogramm (bestehend aus 15 Befehlen)
1
2
3
4
5
pushK 3;
pushK 2;
marke1;
push 1;
push 0;
*;
push 1;
8 pushK 1;
9 slide 3 2;
10 -;
6
11
7
12
13
14
15
push 0;
branchz marke2;
jump marke1;
marke2;
pop
beginnend mit leerem Stack per Hand entsprechend der obigen Regeln aus, indem Sie das Programm und den Stack nach Ausführung jedes Befehls angeben.
(20 Punkte)
b) In dieser Aufgabe soll die Stackmaschine in Haskell implementiert werden. Befehle der Stackmaschine werden durch den folgenden Datentyp Kommando repräsentiert. Für Marken werden dabei
Zahlen verwendet und die arithmetischen Operationen werden durch den Datentyp ArithOp
zusammengefasst:
data Kommando = PushK Int | Pop | Push Int | Op ArithOp | Mark Marke
| Jump Marke | Branchz Marke | Slide Int Int
deriving (Eq,Show)
type Marke = Int
data ArithOp = Add | Mult | Sub | Div
deriving(Eq,Show)
1
Ein Stackmaschinenprogramm ist eine Liste von Befehlen und der Stack ist eine Liste von Zahlen
type Programm = [Kommando]
type Stack = [Int]
Implementieren Sie in Haskell eine Funktion runProgramm :: Programm -> Stack, die ein
Stackmaschinenprogramm erwartet und den resultierenden Stack als Ergebnis liefert. Implementieren Sie hierfür zunächst eine Hilfsfunktion
interpretiere :: Programm -> Stack -> Programm -> Stack
die genau die oben angegebene Funktion I in Haskell umsetzt, und rufen Sie diese innerhalb von
runProgramm auf.
(25 Punkte)
c) Geben Sie ein Stackmaschinenprogramm an, dass für jeden Stack der Form [a, b, c] (wobei a
oben auf dem Stack liegt) als Resultat den Stack [m, n] liefert, wobei m = c − (b ∗ (a + 2)) und
n = (a − b) + c2 + b3 .
(15 Punkte)
Aufgabe 2 (40 Punkte)
Wir betrachten erneut die Jumpy-Programme von Aufgabenblatt 6 und deren Haskell-Repräsentation
vom Typ Sequenz:
data Befehl
= Wiederhole Int Sequenz
| Springe Richtung Int
deriving(Eq,Show)
data Richtung = Links | Rechts | Oben | Unten
deriving(Eq,Show)
type Sequenz = [Befehl]
Ziel der Aufgabe ist es, Zwischencode für die Stackmaschine aus Aufgabe 1 aus Jumpy-Programmen
zu erzeugen. D.h. Sie sollen eine Funktion
codeGenerierung :: Sequenz -> Programm
in Haskell implementieren, die aus einem Jumpy-Programm ein Stackmaschinenprogramm erzeugt.
Dafür modellieren wir den Zustand von Jumpy wie folgt im Stack der Maschine:
Der Zustand wird durch zwei Einträge im Stack repräsentiert: [posx,posy], wobei posx und posy die
Position von Jumpy auf der x-Achse und y-Achse angeben.
Da Jumpy am Anfang an Position (0,0) steht, ist der Stack am Anfang [0,0].
Hinweise:
• Implementieren Sie codeGenerierung, indem Sie zunächst den Code für jeden der einzelnen
Befehle programmieren. Dabei sollte der Stack vor Ausführung des Codes die Form [posx,posy]
haben und nach Ausführung eines Befehls von der Form [posx’,posy’] sein, wobei posx’ und
posy’ den neuen Zustand von Jumpy beschreibt.
• Der Code für Wiederhole i code ist der schwierigste und sollte Sprungmarkierungen benutzen
und nicht den Code code i-mal entfalten, denn dies führt zu sehr langen Stackmaschinenprogrammen.
Verknüpfen Sie den Parser von Aufgabenblatt 6, den Stackmaschinenauswerter von Aufgabe 1 dieses
Blattes und die Kodegenerierung dieser Aufgabe, um Jumpy-Programme auszuführen.
2
Herunterladen