0% found this document useful (0 votes)
78 views22 pages

Languages and Compilers (Sprog Og Oversættere) : Bent Thomsen Department of Computer Science Aalborg University

The document summarizes the different phases of a compiler: 1) Syntax analysis parses the source code and produces an abstract syntax tree. 2) Contextual analysis performs type checking and scope analysis on the abstract syntax tree to produce a decorated abstract syntax tree. 3) Code generation transforms the decorated abstract syntax tree into object code for the target machine. The phases are separate but compilers may interleave the phases in different passes over the source code.

Uploaded by

Aman Ahluwalia
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
78 views22 pages

Languages and Compilers (Sprog Og Oversættere) : Bent Thomsen Department of Computer Science Aalborg University

The document summarizes the different phases of a compiler: 1) Syntax analysis parses the source code and produces an abstract syntax tree. 2) Contextual analysis performs type checking and scope analysis on the abstract syntax tree to produce a decorated abstract syntax tree. 3) Code generation transforms the decorated abstract syntax tree into object code for the target machine. The phases are separate but compilers may interleave the phases in different passes over the source code.

Uploaded by

Aman Ahluwalia
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 22

Languages and Compilers

(SProg og Oversættere)

Bent Thomsen
Department of Computer Science
Aalborg University

With acknowledgement to Norm Hutchinson who’s slides this lecture is based on .


1
Compilation
So far we have treated language processors (including
compilers) as “black boxes”

Now we take a first look "inside the box": how are


compilers built.

And we take a look at the different “phases” and their


relationships

2
The “Phases” of a Compiler

Source Program

Syntax Analysis Error Reports


Abstract Syntax Tree
Contextual Analysis Error Reports
Decorated Abstract Syntax Tree

Code Generation

Object Code

3
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

4
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
This program
program isis useless
useless except
except for
for
!! illustration
illustration
let
let var
var n:
n: integer;
integer;
var
var c:
c: char
char
in
in begin
begin
cc :=
:= ‘&’;
‘&’;
nn :=
:= n+1
n+1
end
end

5
1) Syntax Analysis

Source Program

Syntax Analysis Error Reports

Abstract Syntax Tree Note:


Note:Not
Notall
allcompilers
compilersconstruct
constructan
an
explicit
explicitrepresentation
representationof
ofan
anAST.
AST.(e.g.
(e.g.on
on
aa“single
“singlepass
passcompiler”
compiler”generally
generallyno
noneed
need
to
toconstruct
constructan
anAST)
AST)

6
1) Syntax Analysis -> AST
Program
LetCommand

SequentialCommand
SequentialDeclaration AssignCommand

AssignCommand BinaryExpr

VarDecl VarDecl Char.Expr VNameExp Int.Expr

SimpleT SimpleT SimpleV SimpleV


Ident Ident Ident Ident Ident Char.Lit Ident Ident Op Int.Lit

n Integer c Char c ‘&’ n n + 1


7
2) Contextual Analysis -> Decorated AST

Abstract Syntax Tree

Contextual Analysis Error Reports


Decorated Abstract Syntax Tree

Contextual analysis:
• 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

8
2) Contextual Analysis -> Decorated AST
Program
LetCommand

SequentialCommand
SequentialDeclaration AssignCommand

AssignCommand BinaryExpr :int

VarDecl VarDecl Char.Expr VNameExp Int.Expr


:char :int :int
SimpleT SimpleT SimpleV SimpleV
:char :int
Ident Ident Ident Ident Ident Char.Lit Ident Ident Op Int.Lit

n Integer c Char c ‘&’ n n + 1


9
Contextual Analysis
Finds scope and type errors.
Example 1:
AssignCommand ***TYPE ERROR (incompatible types in
assigncommand)
:int :char

Example 2:

foo not found


SimpleV ***SCOPE ERROR: undeclared variable foo
Ident

foo
10
3) Code Generation

Decorated Abstract Syntax Tree

Code Generation

Object Code

• 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.
11
3) Code Generation

let var n: integer; PUSH 2


var c: char LOADL 38
in begin STORE 1[SB]
c := ‘&’; LOAD 0
n := n+1 LOADL 1
end CALL add
STORE 0[SB]
POP 2
VarDecl address = 0[SB] HALT
SimpleT
Ident Ident

n Integer
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.
• 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.

13
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 calls

Contextual Analyzer Code Generator

14
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 calls
calls
Syntactic Analyzer Contextual Analyzer Code Generator
input output input output input output

Source Text AST Decorated AST Object Code

15
Example: The Triangle Compiler Driver
public
public class
class Compiler
Compiler {{
public
public static
static void
void compileProgram(...)
compileProgram(...) {{
Parser
Parser parser
parser == new
new Parser(...);
Parser(...);
Checker
Checker checker
checker == new
new Checker(...);
Checker(...);
Encoder
Encoder generator
generator == new
new Encoder(...);
Encoder(...);

Program
Program theAST
theAST == parser.parse();
parser.parse();
checker.check(theAST);
checker.check(theAST);
generator.encode(theAST);
generator.encode(theAST);
}}
public
public void
void main(String[]
main(String[] args)
args) {{
...
... compileProgram(...)
compileProgram(...) ...
...
}}
}}
16
Compiler Design Issues

Single Pass Multi Pass

Speed better worse

Memory better for (potentially) better


large programs for small programs
Modularity worse better

Flexibility worse better

“Global” optimization impossible possible

Source Language single pass compilers are not possible


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

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(x); ...
end;

19
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(x); ...
end;
20
Language Issues
Example Java:
– identifiers can be declared before they are used.
– thus a Java compiler need at least two passes

Class Example {
void inc() { n = n + 1; }
int n;
void use() { n = 0 ; inc(); }
}

21
Keep in mind
There are many issues influencing the design of a new
programming language:
– Choice of paradigm
– Syntactic preferences
– Even the compiler implementation
• e.g no of passes
• available tools

There are many issues influencing the design of new


compiler:
– No of passes
– The source, target and implementation language
– Available tools

22

You might also like