7 Solved Questions on Programming Languages - Midterm Exam | CS 421, Exams of Computer Science

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

Typology: Exams

Pre 2010

Uploaded on 03/16/2009

koofers-user-p0w
koofers-user-p0w 🇺🇸

2

(1)

10 documents

1 / 13

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS 421—Summer 2008 1 CS421 Summer 2008 Midterm Solutions
CS421 Summer 2008 Midterm Solutions
CS 421 Programming Languages and Compilers
Summer Term 2008
11:30am–12:45pm, Monday, July 7, 2008
The total time for this exam is 75 minutes.
Print your name and netid below. Also write your name at the bottom of each subsequent page.
Name:
Netid:
This is a closed-book exam. You are allowed one 3 inch by 5 inch card of notes prepared
by yourself. You may write on both sides of the card. This card is not to be shared. All
other materials, besides pens, pencils, and erasers, are to be put away.
Do not share anything with other students. Do not talk to other students. Do not look at
another student’s exam. Also, be careful to not expose your exam to easy viewing by other
students. Violation of any of these rules will count as cheating.
If you believe there is an error, or an ambiguous question, you must document your assump-
tions about what the question means. We are not allowed to answer questions about the exam
in class, and obviously cannot answer these questions for students taking the exam elsewhere.
Including this cover sheet, rules at the end, and scratch pages, there are 13 pages to the exam.
Please verify that you have all 13 pages. You are allowed to tear off the last three (rules and
scratch) if this makes it easier to take the test.
Question Total points Score
1 10
2 15
3 15
4 8
5 12
6 20
7 20
SUBTOTAL 100
Extra Credit 12
TOTAL 112
University of Illinois at Urbana-Champaign Netid:
pf3
pf4
pf5
pf8
pf9
pfa
pfd

Partial preview of the text

Download 7 Solved Questions on Programming Languages - Midterm Exam | CS 421 and more Exams Computer Science in PDF only on Docsity!

CS421 Summer 2008 Midterm Solutions

CS 421 — Programming Languages and Compilers

Summer Term 2008

11:30am–12:45pm, Monday, July 7, 2008

The total time for this exam is 75 minutes.

Print your name and netid below. Also write your name at the bottom of each subsequent page.

Name:

Netid:

  • This is a closed-book exam. You are allowed one 3 inch by 5 inch card of notes prepared by yourself. You may write on both sides of the card. This card is not to be shared. All other materials, besides pens, pencils, and erasers, are to be put away.
  • Do not share anything with other students. Do not talk to other students. Do not look at another student’s exam. Also, be careful to not expose your exam to easy viewing by other students. Violation of any of these rules will count as cheating.
  • If you believe there is an error, or an ambiguous question, you must document your assump- tions about what the question means. We are not allowed to answer questions about the exam in class, and obviously cannot answer these questions for students taking the exam elsewhere.
  • Including this cover sheet, rules at the end, and scratch pages, there are 13 pages to the exam. Please verify that you have all 13 pages. You are allowed to tear off the last three (rules and scratch) if this makes it easier to take the test.

Question Total points Score 1 10 2 15 3 15 4 8 5 12 6 20 7 20 SUBTOTAL 100 Extra Credit 12 TOTAL 112

  1. Short Answer Questions (10 points):

(a) In the following, state TRUE or FALSE for each part separately; each part is 1 point (write your answers to the left): A typical dynamically-typed language: i. assigns types to all expressions at compile time FALSE ii. allows variables to hold values of different types at runtime TRUE iii. always detects all potential type errors in a program FALSE iv. checks that correct types are used in an expression when that expression is executed TRUE

(b) In the following, state TRUE or FALSE for each part separately; each part is 1 point (write your answers to the left): Lexing and parsing: i. any language construct that can be defined with a regular expression can also be defined with a context-free grammar TRUE ii. any language construct that can be defined with a context-free grammar can also be defined with a regular expression FALSE iii. an LL(1) parser can be created for any context-free grammar FALSE iv. LR parsing techniques are strictly more powerful than LL parsing techniques TRUE

(c) (2 points) What value is produced by the following program? let x = 5 and y = 10 in let y = x + y in let f x = x + y in let x = y + x in f x 35

  1. Higher-Order Functions and Data Types (15 points):

You are allowed to use all functions in List, such as List.rev, List.fold left, etc – you do not have to write them yourself.

