Sie sind auf Seite 1von 4

Course Overview

PART I: overview material


1 2 3 4 5 6 7 8 9 Introduction Language processors (tombstone diagrams, bootstrapping) Architecture of a compiler Syntax analysis Contextual analysis Runtime organization Code generation Interpretation Review
1

Chapter 3 Compilation
So far we have treated language processors (including compilers) as black boxes GOAL this lecture: A first look "inside the box": how to build compilers. Different phases and their relationships.

PART II: inside a compiler

PART III: conclusion

Compilation (Chapter 3)

Compilation (Chapter 3)

The Major Phases of a Compiler


Source Program Syntax Analysis Abstract Syntax Tree Contextual Analysis Error Reports Error Reports

Different Phases of a Compiler


The different phases can be seen as different transformation steps to transform source code into object code. The different phases correspond roughly to the different parts of the language specification: Syntax analysis <-> Syntax Contextual analysis <-> Contextual constraints Code generation <-> Semantics

Decorated Abstract Syntax Tree Code Generation Object Code


Compilation (Chapter 3)
3

Compilation (Chapter 3)

Example Program
We now look at each of the three different phases in a little more detail. We look at each of the steps in transforming an example Triangle program into TAM code.
! This program is useless except for ! This program is useless except for ! illustration ! illustration let var n: integer; let var n: integer; var c: char var c: char in begin in begin c := &; c := &; n := n+1 n := n+1 end end Source Program Syntax Analysis

1) Syntax Analysis

Error Reports

Abstract Syntax Tree

Note: Not all compilers construct an Note: Not all compilers construct an explicit representation of an AST. (e.g. on explicit representation of an AST. (e.g. on a single pass compiler generally no need a single pass compiler generally no need to construct an AST) to construct an AST)

Compilation (Chapter 3)

Compilation (Chapter 3)

1) Syntax Analysis --> AST


Program LetCommand

2) Contextual Analysis --> Decorated AST


Abstract Syntax Tree Contextual Analysis Error Reports

SequentialCommand SequentialDeclaration AssignCommand VarDecl SimpleT Ident Ident Ident VarDecl Char.Expr AssignCommand

Decorated Abstract Syntax Tree Contextual analysis:

BinaryExpr VNameExp Int.Expr SimpleV Ident Op Int.Lit

SimpleT SimpleV Ident Ident Char.Lit Ident

Integer

Char

&

1
7

Scope checking: verify that all applied occurrences of identifiers are declared Type checking: verify that all operations in the program are used according to their type rules. Annotate AST: Applied identifier occurrences => declaration Expressions => Type
Compilation (Chapter 3)
8

Compilation (Chapter 3)

2) Contextual Analysis --> Decorated AST


Program LetCommand
SequentialCommand SequentialDeclaration

Contextual Analysis
Finds scope and type errors.
Example 1:
AssignCommand

***TYPE ERROR (incompatible types in AssignCommand)

:char :int
AssignCommand AssignCommand SimpleV BinaryExpr :int

Example 2: foo not found


SimpleV Ident

:int
VarDecl SimpleT Ident Ident Ident VarDecl Char.Expr

:char

VNameExp Int.Expr

:int
SimpleV

:int

SimpleT SimpleV Ident

:char & n

:int + 1
9

Ident Char.Lit Ident

Ident Op Int.Lit

***SCOPE ERROR (undeclared variable foo)

n Integer
Compilation (Chapter 3)

c Char

foo
Compilation (Chapter 3)
10

3) Code Generation
Decorated Abstract Syntax Tree Code Generation Object Code

3) Code Generation
let var n: integer; var c: char in begin c := &; n := n+1 end PUSH 2 LOADL 38 STORE 1[SB] LOAD 0[SB] LOADL 1 CALL add STORE 0[SB] POP 2 HALT

Assumes that program has been thoroughly checked and is well formed (scope & type rules) Takes into account semantics of the source language as well as the target language. Transforms source program into target code.
Compilation (Chapter 3)
11

VarDecl address = 0[SB] SimpleT Ident Ident

n Integer
Compilation (Chapter 3)
12

Compiler Passes
A pass is a complete traversal of the source program, or a complete traversal of some internal representation of the source program (such as an AST). A pass can correspond to a phase but it does not have to! Sometimes a single pass corresponds to several phases that are interleaved in time. What and how many passes a compiler does over the source program is an important design decision.

Single Pass Compiler


A single pass compiler makes a single pass over the source text, parsing, analyzing, and generating code all at once.

Dependency diagram of a typical Single Pass Compiler: Compiler Driver calls Syntactic Analyzer calls Contextual Analyzer calls Code Generator
14

Compilation (Chapter 3)

13

Compilation (Chapter 3)

Multi Pass Compiler


A multi pass compiler makes several passes over the program. The output of a preceding phase is stored in a data structure and used by subsequent phases. Dependency diagram of a typical Multi Pass Compiler: Compiler Driver calls Syntactic Analyzer input Source Text
Compilation (Chapter 3)

Example: Single Pass Compilation of ...


let var n: integer; var c: char in begin c := &; n := n+1 end

calls

calls

Contextual Analyzer Code Generator output input output input output AST Decorated AST Object Code
15

Ident n c

Type int char

Address 0[SB] 1[SB]

PUSH 2 LOADL 38 STORE 1[SB] LOAD 0[SB] LOADL 1 CALL add STORE 0[SB] POP 2 HALT

Compilation (Chapter 3)

16

Compiler Design Issues


Single Pass Speed Memory Modularity Flexibility Global optimization Source Language
Compilation (Chapter 3)

Language Issues
Example Pascal: Pascal was explicitly designed to be easy to implement with a single pass compiler:
Every identifier must be declared before its first use. ? var n:integer; procedure inc; begin n:=n+1 end procedure inc; begin n:=n+1 end; Undeclared Variable! var n:integer;

Multi Pass worse (potentially) better for small programs better better possible

better better for large programs worse worse impossible

single pass compilers are not possible for many programming languages
17

Compilation (Chapter 3)

18

Language Issues
Example Pascal:
Every identifier must be declared before it is used. How to handle mutual recursion then? procedure ping(x:integer) begin ... pong(x-1); ... end; procedure pong(x:integer) begin ... ping(x1); ... end;

Language Issues
Example Pascal:
Every identifier must be declared before it is used. How to handle mutual recursion then? forward procedure pong(x:integer) procedure ping(x:integer) begin ... pong(x-1); ... end; OK! procedure pong(x:integer) begin ... ping(x1); ... end;
19

Compilation (Chapter 3)

Compilation (Chapter 3)

20

Example: The Triangle Compiler Driver


public class Compiler { public class Compiler { public static void compileProgram(...) { public static void compileProgram(...) { Parser parser = new Parser(...); Parser parser = new Parser(...); Checker checker = new Checker(...); Checker checker = new Checker(...); Encoder generator = new Encoder(...); Encoder generator = new Encoder(...); Program theAST = parser.parse( ); // first pass Program theAST = parser.parse( ); // first pass checker.check(theAST ); // second pass checker.check(theAST ); // second pass generator.encode(theAST ); // third pass generator.encode(theAST ); // third pass

} }

} } public static void main(String[ ]] args )) { public static void main(String[ args { ... compileProgram(...); ... ... compileProgram(...); ... } }

Compilation (Chapter 3)

21

Das könnte Ihnen auch gefallen