• Keine Ergebnisse gefunden

5. Bottom up-Parser

N/A
N/A
Protected

Academic year: 2021

Aktie "5. Bottom up-Parser "

Copied!
88
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

5. Bottom up-Parser

5. Bottom up-Parser 5. Bottom up-Parser

syntaktische Analyse

(2)

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:

(3)

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.

(4)

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)

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.

(6)

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.

(7)

5. Bottom up-Parser

I

4

I

7

I

2

I

0

I

8

(

T

$ E

LR(k)-Analysator

v ( v + v ) $

Schaltwerk

Eingabeband

Zustands- Stack

Symbol-

Stack

(8)

5. Bottom up-Parser

Die Aktionstabelle

Damit entscheidet der Analysator über den nächsten Analyseschritt.

t

0

t

1

t

2

... $

I

0 ACCEPT

I

1

I

k

I

2

N → β

: :

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)

(9)

5. Bottom up-Parser

I

2

I I I

N N

N

$ N

1

Die Goto-Tabelle

Damit bestimmt der Analysator den nächsten Stackzustand bei Reduktionen.

N

0

N

1

N

2

...

I

0

I

1

I

2

I

k

:

:

(10)

5. Bottom up-Parser

Die Aktionstabelle von Γ

13

v + * ( ) $

I

0

I

5

I

4

I

1

I

6

ACCEPT

I

2 E→T

I

7 E→T E→T

I

3 T→F T→F T→F T→F

I

4

I

5

I

4

I

5 F→v F→v F→v F→v

I

6

I

5

I

4

I

7

I

5

I

4

I

8

I

6

I

11

I

9 E→ +E T

I

7 E→ +E T E→ +E T

I

10 T→T F* T→T F* T→T F* T→T F*

I

11 F→(E) F→(E) F→(E) F→(E)

(11)

5. Bottom up-Parser

Die Goto-Tabelle von Γ

13

E T F I

0

I

1

I

2

I

3

I

1

I

2

I

3

I

4

I

8

I

2

I

3

I

5

I

6

I

9

I

3

I

7

I

10

I

8

I

9

I

10

I

11

(12)

____________________________________________________________________________________

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

(13)

____________________________________________________________________________________

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

(14)

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.

(15)

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.

(16)

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.

(17)

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)

(18)

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:

(19)

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.

(20)

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

13

E E

E T | E T T F | T * F F v | (E)

Grammatik:

erste LR(0)-Information:

(21)

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)

(22)

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

(23)

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 ]

(24)

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

+ +

(25)

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

i

gibt mit GOTO [I

i

, t ] = I

j

{ Trage I

j

auf 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

i

gibt

→ α 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

i

gibt

{ Trage ACCEPT auf der Position ( , $) in die Aktionstabelle ein I i }

(26)

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

j

auf der Position ( i, N ) in die GOTO-Tabelle ein }

(27)

6. Fehlerbehandlung

6. Die Fehlerbehandlung 6. Die Fehlerbehandlung

Lexikalische Analyse

Code- generierung Speicher-

verwaltung syntaktische

Analyse Interpretation Optimierung Fehler-

Behandlung

(28)

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

(29)

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

(30)

6. Fehlerbehandlung

Klassifikation von Fehlern

Aus der Sicht des Compiler-Entwicklers unterscheiden wir:

Lexikalische Fehler

Syntaktische Fehler

Semantische Fehler

Laufzeitfehler

(31)

6. Fehlerbehandlung

Modell der Fehlerbehandlung

Lexikalische Analyse

Code- generierung Speicher-

verwaltung syntaktische

Analyse Interpretation Optimierung Fehler-

Behandlung

(32)

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

(33)

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.

(34)

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

;

(35)

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

;

(36)

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

(37)

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

(38)

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

(39)

7. Speicherverwaltung

7. Die Speicherverwaltung 7. Die Speicherverwaltung

Speicher- Verwaltung

(40)

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)

(41)

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

(42)

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

(43)

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;

}

(44)

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

(45)

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

(46)

7. Speicherverwaltung

Blockvektoren (II)

Objekte des 2. Unterblocks: a

Objekte des 1. Unterblocks: y, z

Objekte des Hauptprogramms: x, y

(47)

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.

(48)

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

(49)

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.

(50)

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.

(51)

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

(52)

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

(53)

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.

(54)

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

(55)

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

main

(56)

7. 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.

(57)

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

main

(58)

7. 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

(59)

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.

(60)

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];

}

(61)

7. Speicherverwaltung

Deskriptoren für Felder mit dynamischen Grenzen

DSA -Top pointer

Deskriptor von arrayA

Daten von arrayA DSA -Top pointer

Deskriptor von arrayA

(62)

7. Speicherverwaltung

Allgemeiner Aufbau von Feld-Deskriptoren

FeldA : array [u

1

..o

1

, u

2

..o

2

, ... , u

n

..o

n

] of …

u

1

o

1

s

1

u

2

o

2

s

2

. . . . . . . . .

u

n

o

n

s

n

α

0

(63)

7. 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]

