Module 26 Backpatching and Procedures

Similar documents
Intermediate Code Generation Part II

Intermediate Code Generation

UNIT-3. (if we were doing an infix to postfix translator) Figure: conceptual view of syntax directed translation.

ΕΠΛ323 - Θεωρία και Πρακτική Μεταγλωττιστών

Module 25 Control Flow statements and Boolean Expressions

Principles of Programming Languages

CMPSC 160 Translation of Programming Languages. Three-Address Code

Intermediate Code Generation

2 Intermediate Representation. HIR (high level IR) preserves loop structure and. More of a wizardry rather than science. in a set of source languages

Intermediate Code Generation

SYNTAX DIRECTED TRANSLATION FOR CONTROL STRUCTURES

CS2210: Compiler Construction. Code Generation

Compilerconstructie. najaar Rudy van Vliet kamer 140 Snellius, tel rvvliet(at)liacs(dot)nl. college 7, vrijdag 2 november 2018

CSE443 Compilers. Dr. Carl Alphonce 343 Davis Hall

NARESHKUMAR.R, AP\CSE, MAHALAKSHMI ENGINEERING COLLEGE, TRICHY Page 1

Principle of Compilers Lecture VIII: Intermediate Code Generation. Alessandro Artale

CSc 453. Compilers and Systems Software. 16 : Intermediate Code IV. Department of Computer Science University of Arizona

Compilerconstructie. najaar Rudy van Vliet kamer 124 Snellius, tel rvvliet(at)liacs(dot)nl

THEORY OF COMPILATION

Control Structures. Boolean Expressions. CSc 453. Compilers and Systems Software. 16 : Intermediate Code IV

Theory of Compilation Erez Petrank. Lecture 7: Intermediate Representation Part 2: Backpatching

Syntax-Directed Translation

Formal Languages and Compilers Lecture X Intermediate Code Generation

CSCI565 Compiler Design

CMPT 379 Compilers. Anoop Sarkar. 11/13/07 1. TAC: Intermediate Representation. Language + Machine Independent TAC

Intermediate Representa.on

Chapter 6 Intermediate Code Generation

COP5621 Exam 3 - Spring 2005

Principle of Complier Design Prof. Y. N. Srikant Department of Computer Science and Automation Indian Institute of Science, Bangalore

Boolean Expressions. Lecture 31 Sections 6.6, 6.7. Robb T. Koether. Hampden-Sydney College. Wed, Apr 8, 2015

CSCI565 Compiler Design

Lecture 25 Sections 8.4, 8.6. Fri, Apr 24, 2009

Dixita Kagathara Page 1

UNIT IV INTERMEDIATE CODE GENERATION

Generating 3-Address Code from an Attribute Grammar

CSCI Compiler Design

Languages and Compiler Design II IR Code Generation I

Intermediate Code Generation

Module 27 Switch-case statements and Run-time storage management

Compiler. --- Intermediate Code Generation. Zhang Zhizheng.

Compiler Theory. (Intermediate Code Generation Abstract S yntax + 3 Address Code)

PRINCIPLES OF COMPILER DESIGN

Time : 1 Hour Max Marks : 30

Intermediate Code Generation

CSCI Compiler Design

The analysis part breaks up the source program into constituent pieces and creates an intermediate representation of the source program.

Page No 1 (Please look at the next page )

Intermediate Code Generation

Syntax-Directed Translation Part II

Functional Programming. Pure Functional Programming

Concepts Introduced in Chapter 6

Intermediate Code Generation

ECS 142 Project: Code generation hints (2)

LECTURE 17. Expressions and Assignment

PART 6 - RUN-TIME ENVIRONMENT. F. Wotawa TU Graz) Compiler Construction Summer term / 309

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 19: Efficient IL Lowering 5 March 08

CS322 Languages and Compiler Design II. Spring 2012 Lecture 7

CSc 453 Intermediate Code Generation

CSE443 Compilers. Dr. Carl Alphonce 343 Davis Hall

