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

Chapter 5 Symbol Tables and Type Checking

This document outlines a course on principles of compiler design and covers several topics including lexical analysis, syntax analysis, symbol tables, type checking, intermediate code generation, and code optimization. It then provides details on type systems, type expressions, type constructors, and specifying a simple type checker. Key aspects of type checking covered include static checking, type expressions, type systems, type errors, and graph representations of type expressions. The document gives examples of declarations and expressions that could be checked by a simple type checker.

Uploaded by

biruk tsegaye
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
108 views

Chapter 5 Symbol Tables and Type Checking

This document outlines a course on principles of compiler design and covers several topics including lexical analysis, syntax analysis, symbol tables, type checking, intermediate code generation, and code optimization. It then provides details on type systems, type expressions, type constructors, and specifying a simple type checker. Key aspects of type checking covered include static checking, type expressions, type systems, type errors, and graph representations of type expressions. The document gives examples of declarations and expressions that could be checked by a simple type checker.

Uploaded by

biruk tsegaye
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

Principles of Compiler Design

Course Outline
1. Introduction
2. Lexical Analysis
3. Syntax Analysis
4. Syntax Directed Translation
5. Symbol Tables & Type Checking
6. Intermediate Code Generation
7. Run Time Environment
8. Code Generation
9. Code Optimization
1
By: Yohannes Taye Jemberie
Chapter 5: Symbol Tables & Type Checking
Type and Issues in typing
Static Checking
Type Checking
Type Systems
Type Expressions
Type Constructors
Specification of a Simple Type Checker
Equivalence of types
Type Conversions
Types
• Type =
– a set of values
– operations that are allowed on these values.
• Why?
– To generate better code, with less runtime
overhead
– To avoid runtime errors

By: Yohannes Taye Jemberie 3


Type
• Type system for a programming language:
– set of types AND
– rules that specify how a typed program is allowed to
behave
• Actions
– Type checking
• Given an operation and an operand of some type,
determine whether the operation is allowed on that
operand

By: Yohannes Taye Jemberie 4


– Type inference
• Given the type of operands, determine
– the meaning of the operation
– the type of the operation
• OR, without variable declarations, infer type from the
way the variable is used.

By: Yohannes Taye Jemberie 5


Issues in typing
• Does the language have a type system?
– Untyped languages (e.g. assembly) have no type system at all
• When is typing performed?
– Static typing: At compile time
– Dynamic typing: At runtime
• How strictly are the rules enforced?
– Strongly typed: No exceptions
– Weakly typed: With well-defined exceptions
• Type equivalence & subtyping
– When are two types equivalent?
• What does "equivalent" mean anyway?
– When can one type replace another?

By: Yohannes Taye Jemberie 6


Static Checking
• The compiler must check if the source
program follows semantic conventions of the
source language.
• This is called static checking (to distinguish it
from dynamic checking executed during
execution of the program).
• Static checking ensures that certain kind of
errors are detected and reported.

By: Yohannes Taye Jemberie 7


Static Checking (cont’d)
• The following are examples of static checks:
– Type checks
• compatibility checking between operands
– (e.g., a[i] + a[i+1])
– Flow control check
Examples:
• A break instruction in C that is not in an inclosing statement
• A return in Pascal that is not in a function’s body

By: Yohannes Taye Jemberie 8


– uniqueness checks
• the situation in which an object must be defined exactly once
– e.g.,
» an identifier in Pascal

– Name related checks


• the situation in which the same name must appear more than one
times

Example:
• In Ada loops can have names. However, the same name should be
used to start and end the loop.

By: Yohannes Taye Jemberie 9


Type Checking
• Type Checking ?
– The processes of identifying errors in a program
based on explicitly or implicitly stated type
information
• Static (Compile time) vs. Dynamic (Run-time)
• Strongly typed language vs. weakly type language

• Kind Checking
– The processes of identifying errors in a program
based on stated kind information
• Variables
• Functions/procedures

By: Yohannes Taye Jemberie 10


• A type checker verifies that the type construct
matches that expected by its context.
– For example, a type checker should verify that the
type value assigned to a variable is compatible
with the type of the variable.
For instance, mod (%) expects two integer
operands

By: Yohannes Taye Jemberie 11


Type Checking

TYPE CHECKING is the main activity in semantic


