Abschlußprüfung im Fach Compilerbau

static void match(Token expected). { if (lookahead.symb == expected.symb) s.nextToken(); else error(“falsches Token eingelesen“);. } 0701PRÜF. Compilerbau.
449KB Größe 0 Downloads 36 Ansichten
Name:

Vorname:

Hochschule für angewandte Wissenschaften Fachhochschule Würzburg-Schweinfurt Fakultät Informatik und Wirtschaftsinformatik Prof. Grötsch

SS 2010

Abschlußprüfung im Fach Compilerbau (4-stündige Vorlesung, Raum E05) Termin:

21.07.2010

Vorname: ______________

Name:____________________

keine Hilfsmittel, außer Wörterbüchern Antworten sollen nur stichpunktartig sein maximal 90 Punkte, bestanden mit 45 Punkten

1 Endliche Automaten 6 Geben Sie den deterministischen endlichen erkennenden Automaten zum regulären Ausdruck (in klassischer Theorie-Notation)

a(m + k)*m (j + n)* an. 2 Kontextfreie Grammatik

4+4

a) Geben Sie die kontextfreie Grammatik an, die die Sprache

am bn c2n beschreibt (n, m >= 0). b) Wenn Sie die Grammatik mit nur einer epsilon-Regel schreiben können, gibt es die doppelte Punktzahl. 6 3 Linkslineare Grammatik Geben Sie die linkslineare Grammatik an, die die Sprache erzeugt, die der reguläre Ausdruck (in klassischer Theorie-Notation)

(a+b)*bc* beschreibt. 4 lex

8+4

Übersetzen Sie folgende „traditionelle“ Theorie-lex-Muster in lex-reguläre Ausdrücke: (4 Extra-Punkte, wenn die lex-Muster möglichst kompakt formuliert sind). 1) ba + bb + bc+ bd + a + b + c + d 2) 1 + 2 + a1 + a2 + b1+ b2 + c1 + c2 3) (a + b + c + d) (a + b + c + d)* 4) (a + b + c)* (a + b + c + d)*

0701PRÜF

Compilerbau

2/6

Name:

Vorname:

5 Top-down-Parsing Die folgende Grammatik ist gegeben. (0) ::= $ ; exit (1) ::= (2) | (3) | ; (4) ::= ; (5) ::= repeat ; (6) ::= ; (7) | ; (8) ::= bez := (9) | num ; (10) ::= bez + (11) | num ; (12) ::= until bez = num (13) | ;

10

Es folgt das Programmfragment eines Top-down-Parsers nach dem Verfahren des rekursiven Abstiegs. Ergänzen Sie die Prozeduren, die noch nicht ausgeführt sind: /* Programm Aufgabe 7/10 */ public class Parser { static Token lookahead = new Token(); static Scanner s = new Scanner(); public static void main(String[] args) { lookahead = s.nextToken(); s(); if (lookahead.symb == DollarSym) System.out.println("Eingabe ok"); else error(); } static void error(String s) { System.out.println (s); exit(0); } static void match(Token expected) { if (lookahead.symb == expected.symb) s.nextToken(); else error(“falsches Token eingelesen“); }

0701PRÜF

Compilerbau

2/6

Name:

Vorname:

Start() {

// Abarbeitung der Produktionen

} S() {

} REP_ANW() {

} REP_BODY() {

} LINES() {

} LINE() {

} EXPR() {

} CONDI() {

0701PRÜF

Compilerbau

2/6

Name:

Vorname:

} } // end class Parser

0701PRÜF

Compilerbau

2/6

Name:

Vorname:

6 Tripel-Code Gegeben sei das folgende Java-Programmstück: int t = 3; int s = 11; while ((t < 6) && (s > 3)) { t = 1 + 3 * s; s--; }; Überführen Sie das Java-Programmstück in einen Tripel-Code.

10

Hinweis: Verwenden Sie nur folgende Tripel-Code-Anweisungen: := V E1 Speichere den Wert von E1 in der Variablen V, + E1 E2 Addiere E1 und E2, E1 E2 Subtrahiere E2 von E1, * E1 E2 Multipliziere E1 mit E2, < E1 E2 Prüfe, ob E1 kleiner als E2 ist, JC TNr.1 TNr.2 Springe zum Tripel Tnr.2, wenn der Test J TNr.1 Springe zum Tripel TNr.1 Dabei stehen V für Variable, E1 bzw. E2 für Konstante, Variable oder Tripel-Nummern und TNr.1 und TNr.2 für Tripel-Nummern. Um Tripel-Nummern von Konstanten unterscheiden zu können, sind sie in Klammern anzugeben (z.B.: 1: Konstante 1, (1): Tripel-Nummer 1)

7 Abarbeiten einer LR-Parse-Tabelle Gegeben ist folgende Grammatik (in CUP-Notation): (1) AUSDR ::= AUSDR minus QUOTIENT (2) | QUOTIENT ; (3) QUOTIENT ::= QUOTIENT div FACTOR (4) | FACTOR ; (5) FACTOR ::= id (6) | num ; Zu dieser Grammatik gehört folgende LR(1)-Tabelle: Zustand Aktion Sprung id num div $ AUSDR minus 0 s9 s3 1 1 s5 acc 2 r4 r4 r4 3 r6 r6 r6 4 r3 r3 r3 5 s9 s3 6 r1 s8 r1 7 r2 s8 r2 8 s9 s3

0701PRÜF

Compilerbau

2/6

10

QUOTIENT

FACTOR

7

2

6

2

4

Name:

Vorname:

9

r5

r5

r5

Analysieren Sie mit Hilfe der LR-Tabelle das folgende Eingabewort: num minus id div id $ 8 CUP Es folgt ein Auszug aus einem CUP-Programm. Erläutern Sie die durch Rahmen hervorgehobenen Anweisungen.

