005chapter 5 - Symbol Table and Type Checking
005chapter 5 - Symbol Table and Type Checking
As each symbol is encountered in the source code, information about that symbol
Thus, the information collected about the name includes the string of characters by
which it is denoted,
its type (e.g. Integer, real, string), its form (e.g. simple variable a structure), its
Each entry in the symbol table is a pair of the form (name and information)
Usage of Symbol Table by various phases of compiler
Why symbol table?
A symbol table is simply a table which can be either linear or a hash table.
For example, if a symbol table has to store information about the following variable
declaration:
If a compiler is to handle a small amount of data, then the symbol table can be
implemented as an unordered list,
which is easy to code, but it is only suitable for small tables only.
Hash table
Among all, symbol tables are mostly implemented as hash tables, where the source
code symbol itself is treated as a key for the hash function and the return value is the
information about the symbol.
Symbol Table Operations
A symbol table, either linear or hash, should provide the following two main
operations:
a. insert (name) makes an entry for this name
b. lookup (name) finds the relevant occurrence of the name by searching the table
Lookups occur a lot more often than insert
a. Insert operation
This operation is more frequently used by analysis phase,
i.e., the first half of the compiler where tokens are identified and names are stored in the table.
This operation is used to add information in the symbol table about unique names occurring in
the source code.
The format or structure in which the names are stored depends upon the compiler in hand.
An attribute for a symbol in the source code is the information associated with that symbol.
This information contains the value, state, scope, and type about the symbol.
The insert function takes the symbol and its attributes as arguments and stores the information in
the symbol table.
b. Lookup operation
Lookup operation is used to search a name in the symbol table to determine:
if the symbol exists in the table.
if it is declared before it is being used.
Check whether the name is used in the scope.
if the symbol is initialized.
if the symbol declared multiple times.
The global symbol table contains names for one global variable intvalue and two
procedure names.
which should be available to all the child nodes shown above.
The names mentioned in the pro_one symbol table and all its child tables are not
available for pro_two symbols and its child tables.
To determine the scope of a name, symbol tables are arranged in hierarchical
structure as shown in the example below:
Example
Example…
The above program can be represented in a hierarchical structure of symbol tables:
Con’t…
This symbol table data structure hierarchy is stored in the semantic analyzer and
else it will be searched in the parent symbol table until, either the name is found or
global symbol table has been searched for the name.
Type Checking in Compiler
Type checking in compilers is the process of ensuring that all expressions in a
program are compatible with their respective type definitions.
It allows the programmer to limit what types may be used in certain circumstances
and assigns types to values.
Much of what we do in the semantic analysis phase is type checking
The main goal of type checking is:
check that the source program should follow the syntactic and semantic
conventions of the source language.
to check whether the source program is maintained correctly or not.
to check the correctness and data type assignments and type-casting of the data
types, whether it is syntactically correct or not before their execution.
to check the correctness of the program before its execution.
it checks the type rules of the language.
Also determines whether these values are used appropriately or not.
Cont’d…
• Type checking involves comparing the type of an expression with the expected type, and ensuring that
• For example, adding two values of different types (such as a string and a number) would result in a
type error.
• In some languages, type inference can help to reduce the amount of explicit type annotations that are
required.
• In these cases, the compiler can deduce the type of an expression based on its context.
• Once the type checking is complete, the compiler can generate code that is optimized for the specific
Identify the language constructs that have types associated with them.
A language is considered strongly- typed if each and every type error is detected during
compilation.
Type Checking Preventions
Division by zero
Need to verify that the source program follows the syntactic and semantic conventions
After this information is collected, the types involved in each operation are checked.
• Static Type-Checking is also used to determine the amount of memory needed to store the
variable.
Example of Static Type Checking
4 types of static type checking
1- Type Check: operator applied to an incompatible operand.
e.g. error if array variable is added with function variable: 2+2.5 = Error
2- Flow of Control: statements that results in a branch need to be terminated
correctly. While() {
Breack;
} error
3- Uniqueness Check: Object must be defined exactly once for some scenarios
int a = 2; a should be unique
4.Name Related Check: Sometimes the same name must appear two or more time
e.g. main() {
add (x,y);
}
add()
Example: #2
For example, if a and b are of type int and we assign very large values to
them, a * b may not be in the acceptable range of int’s, or an attempt to
compute the ratio between two integers may raise a division by zero.
These kinds of type errors usually cannot be detected at compiler time.
Dynamic Type Checking
Dynamic Type Checking is defined as the type checking being done at run time.
For example, a variable of type double would contain both the
actual double value and some kind of tag indicating "double type".
Common dynamically typed languages are : JavaScript, Php and Python etc.
Most of the languages used both.
Note: Static or Dynamic doesn’t mean Weak or strong
Dynamic typing is more flexible.
A static type system always restricts what can be conveniently expressed.
Dynamic typing results in more compact programs since it is more flexible and does
not require types to be spelled out.
Programming with a static type system often requires more design and
implementation effort.
Figure 5.1: Position of type checker
– A type name