CS 164 Handout 16. Final Examination. There are nine questions on the exam, some in multiple parts. You have 3 hours to work on the

Similar documents
Midterm I - Solution CS164, Spring 2014

CS 164 Handout 11. Midterm Examination. There are seven questions on the exam, each worth between 10 and 20 points.

CSCI Compiler Design

CS164: Midterm I. Fall 2003

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division. P. N. Hilfinger

CSCE 531, Spring 2015 Final Exam Answer Key

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division. P. N. Hilfinger

CS 164 Programming Languages and Compilers Handout 9. Midterm I Solution

Solutions to Written Assignment 4

Midterm II CS164, Spring 2006

COP5621 Exam 4 - Spring 2005

CS143 Final Fall 2009

CS143 Final Spring 2016

CSCE 531 Spring 2009 Final Exam

Faculty of Electrical Engineering, Mathematics, and Computer Science Delft University of Technology

CS 415 Midterm Exam Spring SOLUTION

First Midterm Exam CS164, Fall 2007 Oct 2, 2007

Midterm I (Solutions) CS164, Spring 2002

CS 415 Midterm Exam Fall 2003

CSCI Compiler Design

VIVA QUESTIONS WITH ANSWERS

A Simple Syntax-Directed Translator

CS 164 Programming Languages and Compilers Handout 8. Midterm I

Operational Semantics of Cool