10

terminal PLUS, MAL, LPAREN, RPAREN; terminal Integer NUMBER; non terminal Integer expr; precedence left PLUS; precedence left MAL; . . . expr

::=

NUMBER:n {: RESULT=n; :} | expr:l PLUS expr:r {: RESULT= l + r;:} | expr:l MAL expr:r {: RESULT=new Integer(l * r);:} | LPAREN expr:e RPAREN {: RESULT=e; :} ;

9 LL(1) (Ableitung einer LL(1)-Parse-Tabelle) 1.



2. 3. 4.



5.



6. 7. 8.



9. 10. 11.



::=

| |

5+5+5 + 3

::= ; ::= + | - | ε ; ; ::= * / | | ε ; ::= ( ) id num ;

9.1 Bestimmen Sie zur Grammatik G die Tabelle für FIRST, FOLLOW und die LL(1)Analysefunktion.

0701PRÜF

Compilerbau

2/6

Name:

Vorname:

9.2 Wofür stehen Leerstellen, die keinen Eintrag haben? Wie könnte man sie sinnvoll füllen? (am Besten am Beispiel einer Leerstelle zeigen)

0701PRÜF

Compilerbau

2/6

Name:

Vorname:

FIRST FOLLOW Parsetabelle

0701PRÜF

Compilerbau

+ + +

2/6

-

* * *

/ / /

( ( (

) ) )

id id id

num num num

$ $

Fachhochschule Würzburg-Schweinfurt Fakultät Informatik und Wirtschaftsinformatik Prof. Grötsch

WS 2008

Abschlussprüfung im Fach Techniken des Compilerbaus Termin:

06.02.2009

Vorname: ______________ • • •

Name:____________________

keine Hilfsmittel Antworten sollen nur stichpunktartig sein maximal 90 Punkte, bestanden mit 45 Punkten

1 Kontextfreie Grammatik a) Geben Sie die kontextfreie Grammatik an, die die Sprache

6+2

a2n bm ek cm dn beschreibt (n > 0, m >= 0, k > 0). b) Wenn Sie die korrekte Grammatik ohne epsilon-Regel schreiben können, gibt es 2 Punkte zusätzlich. 2 Kontextfreie Grammatik a) Geben Sie die kontextfreie Grammatik an, die die Sprache

6+2

an bn ck dk beschreibt (n > 0, k >= 0). b) Wenn Sie die korrekte Grammatik ohne epsilon-Regel schreiben können, gibt es 2 Punkte zusätzlich. 3 lex Übersetzen Sie folgende „traditionelle“ „Theorie-reguläre“ Ausdrücke in lex-reguläre Ausdrücke: a) k+ l + m + n + ε b) k + ε + (k + l + m + n)* c) (k + l + m + n) + (k + l + m + n) (n + k + l + m) (k + l + m + n) d) (o (k + l + m) (k + l + m)*) + (p (k + l + m) (k + l + m)*)

12

4 lex-reguläre Ausdrücke 3+3+3+3 Schreiben Sie die folgenden regulären lex-Ausdrücke kürzer bzw. so kurz es geht: a) ([klmn]+) | ε b)

k([k-n]? | o)([k-n] | o)+

c)

k1 | k2 | m1 | m2 | n1 | n2

d) ein Zeichen, das jedes beliebige Zeichen sein kann, jedoch weder das €-Zeichen, noch das $-Zeichen. 0902Bac2stuendig.doc

1

5 lex-reguläre Ausdrücke Beschreiben Sie in Form eines möglichst kompakten lex-Musters: a) b)

die Namen Maier, Meier, Mayer, Meyer, Mair, Meir, Mayr, Meyr Datumsangaben, z.B. 27.3.2009: ein Datum beginnt mit einer Tageszahl zwischen 1 und 31, dann folgt ein Punkt, danach kommt die Monatszahl zwischen 1 und 12, dann wieder ein Punkt, dann kommt die Jahreszahl, die vierstellig ist, und immer mit „20“ anfängt, also eine Zahl zwischen 2000 und 2099. [Vereinfachung: nach unseren Datums-Regeln ist auch der 31.2.2009 ein zulässiges Datum.]

6 Top-down-Parsing Gegeben sei die Grammatik G mit den terminalen Symbolen end ; wiederhole := + > bis bezeichner zahl der Startvariablen und der Regelmenge: (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13)

4+4

12



::= end | |ε ::= ::= wiederhole ::= ; ::= bezeichner := | zahl |ε ::= bezeichner + | zahl ::= bis bezeichner > zahl |ε

