80 likes | 259 Views
Review: Why symbol table? Given an example of the attributes in a symbol table. How to deal with nested scope? How to create the symbol table? Grammar: P->D D ->D; D D->id : T D->proc id; D; S T ->integer | real | array[num] of T | ^T. Type checking
E N D
Review: • Why symbol table? Given an example of the attributes in a symbol table. • How to deal with nested scope? • How to create the symbol table? • Grammar: P->D D ->D; D D->id : T D->proc id; D; S T ->integer | real | array[num] of T | ^T
Type checking • make sure operations can be performed on operands. • Make sure the types of actual arguments matches the types of formal arguments. • Need a type system to do the job. • A type system is a collection of rules for assigning type expression to the various parts of a program. • The type system for a practical language can be complicated. • Type checking of expressions: P->D;E D->D;D | id : T T->char | integer | array[num] of T | ^T E->literal | num | id | E mod E | E[E] | E^
P->D;E D->D;D D->id : T {enter(id.val, T.type);} T->char {T.type = char;} | integer {T.type = integer;} | array[num] of T1 {T.type = array(num.val, T1.type);} | ^T1 {T.type = pointer(T1.type);} E->literal {E.type = char;} | num {E.type = integer;} | id {E.type = lookup(id.val);} | E1 mod E2 {if E1.type == integer && E2.type ==integer then E.type = integer; else E.type =error;} | E1[E2] {if E1.type == array(s, t) && E2.type == integer then E.type = t; else E.type =error;} | E1^ {if E1.type == pointer(t) then E.type = t; else E.type =error;}
Type checking for statements S -> id := E S -> if E then S1 S ->while E do S1 S->S1;S2
Type checking for statements S -> id := E {if id.type == E.type then S.type = void; else S.type = error;} S -> if E then S1 {if E.type == boolean then S.type = S1.type; else S.type = error;} S ->while E do S1 { if E.type == boolean then S.type = S1.type; else S.type = error;} S->S1;S2 {if S1.type == void and S2.type == void then S.type = void; else S.type = type_error; }
Type checking for functions: T->T1->T2 /* function declaration */ {T.type = T1.type ->T2.type} E->E1(E2) /* function call */ {if E1.type == t1.type->t2.type && E2.type == t1.type then T.type = t2.type; else T.type - error; }
Equivalence of type expressions • Name equivalence - each type with different name is different • structural equivalence - names are replaced by the type expressions they define • Example: type link = ^cell; var next : link last : link p: ^cell • Is structural equivalence good for C++?
Other things related to type. • coercion: implicit type conversion: • e.g. double x; ….x = 1; • overloading: • a function or operator can represent different operations in different contexts. • polymorphic functions: • the body of a polymorphic function can be executed with arguments of different types.