Solutions for Midterm Exam 2 - Programming Languages and Compilers | CS 421, Exams of Computer Science

Material Type: Exam; Class: Progrmg Languages & Compilers; Subject: Computer Science; University: University of Illinois - Urbana-Champaign; Term: Spring 2007;

Typology: Exams

Pre 2010

Uploaded on 03/16/2009

koofers-user-0uh
koofers-user-0uh 🇺🇸

10 documents

1 / 5

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Solutions for Sample Questions for Midterm 2 (CS 421 Spring 2007)
On the actual midterm, you will have plenty of space to put your answers.
Some of these questions may be reused for the exam.
1. Write the definition of an OCaml variant type reg_exp to express abstract syntax
trees for regular expressions over a base character set of booleans. Thus, a
boolean is a reg_exp, epsilon is a reg_exp, the concatenation of two reg_exp’s is
a reg_exp, the “choice” of two reg_exp’s is a reg_exp, and the Kleene star of a
reg_exp is a reg_exp.
Solution:
type reg_exp =
Epsilon
| Var of bool
| Choice of (reg_exp * reg_exp)
| Concat of (reg_exp * reg_exp)
| Kleene_star of reg_exp
| Paren of reg_exp (* I would accept it with this case missing *)
2. Given the following OCAML datatype:
type int_seq = Null | Snoc of (int_seq * int)
write a tail-recursive function in OCAML all_pos : int_seq -> bool that returns true if
every integer in the input int_seq to which all_pos is applied is strictly greater than 0
and false otherwise. Thus all_pos (Snoc(Snoc(Snoc(Null,3),5),7)) should returns true,
but
all_pos (Snoc(Null,~1)) and all_pos (Snoc(Snoc(Null, 3),0)) should both return
false.
Solution:
let rec all_pos s =
(match s with Null -> true
| Snoc(seq, x) -> if x <= 0 then false else all_pos seq);;
3. Using the rules provided in class, derive a valid type judgment for
let rec fact = fun n -> if n = 0 then 1 else let r = fact (n - 1) in n * r in fact;;
(The rules will be provided for you on the exam, if this kind of question is asked.)
Solution: (I didn’t just write the tree because it wouldn’t fit.)
By the let_rec rule we have
(1) {fact : int -> int} |- (fun n -> if n = 0 then 1 else let r = fact (n – 1) in n * r) : int -> int
(2) {fact : int -> int} |- fact : int -> int
{} |- let rec fact = fun n -> if n = 0 then 1 else let r = fact (n – 1) in n * r in fact : int -> int
(2) is valid by the variable rule:
(2) {fact : int -> int} |- fact : int -> int
pf3
pf4
pf5

Partial preview of the text

Download Solutions for Midterm Exam 2 - Programming Languages and Compilers | CS 421 and more Exams Computer Science in PDF only on Docsity!

Solutions for Sample Questions for Midterm 2 (CS 421 Spring 2007)

On the actual midterm, you will have plenty of space to put your answers. Some of these questions may be reused for the exam.

  1. Write the definition of an OCaml variant type reg_exp to express abstract syntax trees for regular expressions over a base character set of booleans. Thus, a boolean is a reg_exp, epsilon is a reg_exp , the concatenation of two reg_exp ’s is a reg_exp, the “choice” of two reg_exp ’s is a reg_exp , and the Kleene star of a reg_exp is a reg_exp. Solution: type reg_exp = Epsilon | Var of bool | Choice of (reg_exp * reg_exp) | Concat of (reg_exp * reg_exp) | Kleene_star of reg_exp | Paren of reg_exp (* I would accept it with this case missing *)
  2. Given the following OCAML datatype: type int_seq = Null | Snoc of (int_seq * int) write a tail-recursive function in OCAML all_pos : int_seq -> bool that returns true if every integer in the input int_seq to which all_pos is applied is strictly greater than 0 and false otherwise. Thus all_pos (Snoc(Snoc(Snoc(Null,3),5),7)) should returns true, but all_pos (Snoc(Null,~1)) and all_pos (Snoc(Snoc(Null, 3),0)) should both return false. Solution: let rec all_pos s = (match s with Null -> true | Snoc(seq, x) -> if x <= 0 then false else all_pos seq);;
  3. Using the rules provided in class, derive a valid type judgment for let rec fact = fun n -> if n = 0 then 1 else let r = fact (n - 1) in n * r in fact;; (The rules will be provided for you on the exam, if this kind of question is asked.) Solution: (I didn’t just write the tree because it wouldn’t fit.) By the let_rec rule we have (1) {fact : int -> int} |- (fun n -> if n = 0 then 1 else let r = fact (n – 1) in n * r) : int -> int (2) {fact : int -> int} |- fact : int -> int {} |- let rec fact = fun n -> if n = 0 then 1 else let r = fact (n – 1) in n * r in fact : int -> int (2) is valid by the variable rule: (2) {fact : int -> int} |- fact : int -> int