Es folgt das Programmfragment eines Top-down-Parsers nach dem Verfahren des rekursiven Abstiegs. %{ /* Programm Aufgabe 6/09 */ import java.io.*; import scanner.*; /* Eine Scanner-Klasse (nicht zu bearbeiten) wird vorausgesetzt */ /* (incl. Methode Token nextToken ()) */ /* EndSym Semikolon WiederholeSym Assign Plus GT BisSym */ /* bezeichner zahl EOFSym */ %} %% public class Parser { static Token lookahead = new Token(); static Scanner s = new Scanner();

0902Bac2stuendig.doc

2

public static void main(String[] args) { lookahead = s.nextToken(); s(); if (lookahead.symb == EOFSym) System.out.println("Eingabe ok"); else error(); } static void error(String s) { System.out.println (s); exit(0); } static void match(Token expected) { if (lookahead.symb == expected.symb) s.nextToken(); else error(“falsches Token eingelesen“); } /* Abarbeitung der Produktionen:

*/

s() {

} loop() {

} rumpf() {

} block() {

} statem() {

} 0902Bac2stuendig.doc

3

expr() {

} con(){

}

7 CUP 10+10 Gehen Sie bei der Lösung dieser Aufgabe davon aus, dass ein Scanner existiert, der genau die benötigten Tokens zurückliefert (also pkwTag, pkwEndTag, hubraumTag, usw. außerdem die Tokens bez und hub). Schreiben Sie eine Grammatik für XML-basierten Texten für die Verwaltung von PKWs. Die Texte sind mit den Tags , , , , , versehen, Beispiel:

Passat 2298

Die Bezeichnung ist immer vorhanden, der Hubraum (und die zugehörigen Tags) können entfallen. 7.1: Geben Sie eine Grammatik für den Aufbau der beschriebenen PKW-Texte an. 7.2: Geben Sie einen Auszug aus dem CUP-Programm (CUP-Deklarationen und CUPRegeln) für einen Parser an, der die beschriebenen XML-Texte parst, und die PKWs in der Reihenfolge Bezeichnung Hubraum so ausgibt: gefundener PKW: Passat, 2298 Falls der Hubraum fehlt, soll dafür „unbekannt“ ausgegeben werden, z.B.: gefundener PKW: A6, unbekannt Die Texte sind fehlerfrei, eine Fehlerbehandlung ist deshalb nicht erforderlich.

8 JFlex 10 Schreiben Sie einen Scanner (nur Deklarationen und Regelteil) mit JFlex, der dem Parser von Aufgabe 7 die erwarteten Tokens liefert. Dabei gilt: Hubraum ist immer eine Integer-Zahl, die Bezeichnung eines PKW ist eine Zeichenkette aus Buchstaben und Ziffern (ohne Umlaute, ohne „ß“).

0902Bac2stuendig.doc

4

Fachhochschule Würzburg-Schweinfurt Fakultät Informatik und Wirtschaftsinformatik Prof. Grötsch

SS 2008

Abschlußprüfung im Fach Compilerbau (Diplom) Termin:

18.07..2008

Vorname: ______________ • • •

Name:____________________

keine Hilfsmittel Antworten sollen nur stichpunktartig sein maximal 90 Punkte, bestanden mit 45 Punkten

1 Kontextfreie Grammatik 6+2 a) Geben Sie die kontextfreie Grammatik an, die die Sprache an b2n cm beschreibt (n > 0, m >= 0). b) Wenn Sie die korrekte Grammatik ohne epsilon-Regel schreiben können, gibt es 2 Punkte zusätzlich. 2 Endlicher Automat Geben Sie den endlichen erkennenden deterministischen Automaten zum regulären Ausdruck (b +c)*b(d + e)* an.

6

3 lex-reguläre Ausdrücke 3+3+3+3 Schreiben Sie die folgenden regulären lex-Ausdrücke kürzer bzw. so kurz es geht: a) ([hgfe]+) | ε b)

a([a-d]? | e)([a-d] | e)+

c)

a1 | a2 | b1 | b2 | c1 | c2

d)

alle Zeichen einer Zeile, aber nicht das/die Zeichen, die das Zeilenende repräsentieren.

5 Tripel-Code Gegeben sei das folgende Pascal-Programmstück: a := 0; z := 1; WHILE z < y DO BEGIN a := a+1; z := 2*a + z + 1; END;

7

Die Bezeichner a, y, und z seien als Variable vom Typ INTEGER deklariert, y sei initialisiert.

Name:

Vorname:

Überführen Sie das PASCAL-Programmstück in einen Tripel-Code. Hinweis: Verwenden Sie nur folgende Tripel-Code-Anweisungen: := V E1 Speichere den Wert von E1 in der Variablen V, + E1 E2 Addiere E1 und E2, E1 E2 Subtrahiere E2 von E1, * E1 E2 Multipliziere E1 mit E2, < E1 E2 Prüfe, ob E1 kleiner als E2 ist, JC TNr.1 TNr.2 Springe zum Tripel Tnr.2, wenn der Test von TNr.1 nicht erfolgreich war, J TNr.1 Springe zum Tripel TNr.1 Dabei stehen V für Variable, E1 bzw. E2 für Konstante, Variable oder Tripel-Nummern und TNr.1 und TNr.2 für Tripel-Nummern. Um Tripel-Nummern von Konstanten unterscheiden zu können, sind sie in Klammern anzugeben (z.B.: 1: Konstante 1, (1): Tripel-Nummer 1)

6 Top-down-Parsing Gegeben sei die Grammatik G mit den terminalen Symbolen exit ; loop := + > until ident num der Startvariablen und der Regelmenge: (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13)

12



::= exit | |ε ::= ::= loop ::= ; |ε ::= ident := | num ::= ident + | num ::= until ident > num |ε

