Praktikum Funktionale Programmierung Teil 1: Lexen und Parsen

Ähnliche Dokumente
Praktikum Funktionale Programmierung Teil 2: Typecheck und Transformation

Adressen. Praktikum Funktionale Programmierung Organisation und Überblick. Termine WWW

Praktikum Funktionale Programmierung Organisation und Überblick

Praktikum Funktionale Programmierung Teil 1: Lexen und Parsen

Adressen. Praktikum Funktionale Programmierung Organisation und Überblick. Termine. Studienleistung

Praktikum Funktionale Programmierung Teil 3: Abstrakte Maschinen

Praktikum Funktionale Programmierung 10. Besprechung

Phasen eines Compilers. Grundlagen der Programmierung 2. Programm für heute. LR-Parser, Shift-Reduce-Verfahren. Schiebe-Reduziere-Parser

Grundlegende Datentypen

Praktikum Funktionale Programmierung Teil 3: Abstrakte Maschinen Mark 1 und Mark 2

Grundlegende Datentypen

Praktikum Funktionale Programmierung Teil 5: Codeerzeugung, Compiler, Interpreter und VM

Grundlegende Datentypen

Einführung in Haskell und seine Werkzeuge

Funktionale Programmierung Grundlegende Datentypen

Vorsemesterkurs Informatik Sommersemester Aufgabenblatt Nr. 5A. Lösung zu Aufgabe 1 (Fehler in Haskell-Quelltext: Parsefehler)

So schreiben Sie ein Parser-Programm

Funktionale Programmierung

Tag 7. Pattern Matching und eigene Datentypen

Funktionale Programmierung Mehr funktionale Muster

Compilerbau. Martin Plümicke WS 2018/19

Vorsemesterkurs Informatik

Inhalt Kapitel 11: Formale Syntax und Semantik

Funktionale Programmierung. ALP I Lambda-Kalkül. Teil III SS Prof. Dr. Margarita Esponda. Prof. Dr. Margarita Esponda

Software Entwicklung 1. Fallstudie: Arithmetische Ausdrücke. Rekursive Klassen. Überblick. Annette Bieniusa / Arnd Poetzsch-Heffter

ALP I. Funktionale Programmierung

Software Entwicklung 1

Programmierung WS18/19 Übungsblatt 9 (Abgabe Freitag, den um 12 Uhr)

WS 2012/2013. Robert Giegerich. 21. November 2012

Programmieren in Java

Grundlagen der Programmierung 2 (1.A)

ALP I. Funktionale Programmierung

Grundlagen der Programmierung 2 (1.A)

Die Definition eines Typen kann rekursiv sein, d.h. Typ-Konstruktoren dürfen Elemente des zu definierenden Typ erhalten.

Proinformatik Marco Block Dienstag, den 21. Juli 2009

Einstieg in die Informatik mit Java

JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML.

PROGRAMMIERUNG UND MODELLIERUNG

Übung zur Vorlesung EidP (WS 2018/19) Blatt 4

Proseminar: Fortgeschrittene Programmierung 1

Grundlagen der Programmierung 2 (1.A)

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

Programmieren in Haskell

Algorithmen zur Datenanalyse in C++

Projekt 3 Variablen und Operatoren

Paradigmen der Programmierung

Verwenden Sie für jede Aufgabe die C++ IDE von Eclipse (pro Aufgabe ein Projekt).

2.5 Listen. Kurzschreibweise: [42; 0; 16] Listen werden mithilfe von [] und :: konstruiert.

Einstieg in die Informatik mit Java

Programmieren in Haskell

Spezifikation lexikalischer Einheiten (Token) als reguläre Ausdrücke in einer Lexer-Spezifikationsdatei (z.b. tiger.lex) Übersetzen nach lex.yy.

Programmieren in Java

Grundlagen der Programmierung 2 (Comp-C)

Prüfung Funktionale Programmierung

Nachklausur: Grundlagen der Informatik I, am 02. April 2008 Dirk Seeber, h_da, Fb Informatik. Nachname: Vorname: Matr.-Nr.

Nachklausur: Grundlagen der Informatik I, am 02. April 2008 Dirk Seeber, h_da, Fb Informatik. Nachname: Vorname: Matr.-Nr.

WS 2013/2014. Robert Giegerich. 11. Dezember 2013

Angewandte Mathematik und Programmierung

Funktionale Programmierung und Typtheorie

Programmtransformationen und Induktion in funktionalen Programmen

Haskell. Grundlagen der Programmierung 2. Grundlagen der Programmierung 2 (1.A) Bücher, Literatur, URLs. Haskell. Einführung

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

Klassen in Java. Grundlagen der Programmierung. Stephan Kleuker 68

Programmieren in Haskell Einstieg in Haskell

Concurrent Haskell with Futures. Vorlesung SAFP, WS 2017/18

