5. Bottom up-Parser
5. Bottom up-Parser 5. Bottom up-Parser
syntaktische Analyse
5. Bottom up-Parser
Beispiel einer Bottom up-Analyse
{ }
{ , , ( , ) }
=
= + ∗
→ +
= →
→
13 13
13
N T
P
E,T, F v,
E T | E T, T F | T * F, F v | (E)
( ) ( ) ( ( )
( ) ( ) ( )
( ) ( ) ( )
+ + ← + + ← + + ← + +
← + + ← + + ← + +
← + + ← + + ← +
← + ← ←
v v v F v v T v v) E v v E F v E T v E E v E E F E E T E E
E F E + T E
Vorgegebene Grammatik:
Reduktionsfolge:
5. Bottom up-Parser
Das Handle
Ein Teilstring β einer Satzform α β γ heißt Handle, falls
β die rechte Seite einer Produktion N → β ist und
der Reduktionsschritt α β γ ← α N γ zu einer
linkskanonischen Reduktion fortsetzbar ist.
5. Bottom up-Parser
Bottom up-Analyse noch einmal:
Schritt: Stackinhalt: Eingaberest:
1. v + ( v + v )
2. v + ( v + v )
3. F + ( v + v )
4. T + ( v + v )
5. E + ( v + v )
6. E + ( v + v )
7. E + ( v + v )
8. E + ( v + v )
9. E + ( F + v )
10. E + ( T + v )
11. E + ( E + v )
12. E + ( E + v )
13. E + ( E + v )
14. E + ( E + F )
15. E + ( E + T )
16. E + ( E )
17. E + ( E ) 18. E + ( E ) 19. E + F 20. E + T
21. E
5. Bottom up-Parser
LR(k)-Analyseverfahren
Kriterien für den Fortgang der Analyse
Informationen über den gesamten Stackinhalt und
die nächsten k Zeichen der Eingabe für ein festes k ≥ 0
Vorteile der LR(k)-Methoden
die Sprachklasse LR(k) ist umfangreicher als die Klasse LL(k) alle üblichen syntaktischen Konstruktionen mit LR(k) anlysierbar tabellengesteuert d.h. effizient implementierbar; k=1 genügt.
correct prefix property.
5. Bottom up-Parser
a β τ γ
N τ γ
k
a
LR(k)-Grammatiken
in jeder Satzform ist das Handle β eindeutig bestimmt durch den aktuellen Stackinhalt und
die nächsten k Zeichen der Eingabe.
5. Bottom up-Parser
I
4I
7I
2I
0I
8( ∗
T
$ E
LR(k)-Analysator
v ∗ ( v + v ) $
Schaltwerk
Eingabeband
Zustands- Stack
Symbol-
Stack
5. Bottom up-Parser
Die Aktionstabelle
Damit entscheidet der Analysator über den nächsten Analyseschritt.
t
0t
1t
2... $
I
0 ACCEPTI
1I
kI
2N → β
: :
Mögliche Einträge auf Position ( I
i, t
j) :
Ein Zustand I
k(Aktion = kellern) Eine Produktion N → β (Aktion = reduzieren)
ACCEPT (Eingabe als syntaktisch korrekt akzeptieren)
5. Bottom up-Parser
I
2I I I
N N
N
$ N
1Die Goto-Tabelle
Damit bestimmt der Analysator den nächsten Stackzustand bei Reduktionen.
N
0N
1N
2...
I
0I
1I
2I
k:
:
5. Bottom up-Parser
Die Aktionstabelle von Γ
13v + * ( ) $
I
0I
5I
4I
1I
6ACCEPT
I
2 E→TI
7 E→T E→TI
3 T→F T→F T→F T→FI
4I
5I
4I
5 F→v F→v F→v F→vI
6I
5I
4I
7I
5I
4I
8I
6I
11I
9 E→ +E TI
7 E→ +E T E→ +E TI
10 T→T F* T→T F* T→T F* T→T F*I
11 F→(E) F→(E) F→(E) F→(E)5. Bottom up-Parser
Die Goto-Tabelle von Γ
13E T F I
0I
1I
2I
3I
1I
2I
3I
4I
8I
2I
3I
5I
6I
9I
3I
7I
10I
8I
9I
10I
11____________________________________________________________________________________
5. Bottom up-Parser
Ablauf einer SLR(1)-Analyse (I)
Schritt Stackinhalt Eingabe Reduktion
1. $ v ∗ ( v + v ) + v $
I0
2. $ v ∗ ( v + v ) + v $ v←F
I0 I 5
3. $ F ∗ ( v + v ) + v $ F←T
I0 I 3
4. $ T ∗ ( v + v ) + v $
I0 I 2
5. $ T ∗ ( v + v ) + v $
I0 I 2 I 7
6. $ T ∗ ( v + v ) + v $
I0 I 2 I 7 I 4
7. $ T ∗ ( v + v ) + v $ v←F
I0 I 2 I 7 I 4 I 5
8. $ T ∗ ( F + v ) + v $ F←T
I0 I 2 I 7 I 4 I 3
9. $ T ∗ ( T + v ) + v $ T←E
I0 I 2 I 7 I 4 I 2
10. $ T ∗ ( E + v ) + v $
I0 I 2 I 7 I 4 I 8
11. $ T ∗ ( E + v )+ v $
I 0 I 2 I 7 I 4 I 8 I 6
12. $ T ∗ ( E + v ) + v $ v←F
I 0 I 2 I 7 I 4 I 8 I 6 I 5
13. $ T ∗ ( E + F ) + v $ F←T
I 0 I 2 I 7 I 4 I 8 I 6 I 3
____________________________________________________________________________________
5. Bottom up-Parser
Ablauf einer SLR(1)-Analyse (II)
Schritt Stackinhalt Eingabe Reduktion
14. $ T ∗ ( E + T ) + v $ E T+ ←E
I 0 I 2 I 7 I 4 I 8 I 6 I 9
15. $ T ∗ ( E ) + v $
I 0 I 2 I 7 I 4 I 8
16. $ T ∗ ( E ) + v $ (E)←F
I 0 I 2 I 7 I 4 I 8 I11
17. $ T ∗ F + v $ T F* ←T
I 0 I 2 I 7 I 10
18. $ T + v $ T←E
I 0 I 2
19. $ E + v $
I 0 I 1
20. $ E + v $
I 0 I 1 I 6
21. $ E + v $ v←F
I 0 I 1 I 6 I 5
22. $ E + F $ F←T
I 0 I 1 I 6 I 3
23. $ E + T $ E T+ ←E
I 0 I 1 I 6 I 9
24. $ E $ ACCEPT
I 0 I 1
5. Bottom up-Parser
LR(0)-Items N → ϕ ψ D
a
β γ
ψ ϕ
N
N → ϕ ψ D bedeutet:
Es ist ein Anfang ϕ für das Handle ϕψ
gefunden.
Eine Reduktion mit ϕψ ← N ist möglich,
wenn noch ψ erreicht werden kann.
5. Bottom up-Parser
LR(0)-Informationen
Eine LR(0)-Information ist eine Menge von LR(0)-Items.
Ziel:
LR(0)-Informationensollen alle mögliche Interpretationen
der selben Analysesituation darstellen.
5. Bottom up-Parser
Der Operator HUELLE
Er liefert zu einem LR(0)-Item N → ϕ ψ D die Menge aller LR(0)-Items, die sich der selben Analysesituation zuordnen lassen wie N → ϕ ψ D .
Der Operator wird auf eine LR(0)-Information I angewandt, indem man ihn auf ihre Elemente anwendet.
Verfahren zur Bestimmung der Hülle:
{ nimm I in die Menge HUELLE [ I ] auf } wiederhole
für alle LR(0)-Items der Form N → ϕ D M ψ in der LR(0)-Information I für alle Produktionen der Form M → π der Grammatik
{ nimm M → D π in die Menge HUELLE [ I ] auf }
solange bis HUELLE[ I ] stabil bleibt.
5. Bottom up-Parser
Beispiel zum Operator HUELLE
HUELLE [ E → + E D T ] = *
→ +
→
→
→
→
D D D D D
E E T
T F
T T F
F v
F (E)
5. Bottom up-Parser
Der Operator GOTO
Er beschreibt das Schaltverhalten des Endlichen Automaten, der die Stackzustände ermittelt.
Er liefert zu einer LR(0)-Information I und zu x ∈ V eine neue LR(0)-Information:
GOTO [ I, x ] = HUELLE [ N → α x D β | N → α D x β ∈ I ]
GOTO [ I , ( ] = HUELLE [ F → ( D E ) ] =
( )
*
→
→
→ +
→
→
→
→
D D D D D D D
F E
E T
E E T
T F
T T F F v F (E)
Beispiel:
5. Bottom up-Parser
Die kanonische Kollektion der LR(0)-Informationen (I)
sie stellt die Zustandsmenge des LR(0)-Automaten dar
Verfahren zur Berechnung der kanonschen Kollektion der LR(0)-Informationen { nimm die Menge HUELLE [ →
D
X X ] in die Kollektion C auf } wiederhole
für { alle LR(0)-Information I ∈ C und alle Zeichen x ∈ V } { nimm GOTO [I, x ] in die Kollektion C auf }
solange bis C stabil bleibt.
5. Bottom up-Parser
Die kanonische Kollektion der LR(0)-Informationen (II)
I
0= HUELLE [ → D
E E ] = *
→
→
→ +
→
→
→
→
D
D D D D D D
E E
E T
E E T
T F
T T F F v F (E)
→
→ +
= →
→
P
13E E
E T | E T T F | T * F F v | (E)
Grammatik:
erste LR(0)-Information:
5. Bottom up-Parser
Die kanonische Kollektion der LR(0)-Informationen (III)
I
1= GOTO [ I
0, E ] = HUELLE →
→ +
D
D
E E
E E T = →
→ +
D
D
E E
E E T
I
2= GOTO [ I
0, T ] = HUELLE
*
→
→
D D E T
T T F = → → *
D D E T T T F I
3= GOTO [ I
0, F ] = HUELLE [ T → F D ] = [ T → F D ]
I
4= GOTO [ I
0, ( ] = HUELLE [ F → ( D E ) ] =
( )
*
→
→
→ +
→
→
→
→
D D D D D D D
F E
E T
E E T
T F
T T F
F v
F (E)
5. Bottom up-Parser
Die kanonische Kollektion der LR(0)-Informationen (IV)
I
5= GOTO [ I
0, v ] = HUELLE [ F → v D ] = [ F → v D ]
I
6= GOTO [ I
1, + ] = HUELLE [ E → + E D T ] = *
→ +
→
→
→
→
D D D D D
E E T
T F
T T F
F v
F (E)
I
7= GOTO [ I
2, ∗ ] = HUELLE [ T → T * D F ] =
→ *
→
→
D D D
T T F
F v
F (E) I
8= GOTO [ I
4, E ] = HUELLE → → ( + )
D D
F E
E E T = → → ( + )
D D
F E
E E T
5. Bottom up-Parser
Die kanonische Kollektion der LR(0)-Informationen (V)
I
9= GOTO [ I
6, T ] = HUELLE
*
→ +
→
D D E E T
T T F = → + → *
D D E E T
T T F
I
10= GOTO [ I
7, F ] = HUELLE [ T → T F * D ] = [ T → T F * D ]
I
11= GOTO [ I
8, ) ] = HUELLE [ F → ( ) E D ] = [ F → ( ) E D ]
5. Bottom up-Parser
Der LR(0)-Automat
I4
I3
I2 I1
I0
I9 I8
I7 I6
I5
I11
I10
F ∗
T
F
E
E F
F
) v
T
v
v v
( (
∗ (
(
T
+ +
5. Bottom up-Parser
Verfahren zur Konstruktion Aktionstabelle
für { alle LR(0)-Informationen I
i( 0 ≤ ≤ i n ) } für { alle Terminalzeichen t ∈ T }
falls es ein LR(0)-Item N → α D t β in I
igibt mit GOTO [I
i, t ] = I
j{ Trage I
jauf der Position ( I
i, t) in die Aktionstabelle ein. }
für { alle LR(0)-Informationen I
i( 0 ≤ ≤ i n ) } falls es ein LR(0)-Item N → α D in I
igibt
→ α i
∈
I
Trage N auf allen Positionen ( , t) in die Aktionstabelle ein, für die t FOLLOW(N) ist
für { alle LR(0)-Informationen I
i( 0 ≤ ≤ i n ) } falls es ein LR(0)-Item →
D
X X in I
igibt
{ Trage ACCEPT auf der Position ( , $) in die Aktionstabelle ein I i }
5. Bottom up-Parser
Verfahren zur Konstruktion GOTO-Tabelle
für { alle LR(0)-Informationen I
i( 0 ≤ ≤ i n ) } für { alle N ∈ N }
falls GOTO [I
i, N ] = I
j{ trage I
jauf der Position ( i, N ) in die GOTO-Tabelle ein }
6. Fehlerbehandlung
6. Die Fehlerbehandlung 6. Die Fehlerbehandlung
Lexikalische Analyse
Code- generierung Speicher-
verwaltung syntaktische
Analyse Interpretation Optimierung Fehler-
Behandlung
6. Fehlerbehandlung
Fehler bei der Software-Entwicklung
Aus der Sicht des Entwicklers unterscheiden wir:
Spezifikationsfehler Algorithmische Fehler Codierungsfehler
Mißachtung von Sprach- und Compilereigenschaften
Compilerfehler
6. Fehlerbehandlung
Fehlerreaktionen des Übersetzers
Mögliche Reaktionen des Compilers im Fehlerfall:
keine Reaktion
Abbruch der Compilierung Fehlerbehandlung
Angemessene, benutzerfreundliche Fehlerbehandlung:
quellsprachenbezogene Identifikation der Fehlerstelle,
aussagekräftige, selbsterklärende Fehlermeldungen,
die Vermeidung unnötiger Redundanz
6. Fehlerbehandlung
Klassifikation von Fehlern
Aus der Sicht des Compiler-Entwicklers unterscheiden wir:
Lexikalische Fehler
Syntaktische Fehler
Semantische Fehler
Laufzeitfehler
6. Fehlerbehandlung
Modell der Fehlerbehandlung
Lexikalische Analyse
Code- generierung Speicher-
verwaltung syntaktische
Analyse Interpretation Optimierung Fehler-
Behandlung
6. Fehlerbehandlung
Behandlung lexikalischer Fehler
Typische lexikalische Fehler sind:
Verwendung von Zeichen, die nicht zum Alphabet gehören Zahlbereichsüberschreitung bei Zahlkonstanten
Nichteinhalten von Namenskonventionen Falsche Schreibweise von Wortsymbolen
6. Fehlerbehandlung
Beispiel zur Fehlerbehandlung im Scanner:
Fehler in Wortsymbolen
Bei 80% der Fehler in Wortsymbolen sind:
ein Zeichen zu viel oder zu wenig vorhanden, ein Zeichen falsch geschrieben,
zwei Zeichen vertauscht.
Prüfen, ob das erwartete Wortsymbol falsch geschrieben wurde durch:
Hinzufügen oder Weglassen eines Zeichens, Vertauschen zweier Zeichen,
Abändern eines Zeichens.
6. Fehlerbehandlung
Beispiel zur Fehlerbehandlung im Scanner:
Verwechslung von „;“ und „,“ legalisieren Konventionelle Analyse:
if (sym == varSym) {
getSym();
varDeclaration();
while (sym == comma) { getSym(); varDeclaration(); }
if (sym == semicolon) getSym(); else error(5);
}
var
ident
,
ident
;
6. Fehlerbehandlung
Beispiel zur Fehlerbehandlung im Scanner:
Verwechslung von „;“ und „,“ legalisieren
Fehlertolerante Analyse: Was ist der Preis für diese Modifikation ?
if (sym == varSym) { getSym();
do
{ varDeclaration(ppos);
while (sym == comma)
{ getSym(); varDeclaration(ppos); }
if (sym == semicolon) getSym(); else error(5);
} while (sym == ident);
var
ident
,
ident
;
6. Fehlerbehandlung
S
X Y Z
t
Beispiel zur Fehlerbehandlung im Scanner:
Überlesen von Quelltext
•
X muß im Fehlerfall garantieren, daß Y einen brauchbaren Anfang vorfindet.
•
Generelle Methode:
Überlesen von Quelltext bis zu einem
legalen FOLLOW-Zeichen oder einem
Stop-Zeichen
6. Fehlerbehandlung
Beispiel zur Fehlerbehandlung im Parser:
Hypothesen über den wahrscheinlichen Fehler Legalisieren von fehlendem then
if (sym == ifSym) { getSym();
condition( STAT_START | IDENT | DO_THEN_OF );
if (sym == thenSym) getSym(); else error(16);
statement(followSymSet | UNTIL_ELSE);
if (sym == elseSym) {
getSym();
statement(followSymSet);
}
then
if condition statement
6. Fehlerbehandlung
Weitere Themen der Fehlerbehandlung
Syntaktische Fehler bei der LR- Analyse
Fehlersituation: die Aktionstabelle besitzt keinen Eintrag LR-Analysatoren besitzen die correct prefix-Eigenschaft
Semantische Fehler: werden durch kontextfreie Analyse nicht erkannt fehlende oder falsche Vereinbarungen
typfremde Verwendung von Namen
7. Speicherverwaltung
7. Die Speicherverwaltung 7. Die Speicherverwaltung
Speicher- Verwaltung
7. Speicherverwaltung
Begriffe des Speichermanagement
Lebensdauer von Objekten Gültigkeitsbereich von Objekten
Statische Speicherverwaltung (COBOL, FORTRAN, PASCAL, C, C++) Dynamische Speicherverwaltung (Pascal, C, C++ )
Programmeinheit
Datenraum (DSA = Data Storage Area)
7. Speicherverwaltung
Statische Speicherverwaltung
Merkmale:
Inhalt und Größe der Datenräume sind zur Compile-Zeit bekannt der Compiler kann Objekten feste Adressen zuordnen
Lebensdauer von Objekten = gesamte Programmlaufzeit
Beispiele statischer Speicherverwaltung:
FORTRAN, COBOL
static-Variablen in C-Sprachen
globale Variablen in C-Sprachen
7. Speicherverwaltung
Datenraum einer Programmeinheit
void Polar (float x1, float y1, double& radius, double& winkel) {
// Umrechnung kartesischer Koordinaten in Polarkoordinaten radius = sqrt ( x1*x1 + y1*y1 );
winkel = atan ( y1 / x1 );
return;
}
Wert des Parameter x1 Wert des Parameter y1
Adresse des Parameter radius Adresse des Parameter winkel Länge der Parameterliste
Rückkehradresse Datenraumverkettung Register Save Area
Hilfsvariablen zur Auswertung
der Ausdrücke
7. Speicherverwaltung
Datenraum einer Block-Hierarchie (I)
void main() {
int x, y;
x=1; y=2;
cout << "\n\nWerte auf dem Hauptprogramm-Niveau:\n";
cout << "x = " << x << " y = " << y;
{ int y, z;
x=11; y=22; z=33;
cout << "\n\nWerte im 1. untergeordneten Block:\n";
cout << "x = " << x << " y = " << y << " z = " << z;
} {
int a;
a = 44;
cout << "\n\nWerte im 2. untergeordneten Block:\n";
cout << "x = " << x << " y = " << y << " a = " << a;
} getch(); return;
}
7. Speicherverwaltung
Datenraum einer Block-Hierarchie (II)
Ablage der Variablen im Arbeitsspeicher für dieses Programm:
Objekte des 1. und 2. Unterblocks belegen den selben Platz !
Objekte des 1. Unterblocks:
y, z
Objekte des 2. Unterblocks:
a
Objekte des Hauptprogramms: x, y
7. Speicherverwaltung
Blockvektoren (I)
int main() { int x, y;
x=1; y=2;
cout << "\n\nWerte auf dem Hauptprogramm-Niveau:\n";
cout << "x = " << x << " y = " << y;
{ int y, z;
x=11; y=22; z=33;
cout << "\nWerte im 1. untergeordn. Block:\n";
cout << "x =" << x << " y =" << y << " z =" << z;
{ int a;
a = 44;
cout << "\nWerte im 2. untergeordn. Block:\n";
cout << "x =" << x << " y =" << y << " "
<< "z =" << z << " a =" << a;
} }
getch(); return 0;
} Run
7. Speicherverwaltung
Blockvektoren (II)
Objekte des 2. Unterblocks: a
Objekte des 1. Unterblocks: y, z
Objekte des Hauptprogramms: x, y
7. Speicherverwaltung
Dynamische Speicherverwaltung
Jedem Funktionsaufruf wird ein eigener Datenraum bereitgestellt; er enthält:
Eine Datenobjekte Rückkehr-Information
Verwaltungsinformation für das Environment
Environment
Zum Environment der aktiven Programmeinheit gehören:
ihr eigener Datenraum,
die Datenräume der statisch übergeordneten Prozeduren,
ist eine Programmeinheit mehrfach gleichzeitig aktiv, so gehört
der Datenraum der jüngsten Aktivierung zum Environment.
7. Speicherverwaltung
Datenstack-Verwaltung (I)
// Wahl und Aufruf der naechsten Funktion
#define gotoNext ...
// Ausgabe des aktuellen Environment
void Environment (char fnct, int e, int f) { ... }
// globale Variablen int a=1, b=2;
void A()
{ int r=random(1000); int s=random(1000);
Environment ('A', r, s);
gotoNext;
Environment ('A', r, s);
gotoNext;
} void B()
{ int x=random(1000); int y=random(1000);
Environment ('B', x, y);
gotoNext;
Environment ('B', x, y);
gotoNext;
} void main()
{ int p=111, q=222;
cout << "Protokoll des akt. Environment:\n\n";
Environment ('M', p, q);
A();
Environment ('M', p, q);
getch(); return;
} Run
7. Speicherverwaltung
Datenstack-Verwaltung (II)
Objekte des Hauptprogramms: p, q Globale Objekte: a, b
Objekte der Funktion A: r, s Objekte des Hauptprogramms: p, q Globale Objekte: a, b
Objekte der Funktion B: x, y Objekte der Funktion A: r, s Objekte des Hauptprogramms: p, q Globale Objekte: a, b 1.
3.
2.
7. Speicherverwaltung
Objekte der Funktion B: x, y Objekte der Funktion B: x, y Objekte der Funktion A: r, s
Objekte des Hauptprogramms: p, q Globale Objekte: a, b
Objekte der Funktion B: x, y Objekte der Funktion A: r, s
Objekte des Hauptprogramms: p, q Globale Objekte: a, b
Objekte der Funktion A: r, s Objekte der Funktion B: x, y
Objekte der Funktion A: r, s Objekte des Hauptprogramms: p, q Globale Objekte: a, b 4.
5.
6.
7. Speicherverwaltung
Datenstack-Verwaltung (IV)
program main
var p, q: integer;
procedure A;
var r, s: integer;
begin {A}
...
...
end; {A}
procedure B;
var u, v: integer;
procedure C;
var x, y: integer;
begin {C}
...
...
end; {C}
begin {B}
...
...
end; {B}
begin {main}
...
...
end; {main}
main A
B C
Objekte von C: x, y Objekte von B: u, v Objekte von A: r, s Objekte von main: p, q Aufrufreihenfolge:
main → A
→B → C → C
7. Speicherverwaltung
Rückkehrverwaltung mit Dynamic Links
Objekte der Funktion A: r, s Objekte der Funktion B: x, y
Objekte der Funktion A: r, s Objekte von main: p, q Globale Objekte: a, b
Aufrufreihenfolge:
main → A
→B → C
7. Speicherverwaltung
Environment-Verwaltung mit Static Links
Merkmale:
Static Link-Zeiger verketten alle Datenräume, die zum Environment einer Programmeinheit gehören
Objekte werden adressiert über:
die Niveau-Differenz zwischen dem Niveau ihrer Verwendung und dem Niveau ihrer Vereinbarung und
ihre Distanz zur Basis des Datenraums, dem sie angehören.
7. Speicherverwaltung
Beispiel 1 zu Static Links
(Bezug: C-Programm aus Beispiel 7.4)
Objekte der Funktion A: r, s Objekte der Funktion B: x, y Objekte der Funktion A: r, s Objekte von main: p, q
Globale Objekte: a, b
A
B
main
globals
7. Speicherverwaltung
Beispiel 2 zu Static Links
Objekte von C: x, y Objekte von C: x, y Objekte von B: u, v Objekte von A: r, s Objekte von main: p, q
A
B
C
main7. Speicherverwaltung
Initialisierung der Static Links
Gehe vom Datenraum der aufrufenden Prozedur in der Static Link-Kette um (n-m+1) Schritte zurück. Dabei gilt:
n = Deklarationsniveau der aufrufenden Funktion
m = Deklarationsniveau der gerufenen Funktion
Setze den Static Link-Zeiger der neu aktivierten Prozedur
auf den so erreichten Datenraum.
7. Speicherverwaltung
Beispiele zur Initialisierung der zu Static Links
Aufruf erfolgt im Aufgerufene Funktion
Dekl.-Level des Aufrufs (n)
Dekl.-Level d. gerufenen Funktion (m)
(n-m+1) Schritte zurück
Ziel des Link
Rumpf von main A 1 2 0 main
Rumpf von A B 2 2 1 main
Rumpf von B A 2 2 1 main
Rumpf von B C 2 3 0 B
Rumpf von C A 3 2 2 main
Rumpf von C B 3 2 2 main
(Bezug: Pascal-Programm aus Beispiel 7.5)
A
B
C
main7. Speicherverwaltung
Environment-Verwaltung mit Displays
Objekte werden adressiert über:
das statische Niveau ihrer Deklaration die Distanz zur Basis des
Datenraumes, dem sie angehören
Objekte von C: x, y
Objekte von C: x, y
Objekte von B: u, v
Objekte von A: r, s
Objekte von main: p, q
7. Speicherverwaltung
Initialisierung der Display-Vektoren
Der Display-Vektor wird beim Anlegen eines Datenraumes initialisiert:
(m = Niveau des Aufrufs, n = Niveau der gerufenen Funktion):
Übernimm den Display-Vektor aus dem Datenraum der rufenden Prozedur für die Indexpositionen 0, 1, ... , m-1.
Trage auf der Position m die Adresse des neu angelegten Datenraumes ein.
7. Speicherverwaltung
Felder mit dynamischen Grenzen
In Pascal: arrayA: array[u..n, v..m] of ... ;
In C++: int i, n;
long *arrayA;
cin >> n;
arrayA = new long [n];
for (i=0; i<n; i++)
{
cout << "arrayA[" << i << "] = ";
cin >> arrayA[i];
}
7. Speicherverwaltung
Deskriptoren für Felder mit dynamischen Grenzen
DSA -Top pointer
Deskriptor von arrayA
Daten von arrayA DSA -Top pointer
Deskriptor von arrayA
7. Speicherverwaltung
Allgemeiner Aufbau von Feld-Deskriptoren
FeldA : array [u
1..o
1, u
2..o
2, ... , u
n..o
n] of …
u
1o
1s
1u
2o
2s
2. . . . . . . . .
u
no
ns
nα
07. Speicherverwaltung
Beispiel: Feld-Deskriptor und Anordnung der Feld-Daten
A : array [1..4, 2..3] of integer;
u
1= 1 o
1= 4 s
1= 8 u
2= 2 o
2= 3 s
2= 4 α
0= ...
Deskriptor
logische Anordnung
physikalische Anordnung:
A[1,2]
A[1,3]
A[2,2]
A[2,3]
A[3,2]
A[3,3]
A[4,2]
A[4,3]
A[1,2] A[1,3]
A[2,2] A[2,3]
A[3,2] A[3,3]
A[4,2] A[4,3]
7. Speicherverwaltung
Beispiel zur Adreßrechnung
A : array [1..4, 2..3] of integer;
( )
( [ , ] ) 1 *
( 2) *
A i j i
j α
= + − +
+ −
Adresse Länge einer Zeile
Länge einer Komponente
0
( [ , ] ) ( 1)*8 ( 2)*4
(1*8 2*4) ( *8 *4) ( *8 *4)
A i j i j
i j
i j
α α α
= − − + −
= − + + +
= + +
Adresse
α
0= − α (1*8 2*4) +
7. Speicherverwaltung
Allgemeine Adreßrechnung
( )
( )
( )
1
0 1 1 2 2
1 0 1 1 2 2
1 * , 1, ... , 2
* * ... *
( [ ,..., ] ) * * ... *
n
k k k k
n n
n n n
s
s o u s n n
u s u s u s
A i i i s i s i s
α α
α
−
=
= − + −
= − + + +
= + + + +
Länge einer Feldkomponente für
Adresse
8. Syntaxorientierte Übersetzung
8. Syntaxorientierte Übersetzung 8. Syntaxorientierte Übersetzung
Code- generierung
Inter-
pretation
8. Syntaxorientierte Übersetzung
Zwischensprachen (I): Quadrupelsprachen
Zwischensprachen (I): Quadrupelsprachen
die Anweisungen sind Dreiadreßbefehle
Operator 1. Operand 2. Operand 3. Operand
Quadrupelcode für die Zuweisung Z = A ∗ B + C ∗ D;
1:
MPY A B $HV1
2:
MPY C D $HV2
3:
ADD $HV1 $HV2 $HV3
4:STORE $HV3 Z
8. Syntaxorientierte Übersetzung
Zwischensprachen (II): Tripelsprachen
die Anweisungen sind Zweiadreßbefehle
Operator 1. Operand 2. Operand
Tripelcode für die Zuweisung Z = A ∗ B + C ∗ D;
1:
MPY A B
2:
MPY C D
3:
ADD (1) (2)
4:STORE (3) Z
8. Syntaxorientierte Übersetzung
Zwischensprachen (III): Postfixsprachen
die Anweisungen besitzen einen oder gar keinen expliziten Operanden weitere implizite Operanden liegen im Stack
Jede Operation hat eine eindeutige Zahl von Operanden
Postfixcode für die Zuweisung Z = A ∗ B + C ∗ D
;1:
LOAD A
2:LOAD B
3:
MPY
4:
LOAD C
5:LOAD D
6:
MPY
7:
ADD
8:
STORE Z
8. Syntaxorientierte Übersetzung
Übersetzung von Ausdrücken in Quadrupelcode (I)
Ziel: Generierung von Zwischencode bei der syntaktischen Analyse
Methode: Der Analysestack wird so erweitert, daß während der Analyse semantische Informationen mitgeführt werden können.
Beispiel:
{ }
{ , , ( , ) }
=
= + ∗
→ +
= →
→
13 13
13
N T
P
E , T v ,
E T | E T
T F | T * F
F v | (E)
8. Syntaxorientierte Übersetzung
Übersetzung von Ausdrücken in Quadrupelcode (II)
Semantische Informationen und Aktionen
Als semantische Information merken wir uns Variablen und Hilfsvariablen in einem Array HV . HV[i] bezeichnet sein i-tes Element.
Wenn der Parser eine syntaktische Struktur erkennt erzeugt er mit einer Funktion generate (...) eine Zwischencode-Anweisung im Quadrupel-Format.
Notation: sem(sym) verweist auf die semantische Information zum Token sym .
8. Syntaxorientierte Übersetzung
Übersetzung von Ausdrücken in Quadrupelcode (III)
Die semantischen Aktionen zu den Produktionen von Γ
13sind:
→
E T sem(E) := sem(T)
→ +
1 2
E E T i ++
sem(E1) := hv[i]
generate (ADD, sem(E2), sem(T), hv[i])
→
T F sem(T) := sem(F)
→ ∗
1 2
T T F i ++
sem(T1) := hv[i]
generate (MPY, sem(T2), sem(F), hv[i] )
→
F v sem(F) := sem(v)
→
F (E) sem(F) := sem(E)
8. Syntaxorientierte Übersetzung
Ablauf der Übersetzung von (A+B)∗C
Schritt Stackinhalt Eingabe ZwischenCode
1. ( A + B ) ∗ C
2. ( A + B ) ∗ C
3. ( v + B ) ∗ C
A
4. ( F + B ) ∗ C
A
5. ( T + B ) ∗ C
A
6. ( E + B ) ∗ C
A
7. ( E + B ) ∗ C
A
8. ( E + v ) ∗ C A B
9. ( E + F ) ∗ C A B
10. ( E + T ) ∗ C
A B
Übersetzung von Ausdrücken in Quadrupelcode (IV)
8. Syntaxorientierte Übersetzung
Ablauf der Übersetzung von (A+B)∗C
11. ( E ) ∗ C ADD A B hv[1]
hv[1]
12. ( E ) ∗ C
hv[1]
13. F ∗ C
hv[1]
14. T ∗ C
hv[1]
15. T ∗ C
hv[1]
16. T ∗ v
hv[1] C
17. T ∗ F
hv[1] C
18. T MPY hv[1] C hv[2]
hv[2]
19. E
hv[2]
Übersetzung von Ausdrücken in Quadrupelcode (IV)
8. Syntaxorientierte Übersetzung
Übersetzung von Ausdrücken in Postfixcode (I)
Beispiel-Grammatik Γ
11{ }
{ }
{ }
{ }
, , , , / , ( , )
[ | ]
| | ( )
, ,
,
=
= + − ∗
→ + − + −
= → ∗
→
11 11
11