Midterm 2 Solutions Many acceptable answers; one was the following: (defparameter g1

Type Checking. Outline. General properties of type systems. Types in programming languages. Notation for type rules.

Outline. General properties of type systems. Types in programming languages. Notation for type rules. Common type rules. Logical rules of inference

MIDTERM EXAM (Solutions)

EXAM. CS331 Compiler Design Spring Please read all instructions, including these, carefully

SYED AMMAL ENGINEERING COLLEGE (An ISO 9001:2008 Certified Institution) Dr. E.M. Abdullah Campus, Ramanathapuram

CS 536 Midterm Exam Spring 2013

UVa ID: NAME (print): CS 4501 LDI Midterm 1

CSE 401/M501 18au Midterm Exam 11/2/18. Name ID #

COP5621 Exam 3 - Spring 2005

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

Faculty of Electrical Engineering, Mathematics, and Computer Science Delft University of Technology

About the Authors... iii Introduction... xvii. Chapter 1: System Software... 1

CS 415 Midterm Exam Spring 2002

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division

Operational Semantics of Cool

1. Explain the input buffer scheme for scanning the source program. How the use of sentinels can improve its performance? Describe in detail.

Section A. A grammar that produces more than one parse tree for some sentences is said to be ambiguous.

CS143 - Written Assignment 4 Reference Solutions

CS164: Final Exam. Fall 2003

CS 406/534 Compiler Construction Putting It All Together

Lecture Outline. COOL operational semantics. Operational Semantics of Cool. Motivation. Lecture 13. Notation. The rules. Evaluation Rules So Far

2. Reachability in garbage collection is just an approximation of garbage.

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

QUESTIONS RELATED TO UNIT I, II And III

Briefly describe the purpose of the lexical and syntax analysis phases in a compiler.

CS143 Midterm Fall 2008

CS143 Midterm Sample Solution Fall 2010

Time : 1 Hour Max Marks : 30

DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING Subject Name: CS2352 Principles of Compiler Design Year/Sem : III/VI

KINGS COLLEGE OF ENGINEERING DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING ACADEMIC YEAR / EVEN SEMESTER

4. An interpreter is a program that

CS606- compiler instruction Solved MCQS From Midterm Papers

Run-Time Environments

11. a b c d e. 12. a b c d e. 13. a b c d e. 14. a b c d e. 15. a b c d e

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

Fall 2016 CSE Qualifying Exam CSCE 531, Compilers

PRINCIPLES OF COMPILER DESIGN

Semantic Analysis and Type Checking

Question Bank. 10CS63:Compiler Design

EDAN65: Compilers, Lecture 06 A LR parsing. Görel Hedin Revised:

Today's Topics. CISC 458 Winter J.R. Cordy

MIDTERM EXAMINATION - CS130 - Spring 2003

Two hours UNIVERSITY OF MANCHESTER SCHOOL OF COMPUTER SCIENCE. Date: Friday 20th May 2016 Time: 14:00-16:00

The PCAT Programming Language Reference Manual

CSE 5317 Midterm Examination 4 March Solutions

COMP-421 Compiler Design. Presented by Dr Ioanna Dionysiou

About the Tutorial. Audience. Prerequisites. Copyright & Disclaimer. Compiler Design

COMPILER CONSTRUCTION LAB 2 THE SYMBOL TABLE. Tutorial 2 LABS. PHASES OF A COMPILER Source Program. Lab 2 Symbol table

CSE 401 Final Exam. March 14, 2017 Happy π Day! (3/14) This exam is closed book, closed notes, closed electronics, closed neighbors, open mind,...

Syntax-Directed Translation. Lecture 14

1 Lexical Considerations

Overview of Semantic Analysis. Lecture 9

2.2 Syntax Definition

Lexical Considerations

A simple syntax-directed

Question Points Score

UNIVERSITY OF CALIFORNIA

The SPL Programming Language Reference Manual

CSE 401 Final Exam. December 16, 2010

Faculty of Electrical Engineering, Mathematics, and Computer Science Delft University of Technology

Operational Semantics. One-Slide Summary. Lecture Outline

CSC 467 Lecture 13-14: Semantic Analysis

CS5363 Final Review. cs5363 1

HW 3: Bottom-Up Parsing Techniques

SYLLABUS UNIT - I UNIT - II UNIT - III UNIT - IV CHAPTER - 1 : INTRODUCTION CHAPTER - 4 : SYNTAX AX-DIRECTED TRANSLATION TION CHAPTER - 7 : STORA

CS 2210 Sample Midterm. 1. Determine if each of the following claims is true (T) or false (F).

MODEL ANSWERS COMP36512, May 2016

Compilers. Type checking. Yannis Smaragdakis, U. Athens (original slides by Sam

Formal Languages and Compilers Lecture X Intermediate Code Generation

CSE 582 Autumn 2002 Exam 11/26/02

COL728 Minor1 Exam Compiler Design Sem II, Answer all 5 questions Max. Marks: 20

RYERSON POLYTECHNIC UNIVERSITY DEPARTMENT OF MATH, PHYSICS, AND COMPUTER SCIENCE CPS 710 FINAL EXAM FALL 96 INSTRUCTIONS

COMPILER DESIGN. For COMPUTER SCIENCE

CODE GENERATION Monday, May 31, 2010

COP4020 Spring 2011 Midterm Exam

Transcription:

Final Examination Please read all instructions (including these) carefully. Please print your name at the bottom of each page on the exam. There are nine questions on the exam, some in multiple parts. You have 3 hours to work on the exam. The exam is closed book, but you may refer to your four sheets of prepared notes. Please write your answers in the space provided on the exam, and clearly mark your solutions. You may use the backs of the exam pages as scratch paper. Please do not use any additional scratch paper. Solutions will be graded on correctness and clarity. There are no \tricky" problems on the exam each problem has a relatively simple and straightforward solution. You may get as few as 0 points for a question if your solution is far more complicated than necessary. NAME: Sam P. L. Solution SID or SS#: Problem Max points Points 1 10 2 15 3 50 4 20 5 20 6 15 7 35 8 15 9 20 TOTAL 200 Fall 94 page 1 of 15

1. Scope (10 points) Give a simple program that produces dierent results if executed using lexical scoping than if executed using dynamic scoping. Show what your program produces in both cases. Use any reasonable and clear programming notation. main() var x; proc p1 var x; x := 1; p2(); proc p2 print(x); x := 0; p1(); This program prints 0 with lexical scope and 1 with dynamic scope. Fall 94 page 2 of 15

2. Parsing (15 points) For each of the following questions, we are looking for clarity and brevity as well as the right idea. (a) (5 points) Give a denition of the term derivation. What is a left-most derivation? Begin with the start symbol S. At each step, choose a non-terminal X and replace it by Y1...Yn, where X -> Y1...Yn is a production of the grammar. Any sequence of such replacements is a derivation. A left-most derivation always chooses the leftmost non-terminal for replacement. You could also say that a derivation ends in a string of terminals, but this is not required for full credit. (b) (5 points) Give one advantage of SLR(1) grammars over LR(1) grammars; give one advantage of LR(1) grammars over SLR(1) grammars. An SLR(1) parser generator produces tables of practical size, whereas an LR(1) parser generator often produces tables too large to be useful for realistic languages. larger than the class of SLR(1) grammars. On the other hand, the class of LR(1) grammars is (c) (5 points) Consider a bottom-up parser for a grammar with no -productions and no single productions (i.e., productions with a single symbol on the right-hand side). For an input string with n tokens, what is the maximum number of reduce moves the parser can make? Why? All productions in the grammar have at least two symbols on the right-hand side and one symbol on the left-hand side. Thus, every reduction reduces the number of symbols by at least 1. Therefore, there can be at most n 1 reductions. Fall 94 page 3 of 15

3. (50 points) A few years from now, fanatical graduates of CS164 have succeeded in convincing the world that Cool should replace C++ as the obect-oriented programming language of choice. Naturally, a Cool standards committee is formed. The committee cannot leave a superior design alone and decides that Cool needs some changes. (a) Regular Expressions (10 points) One of the committee members has an obsession with comments. She thinks it is ugly that one cannot write \)" inside a \(" comment; after all, what if that is what you want to write? The proposal is to replace all Cool comments with the following mechanism: A comment begins with one of the special characters $,!, or @ and ends with the same special character. Between the rst and last character, the comment may contain any character except the rst (and last) character. Comments may not be nested. For example,!cool@cs.berkeley.edu! and @Cool code rules!@ are valid comments, but!this is great!! and $Help! are not valid comments. Write a regular expression for comments. Use any reasonable and clear notation. The notation [^c] means "all characters except c." (![^!]*!) (@[^@]*@) ($[^$]*$) Fall 94 page 4 of 15

Someone else on the committee feels that Cool is not expressive enough. He thinks that Cool simply must have backtracking. The proposed backtracking mechanism has two commands: track (e 1 ; e 2 ; : : : ; e n ) back Informally, a track command is evaluated as follows. First, e 1 is evaluated. If e 1 terminates normally, then the result of the expression is the result of evaluating e 1. If e 1 fails (see below), then e 2 is evaluated. If e 2 terminates normally, the result is the value of e 2 ; if e 2 fails, then e 3 is evaluated. This process continues until one of the expressions does not fail. A back command causes a tracked computation to fail. When a back command is executed, control is transferred to the nearest lexically enclosing track command and the next expression is evaluated. The following example evaluates to \1": track (begin 3; back; end, back, 1) (b) Parsing (10 points) Consider the following very simplied grammar for Cool expressions with track and back: E! if E then E else E while E loop E pool track ( ELIST back ELIST! E ) E; ELIST Boldface denotes a keyword, capitalized words are non-terminals, and lowercase words are terminals. A member of the committee observes that the semantics of track(e 1 ; : : : ; e n ) is undened if all of the expressions fail. A simple way to guarantee that at least one expression succeeds is to forbid back statements inside the last expression e n, except for back statements in (all but the last expression of) nested track statements. Rewrite the grammar so that e 1 ; : : : ; e n 1 may contain back statements, but e n cannot, except for nested track statements, where the same rule applies recursively. Your grammar should allow any other proper nesting of expressions. Don't use ellipses (: : : ) in your grammar. E! if E then E else E while E loop E pool track ( ELIST back ELIST! F ) E; ELIST F! if F then F else F while F loop F pool track ( ELIST Fall 94 page 5 of 15

(c) Type Checking (10 points) Write a sound type checking rule for a track expression. Your rule should be reasonably precise it isn't OK simply to say it has type Obect. (Note: Don't worry about the type of back; you don't need it to answer this question.) A typechecking rule is easy to write using the least-upper bound operation on Cool types: A - ei : Ti 1 <= i <= n -------------------------------------- A - track(e1,...,en) : lub(t1,...,tn) Another correct, but less general, answer is: A - ei : T 1 <= i <= n --------------------------- A - track(e1,...,en) : T (d) Code Generation and Semantic Actions (20 points) Write semantic actions to generate code for the original grammar (not the one you wrote) in part (b). For this problem, we are interested only that you generate the correct control structure. Your semantic actions should use attributes. Assign to attribute E:code the code for expression E. You may use any other attributes (inherited or synthesized) you wish. Show the attribute denitions for each production. Use only the following pseudo-assembly instructions in your solution: JUMP L JUMPF L LABEL L unconditional ump to label L ump to label L if the previous instruction evaluates to false gives the label L to the next executable instruction You may use a function newlabel() that returns a unique label. The code attribute is a string; s1s2 denotes concatenation of two strings s1 and s2. To help you get started, a partial solution for while loops is given below (the solution is partial because you may need to add attributes): production: E 1! while E 2 loop E 3 pool while.top = newlabel() while.exit = newlabel() E 1 :code = LABEL while:top E 2 :code JUMPF while:exit E 3 :code JUMP while:top LABEL while:exit If all expressions in a track command fail, the code should ump to the label ERROR. Don't worry about adusting the stack or modifying registers. Do not change the grammar. Fall 94 page 6 of 15

(This page intentionally left almost blank.) E1 -> if E2 then E3 else E4 if.flabel = newlabel() if.exit = newlabel() E1.code = E2.code JUMPF if.flabel E3.code JUMP if.exit LABEL if.flabel E4.code LABEL if.exit E2.label = E3.label = E4.label = E1.label E1 -> while E2 loop E3 pool rules given above, plus: E2.label = E3.label = E1.label E -> track ( ELIST ELIST.exit = newlabel() E.code = ELIST.code LABEL ELIST.exit E -> back E.code = JUMP E.label ELIST -> E ) E.label = ERROR ELIST.code = E.code ELIST1 -> E, ELIST2 ELIST2.exit = ELIST1.exit E.label = newlabel() ELIST1.code = E.code JUMP ELIST1.exit LABEL E.label ELIST2.code Fall 94 page 7 of 15

4. Activation Records (20 points) Consider a program with the following lexical structure. The program is written in a lexically scoped language with nested procedures (like Pascal): proc P() proc Q(proc T()) proc R() proc S() P; R, and S are parameterless procedures; Q takes a parameterless procedure T as a parameter. Suppose that at run-time the following sequence of calls is made: P is called from some lexically-enclosing main program P calls R R calls S S calls P P calls R R calls Q with S as a parameter Q calls T T calls S Draw the stack of activation records present after this sequence of calls. You don't need to show the entire contents of the activation record for each indicate only the name of the procedure being activated, the control (dynamic) link for that activation record, and the access (static) link for that activation record. Fall 94 page 8 of 15

(This page intentionally left almost blank.) Dynamic Links S T Q R P S R P Main Access Links Stack grows upwards. Fall 94 page 9 of 15

5. Cool and Type Checking (20 points) Consider the following Cool program. In the blanks provided, you should ll in both missing type declarations and the types inferred by the compiler for each expression. Fill in the most specic (most accurate) type possible. The nal program should type check correctly using the declarations you ll in. Each blank is the type of the expression immediately to the left; parentheses have been added where necessary to make clear which expression is meant. Class A is a : Int ; init(x : Int ) : SELF TYPE is begin (a Int x Int ) Int ; self SELF TYPE end SELF TYPE Class B inherits A is b : Int 1 Int ; getb() : Int is b Int Class C inherits A is c : Int 2 Int ; getc() : Int is c Int class Main inherits IO is main() : A is let y : Bool in case (if (y Bool ((in int() Int = 0 Int ) Bool )) Bool then (new B) B else (new C) C ) A of x : B ) (x B.init((x B.getb()) Int )) B ; y : C ) (y C.init((y C.getc()) Int )) C ; esac A end A end Fall 94 page 10 of 15

