0% found this document useful (0 votes)
126 views

Chapter 7 Symbol Tables and Error Handler

The document discusses symbol tables and error handling in compilers. It describes how symbol tables are used to store information about variables and functions to track their scope and binding. It covers the implementation of symbol tables as data structures like lists and hash tables. It also discusses different types of errors that can occur during compilation and how compilers perform static type checking to detect errors at compile-time by verifying the program follows language rules.

Uploaded by

Yohannes Dereje
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
126 views

Chapter 7 Symbol Tables and Error Handler

The document discusses symbol tables and error handling in compilers. It describes how symbol tables are used to store information about variables and functions to track their scope and binding. It covers the implementation of symbol tables as data structures like lists and hash tables. It also discusses different types of errors that can occur during compilation and how compilers perform static type checking to detect errors at compile-time by verifying the program follows language rules.

Uploaded by

Yohannes Dereje
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 34

Principles of Compiler Design

Chapter 7: Symbol Tables and Error


Handler
Contents
• Introduction to Symbol Tables

• The contents of a symbol table,


– Data structures for symbol tables, Representing scope information

• Symbol tables:
– Implementation of a simple stack allocation scheme, Implementation of
block-structured languages, Storage allocation in block- structured
languages

• Error detection and recovery:


– Errors, Lexical-phase errors, Syntactic-phase errors, Semantic errors
Introduction to Symbol Tables
• Symbol Table is an important data structure created and
maintained by the compiler in order to keep track of semantics
of variables i.e. it stores information about the scope and
binding information about names, instances of various entities
such as variable and function names, classes, objects.
Introduction to Symbol Tables
Introduction to Symbol Tables
Why symbol table?

 The symbol table used for the following purpose:


 It is used to store the name of all entities in a structured
form at one place.
 It is used to verify if a variable has been declared.
 It is used to determine the scope of a name.
 It is used to implement type checking by verifying
assignments and expressions in the source code is
semantically correct or not.
The Contents of a Symbol Table

 A symbol table is simply a table which can be either linear or a hash table.

 It maintains an entry for each name in the following format:

 For example, if a symbol table has to store information about the following

variable declaration:

 then it should store the entry such as:

 The attribute clause contains the entries related to the name.


Implementation of Symbol Table

 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.
 A symbol table can be implemented in one of the following ways:
 Linear sorted or unsorted list
 Binary Search Tree
 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 format of lookup function varies according to the


programming language.
 The basic format should match the following:
 This method returns 0 zero if the symbol does not exist in
the symbol table.
Scope Management
 A compiler maintains two types of symbol tables:
 a global symbol table which can be accessed by all the procedures and
 scope symbol tables that are created for each scope in the program.

 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 whenever a name needs to be searched in a symbol table, it


is searched using the following algorithm:

 first a symbol will be searched in the current scope,

 i.e. current symbol table.

 if a name is found, then search is completed,

 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 they are compatible.

• 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 types that are used in the program.

• This can lead to faster and more efficient code. Type checking is an important
part of the compiler optimization process.
Conversion

• Conversion from one type to another type is known as implicit if it is to be


done automatically by the compiler.
• Implicit type conversions are also called Coercion and coercion is limited in
many languages.
• Example: An integer may be converted to a real but real is not converted to an
integer.
• Conversion is said to be Explicit if the programmer writes something to do the
Conversion.
• Tasks:
– has to allow “Indexing is only on an array”

– has to check the range of data types used


– INTEGER (int) has a range of -32,768 to +32767

– FLOAT has a range of 1.2E-38 to 3.4E+38.


How to design a Type Checker?

 When designing a type checker for a compiler, here’s the process:

 Identify the types that are available in the language

 Identify the language constructs that have types associated with them.

 Identify the semantic rules for the language

 A language is considered strongly- typed if each and every type error

is detected during compilation.


Type Checking Preventions

 Application of a function to wrong number of arguments

 Application of integer functions to floats

 Use of undeclared variables in expressions

 Functions that do not return values,

 Division by zero

 Array indices out of bounds.


Two Types of Type Checking

1) Static Type Checking

2) Dynamic Type Checking


Static Type Checking
 Static type checking is defined as type checking performed at
compile-time.
 Check the correctness of the program before it execution.
 Need to verify that the source program follows the syntactic and
semantic conventions
 Obtained via declarations and stored in a master symbol table.
 After this information is collected, the types involved in each
operation are checked.
 Languages like Pascal and C have static type checking.
• 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
• Type Check: operator applied to an incompatible operand.
e.g. error if array variable is added with function variable: 2+2.5
= Error
• Flow of Control: statements that results in a branch need to be
terminated correctly. While() {
Breack;
} error
• Uniqueness Check: Object must be defined exactly once for some
scenarios
int a = 2; a should be unique
• 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

 Input and output of type checker is verify syntax tree


 This carried out in semantic phase
 Type checking information added with the semantic rules.
 Basic type checker is performed
Type System

 Type system is a collection of rules applied on Type


expression
 Designing of type checker vary from language to language
E.G : 2+2 = 4
 Each expression has a type associated
 Basic types: Boolean, Int , Char

 Constructed types : Pointer, Array , Structures


Type Expression

 The type of a language construct is denoted by a type

expression.

• A type expression can be:

– A basic type (also called primitive types)

• a primitive data type such as integer, real, char, boolean,

– A type name

• a name can be used to denote a type expression.


Type checking Expression
Questions

1. Explain the contents of Symbol Table.

2. Describe the data structures for Symbol table.

3. Why we need type checking in compiler?


Error Handler

• Errors - all errors should be


– detected

– detected correctly

– detected as soon as possible

– reported at the appropriate place and in a helpful manner

• Purpose
– report errors

– “error recovery” - Be able to proceed with processing


Error Handler

Note: Errors can occur in each phase


– misspelled token
– wrong syntax
– improper procedure call
– statements that cannot be reached

You might also like