(64)

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) +

(65)

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

(66)

8. Syntaxorientierte Übersetzung

8. Syntaxorientierte Übersetzung 8. Syntaxorientierte Übersetzung

Code- generierung

Inter-

pretation

(67)

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

(68)

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

(69)

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

(70)

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)

(71)

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 .

(72)

8. Syntaxorientierte Übersetzung

Übersetzung von Ausdrücken in Quadrupelcode (III)

Die semantischen Aktionen zu den Produktionen von Γ

13

sind:

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)

(73)

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)

(74)

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)

(75)

8. Syntaxorientierte Übersetzung

Übersetzung von Ausdrücken in Postfixcode (I)

Beispiel-Grammatik Γ

11

{ }

{ }

{ }

{ }

, , , , / , ( , )

[ | ]

| | ( )

, ,

,

=

= + − ∗

→ + − + −

= → ∗

 

 

 

 

 

11 11

11

N T

P

expr term fact ident number

expr term term | term

term fact fact | / fact

fact ident number expr

(76)

8. Syntaxorientierte Übersetzung

Übersetzung von Ausdrücken in Postfixcode (II)

Die Architektur der Zielmaschine

LOAD v bringt den Wert der Variablen v in den Stack LIT c bringt den Wert der Konstanten c in den Stack NEG negiert den obersten Stackeintrag

ADD addiert die obersten beiden Stackelemente und legt das Resultat wieder in den Stack

SUB subtrahiert die obersten beiden Stackelemente und legt das Resultat wieder in den Stack

MPY multipliziert die obersten beiden Stackelemente und legt das Resultat wieder in den Stack

DIV dividiert die obersten beiden Stackelemente und

legt das Resultat wieder in den Stack

(77)

8. Syntaxorientierte Übersetzung

Übersetzung von Ausdrücken in Postfixcode (III)

Die semantischen Aktionen zu Γ

11

:

Semantik von: fact → ident number | | ( expr )

für die Struktur ident: erzeuge LOAD v für die Struktur number: erzeuge LIT c

für die Struktur ( expr ): keine semantische Aktion erforderlich !

(78)

8. Syntaxorientierte Übersetzung

Übersetzung von Ausdrücken in Postfixcode (IV)

Die semantischen Aktionen zu Γ

11

:

Semantik von expr → + − [ | ] term { + term | term }

für das Vorzeichen − wird eine NEG-Anweisung generiert, sobald der Operand verarbeitet ist.

Für die Teilstrukturen + term und - term , wird zuerst der Operand verarbeitet und dann die Operation generiert

Semantik von term fact { fact | / fact }

Für die Teilstrukturen ∗ term und / term , wird zuerst der Operand verarbeitet

und dann die Operation generiert

(79)

8. Syntaxorientierte Übersetzung

Übersetzung von Ausdrücken in Postfixcode (V)

Codegenerierung mit einem Recursive Descent-Übersetzer für Ausdrücke (A):

void exprParser::expression (void) { char plusMinus[6];

if ((sym==plus) || (sym == minus))

{ if (sym==minus) strcpy (plusMinus, "NEG\n");

else strcpy (plusMinus, "" );

getSym(); term();

if (strlen(plusMinus)>0) cout << plusMinus ; }

else

{ term(); }

while((sym==plus) || (sym == minus))

{ if (sym==plus) strcpy (plusMinus, "ADD\n");

else strcpy (plusMinus, "SUB\n");

getSym(); term();

cout << plusMinus ; }

}

void exprParser::term(void) { char timesSlash[6];

factor();

while ((sym==times) || (sym == slash))

{ if (sym==times) strcpy (timesSlash, "MPY\n");

else strcpy (timesSlash, "DIV\n");

getSym(); factor();

cout << timesSlash ; }

}

(80)

8. Syntaxorientierte Übersetzung

Übersetzung von Ausdrücken in Postfixcode (VI)

Codegenerierung mit einem Recursive Descent-Übersetzer für Ausdrücke (B):

void exprParser::factor(void) { switch (sym)

{ case ident: getSym();

cout << "LOAD " << id << endl;

break;

case number: getSym();

cout << "LIT " << num << endl;

break;

case lparen: getSym();

expression();

if (sym == rparen) getSym();

else

cout << "Symbol can't follow an expression !\n;

break;

default: cout << "factor expected !" << endl;

break;

} }

Übersetzung einer Beispieldatei

Run

alpha + beta/12;

pi*2/(radius1-radius2);

(x17 - x18) / 15;

a*b+c.

(81)

8. Syntaxorientierte Übersetzung

Übersetzung bedingter Anweisungen (I)

Struktur des zu erzeugenden Code:

Code zur Auswertung der condition

jump on false L

1

Code zur Auswertung des statement

nachfolgender Code then

if condition statement

L

1

:

(82)

8. Syntaxorientierte Übersetzung

Übersetzung bedingter Anweisungen (II)

case ifSym:

getSym();

condition( STAT_START | IDENT | DO_THEN_OF, lev );

if (sym==thenSym) getSym();

else

error(16);