6. (Garbage Collection) (15 points) Garbage collect the following heap using Mark & Sweep garbage collection. Clearly indicate which cells will be marked, and construct the free list resulting from the collection. A B C D E F G Freelist Root nil H I Marked: C,E,F,G,H,I Free-list -> A -> B -> D Fall 94 page 11 of 15

7. (Dataow Analysis and Register Allocation) (35 points) Consider the following fragment of intermediate code: L0: x <- y + x w <- 2 * x if s = u goto L1 x <- w + u u <- u - 1 goto L2 L1: s <- w + 1 L2: y <- s + x if y > 1000 goto L0 L3: (a) (5 points) Draw a control-ow graph for this piece of code. Place each basic block in a single node; be sure to include the conditionals in the basic blocks. (b) (15 points) Annotate your control-ow graph with the set of variables live before and after every statement (not ust before and after every block!), assuming that s and u are live at label L3. Make sure it is clear where your annotations are placed. {s,u,x} {s,u,w,x} {s,u,w,x} {u,w,x} x <- y + x w <- 2 * x if s = u goto L1 {s,u,x,y} {s,u,w} s <- w + 1 {s,u,x} {s,u,x} x <- w + u u <- u - 1 {s,u,x} {s,u,x,y} y <- s + x if y > 1000 goto L0 L3 {s,u} {s,u,x,y} Fall 94 page 12 of 15