analysis.
Goal: calculate and ensure consistency of the type
of every expression in a program
If there are type errors, we need to notify the user.
Otherwise, we need the type information to
generate code that is correct.

By: Yohannes12
Taye Jemberie
Type Systems
• Every language has a set of types and rules for
assigning types to language constructs.
• In almost all languages, types are either basic
or constructed.
• Two types
– Basic types
– Constructed types

By: Yohannes Taye Jemberie 13


Type Systems:
• Basic types
– Atomic types with no internal structure
• e.g.,
– Boolean (AND/OR/XOR operations)
– Characters (STRING OPERATIOSNS)
– Numbers ( *, /, -, + operators)
– Void (null value)

By: Yohannes14
Taye Jemberie
• Constructed types (user-defined types)
– types that are constructed from basic types and
other constructed types
– Var A: Array [1..10] of integer

By: Yohannes Taye Jemberie 15


Type Expressions
• The type of a language construct will be
denoted by a type expression.
• A type expression is either a basic type or
formed by applying an operator called type
constructor to the type expression.
• The type expression may be obtained by using
the following definition.

By: Yohannes Taye Jemberie 16


Type Expressions (cont’d)
• In this chapter the following are type expressions:
– A basic type is a type expression
Ex. Integer, boolean, char, …
– A type name is a type expression
– A type constructor applied to a type expression is a type
expression.
• The type checker uses two more basic types:
– Void  indicates absence of type error
– Type_error  indicates the presence of a type error

By: Yohannes Taye Jemberie 17


Type Constructors
• The following are type constructors:
– Arrays: if I in an index set and T is a type expression, then
Array (I, T) is a type expression
Ex. Array([1..10], integer) is a type expression
– Products: if T1 and T2 are type expressions, the Cartesian
product T1 x T2 is a type expression. X is left associative.
Ex. In function parameters f(True, 5) = Boolean X int

By: Yohannes Taye Jemberie 18


• Records: a record is a special kind of product in which the
fields have names
Record( (field1 X T1)X(field2 X T2)X… )

Ex. struct{ int age; float cgpa; }


record( ( age X integer ) X ( cgpa X float ) )

– Pointers: if T is a type exrpession then Pointer (T) is a type


expression

Ex. Pointer( Integer )

By: Yohannes Taye Jemberie 19


Type Constructors (cont’d)
– Functions:Functions in a programming language
map a domain type D to a range type R.
– the TE of a function has the form
D  R where D is the type expression of the
parameters and R is the TE of the returned value
Ex. int * f (char a, char b)
char X char  Pointer( Integer )

By: Yohannes Taye Jemberie 20


Graph Representation
• A convenient way to represent a type expression is to
use a graph (tree or Graph).
• For example, the type expression corresponding to
the above function declaration is shown below:

X Pointer

char char Integer

char X char  Pointer( Integer )


By: Yohannes Taye Jemberie 21
Type System
• A type system is a collection of rules
implemented by the type checker for
assigning type expressions to the various parts
of a program.
• Different type systems may be used by
different compilers for the same language.
• For example, some compilers implement
stricter rules than others. Lint, for instance,
has much more detailed type system than the
C compiler itself.
By: Yohannes Taye Jemberie 22
Errors
• At the very least, the compiler must report the
nature and location of errors.

• It is also desirable that the type checker


recovers from errors and continues parsing
the rest of the input.

By: Yohannes Taye Jemberie 23


Specification of a Simple Type Checker
• Declarations
The purpose of the semantic actions is to determine
the type expression of a variable and add the type
expression in the symbol table
PD;E
DD;D
D  id : T {addtype (id.lexeme, T.Type)}
T  char {T.type := char}
T  integer {T.type := integer}
T  ^T1 {T.type := pointer (T1.type)}
T  array [num1..num2] of T1
{T.type := array ([num1.val..num2.val], T1.type)}
By: Yohannes Taye Jemberie 24
Simple Type Checker (cont’d)
• Example
Consider the following declarations
A : array[1..10] of ^ array[1..5] of char;
B : char;

Draw the decorated parse tree for the given


declaration.

By: Yohannes Taye Jemberie 25


Simple Type Checker (cont’d)

