Zum Inhalt springen
Sitzung: Jeden Freitag in der Vorlesungszeit ab 16 Uhr c. t. im MAR 0.005. In der vorlesungsfreien Zeit unregelmäßig (Jemensch da?). Macht mit!

PSS Gedächtnisprotokoll Klausur WS 0506: Unterschied zwischen den Versionen

Aus FreitagsrundenWiki
Keine Bearbeitungszusammenfassung
Theresa (Diskussion | Beiträge)
Lösung Aufg. 2
 
(20 dazwischenliegende Versionen von 7 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
Hier fehlen noch ein paar Informationen, mein Gedächtnis ist da etwas lückenhaft!
Die Bearbeitungszeit waren 90 Minuten. Alle Hilfmittel waren zugelassen (Kofferklausur)
Außerdem scheint mir einiges falsch..? naja vorallem die 2. Grammatik ist nicht identisch
 
----
 
<pre>
== Aufgabe 1: Grammatikumformung ==
1. forme die grammatik in ll1 um und zeige das sie ll1 ist.
1. Forme die Grammatik so um, dass sie von einem '''recursive-descent'''-Parser geparst werden kann.
zeige das die ausgangsgrammatik nicht ll1 ist
 
2. Entscheide und begründe, ob die umgeformte Grammatik und die ursprüngliche Grammatik die LL(1)-Eigenschaft erfüllen. Bilde die nötigen First-, Follow- und Directormengen.
 
S  -> E#
E  -> ide
    |  ide ( A )
A  -> P
    |  {Epsilon}
P  -> P , E
    |  E
 
== Aufgabe 2: Parser ==
 
Gegeben folgende Grammatik mit Directormenge:
S  ->  T #
T  ->  ide
        | <T T'>
T' ->  {Epsilon}
        | _ T T' {Das _ war ein ''space''}
 
Ein Wort der Sprache war: <<1 2 4> <1 4 5> 3>
Das ganze repräsentierte einen n-ären Baum
 
DATA token ==
Open
Close
space
id(val:int)
eof
 
1. Entwickle einen passenden Absy.
 
Lösung (Tutorium):
 
DATA absy ==    start(cont: absy)
                tup(args: seq[absy])
                single(val: int)
 
 
2. Schreibe einen Recursive-Descent-/Combinator-Parser ohne Fehlerbehandlung. Falls Combinator: Programmiere auch die Kombinatoren.
 
Lösung (Tutorium):
 
FUN parse: seq[token] -> absy
DEF parse(s) ==
    LET
        (E1, t0) == parseT(s)
        t1 == (shift(eof))(t0)
    IN
        start(E1)
FUN parseT : seq[token] -> absy ** seq[token]
DEF parseT(ide(n)::R) == (single(n), R)
DEF parseT(Open::R) ==
    LET
        (t1, R1) == parseT(R)
        (t2, R2) == parseT1(R1)
    IN
          (tup(t1::t2), rt(R2))
FUN parseT1 : seq[token] -> seq[absy] ** seq[token]
DEF parseT1(Close::R) == (<>, Close::R)
DEF parseT1(space::R) ==
    LET
        (t1, R1) == parseT(R)
        (t2, R2) == parseT1(R1)
    IN
        (t1::t2, R2)
FUN shift : token -> seq[token] -> seq[token]
DEF shift(t)(ft::rt) == rt
 
 
 
== Aufgabe 3: SECD ==
 
Der Ausdruck (λ ''x'' . ''x''(2))(λ ''y'' . ''dup''(''y'')) war mit der SECD-Maschine zu interpretieren, wobei ''dup'' eine triviale Operation war, die ihr Argument verdoppelte.
 
Ergebnis: 4.
 
== Aufgabe 4: Codeerzeugung ==
int f(x:int, y:int){
if(x==0)
return y
else
return f(x-1, x*y)
}
1. Erzeuge Pseudocode für eine abstrakte stackbasierte Maschine und mache die Basisblöcke kenntlich.
 
2. Erläutere den Aufbau eines Stackframes. Warum werden die Komponenten in genau dieser Reihenfolge angeordnet?


S  -> E#
== Aufgabe 5: Unifikation ==
E  -> ide
1. Zeige die Typkorrektheit von ''h''. Gleichungen für jedes τ aufstellen. Umformungen begründen (Was wird hier gemacht?).
| ide ( A )
A  -> P
|
P  -> P , E
| E


2. schreibe einen recursive decent-/combinator-parser ohne fehlerbehandlung für die grammatik:
<pre>
S -> T#
FUN _ o _ : (beta -> gamma) -> (alpha -> beta) -> (alpha -> gamma)
T -> < T T' >
FUN length: string -> nat
T' -> ide
FUN even?: nat -> bool
|
in der sprache war: <<1 2 4> <1 4 5> 3>
das ganze repräsentierte einen n-ären baum
DATA absy ==
node(val:seq[absy])
leaf(val:token)
DATA token ==
Open
Close
space
id(val:???)


3. SECD
FUN h: string -> bool
(\x. x(2))(\y. dup(y))
DEF h(s) == o(even?)(length)(s)
ergebnis 4
dup ist triviale operation


4. codeerzeugung
int f(x:int, y:int){
if(x==0)
return y
else
return f(x-1, x*y)
}
erzeuge pseudocode für eine stackartige maschine
erläutere den stackframe (überlappung und sowas)


5. unifikation
apply(tau1)
length: string -> nat
apply(tau2)
even?: nat -> bool
apply(tau4)
h: string -> ???
o(tau6)
h(s) == ???
even?(tau7)
eval
length(tau5)
eval s
s (tau3)
eval length
??? even?
ergebnis war korrekt, aber das sah vllt. auch etwas anders aus..
</pre>
</pre>
Zur Notation: Erst kommt ein Knoten, dann seine Kinder von links nach rechts.
Der Baum gehört zu ''h''(''s'') und ist korrekt.

Aktuelle Version vom 28. Februar 2012, 18:27 Uhr

Die Bearbeitungszeit waren 90 Minuten. Alle Hilfmittel waren zugelassen (Kofferklausur)


Aufgabe 1: Grammatikumformung

1. Forme die Grammatik so um, dass sie von einem recursive-descent-Parser geparst werden kann.

2. Entscheide und begründe, ob die umgeformte Grammatik und die ursprüngliche Grammatik die LL(1)-Eigenschaft erfüllen. Bilde die nötigen First-, Follow- und Directormengen.

S  -> E#
E  -> ide
   |  ide ( A )
A  -> P
   |  {Epsilon}
P  -> P , E
   |  E

Aufgabe 2: Parser

Gegeben folgende Grammatik mit Directormenge:

S  ->  T #
T  ->  ide
       | <T T'>
T' ->  {Epsilon}
       | _ T T' {Das _ war ein space}

Ein Wort der Sprache war: <<1 2 4> <1 4 5> 3> Das ganze repräsentierte einen n-ären Baum

DATA token ==
	Open
	Close
	space
	id(val:int)
	eof

1. Entwickle einen passenden Absy.

Lösung (Tutorium):

DATA absy ==    start(cont: absy)
                tup(args: seq[absy])
                single(val: int)


2. Schreibe einen Recursive-Descent-/Combinator-Parser ohne Fehlerbehandlung. Falls Combinator: Programmiere auch die Kombinatoren.

Lösung (Tutorium):

FUN parse: seq[token] -> absy
DEF parse(s) ==
    LET
        (E1, t0) == parseT(s)
        t1 == (shift(eof))(t0)
    IN
        start(E1) 

FUN parseT : seq[token] -> absy ** seq[token] 

DEF parseT(ide(n)::R) == (single(n), R) 

DEF parseT(Open::R) ==
    LET
        (t1, R1) == parseT(R)
        (t2, R2) == parseT1(R1)
    IN
         (tup(t1::t2), rt(R2))

FUN parseT1 : seq[token] -> seq[absy] ** seq[token] 

DEF parseT1(Close::R) == (<>, Close::R)

DEF parseT1(space::R) ==
    LET
        (t1, R1) == parseT(R)
        (t2, R2) == parseT1(R1)
    IN
        (t1::t2, R2) 

FUN shift : token -> seq[token] -> seq[token]
DEF shift(t)(ft::rt) == rt


Aufgabe 3: SECD

Der Ausdruck (λ x . x(2))(λ y . dup(y)) war mit der SECD-Maschine zu interpretieren, wobei dup eine triviale Operation war, die ihr Argument verdoppelte.

Ergebnis: 4.

Aufgabe 4: Codeerzeugung

int f(x:int, y:int){
	if(x==0)
		return y
	else
		return f(x-1, x*y)
}

1. Erzeuge Pseudocode für eine abstrakte stackbasierte Maschine und mache die Basisblöcke kenntlich.

2. Erläutere den Aufbau eines Stackframes. Warum werden die Komponenten in genau dieser Reihenfolge angeordnet?

Aufgabe 5: Unifikation

1. Zeige die Typkorrektheit von h. Gleichungen für jedes τ aufstellen. Umformungen begründen (Was wird hier gemacht?).

FUN _ o _ : (beta -> gamma) -> (alpha -> beta) -> (alpha -> gamma)
FUN length: string -> nat
FUN even?: nat -> bool

FUN h: string -> bool
DEF h(s) == o(even?)(length)(s)


apply(tau1)
	apply(tau2)
		apply(tau4)
			o(tau6)
			even?(tau7)
		length(tau5)
	s (tau3)

Zur Notation: Erst kommt ein Knoten, dann seine Kinder von links nach rechts.

Der Baum gehört zu h(s) und ist korrekt.