fixup1 = cx; // Adresse des jpc-Befehls merken generate (jpc, 0, 0); // then-Zweig bedingt umgehen

statement(followSymSet | UNTIL_ELSE, lev);

code[fixup1].a = cx; // Adresse des jpc-Befehls setzen

break;

(83)

8. Syntaxorientierte Übersetzung

Der PL/0-Übersetzer

Die Struktur der Symboltabelle (I)

int tx; // symbol table index struct // symbol table:

{

objType kind; // object type of this entry char name[CMAX+1]; // object identifier

union {

int val; // numerical value for constants struct { int level; // address information

int addr int size;

};

};

} symTable[TXMAX];

(84)

8. Syntaxorientierte Übersetzung

Der PL/0-Übersetzer

Die Struktur der Symboltabelle (II) Einträge für Konstanten:

Konstanten-Name constObj Konstanten-Wert

Einträge für Variablen:

Variablen-Name varObj DeklarationsLevel Relativadr. in der DSA

Einträge für Prozeduren:

Prozedur-Name procObj DeklarationsLevel Adr. der 1. Anweisung DSA-Größe

(85)

8. Syntaxorientierte Übersetzung

Der PL/0-Übersetzer

Die Datenraum-Struktur

Static Link Dynamic Link Rückkehradresse lokale Variablen

lokale Hilfsvariablen

(86)

8. Syntaxorientierte Übersetzung

Der PL/0-Übersetzer

Zwischencode-Anweisungen (I) Transportoperationen:

LIT n bringe einen Literalwert n in den Hilfsvariablenstack

LOD l , a bringe Variable mit der Relativdistanz a und der Niveaudifferenz l in den Stack STO l , a bringe das Stacktop-Element in Variable mit der Relativdistanz a und der

Niveaudifferenz l

INC n Reserviere n Plätze im Laufzeit-Stack für den nächsten Datenraum

Sprungbefehle:

JPU a springe zur Anweisung mit der Adresse a

JPC a Jump on false zur Code-Adresse a

CAL a Aufruf der Prozedur mit der Codeadresse a. (DSA anlegen, initialisieren, springen)

RET Rückkehr aus einer Prozedur

(87)

8. Syntaxorientierte Übersetzung

Der PL/0-Übersetzer

Zwischencode-Anweisungen (II) Arithmetische Operationen

ADD addiere zwei Summanden.

SUB subtrahiere das oberste Stackelement vom darunter stehenden MPY multipliziere zwei Faktoren.

DIV Dividiere das vorletzte Stackelement durch das oberste.

NEG negiere das oberste Stackelement.

Logische Operationen

OD Ist der (einzige) Operand ungerade ? EQ Sind beide Operanden gleich ?

NE Sind beide Operanden ungleich ?

LE Ist der erste Operand kleiner oder gleich dem zweiten ?

GE Ist der erste Operand größer oder gleich dem zweiten ?

LS Ist der erste Operand kleiner als der zweite ?

(88)

8. Syntaxorientierte Übersetzung

Der PL/0-Übersetzer

Zwischencode-Generator

void pl0Parser::generate(opCode opc, int lv, int ad) {

if (cx > CODEMAX)

error(31); // too many code entries else

{

code[cx].o = opc; // generate operation

code[cx].l = lv; // generate level difference code[cx].a = ad; // generate address

cx++; // point to next free entry }

}

Referenzen

ÄHNLICHE DOKUMENTE

Die Regelungen der Muster-Verwaltungsvorschrift Technische Baubestimmungen gelten in Hamburg mit wenigen Abweichungen3. Die Abweichungen sind als Deckblatt der VV

Unterstützerinnen und Unterstützer sammeln können, freut sich Oberbürgermeisterin Jutta Steinruck auch weiterhin über viele neue Projekte aus und für Ludwigshafen. Alle

Auch sagten in Österreich nur 18 Prozent, sie hätten Sympathien für Juden - so wenige wie in keinem anderen Land der Befragung. Umgekehrt bezeichneten 55 Prozent Antisemitismus

Die Aufsichts- und Dienstleistungsdirektion Trier ist dem Vorschlag des Stadtrates gefolgt und hat den Termin für die OB-Wahl in Ludwigshafen auf Sonntag, 24.. September 2017, und

Dann aber vor allem als Besitzer des prächtigen Landhauses mit dem ausgedehnten Park, in dem sich vor den Augen der Kleinhüninger ein herrschaftliches Leben abspielte, mit

Der Generalstabschef, der persönlich für das Kommando und die Ausbildung der Armee verantwortlich wäre, hätte zu seiner direkten Verfügung : den Kommandanten der Zentralschulen und

Man kann auch die Offiziere nicht vron dem Vorwurf freisprechen, daß sie sich "zu sehr von der allgemeinen Stimmung überwältigen lassen, daß sie in dem Gefühl, es nütze ja doch

Oberst Staub nennt den Einheitskommandanten der Rekrutenschule einen Lernenden und sagt, daß der Kompagnie-Instruktor „bekanntlich" die Verantwortung für die Ausbildung