Compilerconstructie najaar 2019 http://www.liacs.leidenuniv.nl/~vlietrvan1/coco/ Rudy van Vliet kamer 140 Snellius, tel. 071-527 2876 rvvliet(at)liacs(dot)nl college 5, vrijdag 11 oktober 2019 Syntax DAG / Types 1
The Phases of a Compiler (from lecture 1) Token stream: � id , 1 � � = � � id , 2 � � + � � id , 3 � �∗� � 60 � Syntax Analyser (parser) Parse tree / syntax tree: = stmt ✟ ❍❍❍❍ ✟ ✟ � ❅ ✟ ❍ � ❅ � ❅ � id , 1 � + ✟ ❍❍❍❍ = expr id ✟ ✟ ✟ ❍ ✑ ◗◗◗ ✑ � id , 2 � ∗ ✑ ✟ ❍❍❍ ✑ ◗ ✟ ✟ ✟ ❍ expr + term � id , 3 � � num , 60 � ★ ❝ ★ ❝ ★ ❝ ∗ term term factor num factor factor id id 2
6.1 Variants of Syntax Trees Directed Acyclic Graphs for Expressions a + a ∗ ( b − c ) + ( b − c ) ∗ d Syntax tree vs DAG. . . Pros DAG. . . 3
Producing Syntax Trees or DAG’s Production Semantic Rules E. node = getNode ( ′ + ′ , E 1 . node , T. node ) 1) E → E 1 + T E. node = getNode ( ′ − ′ , E 1 . node , T. node ) 2) E → E 1 − T 3) E. node = T. node E → T T. node = getNode ( ′ ∗ ′ , T 1 . node , F. node ) 4) T → T 1 ∗ F T. node = getNode ( ′ / ′ , T 1 . node , F. node ) 5) T → T 1 /F 6) T → F T. node = F. node 7) F → ( E ) F. node = E. node 8) F → id F. node = getLeaf ( id , id . entry ) 9) F → num F. node = getLeaf ( num , num . val ) Parse tree a + a ∗ ( b − c ) + ( b − c ) ∗ d . . . 1) p 1 = getLeaf ( id , entry - a ) . . . 4
Producing Syntax Trees or DAG’s 1) p 1 = getLeaf ( id , entry - a ) 2) p 2 = getLeaf ( id , entry - a ) = p 1 3) p 3 = getLeaf ( id , entry - b ) 4) p 4 = getLeaf ( id , entry - c ) p 5 = getNode ( ′ − ′ , p 3 , p 4 ) 5) p 6 = getNode ( ′ ∗ ′ , p 2 , p 5 ) = getNode ( ′ ∗ ′ , p 1 , p 5 ) 6) p 7 = getNode ( ′ + ′ , p 1 , p 6 ) 7) 8) p 8 = getLeaf ( id , entry - b ) = p 3 9) p 9 = getLeaf ( id , entry - c ) = p 4 p 10 = getNode ( ′ − ′ , p 8 , p 9 ) = getNode ( ′ − ′ , p 3 , p 4 ) = p 5 10) 11) p 11 = getLeaf ( id , entry - d ) p 12 = getNode ( ′ ∗ ′ , p 10 , p 11 ) = getNode ( ′ ∗ ′ , p 5 , p 11 ) 12) p 13 = getNode ( ′ + ′ , p 7 , p 12 ) 13) 5
6.1.2 The Value-Number Method An implementation of DAG DAG for i = i + 10 ✲ to entry = 1 id for i ❅ num 2 10 ❅ ❅ + + 3 1 2 � ❅ = 4 1 3 � ❅ � ❅ · · · i 10 5 • Search array for (existing) node • Use hash table 6
Static Checking • Type checks: Verify that type of a construct matches the expected one • Flow-of-control checks: Example: break-statement must be enclosed in while-, for- or switch-statement • . . . 7
6.3 Types and Declarations Types can be used for • Type checking • Translation Type information useful – to determine storage needed – to calculate address of array element – to insert explicit type conversions – to choose right version of operator – . . . 8
6.3 Types and Declarations • Type expressions • Function declaration • Type equivalence • Declarations of variables • Storage layout • Sequences of declarations • Records and classes 9
6.3.1 Type Expressions Types have structure Example: array type int[2][3] array (2 , array (3 , integer )) array ✟ ❍❍❍❍ ✟ ✟ ✟ ❍ ✟ ✟ array 2 ✟ ❍❍❍❍ ✟ ✟ ✟ ❍ ✟ ✟ 3 integer 10
Type Expressions • Basic types: boolean, char, integer, float, void • Type names: typedefs in C, class names in C++ • Type constructors: – array – record: data structure with named fields – → for function types: s → t – Cartesian product × : s × t – . . . 11
6.3 Types and Declarations • Type expressions • Function declaration • Type equivalence • Declarations of variables • Storage layout • Sequences of declarations • Records and classes 12
CFG for Function Declaration F → B id ( OptL ) int B → float | OptL → ǫ | Ps → P Ps | Ps , P P → T id 13
CFG for Function Declaration F → B id ( OptL ) { F. type = → ( OptL . type , B. type ); } B → int { B. type = integer ; } | float { B. type = float ; } → ǫ { OptL . type = void ; } OptL | { OptL . type = Ps . type ; } Ps → P { Ps . type = P. type ; } Ps | Ps 1 , P { Ps . type = × ( Ps 1 . type , P. type ); } T id P. type = T. type ; } P → { 14
6.3 Types and Declarations • Type expressions • Function declaration • Type equivalence • Declarations of variables • Storage layout • Sequences of declarations • Records and classes 15
6.3.2 Type Equivalence S → id = E { if ( id. type == E. type ) then . . . ; else . . . } When are type expressions equivalent? • Structural equivalence • Name equivalence • Use graph representation of type expressions to check equiv- alence – Leaves for basic types and type names – Interior nodes for type constructors – Cycles in case of recursively defined types. . . 16
Structural Equivalence • Same basic type: integer is equivalent to integer • Formed by applying same constructor to structurally equiva- lent types pointer ( integer ) is equivalent to pointer ( integer ) • One is type name of other type link = ^cell; var next : link; last : link; p : ^cell; q, r : ^cell; Name equivalence ... 17
6.3 Types and Declarations • Type expressions • Function declaration • Type equivalence • Declarations of variables • Storage layout • Sequences of declarations • Records and classes 18
6.3.3 Declarations • We need symbol tables to record global and local declarations in procedures, blocks, and structs to resolve names • Symbol table contains type and relative adress of names Example: T id ; D D → | ǫ record ′ { ′ D ′ } ′ T → B C | B → int | float C → ǫ | [ num ] C 19
Structure of Types (Example) record ′ { ′ D ′ } ′ T → B C | int float B → | [ num ] C C → ǫ | int[2][3] T ✏ PPPPPPPPPPP ✏ ✏ ✏ ✏ ✏ ✏ ✏ ✏ ✏ ✏ ✏ P B C ✟ ❍❍❍❍❍❍ ✟ ✟ ✟ ✟ ✟ ❍ [ 2 ] int C ✟ ❍❍❍❍❍❍ ✟ ✟ ✟ ✟ ✟ ❍ [ 3 ] C ǫ array ✟ ❍❍❍❍ ✟ ✟ ✟ ❍ ✟ ✟ array 2 ✟ ❍❍❍❍ ✟ ✟ ✟ ❍ ✟ ✟ 3 integer Interpretation C . . . 20
6.3 Types and Declarations • Type expressions • Function declaration • Type equivalence • Declarations of variables • Storage layout • Sequences of declarations • Records and classes 21
6.3.4 Storage Layout for Local Names • Storage comes in blocks of contiguous bytes • Width of type is number of bytes needed T → B { t = B. type ; w = B. width ; } C { T. type = C. type ; T. width = C. width ; } B → int { B. type = integer ; B. width = 4; } float B. type = float ; B. width = 8; } B → { C. type = t ; C. width = w ; } C → ǫ { [ num ] C 1 C. type = array ( num . value , C 1 . type ); C → { C. width = num . value × C 1 . width ; } 22
Types and Their Widths (Example) t = B. type ; w = B. width ; } T → B { C { T. type = C. type ; T. width = C. width ; } B → int { B. type = integer ; B. width = 4; } B → float { B. type = float ; B. width = 8; } C → ǫ { C. type = t ; C. width = w ; } C → [ num ] C 1 { C. type = array ( num . value , C 1 . type ); C. width = num . value × C 1 . width ; } type = array (2 , array (3 , integer )) ❍ ❨ width =24 ❍ . .................. T . . ❍ . . ❍ . . . . . . . type = array (2 , array (3 , integer )) ③ . . t . . . . ❨ ❍ width =24 ❍ B type = integer . C ............ w ❍ . . . ❍ . . . . width =4 . . . type = array (3 , integer ) . . . width =12 ❍ ❨ ❍ [ 2 ] int C . ............ ❍ . . ❍ . . . . . type = integer . . width =4 [ 3 ] C . . ✸ . . ǫ 23
6.3 Types and Declarations • Type expressions • Function declaration • Type equivalence • Declarations of variables • Storage layout • Sequences of declarations • Records and classes 24
6.3.5 Sequences of Declarations T id ; D D → | ǫ Use offset as next available (relative) address P → { offset = 0; } D D → T id ; { top . put ( id . lexeme , T. type , offset ); offset = offset + T. width ; } D 1 D → ǫ Example: int x ; float y ; 25
6.3 Types and Declarations • Type expressions • Function declaration • Type equivalence • Declarations of variables • Storage layout • Sequences of declarations • Records and classes 26
6.3.6 Fields in Records and Classes Example float x; record { float x; float y; } p; record { int tag; float x; float y; } q; x = p.x + q.x; D → T id ; D | ǫ record ′ { ′ D ′ } ′ T → • Fields are specified by sequence of declarations – Field names within record must be distinct – Relative address for field is relative to data area for that record 27
Fields in Records and Classes Stored in separate symbol table t Record type has form record ( t ) record ′ { ′ Env . push ( top ); T → { top = new Env (); Stack . push ( offset ); offset = 0; } D ′ } ′ { T. type = record ( top ); T. width = offset ; top = Env . pop (); offset = Stack . pop (); } 28
Recommend
More recommend