Name: _______________ 1. INFORMATIK-KLAUSUR − IF1 (GA) 22.09.2000 Gegeben sei die Grammatik der Mini-C++-Programmiersprache (T, N, P, S): T = { void, main, klammerauf, klammerzu, blockklammerauf, blockklammerzu, operator, name, zahl, zuweisungsoperator, selmikolon, if, while, vergleichsoperator } N = { PROGRAMM, BLOCK, ZUWEISUNG, TERM, OPERAND } P = { PROGRAMM ::= void main klammerauf klammerzu BLOCK , BLOCK ::= blockklammerauf ANWFOLG blockklammerzu , ANWFOLG ::= ANWEISUNG ( ANWFOLG ), ANWEISUNG ::= BLOCK | ZUWEISUNG | IFANWEISUNG | WHILEANW , ZUWEISUNG ::= name zuweisungsoperator TERM semikolon , IFANWEISUNG ::= if klammerauf BEDINGUNG klammerzu ANWEISUNG , WHILEANW ::= while klammerauf BEDINGUNG klammerzu ANWEISUNG , BEDINGUNG ::= TERM vergleichsoperator TERM , TERM ::= OPERAND ( operator TERM ) | klammerauf TERM klammerzu (operator TERM ) , OPERAND ::= name | zahl } S = PROGRAMM Für die lexikographische Analyse des Scanners und der Festsetzung der Tokens gelten dabei folgende Regeln: Token P' = { void main if while klammerauf klammerzu blockklammerauf blockklammerzu operator name buchstabe zeichen ziffer zahl vorzeichen zuweisungsoperator semikolon vergleichsoperator } ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= Zeichenkette void main if while ( ) { } +|−|*|/ buchstabe [ zeichen ] a | b | c | ... | y | z buchstabe | ziffer 0 | 1 | 2 | ... | 8 | 9 ( vorzeichen ) ziffer [ ziffer ] +|− = ; <|>|<=|>=|==|!= Bei den Produktionen zu name und zahl bedeuten die eckigen Klammern „[...]“, dass zeichen bzw. ziffer optional und beliebig oft folgen können. Die runden Klammern „(...)“ bei der Produktion zahl bedeuten, dass das vorzeichen optional, aber nur einmal vorangestellt werden darf. Die Mini-C++-Programmiersprache besitzt keine Möglichkeit der Datenein- oder –ausgabe. Dies wäre zwar wünschenswert, würde die Aufgabe allerdings unnötig verkomplizieren. Name: _______________ 1. INFORMATIK-KLAUSUR − IF1 (GA) 22.09.2000 Die Mini-C++-Programmiersprache benötigt keine Variablendeklarationen – alle vorkommenden Variablen seinen als int-Variablen vordefiniert. Dementsprechend sind alle Operatoren int-Operatoren – also auch der Divisionsoperator ( / ) teilt ganzzahlig. Somit ist das folgende Programm ein gültiges Mini-C++-Programm: void main() { a = 45; b = 33; while (b != 0) { h = a - (a / b) * b; a = b; b = h; } g = a; } Aufgabe 1: a) Erstellen Sie eine Variablenbelegungstabelle zum oben abgebildeten MiniC++-Programm. Was leistet dieses Programm? Hinweis: Sollten Sie zu keiner Lösung kommen, so testen Sie das Programm mit dem Zahlenpaar a = 25, b = 15 oder a = 8, b = 6. b) Schreiben Sie ein eigenes Mini-C++-Programm, welches die Quersumme einer Zahl n = 19548 berechnet. Beachten Sie, dass die Mini-C++Programmiersprache keinen modulo-Operator ( % ) besitzt, der Divisionsoperator ( / ) allerdings ganzzahlig teilt und damit eine Restberechnung möglich ist. Aufgabe 2: a) Zeichnen Sie den zur Mini-C++-Programmiersprache zugehörigen ScanAutomaten. Gehen Sie dabei von einer vordefinierten Symboltabelle für die Produktionen P’ aus. b) Implementieren Sie die Fallunterscheidung für den Scan-Automaten (CASE zustand OF-Anweisung in der Unit „Scanner“). Hinweis: Sollten Sie keine Lösung beim Scan-Automaten (Teilaufgabe a) erlangt haben, so lassen Sie sich eine Lösung vom Lehrer geben! Aufgabe3: a) Geben Sie ausgehend von der Startregel S den Ableitungsbaum für das folgende Mini-C++-Programm mit Hilfe der oben angegebenen Produktionsregeln (P) an. void main() { a = 12; b = a * 17; } a) Implementieren Sie die fehlenden Prozeduren zu den Produktionsregeln ANWEISUNG und WHILEANW. (procedure anweisung(...) und procedure whileanw(...) in der Unit “Parser”) Name: _______________ 1. INFORMATIK-KLAUSUR − IF1 (GA) Lösung zu Aufgabe 1a) Das Programm berechnet den ggT zweier Zahlen a und b a 45 33 12 b 33 12 9 h 12 9 g 9 3 3 22.09.2000 3 0 0 3 Lösung zu Aufgabe 1b) void main() { n = 19452; q = 0; while (n > 0) { z = n - (n / 10) * 10; q = q + z; n = n / 10; } } Andere Alternativen sind denkbar – dies ist allerdings die einfachste Lösung. Lösung zu Aufgabe 2a) a..z, 0..9 S3 = S1 a..z 0..9 < = > S0 S2 0..9 +− 0..9 ! (){}*/; S5 = = S4 = S6 S7 Lässt sich nötigenfalls noch vereinfachen (Zustande S1, S2 und S6 können zusammengefasst werden. Lösung zu Aufgabe 2b) siehe Programm Lösung zu Aufgabe 3a) siehe unten Lösung zu Aufgabe 3b) siehe Programm Name: _______________ 1. INFORMATIK-KLAUSUR − IF1 (GA) 22.09.2000 Lösung zu Aufgabe 3a) PROGRAMM void main klammerauf klammerzu void main ( ) BLOCK blockklammerauf ANWFOLG { ANWEISUNG ANWFOLG ZUWEISUNG ANWEISUNG name a zuweisungsoperator = blockklammerzu TERM semikolon OPERAND ; zahl 12 } ZUWEISUNG name b zuweisungsoperator = TERM semikolon OPERAND operator TERM name * OPERAND a zahl 17 ; Name: _______________ 1. INFORMATIK-KLAUSUR − IF1 (GA) 22.09.2000 Aufgabe : Geben Sie die algorithmische Idee des Parsers wieder. Lösung: Die algorithmische Idee des Parser findet sich in seiner rekursiven Struktur wieder. Man spricht von einem Top-Down-Parser, welcher rekursiv die Produktionsregeln – ausgehend von der obersten Startregel – alle eventuell auszuführenden Ersetzungen durchführt. Die Produktionsregeln werden in Form von Prozeduren, welche ineinandergeschachtelt die Hierarchie der einzelnen Produktionsregeln verdeutlichen, implementiert. Damit innerhalb einer Produktionsregel eine Fallunterscheidung möglich ist, welche Produktionsregel als nächstes auszuführen ist, muss der Parser stets ein Token voraus sein. Aufgrund dieses nächsten Tokens muss z. B. innerhalb der ANWEISUNG in verschiedene Anweisungstypen verzweigt werden. Damit das aktuelle Token nicht verloren geht, wird dieses stets in die jeweilig ProduktionsregelProzedur mitgegeben. Output ist dabei ein Fehlercode, welcher dafür benötigt wird, die Parse-Prozedur zu unterbrechen und den Grund des Abbruchs mitzuteilen. 1. INFORMATIK-KLAUSUR − IF1 (GA) Name: _______________ Aufgabe: Ableitungsbaum für ein Fakultätsprogramm Lösung: PROGRAMM void main klammerauf klammerzu BLOCK void main ( ) ANWFOLG blockklammerauf { ANWEISUNG ZUWEISUNG name zuweisungsoperator TERM semikolon n = OPERAND zahl 5 ; blockklammerzu ANWFOLG } ANWEISUNG ANWFOLG ZUWEISUNG ANWEISUNG name zuweisungsoperator TERM semikolon fakultaet = 22.09.2000 OPERAND zahl WHILEANW ; while klammerauf while 1 ( BEDINGUNG TERM vergleichsoperator TERM OPERAND > zahl n 1 TERM fakultaet * ) BLOCK blockklammerauf ANWFOLG blockklammerzu { ANWEISUNG ANWFOLG ; OPERAND name n } ZUWEISUNG ANWEISUNG semikolon OPERAND operator TERM name ANWEISUNG OPERAND name name zuweisungsoperator fakultaet = klammerzu ZUWEISUNG name zuweisungsoperator n = TERM semikolon OPERAND operator TERM name n − ; OPERAND zahl 1