Es folgt das Programmfragment eines Top-down-Parsers nach dem Verfahren des rekursiven Abstiegs. %{ /* Programm Aufgabe 6/08 */ import java.io.*; import scanner.*; /* Eine Scanner-Klasse (nicht zu bearbeiten) wird vorausgesetzt /* (incl. Methode Token nextToken ()) /* ExitSym Semikolon LoopSym Assign Plus GT UntilSym /* bez num DollarSym 0807CompDip_001.doc

Compilerbau

*/ */ */ */ 2/5

Name:

Vorname:

%} %% public class Parser { static Token lookahead = new Token(); static Scanner s = new Scanner(); public static void main(String[] args) { lookahead = s.nextToken(); s(); if (lookahead.symb == DollarSym) System.out.println("Eingabe ok"); else error(); } static void error(String s) { System.out.println (s); exit(0); } static void match(Token expected) { if (lookahead.symb == expected.symb) s.nextToken(); else error(“falsches Token eingelesen“); } /* Abarbeitung der Produktionen: */ s() {

} loop() {

} body() {

} block(){

} 0807CompDip_001.doc

Compilerbau

3/5

Name:

Vorname:

statem() {

} expr() {

} con(){

} 7 CUP 10+10 Schreiben Sie eine Grammatik für XML-basierte Texte mit Namen. Die Texte sind mit Tags , , , , , versehen, Beispiel:

Meier Hans



Entweder Vorname oder Nachname (und die zugehörigen Tags) können entfallen (aber niemals beide). 7.1: Geben Sie eine Grammatik für den Aufbau der beschriebenen Namen-Texte an. 7.2: Geben Sie einen Auszug aus dem CUP-Programm (CUP-Deklarationen und CUPRegeln) für einen Parser an, der die beschriebenen XML-Texte parst, und die Namen in der Reihenfolge Vorname Nachname so ausgibt: gefundener Name: Hans Meier Falls ein Namensteil fehlt, soll dafür „???“ ausgegeben werden, z.B.: gefundener Name: Fritz ??? gefundener Name: ??? Schmitt Die Texte sind fehlerfrei, eine Fehlerbehandlung ist deshalb nicht erforderlich. Gehen Sie davon aus, dass ein Scanner existiert, der genau die benötigten Tokens zurückliefert. 8 JFlex 10 Schreiben Sie einen Scanner (nur Deklarationen und Regelteil), der aus einem Text alle Tags herausfiltert. Beispiele für Tags: ,

0807CompDip_001.doc

Compilerbau

4/5

Name:

Vorname:

Ein Tag beginnt mit „“. Das Zeichen „>“ selbst kann nicht innerhalb eines Tags vorkommen. Tags werden unterdrückt, alle anderen Zeichen werden auf die Standardausgabe ausgegeben. 9 (Ableitung einer LL(1)-Parse-Tabelle) Gegeben sei die Grammatik G mit den terminalen Symbolen end ; wiederhole := + solange bez zahl der Startvariablen und der Regelmenge: (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13)



5+5+5

::= end | |ε ::= ::= wiederhole ::= |ε ::= bez := ; | zahl ; ::= bez + | zahl ::= solange > bez |ε

Bestimmen Sie zur Grammatik G die Tabelle für FIRST, FOLLOW und die LL(1)Analysefunktion. FIRST

end

; wiederhole

:=

+

solange

bez

zahl

ε

FOLLOW

end

; wiederhole

:=

+

solange

bez

zahl

$

LL(1)-Tabelle

end

; wiederhole

:=

+

solange

bez

zahl

$

0807CompDip_001.doc

Compilerbau

5/5

Fachhochschule Würzburg-Schweinfurt Fakultät für Informatik und Wirtschaftsinformatik Prof. Grötsch

WS 2007/2008

Abschlußprüfung im Fach Techniken des Compilerbaus (Bachelor) Termin:

30.01.2008

Vorname: ______________ • • •

Name:____________________

keine Hilfsmittel Antworten sollen nur stichpunktartig sein maximal 90 Punkte, bestanden mit 45 Punkten

1 Kontextfreie Grammatik a) Geben Sie die kontextfreie Grammatik an, die die Sprache

6+2

sn rm t2n beschreibt (n > 0, m >= 0). b) Wenn Sie die korrekte Grammatik ohne epsilon-Regel schreiben können, gibt es 2 Punkte zusätzlich. 2 lex 12 Übersetzen Sie folgende „traditionelle“ Theorie-lex-Muster in lex-reguläre Ausdrücke: a) r + s + t + u + ε b) ε + r + s + t + (r + s + t + u)* c) (r+ s + t +u) + (r + s + t +u) (t + s + r +u) + (r + s + t +u) (t + s + r +u) (t + r + s +u) d) (p (r + s + t) (r + s + t)*) + (q (r + s + t) (r + s + t)*) + ((r + s + t) (r + s +t)*) 3 lex-reguläre Ausdrücke 3+3+3+3 Schreiben Sie die folgenden regulären lex-Ausdrücke kürzer bzw. so kurz es geht: a) s(([s-v]?) | w)(([s-v] | w)+ b)

([01234]+) | ε

c)

( (a|b|c|d) [0123] ) {0,1}

d) eine Zeichenklasse, die beliebige (auch leere) Folgen von in Deutschland allgemein verwendeten Buchstaben definiert – auch ä,ö,ü, Ä, Ö, Ü, ß. Ziffern und Sonderzeichen dürfen nicht vorkommen. 4 Linksrekursion 3+3 4.1 Geben Sie beispielhaft eine (frei erfundene) Grammatikregel an, die im Top-DownParser zu Linksrekursion führen würde. 4.2 Wenn bei einer realen Aufgabe das Problem der Linksrekursion auftreten würde – welche Möglichkeiten hätte man, das Problem zu lösen, bzw. dem Problem aus dem Weg 0801Bac.doc

1

zu gehen?

0801Bac.doc

2

5 lex-reguläre Ausdrücke 3+3+4 Beschreiben Sie in Form eines möglichst kompakten lex-Musters: a) die möglichen Lottozahlen: 1, 2, 3, 4, … 48, 49 b) Postleitzahlen: 5-stellige Integerzahlen, eine führende Null ist erlaubt (aber an den ersten beiden Stellen keine 2 Nullen hintereinander, also: 01234 ist erlaubt, 00123 ist nicht erlaubt). c) E-Mail-Adressen der Firma Meier: in dieser Firma sind alle Mail-Adressen grundsätzlich nach folgendem Muster aufgebaut: [email protected], im Vornamen/Nachnamen dürfen keine Umlaute und kein ß vorkommen, die jeweils ersten Buchstaben (und nur diese) von Vorname/Nachname müssen groß geschrieben werden, und jeder Name besteht aus mindestens einem großen und einem kleinen Buchstaben.

6 Top-down-Parsing Die folgende Grammatik ist gegeben. (1) ::= exit (2) | (3) | ε (4) ::= (5) ::= repeat (6) ::= ; (7) | ε (8) ::= bez := (9) | num (10) ::= bez + (11) | num (12) ::= until bez < num (13) | ε

12

