Grundlagen der Programmierung 2 Aufgabenblatt Nr. 6 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 2013
Aufgabenblatt Nr. 6
Abgabe: Mittwoch 29. Mai 2013 vor! der Vorlesung
Aufgabe 1 (35 Punkte)
Ein Telefonbuch sei als String von einem oder mehreren Telefonbucheinträgen – bestehend aus Namen
und Telefonnumern – gegeben, wobei
• Telefonbucheinträge sind durch das Symbol # getrennt
• Name und Telefonnummer sind durch einen Doppelpunkt : getrennt
• Namen sind dabei entweder in der Form Vorname Nachname (durch genau ein Leerzeichen
getrennt), oder in der Form Nachname, Vorname (Leerzeichen sind nicht erlaubt) gegeben.
Sowohl Nachname als auch Vorname sind Worte, die mit einem Großbuchstaben beginnen und
ansonsten nur aus Buchstaben und dem Bindestrich - bestehen.
• Telefonnummern sind in der Form (Ortsvorwahl)Rufnummer gegeben, wobei die Ortsvorwahl
und die Rufnummern nur aus Ziffern bestehen und die Ortsvorwahl stets mit einer 0 beginnt.
a) Geben Sie eine kontextfreie Grammatik an, die genau obige Telefonbücher erzeugen kann. Sie
können die folgenden Produktionen als bereits gegeben verwenden:
(10 Punkte)
Wort
Buchstaben
Buchstabe
Großbuchstabe
Kleinbuchstabe
Nummer
::=
::=
::=
::=
::=
::=
Großbuchstabe Buchstaben
ε | Buchstabe Buchstaben
Großbuchstabe | Kleinbuchstabe | A | ... | Z
a | ... | z
0 | . . . | 9 | 0 Nummer | . . . | 9 Nummer
b) Der Datentyp Datensatz sei definiert als:
data Datensatz = Datensatz Vorname Nachname Vorwahl Rufnummer
deriving(Eq,Show)
type Vorname
= String
type Nachname = String
type Vorwahl
= String
type Rufnummer = String
Implementieren Sie in Haskell eine Funktion parseTelefon :: String -> [Datensatz], die
ein Telefonbuch als String erhält und und diesen in eine Liste von Datensätzen überführt. Ist
das oben beschriebene Format nicht erfüllt, so soll ein Fehler gemeldet werden. Sie können die
funktionalen Parserkombinatoren aus der Vorlesung verwenden (dies ist aber kein Zwang für
diese Aufgabe).
(25 Punkte)
Beispielaufrufe:
*> parseTelefon "Helga Mueller:(069)123456"
[Datensatz "Helga" "Mueller" "069" "123456"]
*> parseTelefon "Helga Mueller:(069)123456#Maier,Fritz:(010)100"
[Datensatz "Helga" "Mueller" "069" "123456",Datensatz "Fritz" "Maier" "010" "100"]
*> parseTelefon "Helga Mueller:(069)123456???Maier,Fritz:(010)100"
*** Exception: parse error
*> parseTelefon "Helga Mueller:(999)123456"
*** Exception: parse error
*> parseTelefon "Helga Mueller:(0999)123456"
[Datensatz "Helga" "Mueller" "0999" "123456"]
1
Aufgabe 2 (65 Punkte)
Eine Schildkröte kann Programme verarbeiten, die durch die folgende kontextfreie Grammatik
mit Startsymbol Code den Nichtterminalen Code, Command, Number und den Terminalen ;,
turnRight, turnLeft, walk, repeat, {, }, 0,. . . ,9 erzeugt werden können:
Code
::= Command | Command ; Code
Command ::= turnRight | turnLeft | walk Number | repeat Number { Code }
Number
::= 0 | . . . | 9 | 0 Number | . . . | 9 Number
a) Geben Sie eine Linksherleitung für das folgende Programm an:
(10 Punkte)
turnLeft; repeat 10 {turnLeft; walk 5}
b) Geben Sie eine Rechtsherleitung für das folgende Programm an:
(10 Punkte)
turnLeft; walk 5; turnRight
c) Als Syntaxbaum für Schildkrötenprogramme verwenden wir den Typ Sequence, der eine Liste
von AST-Einträgen darstellt, wobei AST definiert sei als:
data AST = REPEAT Int Sequence
| TURNRIGHT
| TURNLEFT
| WALK Int
deriving(Eq,Show)
type Sequence = [AST]
Implementieren Sie mithilfe der in der Vorlesung vorgestellten funktionalen Parserkombinatoren
einen rekursiv absteigenden Parser für Schildkrötenprogramme, der als Eingabe ein Programm
als String erhält und als Ausgabe den Syntaxbaum von Typ Sequence liefert.
(30 Punkte)
Hinweis: Falls Sie Zahlen vom Typ Integer in Zahlen vom Typ Int konvertieren müssen,
können Sie hierfür die Funktion fromIntegral verwenden.
Beispielaufrufe:
*> parseKroete "turnLeft; walk 10; repeat 5 {turnLeft; repeat 2 {walk 20}}"
[TURNLEFT,WALK 10,REPEAT 5 [TURNLEFT,REPEAT 2 [WALK 20]]]
d) Die Semantik der Befehle sei wie folgt festgelegt:
–
–
–
–
turnRight dreht die Schildkröte um 90 Grad nach rechts
turnLeft dreht die Schildkröte um 90 Grad nach links
walk i lässt die Schildkröte i Meter in die aktuelle Richtung laufen.
repeat i c: Der Code c wird i-mal hintereinander ausgeführt.
Wir nehmen an, dass die Schildkröte am Anfang am Punkt (0,0) der zweidimensionalen Ebene
steht und sie Richtung Osten zeigt.
Implementieren Sie eine Funktion endPunkt :: Sequence -> (Int,Int), die ein
Schildkrötenprogramm erwartet und die Position der Schildkröte nach Ausführung des
Programms berechnet.
(15 Punkte)
Beispielaufrufe:
*> endPunkt
(45,100)
*> endPunkt
(5,15)
*> endPunkt
(20,-20)
*> endPunkt
(0,0)
[WALK 20,REPEAT 5 [TURNLEFT,WALK 20,TURNRIGHT,WALK 5]]
[REPEAT 5 [TURNLEFT,WALK 20,REPEAT 10 [TURNRIGHT,WALK 5]]]
(parseKroete "walk 20; turnRight; walk 20")
(parseKroete "walk 20; turnLeft; turnLeft; walk 20")
2
Herunterladen