Document 10805472

advertisement
Long Quiz3 ( 45mins) Name: Person Number: Generating parse tables
Calculating First and Follow sets
Problem 1. (20pts) Parser Technology First
andagain Follow
an fexample
a) Look at our sets:
grammar or well-­‐matched bracket sequences: S → epslon | TS Look again at our grammar for well-matched bracket sequences:
T → (S) S → � | TS
T → (S)
Please write down First set of S and T, and Follow Set of S and T (considering LL(1) parser) By inspection, we can see that
First(S) = { (, � }
First(T ) = { ( }
Follow (S) = { ), $ }
because an S can begin with ( or be empty
because a T must begin with (
because within a complete phrase, an S
can be followed by ) or appear at the end
Follow (T ) = { (, ), $ } because a T can be followed by ( or )
or appear at the end
Later we’ll give a systematic method for computing these sets.
Further convention: take First(a) = {a} for each terminal a.
b) Say you have an xml document <?xml version='1.0' encoding='us-ascii'?>
<slideshow
title="Sample Slide Show"
date="Date of publication"
author="Yours Truly"
>
<slide type="all">
<title>Wake up to WonderWidgets!</title>
</slide>
<slide type="all">
<title>Overview</title>
<item>Why <em>WonderWidgets</em> are great</item>
<item/>
<item>Who <em>buys</em> WonderWidgets</item>
</slide>
</slideshow>
Please convert it to Context Free Grammar for parsing. 7 / 16
Xml -­‐> SlideShow SlideShow -­‐> SlideList SlideList -­‐> Slide SlideList Slide -­‐> Title | Title ItemList ItemList -­‐> Item ItemList | epslon Problem 2. (20pts) Analysis of Definition The Fibonacci function F(n) defined for natural numbers n is as follows. F (n) = 0 if n = 0 = 1 if n = 1 = F(n-­‐1) + F(n-­‐2) otherwise Define an SML-­‐function cntCalls that computes the number of calls to F generated for various input values. (E.g., cntCalls(0) = 1, cntCalls(3) = 5, etc.) What are the values of F(5) and cntCalls(5)? fun cntCall 0 = 1 | cntCall 1 = 2 | cntCall n = cntCall(n-­‐1) + cntCall(n-­‐2) ; Problem 3. (20pts) Understanding Function Definition fun f [] = [] | f (x::xs) = let val s = f xs in (map (fn y => y@[x]) s) end; a) What is the signature of f ? f = fn : 'a list -­‐> 'a list list b) Informally describe the list function computed by f. Give the value and type returned for f ["a"]? -­‐ f["a"]; val it = [] : string list list c) Now formalize what f does using the Induction Principle. There are 2 rules here: 1) x
: x ' xs : xs' f : ! y@ys :[y', ys'].
f (ys)@y
x@xs :[x ', xs'] f (x@xs :[x ', xs']) : [a' list, x ']
Where a’ is type variable mapping f(xs’) -­‐> a’ 2) x
: x ' xs : Nil f : ! y : Nil. Nil
x@xs : x ' f (x@Nil) : x ' Problem4. (20 pts) Writing Function Definition The following SML-­‐definition specifies two concrete datatypes etype and expr. datatype etype = Int | Real; datatype expr = I | J | A | B | Plus of (expr * expr) | Mul of (expr * expr); The type of I and J is Int. The type of A and B is Real. The type of a Plus-­‐
expression is Int, if the subexpressions have Int type; otherwise it is an error. (E.g., if both arguments are Real, it is an error!) The type of a Mul-­‐expression is always Real as long as the subexpressions are well-­‐typed; otherwise it is an error. (Note, a subexpression is well-­‐typed if its type either Int or Real.) Write an SML-­‐function typeInfer that infers the type of an expression whereever feasible (according to the specified notion of type inference) and throws an exception called Error otherwise. For example, -­‐ typeInfer I; val it = Int : etype -­‐ typeInfer (Mul (A,Plus(J,I))); val it = Real : etype -­‐ typeInfer (Mul (A,Plus(B,J))); Upcasting
In Chapter 14 you saw how an object can be used as its own type or
as an object of its base type. In addition, it can be manipulated
fun typeInfer e = of the base type. Taking the address of an
through
an address
object
(either
case ea opointer
f or a reference) and treating it as the address
of
the
I =base
> Int type is called upcasting because of the way inheritance
trees
| Pare
lus(e1, e2) => Rthe
eal base class at the top.
drawn
with
| Mul(e1, e2) => Real ; You also saw a problem arise, which is embodied in the following
code:
//: C15:Instrument2.cpp
// Inheritance
& upcasting
Problem 5. (20pts) Please write down result of following program. #include <iostream>
using namespace std;
enum note { middleC, Csharp, Eflat }; // Etc.
class Instrument {
public:
void play(note) const {
cout << "Instrument::play" << endl;
}
};
// Wind objects are Instruments
// because they have the same interface:
class Wind : public Instrument {
public:
// Redefine interface function:
void play(note) const {
cout << "Wind::play" << endl;
}
};
void tune(Instrument& i) {
// ...
i.play(middleC);
}
int main() {
Wind flute;
tune(flute); // Upcasting
} ///:~
Thinking in C++
662
www.BruceEckel.com
The function tune( ) accepts (by reference) an Instrument, but also
Instrument::play without complaint anything derived from Instrument. In main( ),
you can see this happening as a Wind object is passed to tune( ),
with no cast necessary. This is acceptable; the interface in
Instrumentmust exist in Wind, because Wind is publicly inherited
from Instrument. Upcasting from Wind to Instrumentmay
“narrow” that interface, but never less than the full interface to
Instrument.
The same arguments are true when dealing with pointers; the only
difference is that the user must explicitly take the addresses of
objects as they are passed into the function.
Download