Es folgt das Programmfragment eines Top-down-Parsers nach dem Verfahren des rekursiven Abstiegs. Ergänzen Sie die geforderten nachfolgenden Prozeduren (das Programm muss nicht vollständig erstellt werden !) %{ /* Programm Aufgabe 6/2008 */ import java.io.*; import scanner.*; /* Eine Scanner-Klasse (nicht zu bearbeiten) wird vorausgesetzt /* (incl. Methoden Token getToken() und void error()) /* Folgende Tokens werden geliefert: /* ExitSym, RepeatSym, UntilSym, /* bez, num, Plus, Assign, LT, Semikolon %} %% public class Parser { static Token lookahead = new Token(); static Scanner s = new Scanner(); 0801Bac.doc

*/ */ */ */ */

3

public static void main(String[] args) { lookahead = s.getToken(); expr(); if (lookahead.symb != Token.EOF) { s.error("Fehler: Eingabe wurde nicht vollstaendig verarbeitet"); } System.out.println(); } static void match(int tokensymbol) { if (lookahead.symb == tokensymbol) { lookahead = s.getToken(); } else { s.error("Syntaxfehler in match"); } } […]

// die hier fehlenden Methoden müssen nicht ergänzt werden static void REPEAT_BODY(){

} static void STATEMENTS(){

} static void STATEMENT(){

} […] }

0801Bac.doc

// die hier fehlenden Methoden müssen nicht ergänzt werden

4

7 CUP 10+10 Nehmen Sie an, Sie haben eine Sprache, die folgende Bedingungen zulässt: (x und y stehen für beliebige Bezeichner): Quellsprache if (x < y) if (x > y) if (x == y) if (x != y) if (x = y) Aufgabe 7.1: Geben Sie eine Grammatik nur für die Bedingungen in der Tabelle oben an, (nur if, mit Klammern und Bedingung), terminale Zeichen sind if, klaAuf, klaZu, lt, gt, eq, le, ge, ne, id. (Grammatik muss nicht linksfaktorisiert sein). (lt steht für: , eq: ==, le: =, ne: !=) Im Folgenden soll die angegebene Sprache auf eine primitivere Sprache übersetzt werden, die nur bedingte Sprünge kennt. Beispiel für die Umsetzung: aus if (x < y) { statement; } wird: if !(x < y) goto weiter; statement; weiter: Abbildung: Quellsprache if (x < y) statement; if (x > y) statement; if (x == y) statement;

if (x = y) statement;

0801Bac.doc

primitive Zielsprache if !(x < y) goto weiter; statement; weiter: if !(y < x) goto weiter; statement; weiter: if !(x < y+1) goto weiter; if !(y < x+1) goto weiter; statement; weiter: if !(x < y+1) goto weiter; statement; weiter: if !(y < x+1) goto weiter; statement; weiter:

5

Aufgabe 7.2: Geben Sie einen Auszug aus dem CUP-Programm (CUP-Deklarationen und CUP-Regeln) für die Übersetzung der bedingten Anweisungen aus der Quellsprache (linke Tabellenspalte) in die primitive Zielsprache (rechte Tabellenspalte) an (Ausgabe auf Standard-Ausgabe). (Umfang nur wie in der Tabelle, keine Regeln dazu erfinden). Gehen Sie davon aus, dass ein Scanner existiert, der genau die benötigten Tokens zurückliefert. Hinweis: Beachten Sie, dass Sie an manchen Stellen die Plätze von x und y vertauschen müssen – wenn Sie die entsprechenden Token müssen vom geeigneten Typ deklariert sein.

8 JFlex 10 Schreiben Sie einen Scanner (nur Deklarationen und Regelteil), der aus einem Text nur diejenigen Zeilen ausgibt, in denen „Informatik“ vorkommt. Vor jeder Zeile, die ausgegeben wird, steht die Zeilennummer aus dem ursprünglichen Text. (Hinweis: Die String-Klasse in Java bietet eine Methode boolean contains (String s) (contains ist hier vereinfacht dargestellt – reicht aber zur Lösung der Aufgabe aus)

0801Bac.doc

6

Fachhochschule Würzburg-Schweinfurt Fakultät für Informatik und Wirtschaftsinformatik Prof. Grötsch

SS 2007

Abschlußprüfung im Fach Techniken des Compilerbaus Termin:

17.07.2007

Vorname: ______________ • • •

(Bachelor)

Name:____________________

keine Hilfsmittel Antworten sollen nur stichpunktartig sein maximal 90 Punkte, bestanden mit 45 Punkten

1 Kontextfreie Grammatik a) Geben Sie die kontextfreie Grammatik an, die die Sprache

4+4

rmsn t2n beschreibt (n, m >= 0). b) Wenn Sie die korrekte Grammatik mit nur einer epsilon-Regel schreiben können, gibt es 4 Punkte zusätzlich. 2 lex-reguläre Ausdrücke 3+3+3+3 Schreiben Sie die folgenden regulären lex-Ausdrücke kürzer bzw. so kurz es geht: a) ([r-u]?) ([r-u]?) ([r-u]?) b) [ZaYbFcEeDdCfBzAy]+ c) r|s|t|ε

d) alle Zeichen einer Zeile, aber nicht das/die Zeichen, die das Zeilenende repräsentieren. 3 lex-reguläre Ausdrücke Beschreiben Sie in Form eines möglichst kompakten lex-Musters: a) die zulässigen Lottozahlen (1 .. 49) b) britische Postleitzahlen in folgenden Struktur-Varianten: A9 9AA A99 9AA A9A 9AA AA9 9AA AA99 9AA AA9A 9AA

3+5