TACi: Three-Address Code Interpreter (version 1.0)

Intermediate Code Generation

Concepts Introduced in Chapter 6

Semantic Actions and 3-Address Code Generation

Oberon2 Compiler CS335: Compiler Project

Let us construct the LR(1) items for the grammar given below to construct the LALR parsing table.

A Simple Syntax-Directed Translator

Flow of Control Execution Sequence

Intermediate Code Generation

IR Lowering. Notation. Lowering Methodology. Nested Expressions. Nested Statements CS412/CS413. Introduction to Compilers Tim Teitelbaum

VIVA QUESTIONS WITH ANSWERS

intermediate-code Generation

Semantic Analysis computes additional information related to the meaning of the program once the syntactic structure is known.

PSD3A Principles of Compiler Design Unit : I-V. PSD3A- Principles of Compiler Design

Intermediate Representations

CS 314 Principles of Programming Languages

Code Generation. CS 1622: Code Generation & Register Allocation. Arrays. Why is Code Generation Hard? Multidimensional Arrays. Array Element Address

Intermediate Code Generation

1. Lexical Analysis Phase

Problem Score Max Score 1 Syntax directed translation & type

Introduction. C provides two styles of flow control:

Acknowledgement. CS Compiler Design. Intermediate representations. Intermediate representations. Semantic Analysis - IR Generation

CMSC430 Spring 2014 Midterm 2 Solutions

Basic Structure of Denotational Definitions

Homework 1 Answers. CS 322 Compiler Construction Winter Quarter 2006

Intermediate Representations

520 Principles of Programming Languages. Arithmetic. Variable Declarations. 19: Pascal

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

B.V. Patel Institute of Business Management, Computer & Information Technology, Uka Tarsadia University

CS 6353 Compiler Construction Project Assignments

Chapter 6 Control Flow. June 9, 2015

CS 6353 Compiler Construction Project Assignments

Below are example solutions for each of the questions. These are not the only possible answers, but they are the most common ones.

Syntax Directed Translation

Topic 1: Introduction

Project 3 Due October 21, 2015, 11:59:59pm

COMPILER CONSTRUCTION (Intermediate Code: three address, control flow)

Comp 204: Computer Systems and Their Implementation. Lecture 22: Code Generation and Optimisation

COMP-520 GoLite Tutorial

CS 432 Fall Mike Lam, Professor. Code Generation

LECTURE 3. Compiler Phases

Transcription:

Module 26 Backpatching and Procedures In this module, we would learn to generate three-address code for control flow statements using backpatching. We shall also discuss to combine Boolean expressions and control flow statements to generate three-address code based on Backpatching. The various semantic rules that need to be attached to the productions of the Context Free Grammar are discussed in this module and some example control flow statements are discussed. 26.1Need for Backpatching The syntax directed definition to generate three-address code is typically done in two passes. In the first pass the syntax tree is constructed and annotated with rules. In the second pass a depth first search of the tree is carried out to perform syntax directed translation. If a statement consists of multiple lines of instructions then the labels to branch may not be known in advance if SDD needs to be done in a single pass. To address this issue we introduce a technique called backpatching. The fundamental behind the technique of backpatching is to generate a series of branching statements with the target of jumps unspecified in the first pass. In the second pass we put each statement in a list and fill them with appropriate true and false labels. 26.2Functions to incorporate backpatching Backpatching technique is incorporated using three functions. Makelist(), merge() and backpatch() are the three functions carried out in two passes to generate code using backpatching. makelist(i) This is used to create a new list containing three-address location i, and it returns a pointer to the list. This is the first function which is created to form a true / false list. merge(p 1, p 2 ) This function concatenates lists pointed to by p 1 and p 2, returns a pointer to the concatenated list. This is used to assign the same true / false labels to more than one address. backpatch(p, i) This function is used to insert i' as the target label for each of the statements in the list pointed to by p. Using the information provided by this function labels are attached to all the statements. Consider the Boolean expression a < b or c < d and e < f. To generate three-address code for this, we have already incorporated semantic rules in the previous module. In backpatching the same code is generated in two passes. In the first pass, the following would be generated: 100: if a < b goto _ 101: goto _

