Every compiler uses a symbol table to track all variables, functions, and identifiers in a program.
- Stores information such as the name, type, scope, and memory location of each identifier.
- Built during the early stages of compilation, the symbol table supports error checking, scope management, and code optimization for runtime efficiency.
- It plays a crucial role in ensuring the correct usage of identifiers according to language rules.
Role of Symbol Table in Compiler Phases
It is used by various phases of the compiler as follows:-
- Lexical Analysis: Creates new table entries in the table, for example, entries about tokens.
- Syntax Analysis: Adds information regarding attribute type, scope, dimension, line of reference, use, etc in the table.
- Semantic Analysis: Uses available information in the table to check for semantics i.e. to verify that expressions and assignments are semantically correct(type checking) and update it accordingly.
- Intermediate Code Generation: Refers to symbol table for knowing how much and what type of run-time is allocated and table helps in adding temporary variable information.
- Code Optimization: Uses information present in the symbol table for machine-dependent optimization.
- Target Code generation: Generates code by using the address information of the identifier present in the table.
- Symbol Table entries - Each entry in the symbol table is associated with attributes that support the compiler in different phases.
Example of Using Symbol Table
Let us consider the following program
C
#include <stdio.h>
const float pi = 3.14159f;
float calculateArea(float radius, float pi) {
return pi * radius * radius;
}
int main() {
float distance;
printf("Enter the distance (radius): ");
if (scanf("%f", &distance) != 1) {
printf("Invalid input!\n");
return 1;
}
float area = calculateArea(distance, pi);
printf("Area of circle with radius %.2f = %.5f\n", distance, area);
return 0;
}
Key identifiers involved:
- distance (variable in
main) - pi (constant)
- radius (parameter in
calculateArea) - calculateArea (function)
A symbol table of this program would look like the following.
Name | Type | scope | Memory address | value | Additional Info |
|---|
distance | variable | Global | 0x1000 | Uninitialized | Data type: float |
|---|
pi | constant | Global | 0x1004 | 3.14159 | Data type: float, read-only |
|---|
calculateArea | function | Global | 0x1008 | N/A | Return type: float |
|---|
radius | parameter | Local | 0x2000 | 0x1000 | Data type: float |
|---|
Implementation of Symbol table
Symbol tables can be implemented using various data structures, each with its trade-offs:
- Hash Tables: Offer fast lookup times, making them suitable for large programs.
- Binary Search Trees: Maintain sorted order, which can be beneficial for certain compiler operations.
- Linear Lists: Simpler to implement but less efficient for large numbers of identifiers.
Applications of Symbol Table
- Resolution of variable and function names: Symbol tables are used to identify the data types and memory locations of variables and functions as well as to resolve their names.
- Resolution of scope issues: To resolve naming conflicts and ascertain the range of variables and functions, symbol tables are utilized.
- Information such as memory locations, are used to optimize code execution.
- Code generation: By giving details like memory locations and data kinds, symbol tables are utilized to create machine code from source code.
- Error checking and code debugging: By supplying details about the status of a program during execution, symbol tables are used to check for faults and debug code.
- Code organization and documentation: By supplying details about a program's structure, symbol tables can be used to organize code and make it simpler to understand.
Explore
Compiler Design Basics
Lexical Analysis
Syntax Analysis & Parsers
Syntax Directed Translation & Intermediate Code Generation
Code Optimization & Runtime Environments
Practice Questions