Bonusblatt - informatik.uni

Werbung
Praktische Informatik 3 WS 2007/08
Bonusblatt
Ausgabe: 17. 12. 2007
Abgabe bis 28. 1. 2008
Haskell conquers the continent
Berthold Hoffmann <hof>
Klaus Hartke <hartke>
Christian Maeder <maeder>
Dennis Walter <dw>
Diedrich Wolter <dwolter>
20 Punkte
Die Sprache Haskell ist in der Wahl ihre Schlüsselwörter auf den angelsächsischen Markt
zugeschnitten. Diese sträfliche Vernachlässigung des “continents”, also des guten alten Festlandeuropas mit seinem schier babylonischen Sprachengewirr soll behoben werden, indem nunmehr
auch nationale Dialekte von Haskell in allen Sprachen der europäischen Gemeinschaft auf
den Markt gebracht werden sollen. Das wohlbekannte if-then-else könnte beispielsweise in der
deutschen Fassung wenn-dann-sonst und in der französischen si-alors-sinon heißen. Damit
soll die marktbeherrschende Rolle von Haskell bei den verzögert ausgewerteten funktionalen
Sprachen in allen EU-Ländern ausgebaut werden.
Die Umstellung der Haskell-Systeme wie hugs oder ghc selbst sollte eigentlich ein Kinderspiel
sein, weil sie ja sicher modular implementiert sind, so dass nur die konkreten Zeichenketten für
die Schlüsselwörter ausgetauscht werden müssen. Was aber wird aus den unzähligen Terabyte an
existierenden Haskell-Programmen? Auch die sollten in die nationalen Dialekte von Haskell
übersetzt werden können, damit sie danach besser weiter entwickelt werden können.
Hier kommen Sie ins Spiel! Schreiben Sie ein Haskell-Programm (im ursprünglichen, englischen Dialekt), dessen Hauptfunktion folgende Signatur hat:
type Text = [String]
translate :: [(String,String)] -> Text -> Text
Das erste Argument enthält alle Paare (e, d) von Schlüsselwörtern, die übersetzt werden sollen.
Jedes Auftreten eines Schlüsselworts e im zweiten Argument, (dem Originalprogramm) soll im
Ergebnis (dem Zielprogramm) durch das entsprechende Wort d ersetzt werden. Dabei sind einige
Besonderheiten zu beachten:
• Nur Folgen von Buchstaben mit eventuell eingestreuten Unterstrichen können Schlüsselwörter
sein.
• Es kommen nur maximale Folgen in Frage, d. h., die Folgen müssen von anderen Zeichen
eingeschlossen sein.
• Alle Bezeichner des Quellprogramms, die im Zielprogramm als Schlüsselwörter gelten
würden, werden dem Übersetzer für den Zieldialektes (bzw. eigentlich: dessen Benutzern)
Probleme bereiten, weil dies zu Syntaxfehlern führen. Solche Namenskonflikte (name clashes) können nicht zuverlässig automatisch behoben werden. Sie könnten aber diesen Bezeichnern die Ziffer 1 anhängen und danach noch eine Warnung einfügen, z.B. in Gestalt
eines Kommentars “{- Schlüsselwort <d> verändert zu <d>1! -}”.
Die Signatur von translate erlaubt es, beliebige Wörterlisten für beliebige Sprachen anzugeben
und somit zwischen beliebigen Haskell-Dialekten zu übersetzen, beispielsweise portugiesisches
in ungarisches Haskell. Außerdem könnten Sie (oder die von Ihnen gegründete Firma, später)
es nicht bei der Übersetzung von Schlüsselwörtern belassen, sondern auch die Namen der Typen
und Funktionen im Prelude in die Zielsprache zu übersetzen.
Erstellen Sie das Programm in folgenden Schritten:
1. Implementieren Sie einen Modul Dictionary, der einen abstrakten Datentyp Dictionary
a zur effizienten Darstellung des Wörterbuchs implementiert. Ein Wörterbuch ist eine Liste
von sogenannten Tries, n-stelligen Bäumen, die alle Wörterbucheinträge für den gleichen
Anfangsbuchstaben enthalten, deren Knoten die folgenden Komponenten enthalten:
(a) Der Anfangsbuchstaben aller Wörter in diesem Knoten und seinen Unterbäumen.
(b) Falls dieser Anfangsbuchstabe der letzte eines Wortes sein kann, dessen Übersetzung
(ein Wert vom Typ a), sonst nichts. (Dies kann mit Maybe a implementiert werden.)
(c) Eine Liste von Unterbäumen, für alle mögliche Fortsetzungen der Wörter in diesem
Baum.
Auf dieser Datenstruktur werden Sie folgende Operationen brauchen:
(a) empty:: Dictionary a ist das leere Wörterbuch.
(b) plus:: (String, a) -> Dictionary a -> Dictionary a trägt ein Wort mit seiner Übersetzung in ein Wörterbuch ein.
(c) find:: String -> Dictionary a -> Maybe a liefert die Übersetzung einer Zeichenkette, wenn sie ein Schlüsselwort ist, und nichts sonst.
(d) fill :: [(String,a] -> Dictionary a füllt das Wörterbuch mit einer Liste von
Paaren.
2. Die Funktion translate soll die Wörterliste in das Wörterbuch eintragen und dann den
Programmtext übersetzen. Dazu sollte der Text in Bezeichner und Zwischentext aufgespalten werden, alle als Schlüsselwort erkannten Bezeichner übersetzt werden, und danach
alles wieder zu einem Text zusammengebaut werden.
Für alle Bezeichner, die in der Zielsprache zu Schlüsselwörtern werden, sollen wie oben
diskutiert verändert werden; Dazu brauchen Sie ein “umgekehrtes” Wörterbuch für die
Namenskonflikte der Zielsprache, das aber aus dem ersten leicht berechnet werden kann.
(Die Einträge in diesem Wörterbuch haben den Typ (), d.h., die Funktion find liefert
entweder Just (), wenn der Bezeichner ein Schlüsselwort der Zielsprache ist, oder Nothing
andernfalls.
3. Definieren Sie mindestens ein Wörterbuch, das mindestens die in Tabelle 1 aufgeführten Haskell-Schlüsselwörter nach Deutsch oder nach Französisch übersetzt. Vorschläge
für eine bessere Übersetzung der Schlüsselwörter, Erweiterungen der Wörterbücher oder
Wörterbücher für weitere europäische Sprachen (estnisch, slowenisch) sind willkommen!
(Vom Einstieg in den asiatischen Markt – Chinesisch, Japanisch, Indisch – raten wir jedoch ab, weil das Arbeiten mit Unicode-Zeichen einige zusätzliche Komplikationen mit
sich bringt.)
4. Erweitern Sie dass Programm so, dass es als Kommando
translate Programm.hs Programm.hsd
aufgerufen werden kann und die “hs”-Datei in eine “hsd”-Datei übersetzt.
Ein guter Testfall für Ihr Programm ist Ihr Programm selbst; Übersetzerbauer nennen das auf
gut Deutsch einen “halben bootstrap”. Noch besser übersetzen Sie erst von “hs” nach “hsd” und
dann – mit den inversen Wörterbüchern – zurück und überzeugen sich, ob dabei wieder das
Originalprogramm herauskommt.
Dieses ist Version 0.9 vom 11. Dezember 2007.
Englisch
as
case
class
data
default
deriving
do
else
hiding
if
import
in
infix
infixl
infixr
instance
let
module
newtype
of
otherwise
qualified
then
type
where
Deutsch
als
falls
Klasse
Datentyp
normalerweise
ableitend
tue
sonst
verdeckend
wenn
importiere
in
infix
infixL
infixR
Instanz
sei
Modul
Neuer Typ
von
andernfalls
qualifiziert
dann
Typ
wobei
Französisch
comme
en cas
classe
donnee
normalement
derivant
faites
sinon
cachant
si
importez
en
infixe
infixeG
infixeD
instance
soi
module
nouveau type
de
autrement
qualifie
alors
type
ou
Ihre Lieblingssprache
Tabelle 1: Schlüsselwörter von Haskell in Deutsch und Französisch (und Ihre Lieblingssprache)
Herunterladen