102: if c < d goto _ 103: goto _ 104: if e < f goto _ 105: goto _ In the second pass, the same code is re-run to generate the true, false labels by incorporating short circuit information. 100: if a < b goto TRUE 101: goto 102 102: if c < d goto 104 103: goto FALSE 104: if e < f goto TRUE 105: goto FALSE In this module, we will write semantic rules to generate three-address code based in two passes using the backpatching functions discussed already. 26.3Boolean Expressions and Backpatching The productions for the Boolean expressions are the same. To just generate line numbers and to incorporate backpatching we add new non-terminals as part of the production. This non-terminal just produces ε and doesn t alter the string of the grammar. The semantic rules that incorporate backpatching is given in Table 26.1. A function nextquad() is used to generate the next line number for generating three-address code and that is the reason behind introducing the new nonterminal M. Table 26.1 Semantic rules for incorporating Backpatching Production Semantic Rule Inference M ε { M.quad := nextquad() } The semantic rule associated with this variable helps in generating the next line number to generate three address code E E1 or M E2 { backpatch(e 1.falselist, M.quad); Merge function concatenates the E.truelist := merge(e 1.truelist, truelist of E1 and E2. If E1 is false we need to associate the E 2.truelist); false list of E1 with the next line E.falselist := E 2.falselist } number using M.quad. This line will contain the first instruction corresponding to E2 as this will be evaluated only if E1 is false. The expression E s false list will be E2 s false list after incorporating short circuit

E E1 and M E2 E not E1 E (E1) E id1 relop id2 E true E false { backpatch(e 1.truelist, M.quad); E.truelist := E 2.truelist; E.falselist := merge(e 1.falselist, E 2.falselist); } { E.truelist := E 1.falselist; E.falselist := E 1.truelist } { E.truelist := E 1.truelist; E.falselist := E 1.falselist } { E.truelist := makelist(nextquad()); E.falselist := makelist(nextquad() + 1); emit( if id 1.place relop.op id 2.place goto _ ); emit( goto _ ) } { E.truelist := makelist(nextquad()); E.falselist := nil; emit( goto _ ) } { E.falselist := makelist(nextquad()); E.truelist := nil; emit( goto _ ) } Here as the operator is and, we merge the false list of E1 and E2 s and assign as E s false list. The true list of E is E2 s true list as we will be executing E2 only if E1 is true. To execute E2, we backpatch E1 s true to the line number corresponding to E2 s first instruction which is given by M.quad The false and true lists of E and E1 are reversed. The false and true lists of E and E1 are the same as the parenthesis is just to prioritize the expression E1 The line numbers of truelist and falselist for E is considered as the next line number and its following line number. The code is generated using emit in a similar fashion as explained in the previous modules, with the only difference being the goto is left blank which will be backpatched later. Basic terminating production which will generate a goto blank which will be backpatched with truelist s number Basic terminating production which will generate a goto blank which will be backpatched with falselist s number

Example 26.1 Consider the same example Boolean expression a < b or c < d and e < f. The corresponding derivation tree would be as shown in figure 26.1 E (a < b) E1 or M {102} E2 E3 and M E4 (c<d) {104} (e<f) Figure 26.1 Example derivation tree Consider the first instruction is to start at line number 100. The sequence of three-address code is given in Table 26.2 Table 26.2 Three-address code for the tree of figure 26.1 Line Code Truelist Falselist Inference number 100 if a<b goto --- E1 {100) E1 {101} From the semantic rules for a 101 goto ----- Boolean expression E1 as given in Table 26.1, the two instructions are generated and the corresponding truelist and falselist is given as the line number and the following line number 102 if c < d goto ------- E3 {102} E3 {103} Using M.quad, 102 line 103 goto --------- number is generated. Using the same semantic rule, E3 s truelist and false list are also generated 104 if e < f goto ------ E4 {104} E4 {105} Using the M of the and 105 goto ------------- expression we generate 104 as the line number. Using the same semantic rule, E4 s truelist and falselist is generated E2 {104} E2 {103, 105} E2 is the and of E3 and E4. Using the semantic rule, the false list of E2 is the merger of falselist of E3 and E4. The

