Compiler Design Slide Chapter 1-6
Compiler Design Slide Chapter 1-6
CHAPTER ONE
INTRODUCTION
Types of Compilers
Source – to – Source Compilers
Source – to – Machine Compilers
Language Processing Systems
Source Program
Preprocessor
Preprocessor
Compiler
Assembler
Modified Source Program
Compiler Linker
Target Assembly Program Loader
Assembler
Library files
Linker/Loader Re-locatable object files
Compilers Interpreters
Token Stream
Syntax Analyzer
Lexical Analyzer
Syntax Tree
Code Generator
Code Generator
Target-Machine Code
Lexical Analysis/Scanner
<id, 1> +
<id, 2> *
<id, 3>
60
Semantic Analysis
Uses the syntax tree and the information in the symbol table to
check the source program for semantic consistency with the language
definition
It gathers type information and performs type checking
Type checking
Checks that each operator has matching operands
Type Conversion
position = initial + rate * 60
Semantic analyzer first converts integer 60 to a floating point number
before applying *
Intermediate Code Generation
t2 = id3 * t1
<id, 3>
t3 = id2 + t2 60
id1 = t3
The compiler must also generate temporary name to hold the value computed by a
three-address instruction
Code Optimization
Two Types
The machine-independent code-optimization phase
attempts to improve the intermediate code so that better target
code will result
The machine dependant code-optimization phase
Example
t1 = inttofloat(60) t1 = id3 * 60.0
id1 = id2 + t1
t2 = id3 * t1
t3 = id2 + t2
id1 = t3
Code Generation
its type,
its scope (where in the program its value can be used), and
in the case of procedure names, as the number and types of its arguments, the method of
passing each argument (e.g., by value or by reference), and the type returned
token
Source To semantic
Lexical Analyzer Parser
program analysis
getNextToken
Symbol
table
Tasks of Lexical Analyzer
Identifying Lexemes
if Characters i, f if
else Characters e, l, s, e else
comparison < or > or <= or >= or == or != <=, !=
E = M * C ** 2
<id, pointer to symbol table entry for E>
<assign-op>
<id, pointer to symbol table entry for M>
<mult-op>
<id, pointer to symbol table entry for C>
<exp-op>
<number, integer value 2>
Lexical errors
Panic mode:
Delete one character from the remaining input
Outcome
If char can extend lexeme, all is well, go on.
If char cannot extend lexeme:
Figure out what the complete lexeme is and return its token
Put the lookahead back into the symbol stream
Formalization
How to formalize this pseudo-algorithm ?
Character-at-a-time I/O
Block / Buffered I/O
Block/Buffered I/O
Utilize Block of memory
Stage data from source to buffer block at a time
Maintain two blocks - Why (Recall OS)?
Asynchronous I/O - for 1 block
While Lexical Analysis on 2nd block
Block 1 Block 2
When done, ptr... Still Process token in
issue I/O
2nd block
Buffer Pairs
Two pointers to the input are maintained:
Pointer lexemeBegin, marks the beginning of the
current lexeme, whose extent we are attempting to
determine
Pointer forward scans ahead until a pattern match is
found
E = M * C * * 2 eof
lexemeBegin forward
Algorithm: Buffered I/O with Sentinels
Current token
Alphabet Languages
{0,1} {0,10,100,1000,100000…}
{a,b,c} {abc,aabbcc,aaabbbccc,…}
{A, … ,Z} {TEE,FORE,BALL, FOR,WHILE,GOTO…}
{A,…,Z,a,…,z,0,…9, { All legal PASCAL progs}
+,-,…,<,>,…} {All grammatically correct
English sentences }
Language & Regular Expressions
where:
Each di is a new symbol, not in ∑ and not the same as any
other of the d‟s, and
Each ri is a regular expression over the alphabet ∑ U {d1,d2, .
. . , di-1}
Extensions of Regular Expressions
One or more instances -- r+
Zero or more instances -- r*
Zero or one instance -- r?
Character classes
a1 | a2 | . . . | an
[a1- an]
digit→0 | 1 | . . . | 9
digits→digit+
number→digits(.digits)?(E[+-]?digits)?
All Strings that start with “ab” and end with “ba”
All Strings in Which {1,2,3} exist in ascending order
Recognition of tokens
Regular Token Attribute-Value
Expression
ws - -
if if -
then then -
else else -
id id pointer to table entry
num num pointer to table entry
< relop LT
<= relop LE
= relop EQ
<> relop NE
> relop GT
>= relop GE
Note: Each token has a unique token identifier to define category of lexemes
How is Pattern Matching done?
other
8
* RTN(G)
We‟ve accepted “>” and have read other char that must be unread.
Example : All RELOPs
start < =
0 1 2 return(relop, LE)
>
3 return(relop, NE)
other
= *
4 return(relop, LT)
5 return(relop, EQ)
>
=
6 7 return(relop, GE)
other
8
*
return(relop, GT)
Example TDs : id and delim
id : letter or digit
delim :
delim
start delim other *
28 29 30
blank b
tab ^T
newline ^N
delim blank | tab | newline
ws delim +
Example TDs : Unsigned #s
digit digit digit
E digit
digit digit
digit
Left-most derivation
E→E*E
E→E+E*E
E → id + E * E
E → id + id * E
E → id + id * id
In a parse tree:
All leaf nodes are terminals.
All interior nodes are non-terminals.
In-order traversal gives original input string.
Ambiguity
A grammar G is said to be ambiguous if it has more
than one parse tree (left or right derivation) for at
least one string.
E→E+E
E→E–E
E → id
INPUT
id – id + id
Ambiguity Solution
No method can detect and remove ambiguity
automatically, but it can be removed by
either re-writing the whole grammar without ambiguity,
or
by setting and following associativity and precedence
constraints
Example
2+3*4 can have two different parse trees
(2+3)*4 and
2+(3*4)
Left Recursion
A grammar becomes left-recursive if it has any non-
terminal „A‟ whose derivation contains „A‟ itself as the
left-most symbol
(1) A => Aα | β
(2) S => Aα | β
A => Sd
Removal of Left Recursion
A => Aα | β A => βA‟
A‟ => αA‟ | ε
Algorithm
START
Arrange non-terminals in some order like A1, A2, A3,…, An
for each i from 1 to n
{
for each j from 1 to i-1
{
replace each production of form Ai⟹Aj𝜸
with Ai ⟹ δ1𝜸 | δ2𝜸 | δ3𝜸 |…| 𝜸
where Aj ⟹ δ1 | δ2|…| δn are current Aj productions
}
} Exercises
eliminate immediate left-recursion S => Aα | β
END
A => Sd
Left Factoring
If more than one grammar production rules has a
common prefix string, then the parser cannot make
a choice as to which of the production it should take
to parse the string in hand
A ⟹ αβ | α𝜸 | …
Exercise
E → E + T|T
T → T * F|F
F → (E)|id
Algorithm for Calculating First Set
main(){ E‟(){
if(ch==„+‟){
E();
match(„+‟);
if(ch==„$‟) match(„i‟);
printf(„Successful‟); E‟();
} }
else{
E(){ return;
if(ch==„i‟) }
match(char t){
}
match(„i‟); if(ch==t)
E‟(); ch=getchar()
else
}
error();
}
Recursive decent parsing with
Backtracking
S → rXd | rZd
X → oa | ea
Z → ai
Implemented on a stack
Parsing Table Construction
The parsing table is a two dimensional array M[X,
a] where X is a nonterminal of the grammar and a
is a terminal or $
compiler\parsetableconstruction.pdf
Non-recursive Predictive Parsing
followed by $
$ at the bottom.
grammar followed by $.
Non-recursive Predictive Parsing
id+id*id
Non-recursive Predictive Parsing Rules
Shift. Shift the next input symbol on the top of the stack
Reduce.
The parser knows the right end of the handle is at the top of the
stack. It should then decide what non-terminal should replace that
substring
Input Buffer
LR Parsing Algorithm sm
Xm LR
Parsing Table Stack
sm-1 Parsing
Xm-1 Program Output
...
Has two parts s0
Action and
goto
action goto
Types of LR Parsers
LR(0)
SLR(1) – Simple LR
LALR(1) - Look Ahead LR
CLR(1) – Canonical LR
LR Parsing Algorithm
Action Goto
State
Id + * ( ) $ E T F
0 s5 s4 1 2 3
1 s6 acc
2 r2 s7 r2 r2
3 r4 r4 r4 r4
4 s5 s4 8 2 3
5 r6 r6 r6 r6
6 s5 s4 9 3
7 s5 s4 10
8 s6 s11
9 r1 s7 r1 r1
10 r3 r3 r3 r3
11 r5 r5 r5 r5
LR Parsing Example
On input id*id+id, the sequence of stack and input
contents is
Action Goto
State
a b $ A S
0 s3 s4 2 1
1 acc
2 s3 s4 r2 5
3 s3 s4 6
4 r3 r3 r3
5 r1 r1 r1
6 r2 r2 r2
Types of LR Parsers
LR(0)
SLR(1) – Simple LR
LALR(1) - Look Ahead LR
CLR(1) – Canonical LR
LR Parser Types
There are three widely used algorithms available for
constructing an LR parser:
SLR(1) – Simple LR Parser:
Works on smallest class of grammar
Few number of states, hence very small table
Simple and fast construction
LR(1) – LR Parser:
Works on complete set of LR(1) Grammar
Generates large table and large number of states
Slow construction
LALR(1) – Look-Ahead LR Parser:
Works on intermediate size of grammar
Number of states are same as in SLR(1)
LR(0) PARSING TABLE
CONSTRUCTION
LR(0) Parsing Table Construction
LR(0) Item/Item
Item sets/Canonical LR(0)
LR(0) State
Augmented Grammar
Closure Operation
Goto Operation
LR(0) Item
An LR(0) item (item for short)
is a production of a grammar G with a dot at some position
of the right side
For example
the rule E → E + B has the following four corresponding
items:
E→•E+B
E→E•+B
E→E+•B
E→E+B•
Rules of the form A → ε have only a single item A → .
An item indicates what is the part of a production that
we have seen and what we hope to see.
Item Set
I3 = goto(I0, F) = {[T→F.]}
S‟ → S
S →( L )
S→x
L→S
L→L,S
S‟ ::= . S $
S ::= . ( L )
S ::= . x
Grammar:
S‟ → S
S →( L )
S→x
L→S
L→L,S
S‟ ::= . S $
S ::= . ( L )
S ::= . x
S‟ ::= S . $
Grammar:
S‟ → S
S →( L )
S→x
L→S
L→L,S
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S
S ::= . x L ::= . L , S
S ::= . ( L )
S S ::= . x
S‟ ::= S . $
Grammar:
S‟ → S
S →( L )
S→x
L→S
L→L,S
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S
S ::= . x L ::= . L , S
S ::= . ( L )
S S ::= . x
S‟ ::= S . $
Grammar:
S‟ → S
S →( L )
S→x
L→S
L→L,S
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S
S ::= . x L ::= . L , S
S ::= . ( L )
S S ::= . x
S‟ ::= S . $
Grammar:
S‟ → S
S →( L )
S→x
L→S
L→L,S
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S
S ::= . x L ::= . L , S
S ::= . ( L ) L S ::= ( L . )
S ::= . x L ::= L . , S
S
S‟ ::= S . $
Grammar:
S‟ → S
S →( L )
S→x
L→S
L→L,S
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S
S ::= . x L ::= . L , S
S ::= . ( L ) L S ::= ( L . )
S ::= . x L ::= L . , S
S
S
S‟ ::= S . $
L ::= S .
Grammar:
S‟ → S
S →( L )
S→x S ::= x .
L→S
L→L,S x
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S
S ::= . x L ::= . L , S
S ::= . ( L ) L S ::= ( L . )
S ::= . x L ::= L . , S
S
S
S‟ ::= S . $
L ::= S .
Grammar:
S‟ → S
S →( L )
S→x S ::= x .
L→S
L→L,S x
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S
S ::= . x L ::= . L , S
S ::= . ( L ) L S ::= ( L . )
S ::= . x L ::= L . , S
S
)
S
S‟ ::= S . $
S ::= ( L ) .
L ::= S .
Grammar:
S‟ → S
S →( L )
S→x S ::= x .
L→S L ::= L , . S
L→L,S x S ::= . ( L )
S ::= . x
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S ,
S ::= . x L ::= . L , S
S ::= . ( L ) L S ::= ( L . )
S ::= . x L ::= L . , S
S
)
S
S‟ ::= S . $
S ::= ( L ) .
L ::= S .
Grammar:
S‟ → S
S →( L )
S→x S ::= x .
L→S L ::= L , . S
L→L,S x S ::= . ( L )
S ::= . x
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S ,
S ::= . x L ::= . L , S
S ::= . ( L ) L S ::= ( L . )
S ::= . x L ::= L . , S
S
)
S
S‟ ::= S . $
S ::= ( L ) .
L ::= S .
Grammar:
L ::= L , S .
S‟ → S
S
S →( L )
S→x S ::= x .
L→S L ::= L , . S
L→L,S x S ::= . ( L )
S ::= . x
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S ,
S ::= . x L ::= . L , S
S ::= . ( L ) L S ::= ( L . )
S ::= . x L ::= L . , S
S
)
S
S‟ ::= S . $
S ::= ( L ) .
L ::= S .
Grammar:
L ::= L , S .
S‟ → S
S
S →( L )
S→x S ::= x .
L→S L ::= L , . S
L→L,S x S ::= . ( L )
( S ::= . x
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S ,
S ::= . x L ::= . L , S
S ::= . ( L ) L S ::= ( L . )
S ::= . x L ::= L . , S
S
)
S
S‟ ::= S . $
S ::= ( L ) .
L ::= S .
Grammar:
L ::= L , S .
S‟ → S
S
S →( L )
S→x x
S ::= x .
L→S L ::= L , . S
x S ::= . ( L )
L→L,S x
( S ::= . x
(
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S ,
S ::= . x L ::= . L , S
S ::= . ( L ) L S ::= ( L . )
S ::= . x L ::= L . , S
S
)
S
S‟ ::= S . $
S ::= ( L ) .
L ::= S .
Grammar:
Assigning numbers to states:
9 L ::= L , S .
S‟ → S
S
S →( L )
x 8
S→x 2 S ::= x .
L→S L ::= L , . S
x S ::= . ( L )
L→L,S x
( S ::= . x
1 (
S‟ ::= . S $ S ::= ( . L )
S ::= . ( L ) L ::= . S ,
S ::= . x ( L ::= . L , S 5
S ::= . ( L ) L S ::= ( L . )
3 S ::= . x L ::= L . , S
S
)
S
4 S‟ ::= S . $
6 S ::= ( L ) .
7 L ::= S .
The LR(0) Parsing Table
S‟ → S
S →( L ) states ( ) x , $ S L
S→x 1 s3 s2 g4
L→S
2 r2 r2 r2 r2 r2
L→L,S
3 s3 s2 g7 g5
4 a
5 s6 s8
6 r1 r1 r1 r1 r1
7 r3 r3 r3 r3 r3
8 s3 s2 g9
9 r4 r4 r4 r4 r4
Construct the LR(0) parsing table for G
S→ AA
A→aA/b
parse the input
aabb$
LR(0)
LR(0) doesn't look ahead at all
we only use the terminal to figure out which state to go to next,
not to decide whether to shift or reduce
Example
states ( ) x , $ S L
S→ X 1 s3 s2 g4
2 r2 r2 r2 r2 r2
X→a 3 s3 s2 g7 g5
X→ab ignore next automaton state
states no look-ahead S L
input: ( x , x ) $ 1 shift g4
2 reduce 2
stack: 1(3L5
3 shift g7 g5
SLR(1) PARSING TABLE
CONSTRUCTION
SLR(1) Parse Table Generation
S→ X
X→a
X→ab
Grammar:
SLR(1) Set of Items collection
S’→S
S→L=R [S→L=R.]
S→R 9
R→L R
[S→L.= R]
L→*R 2 = 6
[R→L.] [S→L =.R]
L→id
L [R→.L]
[S‟→.S] [L→.*R]
0 [S→.L=R] R 3 [S→R.] [L→.id]
[S→.R] * *
[L→.*R] L
[L→.id] * 4 [L→*.R] L 8
[R→.L] [L→.*R] id
[R→L.]
S [L→.id]
[R→.L] R
id id
1 S‟ → S . 7
[L→*R.]
[L→id.]
5
SLR(1) Parsing Table
S’→S states = * id $ S L R
S→L=R 0 s4 s5 1 2 3
S→R
R→L 1 acc
L→*R 2 s6/r3 r3
L→id 3 r2
4 s4 s5 8 7
5 r5 r5
F(S) = {$}
F(L)={$,=} 6 s4 s5 8 9
F(R)={$,=} 7 r4 r4
8 r3 r3
9 r1
Solution
right-hand-side
position (the dot)
look ahead symbol LR(1)
X → s1. s2
X → s1. s2, T
LR(1) Closure Operation
I is a set of LR(1) items, then closure(I) is found using
the following algorithm:
Closure(I)
repeat for all items [A →α•Xβ, c] in I
for any production X → γ
for any d ∈First(βc)
I = I ∪{ [X →• γ, d] }
until I does not change
LR(1) Closure Operation
If I is the set of LR(1) one item: {S‟→.S, $}, then
closure(I) contains the items: S’→S
{ S→L=R
[S‟→.S, $] S→R
[S→.L=R, $] R→L
L→*R
[S→.R, $]
L→id
[L→.*R, =]
[L→.id, =]
[R→.L, $]
[L→.*R, $]
FIRST($) = {$}
[L→.id, $]
FIRST(=R$) = {=}
}
LR(1) Goto Operation
CHAPTER TWO
•Strings
•Regular expressions
•Tokens
•Transition diagrams
•Finite Automata
A Step-Back
CHAPTER THREE
•Grammars
•Derivations
•Parse-trees
•Top-down parsing (LL)
•Bottom-up paring (LR, SLR,LALR)
We Need Some Tools
To help in semantic analysis
To help in intermediate code generation
Two such tools
Semantic rules (Syntax-Directed Definitions)
Semantic actions (Syntax Directed Translations)
What does a semantic analyzer do?
Semantic analysis judges whether the syntax structure
constructed in the source program derives any meaning or
not.
For Example
int a = “value”;
should not issue an error in lexical and syntax analysis phase, as it is
lexically and structurally correct, but it should generate a semantic
error as the type of the assignment differs
The following tasks should be performed in semantic
analysis:
Scope resolution
Type checking
Array-bound checking
Semantic Errors
These are some of the semantics errors that the
semantic analyzer is expected to recognize:
Type mismatch
Undeclared variable
Synthesized Attributes
Attribute of a node is defined in terms of:
Attribute values at children of the node
Definition
An S-Attributed Definition is a Syntax Directed
Definition that uses only synthesized attributes.
Evaluation Order
Semantic rules in an S-Attributed Definition can be
evaluated by a bottom-up, or PostOrder, traversal of
the parse-tree
S-attributed Grammar Example
Example of an S-attributed grammar:
Syntax Rules Semantic Rules
L → En print(E.val)
E → E1 + T E.val = E1.val + T.val
E→ T E.val = T.val
T → T1* F T.val = T1.val F.val
T→ F T.val = F.val
F → (E) F.val = E.val
F → digit F.val =digit.lexval
S-attributed Grammar Example
The annotated parse-tree for the input 3*5+4n
from the above S-attributed grammar is:
S-attributed Grammar Example
Exercises
Give the annotated parse tree of (3+4)*(5+6)n from
the following grammar
Syntax Rules Semantic Rules
L → En print(E.val)
E → E1 + T E.val = E1.val + T.val
E → T E.val = T.val
T → T1* F T.val = T1.val F.val
T → F T.val = F.val
F → (E) F.val = E.val
F → digit F.val =digit.lexval
L-attributed Grammars
Definition
An L-Attributed Definition is a Syntax Directed
Definition that uses both synthesized and Inherited
attributes.
It
is always possible to rewrite a syntax directed
definition to use only synthesized attributes,
Evaluation Order.
Inherited
attributes cannot be evaluated by a simple
PreOrder traversal of the parse-tree:
L-attributed Grammar Example
An L-Attributed grammar that associates to an identifier
its type
PRODUCTION SEMANTIC RULE
D → TL L.in := T.type
T → int T.type :=integer
T → real T.type :=real
L → L1, id L1.in := L.in; addtype(id.entry, L.in)
L → id addtype(id.entry, L.in)
L-attributed Grammar Example
The annotated parse-tree for the input real id1, id2, id3 from the
above L-attributed grammar is:
Dependency Graphs
S-Attributed Definitions
L-Attributed Definitions
Dependency Graph
a4=real;
a5=a4;
addtype(id3.entry,a5);
a7=a5;
addtype(id2.entry,a7);
a9=a7;
addtype(id1.entry,a5);
202
Evaluating Semantic Rules
203
L-Attributed Definitions
Evaluation of S-Attributed Definitions
Dynamic Check
executed during execution of the program
Examples of static checks
Type Checks
Checks if an operator has the right type of operands
Flow-of-Control Checks
Statements that cause flow of control to leave a construct must
have some place to which to transfer the flow of control
For example, a break instruction in C that is not in an enclosing
statement
Uniqueness Checks
There are situations in which an object must be defined exactly
once
For example, in Pascal, an identifier must be declared uniquely
Name-Related Checks
Sometimes, the same name must appear two or more times .
For example, in Ada, a loop or block may have a name that appears
at the beginning and end of the construct.
Examples of Dynamic Checks
Array Out of Bound
int [] a = new int [10];
for (int i=0; i<20; ++i)
a[i] = i;
Division by zero
float a=50;
for (int i=0; i<5; ++i)
a= a/i;
Type Checking Introduction
A compiler must check that a program follows the Type Rules
of a language.
The Type Checker is a module of a compiler devoted to type
checking tasks
Examples of Tasks
The operator mod is defined only if the operands are integers;
Indexing is allowed only on an array and the index must be an
integer;
A function must have a precise number of arguments and the
parameters must have a correct type;
etc...
Type Checker
Type checker verifies that the type of a construct
(constant, variable, array, list, object)matches what is
expected in its usage context
E.g.
int x=“abc”;
Some operators (+,-,*,/) are “overloaded”; i.e, they
can apply to objects of different types
Functions may be polymorphic; i.e, accept arguments of
different types.
Type information produced by the type checker may be
needed when the code is generated
Types of Types
Basic types
are atomic types that have no internal structure as far as
the programmer is concerned
They include types like integer, real, boolean, character , and
enumerated types
Constructed types
include arrays, records, sets, and structures constructed from
the basic types and/or other constructed types
Pointers and functions are also constructed types
Type Checker
E + E
a b
a b
The compiler maintains a global offset variable that indicates the first
address not yet allocated
The procedure enter(name, type, address) creates a symbol table entry for
name, give it the type type and the relative address address
SDT for Declaration statements
Example: Semantic actions for the declaration part
Production Semantic Rules
P→{offset := 0} D S
D→D; D
D→id :T {enter(id.name, T.type, offset);
offset := offset + T.width}
T→integer {T.type := integer;
T.width := 4}
T→real {T.type := real;
T.width := 8}
T→array[num] of T1 {T.type := array (num.val, T1.type);
T.width := num.val * T1.width}
T→^T1 {T.type := pointer (T1.type);
T.width := 4}
Example
How many memory cells will be allocated for the
following declaration statements?
x : int;
arr : array[5] of int;
Assignment Statements
lookup(lexeme)
checks if there is an entry for this occurrence of the name in
the symbol table, and
if so a pointer to the entry is returned; otherwise nil is
returned.
newtemp
generates temporary variables and
reserve a memory area for the variables by modifying the
offset and putting in the symbol table the reserved
memories‟ addresses
TAC SDD for assignment statements
Example: generation of the three-address code for
the assignment statement and simple expressions
Production Semantic Rules
S→id := E p := lookup (id.name);
S.code := E.code || If p <> nil then gen (p.lexeme, ‘:=’, E.place) else error
E→E1 + E2 E.place := newtemp;
E.code := E1.code || E2.code || gen (E.place, ‘:=’, E1.place, ‘+’, E2.place)
E→E1 * E2 E.place := newtemp;
E.code := E1.code || E2.code || gen (E.place, ‘:=’, E1.place, ‘*’, E2.place)
E→- E1 E.place := newtemp;
E.code := E1.code || gen (E.place, ‘:= uminus ’, E1.place)
E→(E1) E.place := newtemp;
E.code := E1.code
E→id p := lookup (id.lexeme)
if p <> nil then E.place = p.lexeme else error
E.code := ’’ /* empty code */
E→num E.place := newtemp;
E.code := gen (E.place, ‘:= num.value)
Example
Generate the three-address code for the input a:=
x + y * z from the previous SDT:
Exercise
Generate the three-address code for the input
num:= (x + y) * (z + m) from the previous SDT:
i=2*n+k
Addressing Array Elements
Width of each array element is w,
Relative address of the array base and
Lower bound of the index low, then the ith element of
the array is found at the address: base + (i – low) * w
For example
A : array [5..10] of integer;
if it is stored at the address 100
A[7] = 100 + (7 – 5) * 4
When the index is constant as above, it is possible to
evaluate the address of A[i] at compile time
Addressing Array Elements
A : array [5..10] of integer;
A[7] = 100 + (7 – 5) * 4