wobei A für einen beliebigen grossen Buchstaben und 9 für eine beliebige Ziffer steht. Bitte beachten Sie das Leerzeichen zwischen den beiden Gruppen. (Erläuterung zur Struktur finden Sie in http://en.wikipedia.org/wiki/UK_postcodes)

Name:

Vorname:

4 lex 8+4 Übersetzen Sie folgende „traditionelle“ Theorie-lex-Muster in lex-reguläre Ausdrücke: (4 Extra-Punkte, wenn die lex-Muster möglichst kompakt formuliert sind). a) ba + bb + cb + ca b) (1+2+3+4+5+6+7+8+9) (0+1+2+3+4+5+6+7+8+9)* c) (a + b + c)*(a + b + c + d)* d) (0+1+2+3+4+5+6+7+8+9) (0+1+2+3+4+5+6+7+8+9)* 5 Top-down-Parsing

10

Die folgende Grammatik ist gegeben. (0) : $ ; (1) : exit (2) | (3) | ε ; (4) : ; (5) : repeat ; (6) : ; (7) | ε ; (8) : bez := (9) | num ; (10) : bez + (11) | num ; (12) : while < num (13) | ε ; Es folgt das Programmfragment eines Top-down-Parsers nach dem Verfahren des rekursiven Abstiegs. Ergänzen Sie die nachfolgenden Prozeduren, die noch nicht ausgeführt sind.

%{ /*

Programm Aufgabe 5/2007 */

import java.io.*; import scanner.*; /* Eine Scanner-Klasse (nicht zu bearbeiten) wird vorausgesetzt /* (incl. Methoden Token getToken() und void error()) /* Folgende Tokens werden geliefert:

*/ */ */

/* /* %} %%

*/ */

Dollar, ExitSym, RepeatSym, UntilSym, WhileSym, bez, num, Plus, Assign, Semikolon,

070107_07PRFBacV2.doc

Compilerbau

2/8

Name:

Vorname:

public class Parser { static Token lookahead = new Token(); static Scanner s = new Scanner(); public static void main(String[] args) { lookahead = s.getToken(); expr(); if (lookahead.symb != Token.Dollar) { s.error("Fehler: Eingabe wurde nicht vollstaendig verarbeitet"); } System.out.println(); } static void match(int tokensymbol) { if (lookahead.symb == tokensymbol) { lookahead = s.getToken(); } else { s.error("Syntaxfehler in match"); } } Start() { } S() {

} SCHLEIFE() {

} RUMPF() { } ANWEISUNGEN() {

} 070107_07PRFBacV2.doc

Compilerbau

3/8

Name:

Vorname:

STATEMENT() {

} AUSDRUCK() {

} BEDINGUNG() {

} }

6 CUP / JFlex

8+10

Der Deutsche Fußballverband (DFB) hat die Syntax für die Namensgebung von Fußballvereinen standardisiert, und ein Prüfprogramm in Auftrag gegeben, das die Namen von Fußballvereinen auf syntaktische Korrektheit überprüft. 1. Die Grammatik für Namen von Fußballvereinen ::= stadtname | stadtnameEr | stadtname jahreszahl2 | stadtname ; ::= | | | | ;

1.FC FC TSV VfB VfL



SC SV

::= | ;

::= | ε ;

070107_07PRFBacV2.doc

Compilerbau

4/8

Name:

Vorname:



::= | | ;

Bayern Sachsen Hessen



::= | | | | | | ;

jahreszahl4 Werder Eintracht Borussia Energie Bayer Hertha

2. Zusätzliche Angaben 1. jahreszahl4: positive Integerzahl ohne Vorzeichen, vierstellig, zwischen 1820 und 2007, 2. jahreszahl2: beliebiges zweistellige Integerzahl, 3. stadtname: beginnt mit einem Großbuchstaben, danach folgen beliebig viele Kleinbuchstaben (mindestens 1), die letzten beiden Buchstaben sind nicht „er“ 4. stadtnameEr: beginnt mit einem Großbuchstaben, dann beliebig viele Kleinbuchstaben (mindestens 1), als letztes folgen die beiden Kleinbuchstaben „er“. 5. alle anderen Terminale stehen für die entsprechende Zeichenkette, z.B. Eintracht für die Zeichenkette „Eintracht“ Aufgabenstellung Aufgabe 6: 1. Skizzieren Sie einen Scanner mit JFlex (Regelteil, wichtige Deklarationen), der die Tokens jahreszahl4, jahreszahl2, stadtname, stadtnameEr liefert. Andere Zeichenketten, die keines dieser Token repräsentieren, werden ignoriert. 2. Skizzieren Sie einen Parser mit CUP, der die Tokens von JFlex entgegennimmt und gemäß der Grammatik für DFB-Vereinsnamen überprüft. Ein korrekter Vereinsname wird ausgedruckt, ein nicht korrekter führt zu einer Fehlermeldung. (siehe auch Anhang)

7 JFlex pur 10 Schreiben Sie einen Scanner (Regelteil und Deklarationen) mit JFlex, der folgendes leistet: Er erweitert einen eingegebenen Text und gibt ihn vollständig auf Standardausgabe aus, wobei folgende Abkürzungen durch ihre Langfassung zu ersetzen sind: RL RTFM ILD IDA DAU FAQ mfg z.B. 070107_07PRFBacV2.doc

Real life Read the fucking manual Ich liebe dich Ich dich auch dümmster anzunehmender User frequently asked questions Mit freundlichen Grüßen zum Beispiel Compilerbau

5/8

Name:

Vorname:

FH

070107_07PRFBacV2.doc

Fachhochschule

Compilerbau

6/8

Name:

Vorname:

8 Grundsätzliches Ordnen Sie in die untenstehende Tabelle die folgenden Begriffe ein:

8

Parser, kontextfreie Grammatik, Scanner, bottom-up, lineare Analyse, JFlex, CUP, regulärer Ausdruck, hierarchische Analyse: lexikalische Analyse

syntaktische Analyse

9 JFlex-Prinzip 4 Ein Scanner soll Namen und Schlüsselwörter erkennen. Z.B. ist exp ein Schlüsselwort, (Token expToken), exportDatei ist ein Name, (Token id). Wie wird sichergestellt, a) dass für exp tatsächlich expToken (und nicht id) geliefert wird, b) wie erreicht man, dass für exportDatei nicht expToken (und anschließend id für ortDatei) zurückgeliedert wird?

