Professional Documents
Culture Documents
Chapter 5
Chapter 5
Type checking
1
Outline
• Type checking
• Static versus Dynamic Checking
• Static checking
• Type systems
• Type Expression
• Specification of a simple type checker
• A Simple Language example
• Structural Equivalence of Type Expressions
• Names for Type Expressions
• Type Conversions or casting
2
Type checking
• The compiler must check that the source program follows both
the syntactic and semantic conventions of the source language.
• Semantic Checks
– Static – done during compilation
– Dynamic – done during run-time
• This checking is called static checking (to distinguish it from
dynamic checking executed during execution of the target
program).
• Static checking ensures that certain kind of errors will be
detected and reported.
3
Position of type checker
Syntax Parse
Token Parser tree Type tree IC gen
stream checker
IC code
5
Why static checking?
• Parsing finds syntactic errors
– An input that can't be derived from the grammar
10
Static checking
Typical examples of static checking are:
– Type checks
– Flow-of-control checks
– Uniqueness checks…
Type checks:
• a compiler should report an error if an operator is applied to an
incompatible operand.
Example: if an array variable and a function variable are added
together.
int a, c[10],d;
d = c + d;
11
Type checking
Flow of control check:
• Statements that cause flow of control to leave a construct must have some place
to which to transfer the flow of control.
• Example: a break statement in C causes control to leave the smallest enclosing
while, for, or switch statement.
• An error occurs if such an enclosing statement does not exist.
for(i=0;i<attempts;i++)
{
cout<<“Please enter your
password:”;
Cin>>password;
if(verify(password))
break;//OK
cout<<“incorrect\n”;
} 12
Flow of control example…
foo()
{
foo()
…
{…
break;//ERROR
switch(a)
}
{ case 0:
…
break;// OK
foo()
case 1:
{…
…
while (n)
}
{…
}
if (i>10)
break;// OK
}
}
13
Type checking…
Uniqueness check:
• Variables or objects must be defined exactly once.
• Example: in most PL, an identifier must be declared uniquely.
16
Type systems
• A type system is a collection of rules for assigning type
expressions to the parts of a program.
17
Type expressions
• The type of a language construct is 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 followings are type expressions:
– A basic type is a type expression:
Example: boolean, char, integer, and real
- A special basic type, type_error, will signal an error during
type checking.
- A basic type void denoting “the absence of a value” allows
statement to be checked.
18
Type expressions…
• The following are type constructors:
• Arrays: if I in an index set and T is a type expression, then
Array (I, T) is a TE:
In java, int[] A = new int[10];
In C++ int A[10];
In pascal var A: array [1…10] of integer;
associates the type expression array(1..10, integer) with A.
19
Type expressions…
20
Type expressions…
• Functions: 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.
• For example:
– mod function has domain type int x int, a pair of
integers and range type int, thus mod has
int x int int
• The TE corresponding to the Pascal declaration:
function f (a, b : char): ^Integer:
char x char pointer (integer)
21
Type expressions…
• A convenient way to represent a type expression is to use a graph (tree or DAG).
• For example, the type expression corresponding to the above function
declaration can be represented with the tree shown below:
TE: char x char pointer (integer)
X pointer X pointer
char char
integer char integer
Tree DAG 22
Example: tree and DGA
int *foo(char *, char *)
DAG
TREE
foo foo
23
Type Expression (summary)
• The type of a language construct is denoted by a type expression.
• A type expression can be:
– A basic type
• a primitive data type such as integer, real, char, boolean, …
• type-error to signal a type error
• void : no type
– A type name
• a name can be used to denote a type expression.
27
Specification of a simple type checker
Translation schemes for Declarations
P D;E|D;S
DD;D
D id : T {addtype (id.entry, T. Type)}
T boolean { T.type:= boolean}
T char {T.type : = char}
T integer {T.type : = integer}
T ^T1 {T.type := pointer (T1.type)}
T array [ num ] of T1 {T.type := array (1…num.val, T1.type)}
28
Specification of a simple type checker…
29
Specification of a simple type checker…
Translation scheme for type checking of Expressions:
33
Specification of a simple type checker…
• Functions:
T→ TT EE(E)
Type constructs
35
Specification of a simple type checker…
36
Exercises
• For the translation scheme of a simple type checker
presented above, draw the decorated parse tree for:
37
P
E
;
addtype(A, array(1…10, pointer(array(1…5,char)))
D
T. type= pointer(array(1…5,char))
array [ 1…10 ] of
A ^ T1. type= array(1…5,char)
T.type=char
array [ 1…10 ] of
char 38
P
addtype(id.entry, T.type) E
;
D
D
T. type=array(1…10,T.type)
id.entry=A : ; id.entry=B :
T.type=
T. type=pointer(T1.type) char
array [ 1…10 ] of char
A ^ T1. type=array(1…5,T.type)
T.type=char
array [ 1…10 ] of
char 39
Exercises
• For the translation scheme of a simple type checker
presented above, draw the decorated parse tree for:
a: array [1…5] of integer;
b: integer;
c: char
b=a[1];
if b = a[10] then
b = b + 1;
c = a[5];
40
Equivalence of Types
• An “equal operator” is not defined except between basic
types.
• i.e doesn’t work for type name and constructed type
expressions.
• Hence an “equivalent” operator is appropriate.
• Natural notion of equivalence is Structural equivalence.
• But there are two types of equivalence:
1 - Structural Equivalence
2 - Name Equivalence
41
Structural Equivalence
• Two type expressions are structurally equivalent iff:
– They have the same basic types
– They can be formed by applying same constructor to
structural equivalence type
Example: char is equivalent only to char.
pointer(char) to pointer(char)
Note:
Two type expressions are name equivalent iff they are
identical.
42
Structural Equivalence of Type
Expressions
• How do we know that two type expressions are equal?
• As long as type expressions are built from basic types (no type names),
we may use structural equivalence between two type expressions
43
Names for Type Expressions
• In some programming languages, we give a name to a type
expression, and we use that name as a type expression afterwards.
44
Name Equivalence example
Example:
type ptr = ^ integer
var A , B : ptr
C : ^ integer
D, E : ^ integer
45
Type Conversions
x+y what is the type of this expression (int or real)?
46
Type Conversions…
• 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 need to implicitly converted.
inttoreal y,t1
real+ t1,x,t2
47
Type conversion
• Conversion from one type to another is said to be implicit it if is
done automatically by the compiler, and is also called
coercion.
48