(c) (15 points) Draw the register interference graph for the intermediate code given on the previous page. S Y U W X Fall 94 page 13 of 15

8. Type Checking (15 points) Consider the following C-like expression language: e! e 1 [e 2 ] In this grammar, i represents an integer. Now consider the following type language and type rules: T! int &e e i pointer(t) array(t) A ` i : int A ` e 1 : array(t) A ` e 2 : int A ` e 1 [e 2 ] : T A ` e : T A ` &e : pointer(t) A ` e : pointer(t) A ` e : T [IN T ] [ARRAY ] [P OIN T ER] [DEREF ] Now consider the expression &((B)[1]). (The parentheses are included only to clarify precedence and are not part of the expression.) Given the type assumptions A = fb : pointer(array(int))g, show the type derivation for the expression. Indicate the rule you use at each step. A - B : pointer(array(int)) ----------------------------- [DEREF] ------------ [INT] A - *B : array(int) A - 1 : int -------------------------------------------- [ARRAY] A - (*B)[1] : int ------------------------------------------------------ [POINTER] { B:pointer(array(int)) } - &((*B)[1]) : pointer(int) Fall 94 page 14 of 15

9. Optimization (20 points) Consider the following fragment of intermediate code: y := w z := 4 v := y * y u := z + 2 r := w ** 2 (* exponentiation *) t := r + v s := u * t Assume that only the variable s is live on exit from this fragment. Show the result of applying as much constant propagation, algebraic simplication, common sub-expression elimination, constant folding, and dead code elimination as possible to this code. Show the optimizations you perform and the order in which they are applied as part of your answer. You need not show the entire code sequence after every optimization, but you should explain clearly what changes at each step. w ** 2 => w * w algebraic simplification/strength reduction replace y by w copy propagation replace r := w * w by r := v common subexpression elimination replace r by v copy propagation replace z by 4 constant propagation replace 4+2 by 6 constant folding replace u by 6 constant propagation remove assignments to y,z,u,r dead code elimination Result: v := w * w t := v + v s := 6 * t If you wanted to get really fancy---not required for full credit---you could continue: t := 2 * v replace s := 6 * t by 12 * v eliminate assignment to t algebraic "optimization" (see below) a kind of constant propagation dead code Result: v := w * w s := 12 * v Most compilers will not find this last sequence of optimizations, because the step v + v => 2 * v is not an improvement on most machines (in other words, * is usually slower than +). Fall 94 page 15 of 15