070107_07PRFBacV2.doc

Compilerbau

7/8

Name:

Vorname:

Anhang: Auszug aus einem CUP-Programm terminal

ADRESSBEGIN, ADRESSEND, NAMEBEGIN, NAMEEND,STRBEGIN, STREND, NRBEGIN, NREND, ORTBEGIN, ORTEND, VORNAMEBEGIN, VORNAMEEND, NACHNAMEBEGIN, NACHNAMEEND, PLZBEGIN, PLZEND, ORTSNAMEBEGIN, ORTSNAMEEND; terminal String ZEICHENKETTE; non terminal adressenliste, adresse, knotenliste, knoten, nameliste, nameknoten, ortliste, ortknoten; non terminal String zeichenkette;

adressenliste adresse knotenliste

knoten

::= adresse adressenliste | ; ::= ADRESSBEGIN knotenliste {: Adress.print(); :} ADRESSEND ; ::= knoten knotenliste | ; ::= | |

nameliste nameknoten

| ; ::= | ; ::= |

NAMEBEGIN nameliste NAMEEND STRBEGIN zeichenkette:zk {:Adress.setStr(zk); :} STREND NRBEGIN zeichenkette:zk {: Adress.setNr(zk); :} NREND ORTBEGIN ortliste ORTEND nameliste nameknoten VORNAMEBEGIN zeichenkette:zk {: Adress.setVorname(zk); :} VORNAMEEND NACHNAMEBEGIN zeichenkette:zk {: Adress.setNachname(zk); :} NACHNAMEEND

; ortliste

::= | ;

ortliste ortknoten

ortknoten

::=

PLZBEGIN zeichenkette:zk {: Adress.setPlz(zk); :} PLZEND ORTSNAMEBEGIN zeichenkette:zk {: Adress.setOrtsname(zk); :} ORTSNAMEEND

| zeichenkette

070107_07PRFBacV2.doc

; ::= | ;

ZEICHENKETTE:zk {: RESULT = zk; :} {: RESULT = ""; :}

Compilerbau

8/8

Fachhochschule Würzburg-Schweinfurt-Aschaffenburg Studiengang Informatik Prof. Grötsch

SS 2000

Abschlußprüfung im Fach Compilerbau Termin:

17.7.2000

Vorname: ______________   

Name:____________________

keine Hilfsmittel Antworten sollen nur stichpunktartig sein maximal 90 Punkte, bestanden mit 45 Punkten

1. Endlicher Automat 6 Punkte Geben Sie den endlichen erkennenden deterministischen Automaten zum regulären Ausdruck (b + c)*b (d + e)* an. 2. Linkslineare Grammatik Geben Sie die linkslineare Grammatik an, die den regulären Ausdruck v(x+y)*z* erzeugt.

5 Punkte

3 Tripel-Code Gegeben sei das folgende C-Programmstück:

10 Punkte

s = 0; t = 1; while (t < y) { s := s+1; t := 2*s + t + 1; }

Die Bezeichner s, t, und y seien als Variable vom Typ int deklariert, y sei initialisiert. Überführen Sie das C-Programmstück in einen Tripel-Code. Hinweis: Verwenden Sie nur folgende Tripel-Code-Anweisungen: := V E1 Speichere den Wert von E1 in der Variablen V, + E1 E2 Addiere E1 und E2, E1 E2 Subtrahiere E2 von E1, * E1 E2 Multipliziere E1 mit E2, < E1 E2 Prüfe, ob E1 kleiner als E2 ist, JC TNr.1 TNr.2 Springe zum Tripel Tnr.2, wenn der Test von TNr.1 nicht erfolgreich war, J TNr.1 Springe zum Tripel TNr.1 Dabei stehen V für Variable, E1 bzw. E2 für Konstante, Variable oder Tripel-Nummern und TNr.1 und TNr.2 für Tripel-Nummern. Um Tripel-Nummern von Konstanten unterscheiden zu können, sind sie in Klammern anzugeben (z.B.: 1: Konstante 1, (1): Tripel-Nummer 1) __________________________________________________________________________ 17.7.2000 PRÜF7_00 -1/7-

Compilerbau SS 2000

Vorname:

Name:

.

4 Phasen 4+2 Punkte 4.1 Beschriften Sie das nachfolgende Übersichtsbild über die Phasen eines Compilers. Quellprogramm

Zielprogramm 4.2 Erläutern Sie, weshalb die Komponenten links und rechts im Bild außerhalb des sequentiellen Ablaufs der anderen Phasen gezeichnet sind.

5 Reguläre lex-Ausdrücke 6 Punkte Die Norm IEC 61131-3 (Programmiersprachen für speicherprogrammierbare Steuerungen) läßt bei Integer-Konstanten zu, daß zwischen 2 Ziffern einzelne Unterstriche ('_') auftreten können. Führende Nullen sind erlaubt. Beispiel: erlaubt: 123_456, -1_2_3_4, +123_456 nicht erlaubt: _123, 1_ _2, 123_ Geben Sie ein lex-Muster für Integer-Konstanten nach IEC 61131-3 an.

___________________________________________________________________________ 17.7.2000 PRÜF7_00 -2/7-

Compilerbau SS 2000

Vorname:

Name:

.

6 Ableitung einer LL(1)-Parse-Tabelle 3 + 3 +15 Punkte Gegeben sei die Grammatik G mit den terminalen Symbolen begin end procedure bez in out inout typebez , ( ) ; der Startvariablen und der Regelmenge: (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14)