By the fun rule we have (3) {n : int, fact : int -> int} |- (if n = 0 then 1 else let r = fact (n – 1) in n * r) : int (1) {fact : int -> int} |- (fun n -> if n = 0 then 1 else let r = fact (n – 1) in n * r) : int -> int By the if_then_else rule we have (4) {n : int, fact : int -> int} |- (n = 0) : bool (5) {n : int, fact : int -> int} |- 1:int (6) {n : int, fact : int -> int} |- (let r = fact (n – 1) in n * r) : int (3) {n : int, fact : int -> int} |- (if n = 0 then 1 else let r = fact (n – 1) in n * r) : int (5) is valid by the rule for constants. By the rule for binary relations we have (7) {n : int, fact : int -> int} |- n : int (8) ) {n : int, fact : int -> int} |- 0 : int (4) {n : int, fact : int -> int} |- (n = 0) : bool (7) is valid by the rule for variables. (8) is valid by the rule for constants. By the rule for let, we have (9) {n:int, fact:int -> int} |- fact (n – 1) : int (10) {r:int, n:int, fact:int -> int} |- (n * r) : int (6) {n : int, fact : int -> int} |- (let r = fact (n – 1) in n * r) : int By the rule for applications we have (11) {n:int, fact:int -> int} |- fact : int -> int (12){n:int, fact:int -> int} |- (n – 1) : int (9) {n:int, fact:int -> int} |- fact (n – 1) : int (11) is valid by the variable rule. By the rule for binary operations, we have (13){n:int, fact:int -> int} |- n : int (14){n:int, fact:int -> int} |- 1 : int (12){n:int, fact:int -> int} |- (n – 1) : int (13) is valid by the variable rule. (14) is valid by the constant rule. Thus (12) is valid. Thus (9) is valid. We have (10) left. By the rule for binary operations we have: (15) {r:int, n:int, fact:int -> int} |- n: int (16) {r:int, n:int, fact:int -> int} |- r : int (10) {r:int, n:int, fact:int -> int} |- (n * r) : int (15) and (16) are both valid by the variable rule. Hence (10) is valid. Hence (6) is valid. Hence (3) is valid, and hence (1) is valid

  1. G!i!v!e! !a! (most general) !u!n!i!f!i!e!r! !f!o!r! !t!h!e! !f!o!l!l!o!w!i!n!g! !u!n!i!f!i!c!a!t!i!o!n! !i!n!s!t!a!n!c!e!.! !Capital !l!e!tt!!e!r!s! ! d!e!n!o!t!e! !v!a!r!i!a!b!l!e!s! !o!f! !u!n!i!f! i!c!a!t!i!o!n!.! !S!h!o!w! !y!o!u!r! !w!o!r!k! !b!y! !l!i!s!t!i!n!g! !t!h!e! !o!p!e!r!a!t!i!o!n! ! p!e!r!f!o!r!m!e!d! !i!n! !e!a!c!h! !s!t!e!p! !o!f! !t!h!e! !u!n!i!f!i!c!a!t!i!o!n! !a!n!d! !t!h!e! !r!e!s!u!l!t! !o!f! !t!h!a!t! !s!t!e!p!.! !!! {X = f(g(x),W), h(y) = Y, f(Z,x) = f(Y,W)} Solution:
  1. Consider the following grammar: ::= | ::= | ( ::= ] | | ( ::= 0 | 1 For each of the following strings, give a parse tree for the following expression as an , if one exists, or write “No parse” otherwise: a. ( 0 1 ( 1 ] ( ( 1 0 ] 1 Solution:

( ( 0 ( 1 ( 1 ] 1 ] 0 b. 0 ( 1 0 ( 1 ] Solution:

0 ( 1 0 ( ] c. ( 0 ( 1 0 1] 0 ] Solution: No parse tree

  1. Consider the following ambiguous grammar (Capitals are nonterminals, lowercase are terminals): S → A a B | B a A A → b | c B → a | b Give an example of a string for which this grammar has two different parse trees, and give its parse trees. Solution: String: bab S S A a B B a A b b b b
  2. Write an unambiguous grammar generating the set of all strings over the alphabet {0, 1, +, - } , where + and – are infixed operators which both associate to the left and such that + binds more tightly than -. Solution: ::= || - :: | + ::= 0 | 1