E {100, 104} E {103, 105} truelist of E2 is the truelist of E4 E is the or of E1 and E2. So the truelist of E is the truelist of the merger of E1 and E2. The falselist of E is the false list of E2 100 if a<b goto TRUE At line number s 100 and 104, overall True value should be backpatched as E.true is {100, 104} 101 goto 102 To execute the expression E3 102 if c < d goto 104 To execute E4 103 goto FALSE At line number s 103, 105 overall false should be backpatched as E.false is {103, 105} 104 if e < f goto TRUE At line number s 100 and 104, overall True value should be backpatched as E.true is {100, 104} 105 goto FALSE At line number s 103, 105 overall false should be backpatched as E.false is {103, 105 26.4 Control flow statements and Backpatching Control flow statements have been discussed in the previous module along with their semantic rules. As Boolean expressions are part of control flow statements, backpatching can be applied to control flow statements also. Consider the following grammar with productions for control flow statements. S if E then S if E then S else S while E do S begin L end A L L ; S S Example of the statements could be a sequences of statements separated by ;. S 1 ; S 2 ; S 3 ; S 4 ; S 5 ; etc. The attributes of S is S.nextlist which will backpatch list for jumps to the next statement after S (or nil). Similarly the attributes of L is also L.nextlist which backpatch list for jumps to the next statement after L (or nil). For the example of the sequence of statements S1, S2, S3, S4, S5, etc.. we will have the code for S1 to S5 followed by the backpatch of each statement, to the statement following it.

100: Code for S1 200: Code for S2 300: Code for S3 400: Code for S4 500: Code for S5 The following backpatch will ensure that the sequence of statements are executed in the order. backpatch(s 1.nextlist, 200) backpatch(s 2.nextlist, 300) backpatch(s 3.nextlist, 400) backpatch(s 4.nextlist, 500) Our aim would be to add semantic rules to handle such a scenario and other control flow statements. The semantic rules are given in Table 26.3. In this case also we use a dummy variable M to generate the next line number. Table 26.3 Semantic rules for control flow statements to incorporate backpatching Production Semantic Rules Inference S A { S.nextlist := nil } This production is a termination production and hence there is no need for a backpatch S begin L end { S.nextlist := L.nextlist } Both S and L has a nextlist attribute and they are set to the same. The statements between begin and end are run only once. S if E then M S 1 { backpatch(e.truelist, M.quad); S.nextlist := merge(e.falselist, S 1.nextlist) } The variable M produces ε and it indicates the same semantic rule as discussed in the table 26.1. If the expression is false, then the statement S1 need to be skipped. If Expression is true, then S1 should be executed. In both the scenarios, the statement that is available outside S1 need to be continued. To carry out this, the falselist of E and the nextlist of S1 are merged and that is assigned as S s nextlist. If expression is true then the statement S1 is to be

L L 1 ; M S { backpatch(l 1.nextlist, M.quad); L.nextlist := S.nextlist; } executed. To incorporate this we backpatch the truelist of the expression to S1 which is done with the help of M.quad After executing L1, we need to execute S. To incorporate this we backpatch L1 s nextlist with M.quad which corresponds to the statement comprising S. The next of L and S are same L S { L.nextlist := S.nextlist; } There is no backpatching and we simply say the nextlist of L and S are same S if E then M S 1 N else M 2 S 2 S while M 1 E do M 2 S 1 { backpatch(e.truelist, M 1.quad); backpatch(e.falselist, M 2.quad); S.nextlist := merge(s 1.nextlist, merge(n.nextlist, S 2.nextlist)) } { backpatch(s 1,nextlist, M 1.quad); backpatch(e.truelist, M 2.quad); S.nextlist := E.falselist; emit( goto _ ) } The expression is evaluated and if it is true S1 is to be executed and S2 if the statement is false. This is implemented by backpatching the truelist and falselist to M1.quad and M2.quad which is the beginning of statements S1, S2 respectively. After executing S1, S2 need to be skipped and the statement which is available after S needs to be executed. After executing S2 by skipping S1, we need to execute the statement outside the body of S. To incorporate this we use the symbol N to skip S2. We assign the nextlist of S as S1 s next and S2 s next. The variable M2 helps to go to go to statement S1 if the expression is true. If the expression is false then we need to go to the statement following S1 which is done as the nextlist of S the same as E s falselist. To incorporate continuation of the loop, M1 is used which is to come back after finishing

N { N.nextlist := makelist(nextquad()); emit( goto _ ) } S1. This is same as S.begin which was discussed in the previous module. The goto is to loop again to execute the expression E. The goto is to skip S2 which is part of if-then-else and go to the statement following S2. The control flow statements are the same as given in the previous module. Let us discuss the concept of control flow statements using an example. Example 26.2 Consider the following code block: while a < b do if c < d then x : = y + z else x : = y - z Using the while and if-then-else grammar the following will be the split While M1 E1 do M2 S1 100 a < b 102 if E then M1 S11 N else M2 S12 c < d 104 x := y+z 105 106 x := y-z The code and the backpatched code are discussed in table 26. 4 Table 26.4 Code and Backpatched code for the example while Line Code Truelist Falselist Inference number 100 if (a<b) goto --- {102} S.nextlist S1 s next is M1.quad and hence is assigned 100. E.truelist is M2.quad and E.falselist is S.nextlist 101 goto --- E.falselist to be backpatched here. 102 if (c < d) goto --- {104} {106} If Expression is true we go to M1.quad and to M2.quad if expression is false. 103 goto ---

104 x:= y + z The statement S11 is evaluated here 105 goto --- This goto is part of the variable N to go to N.nextlist. N.nextlist, S12.nextlist, S11.nextlist all will be S1 s nextlist which is M1.quad 106 x:= y z Statement S12 is evaluated here 107 goto --- S12 s nextlist 108 S.next 100 if (a<b) goto 102 True of the expression to the body of S1 101 goto 108 False of the expression to the statement after the while s body 102 if (c < d) goto 104 To evaluate S11 103 goto 106 To evaluate S12 104 x:= y + z 105 goto 100 To go to S.begin. This is from the semantic rule corresponding to variable N 106 x:= y z 107 goto 100 To go to S.begin. This is from the semantic rule corresponding to while 108 S.next 26.5 Semantic rules for Procedures After discussing the semantic rules for all programming constructs for the Pascal programming language, we will now look at discussing the semantic rules for generating three-address code for procedure calls. Consider the grammar for the procedures as follows: S call id ( Elist ) Elist Elist, E E A statement could involve calling a procedure. A procedure is called with the name and a list of parameters. The first production is to invoke a procedure call. The variable Elist indicates a set of parameters and that is given in the second production. Consider the following example involving a call to a function foo(a+1, b, 7)

. This would be split with new temporary variables t1 and t2 as follows t1 := a + 1 t2 := 7 This will be sequenced using the following split of three-address code. param t1 computing the value a+1 param b computing and accessing b param t2 accessing the value 7 call foo 3 function foo will be called with the queue address having the parameters To incorporate the above sequence of statements for any procedure calls, we will write semantic rules for the same. 1. S call id ( Elist ) The following would be semantic rule. { for each item p on queue do emit( param p); emit( call id.place queue ) } Each of the parameters are split and put on a queue. We generate three address code for each of the parameters p. Then a final three-address code to invoke the procedure with the argument as the address of the queue is generated. 2. Elist Elist, E - append E.place to the end of queue 3. Elist E - initialize queue to contain only E.place Summary: In this module we discussed the backpatching approach to generate three-address code for control flow statements, Boolean expressions and procedures. The next module will discuss the next phase of the compiler namely Code generation.