• Expressions
E  literal
E  num
E  id
E  E1 mod E2
E  E1[E2]
E  ^E1
By: Yohannes Taye Jemberie 26
Simple Type Checker (cont’d)
• Expressions
E  literal {E.type := char}
E  num {E.type := integer}
E  id {E.type := lookup (id.lexeme)}
E  E1 mod E2 {E.type := if E1.type = integer and E2.type := integer then
Integer
Else
Type_error
}
E  E1 [E2] {
E.type := if E2.type = integer and E1.type := array (s, t) then
t
Else
Type_error
}
E  ^E1 { E.type := if E2.type = pointer (t) then
t
Else
Type_error }
By: Yohannes Taye Jemberie 27
Simple Type Checker (cont’d)
• Statements

S  id := E
S  if E then S1
S  while E do S1
S  S1 ; S2

By: Yohannes Taye Jemberie 28


Simple Type Checker (cont’d)
• Statements
S  id := E {S.type := if id.type = E.type then
void
Else
Type_error}
S  if E then S1 {S.type := if E.type = Boolean then
S1.type
Else
Type_error}
S  while E do S1 {S.type := if E.type = Boolean then
S1.type
Else
Type_error}
S  S1 ; S 2 {S.type := if S1.type = void and S2.type = void then
void
Else
Type_error}
By: Yohannes Taye Jemberie 29
Simple Type Checker (cont’d)
The following example gives a type checking
system for function calls:
E  E1 (E2)
{ E.type := if E2.type = s and E1.type = s  t then
t
Else
Type_error
}

By: Yohannes Taye Jemberie 30


Equivalence of types
• Types MUST be checked for compatibility and equivalent
• Examples include
– Assignment statements
– Formal and actual parameters of procedure/function calls
• Compilers must detect and report any situation that
violates the type incompatibility
– e.g., found integers but compilers expected real
Type checkers need to ask questions like:
– “if E1.type == E2.type, then …”
What does it mean for two type expressions to be equal?

By: Yohannes Taye Jemberie 31


Equivalence of types (cont’d)
• There are two kinds of type equivalence
– Name equivalence (used for almost all languages)
– Structural equivalence (difficult to implement)

• A natural notion of equivalence is structural equivalence:

By: Yohannes Taye Jemberie 32


Name equivalence
• Two types are name equivalent if they have
the SAME NAME
• e.g.
– Type t1 = Array [1..10] of integer;
– Type t2 = Array [1..10] of integer;
– are they name equivalent? No because they have
distinct type definitions (names)

By: Yohannes Taye Jemberie 33


Structural equivalence
• two type expressions are structurally equivalent if and only if
they are the same basic type or are formed by applying the
same constructor to structurally equivalent types.
• For example,
– integer is equivalent only to integer
– pointer (integer) is structurally equivalent to pointer (integer).
• Some relaxing rules are very often added to this notion of
equivalence.
– For example, when arrays are passed as parameter, the array
boundaries of the effective parameters may not be the same as those
of the formal parameters.

By: Yohannes Taye Jemberie 34


Equivalence of types (…cont’d)
• In some languages, types may be given names. For
example in Pascal we can define:
Type:
Ptr = ^Integer;
Var
A : Ptr;
B : Ptr;
C : ^Integer;
D, E : ^Integer;
• Have the variables A, B, C, D, E the same type?
Surprisingly, the answer varies from implementation
to implementation.
By: Yohannes Taye Jemberie 35
Type Conversions
• Suppose we encounter an expression x+i where x has
type float and i has type int.
• CPU instructions for addition could take EITHER float
OR int as operands, but not a mix.
• This means the compiler must sometimes convert
the operands of arithmetic expressions to ensure
that operands are consistent with operators.

By: Yohannes Taye Jemberie 36


• However, most languages accept such
expressions to be used; the compiler will be in
charge of converting one of the operand into
the type of the other.
• The type checker can be used to insert these
conversion operations into the intermediate
representation of the source program.
• For example, an operator inttoreal may be
inserted whenever an operand needs to be
implicitly converted.

By: Yohannes Taye Jemberie 37


Type coercion
• If type conversion is done by the compiler
without the programmer requesting it, it is
called IMPLICIT conversion or type COERCION.
• EXPLICIT conversions are those that the
programmer specifices, e.g.
x = (int)y * 2;

By: Yohannes Taye Jemberie 38


Type Conversions (…cont’d)
• Explicit – done by the programmer
Ex. float pi = 3.14;
int x = (int)pi;
• Implicit – done by the compiler
Ex. int x = 10;
float y = x;

By: Yohannes Taye Jemberie 39

You might also like