Given the following OCaml datatype: type list_tree = Empty | Node of list_tree * list_tree | Leaf of int list;; (a) (5 points) Write a recursive function fold list tree: val fold_list_tree : (’a -> ’a -> ’a) -> (int list -> ’a) -> ’a -> list_tree -> ’a = that folds a function over a list tree. It should take a function that works over Nodes (typed between the first set of parens in the type signature for fold list tree), a function that works over Leafs (typed between the second set of parens in the type signature for fold list tree), and an identity for Empty, as well as the list tree, returning the value of the fold computation. 1 # let rec fold_list_tree nf lf i tree = 2 match tree with 3 | Empty -> i 4 | Node (lt,rt) -> nf (fold_list_tree nf lf i lt) (fold_list_tree nf lf i rt) 5 | Leaf il -> lf il 6 val fold_list_tree : 7 (’a -> ’a -> ’a) -> (int list -> ’a) -> ’a -> list_tree -> ’a =

(b) (5 points) Write a function prod list tree, using fold list tree, that will calcu- late the product of all the integers stored in the integer lists in the Leaf nodes of the list tree. 1 # let prod_list_tree lt = 2 fold_list_tree (fun x y -> x * y) (fun il -> List.fold_left ( * ) 1 il) 1 lt 3 val prod_list_tree : list_tree -> int = 4 # lt1;; 5 - : list_tree = 6 Node (Node (Leaf [1; 2; 3], Empty), 7 Node (Node (Leaf [4; 5; 6], Leaf [7; 8; 9]), Node (Empty, Leaf []))) 8 # prod_list_tree lt1;; 9 - : int = 362880

(c) (5 points) Write a function flip list tree, using fold list tree, that will switch the left and right trees in any Node and reverse the lists stored in any Leaf. 1 # let flip_list_tree lt = 2 fold_list_tree (fun x y -> Node (y, x)) (fun il -> Leaf (List.rev il)) Empty lt;; 3 val flip_list_tree : list_tree -> list_tree = 4 # lt1;; 5 - : list_tree = 6 Node (Node (Leaf [1; 2; 3], Empty), 7 Node (Node (Leaf [4; 5; 6], Leaf [7; 8; 9]), Node (Empty, Leaf []))) 8 # flip_list_tree lt1;; 9 - : list_tree = 10 Node (Node (Node (Leaf [], Empty), Node (Leaf [9; 8; 7], Leaf [6; 5; 4])), 11 Node (Empty, Leaf [3; 2; 1]))

  1. Regular Expressions (8 points):

(a) (4 points) Over the alphabet {a, b, c}, give a regular expression generating exactly those strings over {a, b, c} such that no b occurs after the final c. Remember, this does not mean the string needs to contain a c!

(a + b)∗^ + ((a + b + c)∗ca∗)

(b) (4 points) Over the alphabet {a, b, c}, give a regular expression generating exactly those strings over {a, b, c} where any a in the string occurs before any b but after at least one c (i.e. if there is an a in the string, there is at least one c before it; a mix of a and c characters can then occur, followed by a mix of b and c characters; if there is no a, c is allowed but not required.).

(c(c + a)∗(c + b)∗) + (b + c)∗

  1. Context-Free Grammars, Derivations, and Parse Trees (20 points): The following ex- ercises make use of this grammar for arithmetic expressions. Here, the start symbol is E, id refers to identifiers made up of one lowercase character (a, b, · · · , y, z), and num refers to any integer:

E → E + T T → T ∗ F F → id E → E − T T → T /F F → num E → T T → F F → (E)

(a) (5 points) Show a leftmost derivation for the following term: x ∗ y + (5 − 3)

E ⇒ E + T ⇒ T + T ⇒ T ∗ F + T ⇒ F ∗ F + T ⇒ x ∗ F + T ⇒ x ∗ y + T ⇒ x ∗ y + F ⇒ x ∗ y + (E) ⇒ x ∗ y + (E − T ) ⇒ x ∗ y + (T − T ) ⇒ x ∗ y + (F − T ) ⇒ x ∗ y + (5 − T ) ⇒ x ∗ y + (5 − F ) ⇒ x ∗ y + (5 − 3)

(b) (5 points) Show a rightmost derivation for the same term:

E ⇒ E + T ⇒ E + F ⇒ E + (E) ⇒ E + (E − T ) ⇒ E + (E − F ) ⇒ E + (E − 3) ⇒

E + (T − 3) ⇒ E + (F − 3) ⇒ E + (5 − 3) ⇒ T + (5 − 3) ⇒ T ∗ F + (5 − 3) ⇒

T ∗ y + (5 − 3) ⇒ F ∗ y + (5 − 3) ⇒ x ∗ y + (5 − 3)

E → E + T T → T ∗ F F → id E → E − T T → T /F F → num E → T T → F F → (E)

(c) (6 points) Provide a parse tree for the same term, x ∗ y + (5 − 3), using the canonical derivation. Note here that we don’t need to bother with the derivation order here, since the grammar is unambiguous – if this grammar were ambiguous, the derivation would matter, since we could get different parse trees:

E

E +^ T

T F

T * F (^ E )

F y^ E -^ T