Java Übung. Übung 2. Werner Gaulke. 19. April Universität Duisburg-Essen Kommedia, Übung EinPro SS06, Einführung in Java - Übung.

Programmieren in Haskell

LR-Parser, Shift-Reduce-Verfahren

Kommunikationsmuster (T) Interprozesskommunikation (T) Kommunikation über Pipes (P) Parserspezifikation und -generierung (P)

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

Praktische Informatik 3: Funktionale Programmierung Vorlesung 11 vom : Monaden als Berechnungsmuster

Einführung in die funktionale Programmierung

Einführung in Haskell

WS 2013/2014. Robert Giegerich. 11. Dezember 2013

Vorsicht bei redundanten und unvollständigen Matches!

Grundlagen der Programmierung 3 A

Was bisher geschah. deklarative Programmierung. funktionale Programmierung (Haskell):

Einführung in die Programmiertechnik

Programmieren in Haskell Einführung

Pascal Schärli

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 12/13. Kapitel 3. Grunddatentypen, Ausdrücke und Variable

Beuth Hochschule Einführende Gentle-Programme WS12/13, S. 1

Felder - Arrays. Typ feldname[] = new Typ[<ganze Zahl >]; Beispiel: double vektor[] = new double[5]; auch eine Initialisierung ist möglich.

Einstieg in die Informatik mit Java

Rekursive Abstiegsparser sind durch gegenseitig rekursive Funktionen - eine für jedes Nichtterminalsymbol der Grammatik - definiert.

Vorsemesterkurs Informatik

Thomas Behr. 17. November 2011

3 Syntax von Programmiersprachen

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

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 29

Objektorientierte Programmierung. Kapitel 22: Aufzählungstypen (Enumeration Types)

yacc - eine Einführung

Transkript:

Stand der Folien: SoSe 2011 Praktikum Funktionale Programmierung Teil 1: Lexen und Parsen Dr. David Sabel Sommersemester 2011

Übersicht FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 2/20

Übersicht FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 2/20

Übersicht FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 2/20

Übersicht Bearbeitungszeit: 3 Wochen FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 2/20

Der Lexer Format des Quelltexts: Zwei Teile: 1 Datentypdefinitionen (optional, kann auch fehlen) 2 Schlüsselwort expression gefolgt von einem Ausdruck FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 3/20

Erster Teil: Datentypdefinitionen data Typname =Konstruktordefinition 1... Konstruktordefinition n Konstruktordefinition ist von der Form: KonstruktorName 1 Argumenttyp 1... Argumenttyp m KonstruktorName und Typname müssen mit einem Großbuchstaben beginnen und dürfen nur Buchstaben enthalten. Argumenttypen entsprechend der Grammatik: Typ ::= (Typ -> Typ) Typname Syntaktische Einheiten: data, =, (, ), ->, sowie Namen der Typen- und Datenkonstruktoren Der Parser (!) prüft noch: Alle Konstruktornamen und Typnamen müssen verschieden sein, alle verwendeten Typnamen müssen definiert sein Ausnahme: Unit, wird automatisch eingefügt: data Unit = Unit FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 4/20

Zweiter Teil: Ausdruck Eingeleitet mit dem Schlüsselwort expression Wie in der Syntax, jedoch -> statt, \ statt λ. Semikolons und {, } müssen vorhanden sein beliebige ( und )-Klammern case statt case T Variablennamen: Beginnen mit Kleinbuchstaben und bestehen aus Buchstaben und Zahlen Syntaktische Einheiten: expression, case, of, letrec, in, seq, newmvar, putmvar, takemvar, return, forkio, \, >>=, ;, =, ->, (, ), {, } und Variablennamen. FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 5/20

Kommentare Im Quelltext sind überall Zeilenkommentare erlaubt Syntax: -- Kommentar bis zum Zeilende FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 6/20

Ausgabe des Lexer Liste von Token In CHF.Parse.Lexer ist der Typ für Token definiert > data Token label = TokenKeyword String label > TokenSymbol String label > TokenVar String label > TokenCons String label > TokenUnknown Char label > type TokenType = Token SourceMark > type SourceMark = (Int,Int) -- (Zeile, Spalte) TokenKeyword: gefundenes Schlüsselwort TokenSymbol: gefundenes Symbol TokenVar: gefundene Variable TokenCons: gefundener Daten- oder Typkonstruktor TokenUnknown: unbekanntes Zeichen im Quelltext Zweites Argument label gibt die Position im Quelltext als SourceMark an. FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 7/20

