Compilerbau SS 2016 - Aufgabenblatt 2 Aufgabe 1 (Kontextfreie

Werbung
Prof. Dr. M. Jäger
FB MNI
Compilerbau SS 2016 - Aufgabenblatt 2
Aufgabe 1 (Kontextfreie Grammatiken)
a) Beschreiben Sie die Menge der Oktalziffern mit einer kontextfreien Grammatik.
b) Beschreiben Sie die Menge der Oktalzahlen mit einer kontextfreien Grammatik.
Aufgabe 2 (Kontextfreie Grammatiken)
Betrachten Sie die folgende Grammatik G:
1) S → SS
2) S → 3) S → aSbb
a) Beweisen, Sie: abbaabbbb ∈ L(G)
b) Beweisen Sie: aaabbbb ∈
/ L(G)
c) Versuchen Sie, L(G) auf andere Weise zu beschreiben.
d) Geben Sie für abb zwei verschiedene Linksableitungen an.
Aufgabe 3 (Kontextfreie Grammatiken)
Betrachten Sie die folgende Grammatik (S sei Startsymbol, S,A,B,C Nonterminalsymbole):
1) S → BAC
2) S → 3) B → bBbCb
4) B → d
5) B → 6) A → aA
7) A → e
8) C → cC
9) C → a) Geben Sie eine Linksableitung für das Wort bdbbe an.
b) Geben Sie eine Rechtsableitung für das Wort bdbbe an.
c) Geben Sie den Ableitungsbaum für das Wort bdbbe an.
Aufgabe 4 (Erste Erfahrungen mit einem Compilergenerator)
Die nachfolgende kontextfreie Grammatik beschreibt Programme, die aus einer Folge von beliebig
vielen Zeilen bestehen. Das Startsymbol ist Input und das Nonterminalsymbol für eine Zeile ist Line.
In der herkömmlichen Schreibweise lauten die Ableitungsregeln für das Startsymbol:
Input
Input
→
→
ε
Input Line
oder abgekürzt:
1
Input → ε | Input Line
In der Syntax für den Generator bison:
Input:
%empty | Input Line ;
Eine Zeile ist leer oder enthält einen arithmetischen Ausdruck Exp und wird mit Newline-Zeichen
(’\n’) abgeschlossen:
Line:
’\n’ | Exp ’\n’ ;
Im einfachen Fall ist Exp eine ganze Zahl (Intlit), ansonsten eine Addition, Subtraktion, Multiplikation oder Division in Postfix-Notation: Operand1 Space Operand2 Space Operator
Ein trivialer Scanner liefert pro Zeichen ein Token, dass der Kodierung des Zeichens entspricht.
Er erkennt also keine Zahlen, so dass auch deren Aufbau in der Grammatik mit Ableitungsregeln
beschrieben werden muss.
Der bison-Generator benötigt neben der Grammatik in seiner Eingabedatei grammatik.y einen Scanner (Funktion yylex) und eine Fehlerausgabefunktion (Funktion yyerror ). Er generiert in der Ausgabedatei grammatik.tab.c einen Parser (Funktion yyparse), wenn man ihn wie folgt aufruft:
bison -dtv grammatik.y
Die gesamte Eingabedatei grammatik.y“ ist unten angegeben.
”
Aufgabenstellung
a) Lassen Sie mit bison einen Parser generieren, übersetzen Sie ihm mit dem C-Compiler und
testen Sie ihn in mit einigen korrekten und einigen falschen Beispieleingaben.
b) Ist das Symbol Space in den Regeln für die binären Operationen nötig? Was passiert, wenn
man es weglässt?
c) Ändern Sie die Grammatik so, dass mehr als ein Leerzeichen sowie auch Tabulatorzeichen
zwischen den Operanden stehen können und testen Sie das Ergebnis.
d) Ändern Sie die Grammatik so, dass die Leerzeichen nach dem zweiten Operanden optional
sind und testen Sie das Ergebnis.
2
Die Eingabedatei grammatik.y:
/* Der Generator kopiert den folgenden C-Code ohne Änderung
%{
#include <stdio.h>
int yylex (void);
void yyerror (char const *);
%}
*/
/* Hier beginnt die Grammatik, aus der die Definition von "yyparse" generiert wird */
%%
Input: %empty | Input Line
;
Line:
;
Exp:
| Exp
| Exp
| Exp
| Exp
;
’\n’ | Exp ’\n’
Intlit
Space Exp
Space Exp
Space Exp
Space Exp
Space
Space
Space
Space
’+’
’-’
’*’
’/’
Space : ’ ’
;
Intlit :
;
Digit | Intlit Digit
Digit: ’0’ | ’1’ | ’2’ | ’3’ | ’4’ | ’5’ | ’6’ | ’7’ | ’8’ | ’9’
;
%%
/* Der Generator kopiert den folgenden C-Code ohne Änderung
*/
void yyerror (char const *s){
fprintf(stderr, "Fehler: %s", s);
}
/* Der triviale Scanner */
int yylex() {
return getchar();
}
int main(){
yyparse(); /* Aufruf des generierten Parsers */
}
Aufgabe 5 (Semantische Aktionen)
Berechnung der Werte: In die rechte Seite einer Ableitungsregel kann eine semantische Aktion“
”
eingefügt werden. Dies ist weitgehend C-Code, allerdings mit Erweiterungen: Jedem GrammatikSymbol kann ein Wert zugeordnet werden ( Attribut“ oder semantischer Wert“). In der semantischen
”
”
Aktion steht $$ für den Wert des Nontermioalsymbols auf der linken Regelseite und $1, $2 usw. für
den Wert des i-ten Symbols der rechten Regelseite. Der Typ der Werte ist int, wenn man es nicht
anders festlegt.
Aufgabenstellung:
a) Erklären Sie sich die semantischen Aktionen und testen Sie den generierten Interpretierer aus.
3
b) Stellen Sie die Grammatik so um, dass statt dezimaler Zahlen hexadezimale Zahlen verarbeitet
werden und testen Sie den Interpretierer aus.
%{
#include <stdio.h>
int yylex (void);
void yyerror (char const *);
%}
%%
Input:
%empty
| Input Line
;
Line:
’\n’
| Exp ’\n’
;
Exp:
Intlit
| Exp Space
| Exp Space
| Exp Space
| Exp Space
;
{ printf ("%d\n", $1); }
Exp
Exp
Exp
Exp
Space
Space
Space
Space
’+’
’-’
’*’
’/’
{
{
{
{
{
$$
$$
$$
$$
$$
=
=
=
=
=
$1;
$1 +
$1 $1 *
$1 /
$3;
$3;
$3;
$3;
}
}
}
}
}
Space : ’ ’
;
Intlit :
Digit:
’0’ {
| ’1’ {
| ’2’ {
| ’3’ {
| ’4’ {
| ’5’ {
| ’6’ {
| ’7’ {
| ’8’ {
| ’9’ {
;
Digit
{ $$ = $1 ; }
| Intlit Digit { $$ = 10*$1 + $2; } ;
$$
$$
$$
$$
$$
$$
$$
$$
$$
$$
=
=
=
=
=
=
=
=
=
=
0;
1;
2;
3;
4;
5;
6;
7;
8;
9;
}
}
}
}
}
}
}
}
}
}
%%
void yyerror (char const *s){
fprintf(stderr, "Fehler: %s", s);
}
int yylex() {
return getchar();
}
main(){
yyparse();
}
4
Herunterladen