x (^) T F

F 3

(d) (2 points, circle the answer) Is there a unique parse tree for this term? True /False If this were not true, then we would have two different ways of interpreting this term in the language.

(e) (2 points, circle the answer) Is there a unique leftmost derivation for this term? True /False If this were not true, we would have an ambiguous grammar.

  1. Extra Credit: Unification (12 points):

(a) (10 points) Give a most general unifier for the following unification problem. Lower case letters (f, g, h, a, b, c) are constants or term constructors: specifically, f is a term constructors with arity 2, g and h are term constructors with arity 1, and a, b, and c are constant terms with arity 0. Letters α,β, δ, and γ are variables. Show your work by listing the operation performed in each step of unification – decompose, orient, delete, eliminate – and the result of the step. If unification is not possible, work as far as possible and show where unification fails. If unification does not fail, show the final substitution, which should be a set of variable to term mappings.

{f(f(α, g(b)), g(β)) = f(γ, g(a)) ; g(α) = g(h(δ)) ; f(h(δ), γ) = f(h(c), γ)} decompose {f(α, g(b)) = γ ; g(β) = g(a) ; g(α) = g(h(δ)) ; f(h(δ), γ) = f(h(c), γ)} orient {γ = f(α, g(b)) ; g(β) = g(a) ; g(α) = g(h(δ)) ; f(h(δ), γ) = f(h(c), γ)} decompose {γ = f(α, g(b)) ; β = a ; g(α) = g(h(δ)) ; f(h(δ), γ) = f(h(c), γ)} decompose {γ = f(α, g(b)) ; β = a ; α = h(δ) ; f(h(δ), γ) = f(h(c), γ)} decompose {γ = f(α, g(b)) ; β = a ; α = h(δ) ; h(δ) = h(c) ; γ = γ } delete {γ = f(α, g(b)) ; β = a ; α = h(δ) ; h(δ) = h(c) } decompose {γ = f(α, g(b)) ; β = a ; α = h(δ) ; δ = c } eliminate {γ = f(α, g(b)) ; β = a ; α = h(c) ; δ = c } eliminate {γ = f(h(c), g(b)) ; β = a ; α = h(c) ; δ = c }

FINAL {γ = f(h(c), g(b)) ; β = a ; α = h(c) ; δ = c }

(b) (2 points) Using the unifier discovered above, apply the substitution and show the final terms, which should be equalities and which should have no variables. If unification got stuck above, just write “unification failed” below.

  • f(f(α, g(b)), g(β)) = f(γ, g(a)) → f(f(h(c), g(b)), g(a)) = f(f(h(c), g(b)), g(a))
  • g(α) = g(h(δ)) → g(h(c)) = g(h(c))
  • f(h(δ), γ) = f(h(c), γ) → f(h(c), f(h(c), g(b))) = f(h(c), f(h(c), g(b)))

Rules for type derivations:

Constants

⊢ n : int (assuming n is an int)

⊢ true : bool

⊢ false : bool

Variables

Γ ⊢ x : τ if(x : τ ) ∈ Γ

Arithmetic Operators Γ ⊢ e 1 : int Γ ⊢ e 2 : int Γ ⊢ e 1 ⊕ e 2 : int

(⊕ ∈ {+, −, ∗, /, · · · })

Relational Operators Γ ⊢ e 1 : int Γ ⊢ e 2 : int Γ ⊢ e 1 ∼ e 2 : bool

(∼ ∈ {<, >, ≤, ≥, =, 6 =, · · · })

Booleans Γ ⊢ e 1 : bool Γ ⊢ e 2 : bool Γ ⊢ e 1 && e 2 : bool Γ ⊢ e 1 : bool Γ ⊢ e 2 : bool Γ ⊢ e 1 || e 2 : bool Γ ⊢ e 1 : bool Γ ⊢! e 1 : bool If Γ ⊢ e 1 : bool Γ ⊢ e 2 : τ Γ ⊢ e 3 : τ Γ ⊢ if e 1 then e 2 else e 3 : τ Function Abstraction Γ ∪ [x : τ 1 ] ⊢ e : τ 2 Γ ⊢ fun x−>e : τ 1 → τ 2 Function Application Γ ⊢ e 1 : τ 1 → τ 2 Γ ⊢ e 2 : τ 1 Γ ⊢ e 1 e 2 : τ 2 Let Γ ⊢ e 1 : τ Γ ∪ [x : τ ] ⊢ e 2 : τ ′ Γ ⊢ let x = e 1 in e 2 : τ ′ Letrec Γ ∪ [x : τ ] ⊢ e 1 : τ Γ ∪ [x : τ ] ⊢ e 2 : τ ′ Γ ⊢ let rec x = e 1 in e 2 : τ ′

  • Scratch Page
  • Scratch Page