Aufgabe 1 lexchf :: String -> [TokenType] implementieren getlabel :: Token label -> label implementieren showtoken :: Token label -> String implementieren *CHF.Parse.Lexer> lexchf "data Bool = True False expression \\x -> x" [TokenKeyword "data" (1,1),TokenCons "Bool" (1,6),TokenSymbol "=" (1,11), TokenCons "True" (1,13),TokenSymbol " " (1,18),TokenCons "False" (1,20), TokenKeyword "expression" (1,26),TokenSymbol "\\" (1,37), TokenVar "x" (1,38),TokenSymbol "->" (1,40),TokenVar "x" (1,43)] *CHF.Parse.Lexer> lexchf "expression 1+1" [TokenKeyword "expression" (1,1),TokenUnknown 1 (1,12), TokenUnknown + (1,13),TokenUnknown 1 (1,14)] *CHF.Parse.Lexer> lexchf "expression (return True) >>= \\x -> putmvar x True" [TokenKeyword "expression" (1,1),TokenSymbol "(" (1,12), TokenKeyword "return" (1,13),TokenCons "True" (1,20),TokenSymbol ")" (1,24), TokenSymbol ">>=" (1,26),TokenSymbol "\\" (1,30),TokenVar "x" (1,31), TokenSymbol "->" (1,33),TokenKeyword "putmvar" (1,36),TokenVar "x" (1,44), TokenCons "True" (1,46)] *CHF.Parse.Lexer> getlabel (TokenVar "x" (1,38)) (1,38) *CHF.Parse.Lexer> showtoken (TokenVar "x" (1,38)) "x" *CHF.Parse.Lexer> showtoken (TokenKeyword "letrec" (20,20)) "letrec" *CHF.Parse.Lexer> getlabel (TokenKeyword "letrec" (20,20)) (20,20) FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 8/20

Parsen mit Happy Ziel des Parsens: Tokenstrom in Datentyp (Parsebaum) verwandeln Dabei syntaktische Fehler entdecken Tool: happy, Parsergenerator, erstellt automatisch einen Parser Größtenteils bereits vorgegeben. Happy erstellt CHF.Parse.Parser, beinhaltet: parsechf :: String -> ParserOutput parse :: [TokenType] -> ParserOutput FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 9/20

Ausgabe des Parsers > type ParserOutput = ParseTree () ConsName VarName > data ParseTree a cname vname = > ParseTree [TDef cname cname] (Expr a cname vname) > deriving(eq,show) > type ConsName = (SourceMark,String) > type VarName = (SourceMark,String) FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 10/20

Darstellung von Ausdrücken > data Expr label cname v = > Var v > Lam v (Expr label cname v) > App (Expr label cname v) (Expr label cname v) > Seq (Expr label cname v) (Expr label cname v) > Cons (Either MAction cname) [Expr label cname v] > Case (Expr label cname v) [CAlt label cname v] > Letrec [Binding label cname v] (Expr label cname v) > Label label (Expr label cname v) > data MAction = Fork Return Take Put New Bind > data CAlt label cname v = > CAlt cname [v] (Expr label cname v) > data Binding label cname v = > v :=: (Expr label cname v) FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 11/20

Darstellung der Datentyp-Definitionen > data TDef tname cname = TDef tname [(cname,type tname)] > data Type tname = > TC tname > (Type tname) :->: (Type tname) > TVar String > TIO (Type tname) > TMVar (Type tname) FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 12/20

Beispiel Eingabe: data Bool = True False data ListBool = NilBool ConsBool Bool ListBool expression (seq True True) Ausgabe: ParseTree [TDef ((1,6),"Bool") [(((1,13),"True"),TC ((1,6),"Bool")), (((2,13),"False"),TC ((1,6),"Bool"))], TDef ((3,6),"ListBool") [(((3,17),"NilBool"),TC ((3,6),"ListBool")), (((4,17),"ConsBool"), TC ((4,26),"Bool") :->: (TC ((4,31),"ListBool") :->: TC ((3,6),"ListBool")))], TDef ((1,6),"Unit") [(((1,13),"Unit"),TC ((1,6),"Unit"))] ] (Seq (Cons (Right ((7,6),"True")) []) (Cons (Right ((7,11),"True")) []) ) FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 13/20

Die Parserdefinition (Auszüge) (1) > %token > var { TokenVar } > cons { TokenCons } > { TokenSymbol " " _ } > \\ { TokenSymbol "\\" _ } > >>= { TokenSymbol ">>=" _ } > ; { TokenSymbol ";" _ } > = { TokenSymbol "=" _ } > -> { TokenSymbol "->" _ } > ( { TokenSymbol "(" _ } > { { TokenSymbol "{" _ } > ) { TokenSymbol ")" _ } > } { TokenSymbol "}" _ } > case { TokenKeyword "case" _ } > of { TokenKeyword "of" _ } > letrec { TokenKeyword "letrec" _ } > in { TokenKeyword "in" _ } > seq { TokenKeyword "seq" _ } > newmvar { TokenKeyword "newmvar" _ } > putmvar { TokenKeyword "putmvar" _ } > takemvar { TokenKeyword "takemvar" _ } > forkio { TokenKeyword "forkio" _} > return { TokenKeyword "return" _ } > data { TokenKeyword "data" _ } > expr { TokenKeyword "expression" _ } FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 14/20

