We already had a preliminary discussion about Symbol Tables in Chapter 3, Section 3.2. A Symbol Table exists throughout the compilation steps. Major operations required for a symbol table are:
The Symbol Table is accessed at every stage of the compilation process:
Scanning: Insertion of new identifiers.
Parsing: Access to ensure that an operand exists.
Semantic analysis:
Intermediate Representation generation: Memory allocation and relative address calculation for jumps etc.
Optimization: All memory accesses are through the Symbol Table.
Target code generation: Translation of relative addresses to absolute addresses in terms of word length, word boundary, etc.
Thus, the Symbol Table is a store house of context-sensitive and run-time information about every identifier in the source program. That is why sometimes it is called the Environment.
All accesses relating to an identifier require to first find the attributes of the identifier from the Symbol Table. In real-world compilers, it is usually organized as a hash table, which provides fast access. Compiler-generated temporary memory locations may also be stored in the symbol table.
The following attributes are stored in a Symbol Table for each identifier:
After addition of semantic actions for type setting in the yacc grammar of the miniC language as shown below:
decl: dtype ‘:’ dlist ;
dtype: IVAR | VAR | SVAR ;
dlist: VAR { type($1) = type($<sym>0); }
| dlist ‘,’ VAR { type($3) = type($<sym>0); }
;
For the following declarations,
int : a
float : f
string : s
we obtained the following Symbol Table dump:
[DEG](261){42652ee1}
[E](261){402df854}
[PI](261){40490fdb}
[a](275){0} <–––––––––+
[cos](262){8048blc} |
[else](267){0} |
[f](261){0} <–––+ |
| |
[float](261){0} <–––+ |
[for](265){0} |
[if](266){0} |
[int](275){0} <–––––––––+
[s](276){0} <–––+
[sin](262){8048c0c} |
[string](276){0} <–––+
[while](264){0}
For declaration of a function,
func ack(){
return 1
}
we obtained the following entry in the Symbol Table
[ack](268){8050d80}
due to the following type setting action in the grammar:
defn: FUNC procname { type($2) = FUNCTION;}
‘(’ ‘)’ stmt { }
| PROC procname { type($2) = PROCEDURE;}
‘(’ ‘)’ stmt { }
;
3.133.158.36