The most closely nested rule Given several different declarations for the same name the declaration that applies to a reference is the one in the most closely nested block to the reference Int 1, J Int f(int size) i char i, temp double j char Fig 6.14
The most closely nested rule: Given several different declarations for the same name, the declaration that applies to a reference is the one in the most closely nested block to the reference. Int i, j ; Int f(int size) { char i, temp; … {double j; … } {char * j; … } } Fig 6.14
For each name. the linked lists in each bucket behave as a stack for the different declarations of that name Indices buckets lists of items i(char) Size(int) j(int) temp(char)● 5 F(function) (a) After processing the declarations of the body of f
For each name, the linked lists in each bucket behave as a stack for the different declarations of that name. Indices buckets lists of items (a) After processing the declarations of the body of f 1 2 3 4 5 i(char) i (int) Size(int) j(int) temp(char) F(function)
Indices buckets lists of items I(char) i(int) J(char s size(int) j(int) temp(char) F(function) (b) After processing the declarations of the second nested compound statement within the body of f
Indices buckets lists of items (b) After processing the declarations of the second nested compound statement within the body of f 1 I(char) i(int) 2 J(char *) size(int) 3 4 temp(char) 5 F(function) j(int)
Indices buckets lists of items I(int) j(int) F( (function)|● (c) After exiting the body of f(and deleting its declarations) In fact it is necessary to keep the declarations in the table(at least not to de-allocate their memory), so the delete operation is simply to mark them as no longer active
Indices buckets lists of items (c) After exiting the body of f (and deleting its declarations) In fact it is necessary to keep the declarations in the table (at least not to de-allocate their memory), so the delete operation is simply to mark them as no longer active. 1 I(int) 2 j(int) 3 4 5 F(function)
The other solutions to the implementation of nested scopes: Build a new symbol table for each scope and to link the tables from inner to outer scopes together Lookup operation will automatically continue the search with an enclosing table if it fails to find a name in the current table Leaving a scope simply requires resetting the access pointer to the next outermost scope Size( int) j(char * F(function)
The other solutions to the implementation of nested scopes: – Build a new symbol table for each scope and to link the tables from inner to outer scopes together. – Lookup operation will automatically continue the search with an enclosing table if it fails to find a name in the current table. – Leaving a scope simply requires resetting the access pointer to the next outermost scope. I(char) j(int) Size(int) j(int) temp(char) F(function) j(char *)