Die Parserdefinition (Auszüge) (2) > %right -> > %right >>= > %left seq > %nonassoc in > %nonassoc of > %nonassoc case > %nonassoc letrec > %nonassoc forkio > %nonassoc takemvar > %nonassoc putmvar > %nonassoc return > %nonassoc newmvar > %% FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 15/20

Die Parserdefinition (Auszüge) (3) > SOURCECODE :: {ParserOutput} > SOURCECODE : EXPR { checkparsetree $ ParseTree [] $1 } > TDEFS EXPR { checkparsetree $ ParseTree $1 $2 } Grammatik f"ur die Datentypdefinitionen: > TDEFS : TDEFSIT { checktdefs $1 } > TDEFSIT : TDEF { [$1] } > TDEF TDEFSIT { $1:$2 } > TDEF : data cons = CDEFS { (TDef > (mkcons $2) > (liststotypes $4 (TC $ mkcons $2))) } > CDEFS : CDEF { [$1] } > CDEF CDEFS { $1:$3 } > CDEF : cons { (mkcons $1,[]) } > cons TYPE { (mkcons $1,$2) } > TYPE : TK { [$1] } > TK TYPE { $1:$2 } > TK : cons { TC $ mkcons $1 } > ( TK -> TK ) { $2 :->: $4 } FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 16/20

Die Parserdefinition (Auszüge) (4) Grammatik f"ur Ausdr"ucke: > EXPR : expr REXPR { $2 } > REXPR : letrec BINDS in REXPR { checkbinds $4 $2 $1 } > \\ var -> REXPR { Lam (mkvar $2) $4 } > REXPR >>= REXPR { Cons (Left Bind) [$1,$3] } > AEXPR { $1 } > AEXPR : IEXPR { $1 } > cons CONSARGS { Cons (Right (mkcons $1)) $2 } > IEXPR CONSARGS { mkapp $1 $2} > cons { Cons (Right (mkcons $1)) [] } > BINDS : BIND { [$1] } > BIND ; BINDS { $1:$3 } > BIND : var = REXPR { (mkvar $1) :=: $3 } > IEXPR : seq IEXPR IEXPR { Seq $2 $3}... > forkio IEXPR { Cons (Left Fork) [$2] } > ( REXPR ) { $2 } > var { Var (mkvar $1) } > case REXPR of { ALTS } { checkalts $1 $2 $5 } > ALTS : ALT { [$1] } > ALT ; ALTS { $1:$3 } > ALT : PAT -> REXPR { checkalt $2 (CAlt (fst $1) (snd $1) $3) } > PAT : cons { (mkcons $1,[]) } > ( cons VARARGS ) { (mkcons $2,$3) }... FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 17/20

Aufgabe 2 Implementieren: checkalt :: TokenType -> CAlt () ConsName VarName -> CAlt () ConsName VarName checkalts :: TokenType -> (Expr () ConsName VarName) -> [CAlt () ConsName VarName] -> (Expr () ConsName VarName) checkbinds :: Expr () ConsName VarName -> [Binding () ConsName VarName] -> TokenType -> Expr () ConsName VarName FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 18/20

Aufgabe 3 Implementieren Sie in der Parser-Definition Parser.ly eine Funktion: checkparsetree :: ParserOutput -> ParserOutput, die den geparsten Ausdruck rekursiv durchläuft und für alle dort auftretenden Konstruktoren (auch in den Pattern der case-alternativen) prüft, ob die Konstruktornamen in den Typdefinitionen (erste Komponente von ParseTree) definiert werden. Ist dies der Fall, so wird der ParseTree unverändert zurückgegeben. Anderenfalls soll eine aussagekräftige Fehlermeldung (mit Position des falschen Namens) generiert werden. Ein Beispiel ist: parsechf "expression True" *** Exception: Constructor "True" not defined Zeile: 1 Spalte: 12 FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 19/20

Aufgabe 4 Erstellen Sie mit happy den Parser, indem Sie happy -iinfo.txt Parser.ly aufrufen. Dies erstellt die Haskell-Quelltext-Datei Parser.hs sowie eine Datei info.txt die Auskunft über die Zustände des erstellten Shift-Reduce-Parsers gibt. Schauen Sie sich den Inhalt von info.txt an, um die Wirkungsweise des Parsers (etwas) zu verstehen. Testen Sie anschließend den Parser mit einigen Eingaben. Welche Ausdrücke können geparst werden? Welche Klammern kann der Benutzer weglassen, welche nicht? FP-PR Teil 1: Lexen & Parsen Sommersemester 2011 D. Sabel 20/20