Print CC
Print CC
outline outline
• a syntax-directed translation scheme embeds • The most general approach to syntax-
program fragments called semantic actions directed translation is to construct a parse
within production bodies.
tree or a syntax tree, and then to compute
E → El +T { print ' + ' }
the values of attributes at the nodes of the
The position of a semantic action in a production tree by visiting the nodes of the tree.
body determines the order in which the action is
executed. • a class of syntax-directed translations called
in general, semantic actions may occur at any "L-attributed translations "
position in a production body. • a smaller class, called "S-attributed
translations" (S for synthesized )
5.1.1 Inherited and Synthesized Attributes 5.1.1 Inherited and Synthesized Attributes
• PRODUCTION •SEMANTIC RULES
1) L → E n L.val = E.val • An S-attributed SDD can be implemented naturally in
2) E → E l + T E.val=E1.val+T.val conjunction with an LR parser.
3) E → T E.val = T.val • An SDD without side effects is sometimes called an
4) T → Tl * F T.val=Tl.val F.val attribute grammar.
5) T → F T.val = F.val
• The rules in an attribute grammar define the value of an
6) F → ( E ) F.val = E.val attribute purely in terms of the values of other attributes
7) F → digit F. val = digit .lexval and constants.
S-attributed: An SDD that involves only synthesized
attributes is called S-attributed .
•When an SDD is S-attributed, we can evaluate its S-attributed definitions can be implemented during
attributes in any bottom up order of the nodes of the bottom-up parsing, since a bottom-up parse
parse tree. (performing a postorder traversal of the parse corresponds to a postorder traversal.
tree)
5.2.4 L-Attributed Definitions 5.2.4 L-Attributed Definitions
each attribute must be either
• Synthesized, or
• Inherited, but with the rules limited as follows.
• between the attributes associated with a Suppose that there is a production A → X 1X2 …… Xn,
production body, dependency-graph edges can and that there is an inherited attribute Xi.a computed
go from left to right, but not from right to left by a rule associated with this production.
(hence "L-attributed"). (1) Inherited attributes associated with the head A.
(2) Either inherited or synthesized attributes associated
with the occurrences of symbols X1, X2,. . . , Xi-1
located to the left of Xi.
(3) Inherited or synthesized attributes associated with this
occurrence of Xi itself, but only in such a way that
there are no cycles in a dependency graph formed by
the attributes of this Xi.
5.2.5 Semantic Rules with Controlled 5.2.5 Semantic Rules with Controlled
Side Effects Side Effects
• control side effects in SDD's in one of the • Example 5.10 : The SDD in Fig. 5.8 takes a simple
declaration D consisting of a basic type T followed by a
following ways: list L of identifiers.
• Permit incidental side effects that do not 1) D → T L L.inh = T.type
constrain attribute evaluation. 2) T → int T. type = integer
• Constrain the allowable evaluation orders, so 3) T → float T.type = float
4) L → L1 , id Ll.inh=L.inh
that the same translation is produced for any
allowable order. addType(id.entry, L.inh)
5) L → id add Type(id entry, L.inh)
5.2.5 Semantic Rules with Controlled 5.3 Applications of Syntax-Directed
Side Effects Translation
• two SDD's for constructing syntax trees for
expressions.
The first, an S-attributed definition, is suitable for
use during bottom-up parsing.
The second, L-attributed, is suitable for use
during top-down parsing.
• The final example of this section is an L-
attributed definition that deals with basic
and array types.
Figure 5.9: Dependency graph for a declaration float idl,id2,id3
作业
• 5.2.2
CS 335: Runtime
• 5.2.3 (a, b, c)
Environments
• 5.3.1 Swarnendu Biswas
Semester 2019-2020-II
CSE, IIT Kanpur
Content influenced by many excellent references, see References slide for acknowledgements.
An Overview of Compilation Abstraction Spectrum
source program target program
• Translating source code requires dealing with all programming
language abstractions
lexical analyzer code generator • For example, names, procedures, objects, flow of control, and exceptions
symbol table
• Physical computer operates in terms of several primitive operations
• Arithmetic, data movement, and control jumps
syntax analyzer error handler code optimizer • It is not enough to just translate intermediate code to machine code
• For e.g., need to manage memory when a program is executing
intermediate code
semantic analyzer
generator
enter main()
• Procedure calls and returns are usually managed by When will a control stack work?
a run-time stack called the control stack qsort(2,3)
• Once a function returns, its activation record cannot be referenced again
• Each live activation has an activation record on the
control stack qsort(1,3) • We do not need to store old nodes in the activation tree
• Stores control information and data storage needed to • Every activation record has either finished executing or is an ancestor of
manage the activation qsort(1,9)
the current activation record
• Also called a frame
main()
• Frame is pushed when activation begins and popped When will a control stack not work?
when activation ends
• Once a function returns, its activation record cannot be referenced again
• Suppose node 𝑛 is at the top of the stack, then the
stack contains the nodes along the path from 𝑛 to • Function closures – procedure and run-time context to define free
the root variables
CS 335 Swarnendu Biswas CS 335 Swarnendu Biswas
the current activation record • Local data – field for local data
Access link
• Saved machine status – information about the
When will a control stack not work? machine state before the procedure call Saved machine
status
• Return address (value of program counter)
• Once a function returns, its activation record cannot be referenced again • Register contents Local data
• Function closures – procedure and run-time context to define free • Access link – access nonlocal data
variables Temporaries
• Contents and position of fields may vary Local data Frame for main() rdArr() is activated
epilogue
• Place values communicated between caller and callee at the beginning of the Parameters and return value
callee’s activation record, close to the caller's activation record
Control link
• Fixed-length items are placed in the middle
Caller’s responsibility
• Top-of-stack points to the end of the fixed-length fields Parameters and return value
• Fixed-length data items are accessed by fixed offsets from top-of-stack pointer
responsibility
Control link
• Variable-length fields records are actually "above" the top-of-stack Links and saved status
Caller’s
top_stack
Temporaries and local data
• Scope is the part of a program to which a name declaration applies procedure Fee1; Scope x y z
var x2: integer; Main <1,0> <1,4> <1,8>
• Scope rules provide control over access to data and names begin { Fee1 }
Fee <2,0> <1,4> <1,8>
x2 := 1;
• Lexical scope – a name refers to the definition that is lexically closest Fie <1,0> <2,0> <2,8>
y1 := x2*2+1
to the use end;
Foe <1,0> <2,0> <3,0>
• Compilers can use a static coordinate for a name for lexically-scoped procedure Fie1; Fum <1,0> <4,0> <3,0>
Activation record
sized local data on the stack …
• Procedure 𝑃 cannot have multiple active invocations if it does not call other Control link
procedures Links and saved status
top_stack …
CS 335 Swarnendu Biswas CS 335 Swarnendu Biswas
Data Access without Nested Procedures Access to Nonlocal Data in Nested Procedures
• Consider C-family of languages • This is challenging for nested procedures
• Any name local to a procedure is nonlocal to other procedures
• Suppose procedure 𝑝 at lexical level 𝑚 is nested in procedure 𝑞 at
• Simple rules level 𝑛, and 𝑥 is declared in 𝑞
• Global variables are in static storage • Our aim is to resolve a nonlocal name 𝑥 in 𝑝
• Addresses are fixed and determined at compile time
• Any other name must be local to the activation at the top of the stack
• Compiler models the reference by a static distance coordinate <𝑚 −
𝑛, 𝑜> where 𝑜 is 𝑥’s offset in the activation record for 𝑞
• Compiler needs to translate <𝑚 − 𝑛, 𝑜> into a runtime address
Temporaries
• Procedures not nested within other procedures have nesting depth 1 let let
2) val a = array(11,O); 8) val v= ... ;
• For example, all functions in C have depth 1
3) fun readArray(inputFi1e) = ... ; 9) fun partition(y,z) =
• If 𝑝 is defined immediately within a procedure at depth 𝑖, then 𝑝 is at 4) ...a... ; 10) ...a...v...exchange...
depth 𝑖 + 1 5) fun exchange(i, j) = in
6) ...a... ; 11) ...a...v...partition...quicksort
end
Coordinate Code
Example of Access Links sort
Manipulating Access Links
<2, 24> loadAI rarp, 24 ⇒ r2
access link <1, 12> loadAI rarp, aloff ⇒ r1
loadAI r1, 12 ⇒ r2
𝑎
sort sort sort Level 0 <0, 16> loadAI rarp, aloff ⇒ r1
qsort(1,9) loadAI r1, aloff ⇒ r1
access link access link access link Level 1 Actual loadAI r1, 16 ⇒ r2
access link parameters
𝑎 𝑎 𝑎 Level 2 Actual
𝑣 parameters Returned
qsort(1,9) qsort(1,9) qsort(1,9) Actual
Returned values
qsort(1,3) parameters
access link access link access link Returned values Control link
access link values
𝑣 𝑣 𝑣 Control link
𝑣 Access link
ARP Control link
qsort(1,3) qsort(1,3) Access link Saved machine
part(1,3)
access link access link Access link Saved machine status
access link status
𝑣 𝑣 Saved machine Local data
status Local data
part(1,3) Temporaries
exchg(1,3) Local data
access link Temporaries
access link
Temporaries
Operations Operations
lookup() This method returns 0 (zero) if the symbol does not
lookup() operation is used to search a name in the exist in the symbol table. If the symbol exists in the
symbol table to determine: symbol table, it returns its attributes stored in the
table.
if the symbol exists in the table.
if it is declared before it is being used.
if the name is used in the scope.
if the symbol is initialized.
if the symbol declared multiple times.
The basic format should match the following:
lookup(symbol)
Hash table Hash table Hash table Hash table Hash table
of of of null of of null
Locals Globals Keywords Globals Keywords
Locating a Symbol Locating a Symbol
If we enter another function, a new level 3 When we look up an identifier, we begin the
hash table is created. search at the head of the list.
Hash table Hash table Hash table Hash table Hash table Hash table
of of of null of of of null
Locals Globals Keywords Locals Globals Keywords
Hash table Hash table Hash table Hash table Hash table Hash table
of of of null of of of null
Locals Globals Keywords Locals Globals Keywords
(Test) (setValue)
(Test) (setValue) Symbol Kind Type Properties Symbol Kind Type Properties
Symbol Kind Type Properties Symbol Kind Type Properties
b var int … c var int …
b var int … c var int …
(block1)
(block1) void setValue(int c) { lookup(myValue) Symbol Kind Type Properties
void setValue(int c) { lookup(value) Symbol Kind Type Properties value = c; d var int …
value = c; d var int …
{ int d = c;
{ int d = c; c = c + d;
c = c + d; myValue = c;
value = c; }
} }
25 26
}
Design Of a Compiler
L exical A nalysis
S yntax A nalysis
Table Error
M gmt
Routine
Intermediate Code Generation Handling
Routine
Presented By:
Code Optimization
Amita das
Jayanti bhattacharya Code Generation
Jaistha Upadhyay
Object code
What is optimization?
In computing, optimization is the process of modifying a system to make
some aspect of it work more efficiently or use fewer resources. F or
instance, a computer program may be optimized so that it executes more
rapidly, or is capable of operating with less memory storage or other
resources, or draw less power. The system may be a single computer
program, a collection of computers or even an entire network such as the
internet.
Levels' of optimization
Assembly level
Optimization can occur at a number of 'levels':
Design level
A t the lowest level, writing code using an A ssembly language designed for
a particular hardware platform will normally produce the most efficient
A t the highest level, the design may be optimized to make best use code since the programmer can take advantage of the full repertoire of
of the available resources. The implementation of this design will machine instructions. The operating systems of most machines has been
benefit from the use of suitable efficient algorithms and the traditionally written in A ssembler code for this reason.
implementation of these algorithms will benefit from writing good
quality code. The architectural design of a system overwhelmingly
affects its performance. The choice of algorithm affects efficiency Runtime
more than any other item of the design.
Compile level
Just In Time Compiler and assembler programmers are able to perform
runtime optimization.
Use of an optimizing compiler tends to ensure that the executable
program is optimized at least as much as the compiler can predict.
Loop Invariant
Loop optimization
i =1 i =1
L oop optimization plays an important role in improving the s= 0 s= 0
performance of the source code by reducing overheads
do{ a =5
associated with executing loops.
s= s + i do{
a =5 s= s + i
L oop Optimization can be done by removing:
i =i +1 i =i +1
• L oop invariant
{ {
• Induction variables
while (i < =n) while (i < =n)
B4 B4
if i >= j goto B6 if i >= j goto B6
B4 B4
if i >= j goto B6 if i >= j goto B6
B1 Common Subexpression Elimination B1 Common Subexpression Elimination
i=m-1 i=m-1
j=n j=n
t1 =4 * n t1 =4 * n
v = a[t1] B5 B6 v = a[t1] B5 B6
B2 t6 = 4 * i t11 = 4 * i B2 t6 = 4 * i t11 = 4 * i
B4 B4
if i >= j goto B6 if i >= j goto B6
t5 = a[t4] t5 = a[t4]
if t5 > v goto B3 if t5 > v goto B3
B4 B4
if i >= j goto B6 if i >= j goto B6
B4 B4
if i >= j goto B6 if i >= j goto B6
B1 Common Subexpression Elimination B1 Common Subexpression Elimination
i=m-1 i=m-1
j=n j=n
t1 =4 * n t1 =4 * n
v = a[t1] B5 B6 v = a[t1] B5 B6
B2 x = t3 B2 x = t3
t11 = 4 * i x = t3
i=i +1 a[t2] = t5 i=i +1 a[t2] = t5
x = a[t11] t14 = a[t1]
t2 = 4 * i a[t4] = x t2 = 4 * i a[t4] = x
t13 = 4 * n a[t2] = t14
t3 = a[t2] goto B2 t3 = a[t2] goto B2
t14 = a[t13] a[t1] = x
if t3 < v goto B2 if t3 < v goto B2
a[t11] = t14
B3 B3
a[t13] = x Similarly for B6
j=j–1 j=j–1
t4 = 4 * j t4 = 4 * j
t5 = a[t4] t5 = a[t4]
if t5 > v goto B3 if t5 > v goto B3
B4 B4
if i >= j goto B6 if i >= j goto B6
B4 B4
if i >= j goto B6 if i >= j goto B6
B3 B3 if t3 < v goto B2
j=j–1
t4 = 4 * j t4 = t4 - 4
t5 = a[t4] t5 = a[t4]
if t5 > v goto B3 if t5 > v goto B3
B4 B4
if i >= j goto B6 if i >= j goto B6