0% found this document useful (0 votes)
80 views24 pages

Symbol Table

The document discusses the concept and implementation of a Symbol Table in compiler design, which is a data structure that stores information about names in a source program, including their attributes and scope. It outlines the responsibilities of the Symbol Table, the operations for managing entries, and various organizational methods such as linear lists, search trees, and hash tables. Additionally, it covers scope rules, overloading, and the differences between static and dynamic scoping in programming languages.

Uploaded by

amanhabtamu32
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
80 views24 pages

Symbol Table

The document discusses the concept and implementation of a Symbol Table in compiler design, which is a data structure that stores information about names in a source program, including their attributes and scope. It outlines the responsibilities of the Symbol Table, the operations for managing entries, and various organizational methods such as linear lists, search trees, and hash tables. Additionally, it covers scope rules, overloading, and the differences between static and dynamic scoping in programming languages.

Uploaded by

amanhabtamu32
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 24

Compiler Design

Department of Computer Science

1
Symbol Table

2
Symbol Table
• Symbol Table is a data structure meant to collect information about
names appearing in the source program.
• It keeps track about the scope/binding information about names.
• Each entry in the symbol table has a pair of the form (name and
information).
• Information consists of attributes (e.g. type, location) depending
on the language.
• Whenever a name is encountered, it is checked in the symbol table to
see if already occurs. If not, a new entry is created.
• In some cases, the symbol table record is created by lexical analyzer
as soon as the name is encountered in the input, and the attributes of
the name are entered when the declarations are processed.

3
Symbol Table Entries
• We will store the following information about
identifiers.

 The name (as a string).


 The data type.
 The block level.
 Its scope (global, local, or parameter).
 Its offset from the base pointer (for local variables
and parameters only).

4
Symbol Table Entries
• This information is stored in an object called an
IdEntry.
• This information may not all be known at once.
• We may begin by knowing only the name and data
type, and then later learn the block level, scope, and
the offset.

5
Symbol Table
• If same name can be used to denote different program
elements in the same block, the symbol table record is created
only when the name’s syntactic role is discovered.
• used during all phases of compilation
• maintains information about many source language constructs
• incrementally constructed and expanded during the analysis
phases
• used directly in the code generation phases
• A name can represent:
– Variable, Type, Constant, Parameter, Record, Record Field, Procedure,
Array, Label, file etc..

6
Responsibilities of Symbol Table
1. It maintains all declared names and their properties
• Type, value (for named constants), address (for variables,
fields and methods), parameters (for methods)…
2. It is used to retrieve the properties of a name:
• Mapping: name ⇒ (type, value, address, ...)
3. It manages the scopes of names

Contents of the symbol table


– Object nodes: Information about declared names
– Structure nodes: Information about type structures
– Scope nodes: for managing the visibility of names
7
Constructing the Symbol Table
• There are three main operations to be carried out on the
symbol table:
– determining whether a string has already been stored.
– inserting an entry for a string.
– deleting a string when it goes out of scope.
• This requires three functions:
– lookup(s): returns the index of the entry for string s, or 0 if
there is no entry
– insert(s,t): add a new entry for string s (of token t), and
return its index
– delete(s): deletes s from the table (or, typically, hides it)
8
Inserting a Symbol
• The insert(s) function will insert a new symbol into the
symbol table.
• Each symbol has a block level.
– Block level 1 = Keywords.
– Block level 2 = Global variables.
– Block level 3 = Parameters and local variables.
• insert(s) will create an IdEntry object and store it in the table.
• When the symbol is first encountered by the lexer, we do not
yet know the scope or type.
• That is determined later by the parser.

9
Block levels
• Keywords, global variables, and local variables are
stored at different block levels.
• C and C++ recognize further levels (blocks) within
functions, delimited by braces { }.
• However, in C, variables local to a block must be
declared at the beginning of the block.
• Every time we enter a block, the block level increases
by 1 and every time we leave a block, it decreases by
1.

