Namensliste Teil der semantischen Aktionen Führt eine Liste über alle gültigen Bezeichner und die Eigenschaften der benannten Sprachkonstrukte Realisiert nebenbei die Gültigkeitsbereiche von Bezeichnern Operationen der Namensliste: einfügen eines Bezeichners in die aktuelle Namensliste lokale Suche eines Bezeichners in der aktuellen Namensliste globale Suche eines Bezeichners „von innen nach außen“
Implementationsvarianten Namensliste für jede Prozedur Jede Prozedur verfügt über ihre eigene Namensliste. Über Eltern-Kind-Beziehungen ist die globale Suche von „innen nach außen“ möglich. Pulsierender Keller Alle Namen werden in einem Keller geführt. Anfang einer jeden lokalen Namensliste muss mitgeführt werden.
Namenslisteneintrag typedef struct { Member eines Namenslisteneintrags tKz Kz; short IdxProc; void* pObj; int Len; char* pName; }tBez; Member eines Namenslisteneintrags (KzName) Prozedurnummer Pointer auf benanntes Objekt (Var, Const Proc) Pointer auf Name Kennzeichen und Länge sind redundant
Anmerkungen zur Variablenbeschreibung Variablen werden zur Laufzeit im Stack angelegt In jeder neuen Prozedur beginnt die Adressierung der Variablen mit 0 Mit jeder neuen Variablen wird ein Variablenzähler (SpzzVar) um 4 erhöht 1. Variable: relAddr=0 2. Variable: relAddr=4 3. Variable: relAddr:=8 . . .
Variablenbeschreibung Member Variablenbeschreibung KzVar Displacement typedef struct tVAR { tKz Kz; int Dspl; }tVar;
Anmerkungen zur Konstantenbeschreibung Alle Konstanten werden in einem Konstantenblock gesammelt, der am Ende an den generierten Code angehängt wird. Die Konstanten sind 4 Byte groß Die Konstanten werden indiziert 1. Konstante: ConstBlock[0] 2. Konstante: ConstBlock[1]
Konstanten am Ende des Codes 0000: 1A EntryProc 0018,0000,0004 0007: 04 PushAdrVarMain 0000 000A: 06 PushConst 0000 000D: 0A VzMinus 000E: 06 PushConst 0001 0011: 06 PushConst 0002 0014: 0E Mul 0015: 0C Add 0016: 07 StoreVal 0017: 17 ReturnProc Const 0000:0001 Const 0001:0002 Const 0002:0003 var a; begin a:=-1+2*3 end. 0000 01 00 00 00 1a 18 00 00 00 04 00 04 00 00 06 00 |................| 0010 00 0a 06 01 00 06 02 00 0e 0c 07 17 01 00 00 00 |................| 0020 02 00 00 00 03 00 00 00 |........|
Konstantenbeschreibung typedef struct tCONST { tKz Kz; long Val; int Idx; }tConst; Member der Konstantenbeschreibung KzConst Wert der Konstanten Index der Konstanten im ConstBlock
Anmerkungen zur Procedurebeschreibung Jede Prozedur und das Hauptprogramm erhalten eine Nummer, das Hauptprogramm hat die Nummer 0 Die Nummern werden fortlaufend vergeben Jede Prozedurbeschreibung enthält eine Namensliste mit den lokalen Namen Der Name einer Prozedur steht dabei immer in der übergeordneten Namensliste
Prozedurbeschreibung KzProc Prozedurnummer Pointer auf die Prozedurbeschreibung der Parentprozedur Lokale Namensliste der prozedur Speicherplatzzuordnungs zähler für Variable typedef struct tPROC { tKz Kz; short IdxProc; struct tPROC*pParent; tList *pLBez; int SpzzVar; }tProc;
Namensliste (Schnappschuss) vereinfachte Darstellung KzProc NULL KzBez “C“ NULL KzBez “A“ NULL KzBez “B“ NULL KzBez “P1“ NULL KzConst 0 (value) 0 (idx) KzVar 0 (Displ) KzVar 4 (Displ) KzProc 1 NULL KzBez 1 “V1“ KzVar 0 (Displ) NULL KzBez 1 “V2“ KzVar 4 (Displ) const c=0; var a,b; Procedure p1; var v1,v2; ... end; procedure p2; var x1,x2; . . .
KzProc NULL KzBez “C“ NULL KzBez “A“ NULL KzBez “B“ NULL KzBez “P1“ NULL KzBez “P2“ NULL KzConst 0 (value) 0 (idx) KzVar 0 (Displ) KzVar 4 (Displ) KzProc 1 NULL const c=0; var a,b; Procedure p1; var v1,v2; ... end; procedure p2; var x1,x2; . . . NULL KzBez 2 “X1“ KzVar 0 (Displ) NULL KzBez 2 “X2“ KzVar 4 (Displ) KzProc 2
Realisierung als Stack X1 KzVar RelAdr=0 X2 RelAdr=4 C B P1 Val=0 Index=0 A P2 IdxProc=1 KzProc (pParent) KzConst pParent=0 IdxProc=0 const c=0; var a,b; Procedure p1; var v1,v2; ... end; procedure p2; var x1,x2; . . .
Funktionen zur Namensliste tBez* createBez(char*pBez); tConst* createConst(long Val); tConst* searchConst(long Val); int createVar(void); tProc* createProc(tProc*pParent); tBez* searchBez(tProc*pProc,char* pBez); tBez* searchBezGlobal(char* pBez);
“const“ ident “=“ numeral “;“ “var“ “procedure“ block statement (bl1) (bl2) (bl3) (bl4) (bl5) (bl6) “,“
'.' 'CONST' 'VAR' 'PROCEDURE' numeral '(' expression ')' ident '-' block '.' ident ':=' expression 'IF' condition 'THEN' statement 'WHILE' 'DO' 'BEGIN 'END' ';' 'CALL' '?' '!' 'CONST' ident '=' numeral ';' 'VAR' 'PROCEDURE' block statement ',' numeral '(' expression ')' ident '-' term '+' 'odd' expression '='|'#'|'<'|'>' '<='|'>=' factor '*' '/'