Chapter 5:Semantic Analysis

Type checking for expressions

E literal E.type = char
E num E.type = integer
E id E.type = lookup(id.entry)
E E1 mod E2 E.type = if E 1 .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 E1 .type==pointer(t)
 
then t
 
else type_error

The following rules are used to type-check expressions, where the synthesized attribute type for E gives the type expression assigned by the type system to the expression generated by E.

The following semantic rules say that constants represented by the tokens literal and num have type char and integer , respectively:

E -> literal { E.type := char }

E -> num { E.type := integer }

. The function lookup ( e ) is used to fetch the type saved in the symbol-table entry pointed to by e. When an identifier appears in an expression, its declared type is fetched and assigned to the attribute type:

E -> id { E.type := lookup ( id . entry ) }

. According to the following rule, the expression formed by applying the mod operator to two sub-expressions of type integer has type integer ; otherwise, its type is type_error .

E -> E1 mod E2 { E.type := if E1.type == integer and E2.type == integer then integer else type_error }

In an array reference E1 [ E2 ], the index expression E2 must have type integer , inwhich case the result is the element type t obtained from the type array ( s, t ) of E1.

E -> E1 [ E2 ] { E.type := if E2.type == integer and E1.type == array ( s, t ) then t else type_error }

. Within expressions, the postfix operator yields the object pointed to by its operand.The type of E is the type t of the object pointed to by the pointer E:

E E1 { E.type := if E1.type == pointer ( t ) then t else type_error }