10
Implementation
• Each entry in a symbol table can be implemented as a record
that consists of several fields.
• The entries in symbol table records are not uniform and
depends on the program element identified by the name.
• Some information about the name may be kept outside of the
symbol table record and/or some fields of the record may be left
vacant for the reason of uniformity. A pointer to this
information may be stored in the record.
• The name may be stored in the symbol table record itself, or it
can be stored in a separate array of characters and a pointer to
it in the symbol table.

11
Symbol table organization
• There are various approaches to symbol table
organization.
– Linear List
– Search Tree, and
– Hash Table

12
Linear List
• It is the simplest approach in symbol table organization.
• The new names are added to the table in the order they arrive.
• A name is searched for its existence linearly.
• The average number of comparisons required are proportional to
0.5* (n+1) where n=number of entries in the table.
• It takes less space but more access time.

13
Search Tree
• It is more efficient than Linear trees.
• We provide two links – left and right, which point to record in
the search tree.
• A new name is added at a proper location in the tree such
that it can be accessed alphabetically.
• For any node name1 in the tree, all names accessible by
following the left link precede name1 alphabetically.
• Similarly, for any node name1 in the tree, all names accessible
by following the right link succeed name1 alphabetically.
• The time for adding/searching a name is proportional to
(m+n) log2 n.

14
Search Tree
• Left and right use as binary search tree.
• The property of this tree is,
– All names (Name ‘j’) accessible from Name ‘i' by using the LEFT ‘i’
is always lesser than NAME ‘i’. i.e., Name ‘j’ < Name ‘i’
– All names (Name ‘k’) accessible from Name ‘i' by using the RIGHT ‘i’
is always greater than NAME ‘i’. i.e., Name ‘k’ > Name ‘i’.

15
Hash Table
• A hash table is a table of k-pointers from 0 to k-1 that point to
the symbol table and record within the symbol table.
• To search a value, we find out the hash value of the name
by applying suitable hash function.
• The hash function maps the name into an integer values
between 0 and k-1 and uses it as an index in the hash table to
search the list of the table records that are built on that hash
index.
• To add a non-existing name, we create a record for that
name and insert it at the head of the list.

16
Hash Table

17
Scope Information
• Each name possesses a region of validity within the source
program called scope of that name.
• The rules governing the scope of names in the block-
structured language are as follows:
– A name declared within block B is valid only within B.
– If block B1 is nested within B2, then any name that is valid
for B2 is also valid for B1, unless identifier for that name is
re-declared in B1.
• These rules require a more complicated symbol table
organization that simply a list of associations between names
and attributes.

18
Scope: Example
int i; i is globally accessible

int f1(int k) { a new integer k, in f1 only


int j; a new integer j, in f1 only
...
print i; (the global variable)
}

int f2() {
a different j, in f2 only
int j;
...
}
19
Scope
• There are two types of scope:
– Static scope
– Dynamic scope
• Most modern languages implement static scope (i.e.,
the scope of binding is determined at compile-
time).

20
Static Scope
• Static scope is also called lexical scope because the bindings
between name and objects can be determined by examining
the program text.
• Static Scope Rules:
– The simplest static scope rule has only a single, global
scope (e.g., early Basic).
– A more complex scope rule distinguishes between global
and local variables (e.g.,Fortran).
– Languages that support nested functions (e.g., Pascal,
Algol) require an even more complicated scope rule.

21
Dynamic Scope
• The bindings between names and objects depend on the flow
of control at run time.
• In, general, the flow of control cannot be predicted in advance
by the compiler.
• Languages with dynamic scoping tend to be interpreted rather
than compiled.

22
Overloading
• In most languages, a name may denote different objects.
• Example. In Pascal, a name may denote a function and its
return value.

function abc() : integer


begin
abc := abc + 1;
end
as a function
as return value

23
Overloading: Implementation
• How to accommodate overloading in symbol table?
 Link together all possible definitions of an overloading name.
 Call this an overloading chain.
 Whenever a name that can be overloaded is defined:
• if the name is already in the current scope, then add the new
definition in the overloading chain;
• if it is not already there, then enter the name in the current
scope, and link the new entry to any existing definitions;
• search the chain for an appropriate one, depending on the
context.
 Whenever a scope is closed, delete the overloading definitions
defined in this scope from the head of the chain.
24

You might also like