::= ::= ::= | ::= | ::= ::= | ::= | | | ::=

; procedure begin end  ()  bez ,  in out inout  typebez

6.1 Zeichnen Sie den Ableitungsbaum für das Wort: procedure bez (in bez typebez, out bez typebez,); 6.2 Geben Sie die Rechtsableitung an für : procedure bez (in bez typebez,); 6.3 Bestimmen Sie zur Grammatik G die Tabelle für FIRST, FOLLOW und die LL(1)Analysefunktion. begin end

procedure

bez in

out inout typebez ,

(

)

;



begin end

procedure

bez in

out inout typebez ,

(

)

;

$

LL(1)-Tabelle begin end S SIGNATUR BODY NAME PARS

procedure

bez in

out inout typebez ,

(

)

;

$

FIRST

S SIGNATUR BODY NAME PARS PARAMETERS

INOUT TYPE FOLLOW S SIGNATUR BODY NAME PARS PARAMETERS

INOUT TYPE

PARAMETERS

INOUT TYPE ___________________________________________________________________________ 17.7.2000 PRÜF7_00 -3/7-

Compilerbau SS 2000

Vorname:

Name:

.

7 lex / yacc 2 + 8 + 4 Punkte Gegeben ist folgendes Übersetzungsschema: (0) ::= $ (1) ::= exit (2) | (3) |  (4) ::= (5) ::= repeat (6) ::= ; (7) |  (8) ::= bez := (9) | num { printf($1); } (10) ::= bez + (11) | num { printf($1); } (12) ::= until bez < num (13) |  7.1 Schreiben Sie zu der Grammatik einen mit yacc-Parser. Setzen Sie voraus, daß ein lex-Teil existiert, der die gewünschten token und sonstigen benötigten Daten liefert. (Es geht nur darum, die Syntax zu prüfen - außer den Testausgaben soll nichts ausgegeben werden.) 7.2 Geben Sie den zugehörigen lex-Teil an. (bez beginnt mit einem Buchstaben, dann folgen beliebig viele Buchstaben oder Ziffern. num ist eine Integer-Zahlen ohne Vorzeichen.) (Eine Symboltabellenverwaltung ist hier nicht erforderlich.) 7.3 Statt $1 könnte man im yacc-Teil hier auch yylval ausgeben. Warum kann man bei der Umwandlung von Infix- in Postfix-Ausdrücke yylval nicht verwenden, und muß mit $x arbeiten ? 8 Yacc Das folgende korrekte yacc-Programm sei gegeben:

4+2+2+2 Punkte

%token ZAHL %left '+' '-' %left '*' '/' %% zeile

ausdruck

: | ;

zeile ausdruck '\n'

: | | | | | ;

ZAHL ausdruck '+' ausdruck '-' ausdruck '*' ausdruck '/' '(' ausdruck

ausdruck ausdruck ausdruck ausdruck ')'

{ printf("%d\n", $2);}

{ { { { {

$$ $$ $$ $$ $$

= = = = =

$1 + $3; $1 - $3; $1 * $3; $1 / $3; $2; }

} } } }

%% #include #include int yylex(void) { char c; c = getchar(); while (c == ' ') c = getchar(); if (isdigit(c)) { ungetc(c, stdin); scanf("%d", &yylval);

___________________________________________________________________________ 17.7.2000 PRÜF7_00 -4/7-

Compilerbau SS 2000

Vorname:

Name:

.

return ZAHL; } return c; }

Erläutern Sie: 8.1 Was tut das Programm ? 8.2 Was wäre in obigem Beispiel, wenn man die %left-Deklarationen wegließe ? 8.3 Wie werden die arithmetischen Operatoren vom Scanner an den Parser übergeben ? 8.4 Weshalb wird im unteren Teil mit ungetc() (schreibt ein Zeichen in den Eingabestrom zurück) gearbeitet ? 9 Top-down-Parsing 12 Punkte Die folgende Grammatik ist gegeben. (0) ::= $ (1) ::= exit (2) | (3) |  (4) ::= (5) ::= repeat (6) ::= ; (7) |  (8) ::= bez := (9) | num ::= bez + (10) (11) | num (12) ::= until bez < num (13) |  Es folgt das Programmfragment eines Top-down-Parsers nach dem Verfahren des rekursiven Abstiegs. Ergänzen Sie die nachfolgenden Prozeduren, die noch nicht ausgeführt sind. %{ /* Programm Aufgabe 9/00 */ #include /* hier steht der lex-Teil, der dem Top-down-Parser die Tokens liefert. /* Seine Bearbeitung gehört nicht zur Aufgabenstellung /* Folgende Tokens werden geliefert: /* ExitSym, RepeatSym, UntilSym, /* bez, num, Plus, Assign, LT, Semikolon, DollarSym %} %%

*/ */ */ */ */

void main(void) { NextToken(); Start(); if (Act_Token == Dollar) printf("Eingabe akzeptiert"); else Error(); } NextToken() { Act_Token = yylex(); } ___________________________________________________________________________ 17.7.2000 PRÜF7_00 -5/7-

Compilerbau SS 2000

Vorname:

Name:

.

Error() { printf("Fehler: bei Token %d\n", Act_Token); exit(0); } Match(Token Expected) { if (Act_Token == Expected) NextToken(); else Error(); } /* Abarbeitung der Produktionen: */ Start() { } S() { } REPEAT_A() { } REPEAT_BODY() { } STATEMENTS() {

} STATEMENT() {

} EXPRESSION() { } CONDITION() { } ___________________________________________________________________________ 17.7.2000 PRÜF7_00 -6/7-

Compilerbau SS 2000

Vorname:

Name:

.

}

___________________________________________________________________________ 17.7.2000 PRÜF7_00 -7/7-