![]() |
![]() |
|
Due
Deliverables: Name your code file hw07.rkt. Since, in addition to code, you'll have trees that you draw (presumably by hand), submit a second file hw07.pdf which you'll also print, for your hardcopy. You can either:
preserve indentation: If you print your code via some other method (like pasting into a google-doc), be sure to preserve your good indentation with a monospace font like Consolas or Courier New.
As usual: Include your name and the assignment-number near the top of the file, along with a link to this assignment page.
Reading: Scott §3.6.4 and §11.6 (lambda expressions); §2.1 (grammars). ; functional vs imperative trade-offs: 11.8 ; functional overall: all of 11, incl. 11.2(FP concepts)
Hint: A good, descriptive name for one of your parameters would be “keep?”.Use define instead of define/contract, but put the signature in a comment. Recall that the for the first argument of my-filter is itself a function, so your contract will look like (-> (-> ) (listof ) (listof ))! You can write
Tor
T?or
αas a type-variable.
Notice that several of the image-creating functions imported via (require 2htdp/image) are similar, in that they happen to take four arguments: two non-negative numbers v and w, a drawing mode (e.g. 'solid or #o162 (a transparency)) and a color. Two such examples are ellipse and rhombus.
(check-expect (shapes-in-a-row |
list-of-function; give its full signature1 (-> (listof (-> )) ).
Do not use define to create these functions; your answer should be of the form (shapes-in-a-row (list (lambda …) (lambda …))).
This is actually an example of theadaptor pattern: shapes-in-a-row expects functions that meet a certain interface (4 inputs), but the functions we have (star, pulled-polygon) need to be adapted to satisfy that interface. This can be easy (a couple lines, as above) in languages with anonymous functions and dynamic-typing (or good type inference); otherwise it might require writing entire classes and interfaces.
(define positive-integer? (and/f integer? positive?)) (check-expect (positive-integer? 17) #t) (check-expect (positive-integer? -7) #f) (check-expect (positive-integer? 0) #f) (check-expect (positive-integer? "hello") #f) ; Note that `(integer? "hello")` is #f. (define non-empty-string? (and/f string? (λ(str) (not (string=? "" str)))) (check-expect (non-empty-string? "hello") #t) (check-expect (non-empty-string? "") #f) (check-expect (non-empty-string? 99) #f) |
Gloss over “missing rules”: Presume that <id> ⇒* x, and similarly that <number> ⇒* 2 and <number> ⇒* 3, even though we aren't shown the rules for <id> nor <number>. In your derivation you'll have a step using “⇒*” where (exactly) one of those non-terminals gets replaced (to show that there are technically multiple steps that are not being shown).
caution: Don't use the grammar of Example 2.8 by mistake.
<JsFunc> → function <JsIdent>( <JsIdents> ) { <JsBody> } this is one long rule which contains two newlines |
For the grammar rules below, write them as in class: in basic BNF using “→” (and “ε”), but not using Extended BNF constructs like ? and * (nor equivalently, written as opt and …).
As we consider how to define <JsIdents>, a comma-separated list of identifiers, we note that the book has something similar: in the example of <id_list> (Examples 2.20 and 2.21 in §2.3), they present rules for a non-empty list of comma-separated identifiers. The book includes a semicolon at the end, which we're ignoring. We do need to figure out how to adapt it to allow the possibility of zero identifiers.
Working towards a solution, the programmer MC Carthy comes up with the following attempt for a nonterminal that generates repetitions of the letter “x”, separated by commas and ending in a semicolon (which we won't end with in our part (c), next):
<Xs> → ε | x | x, <Xs> |
Prove that this grammar is actually not what we want, by giving a derivation of some string which is not a valid comma-separated list-of-“x”s. As usual, for full credit give the shortest correct answer.2
Gloss over “missing rules”: Since we're presuming that <JsIdent> ⇒* a and <JsStmt> ⇒* z = a*b; (using rules we haven't been shown), in your tree just draw a dotted line “⋮” between them e.g. from <JsIdent> to its leaf/descendent a, and from <JsStmt> to its leaf/descendent z = a*b;.
Generating a grammar
Create a grammar for Java's boolean expressions.
(That is: rules describing exactly what you are allowed to put, say,
inside the parentheses of a Java if (…) … statement.)
For this problem, assume that you already have grammar rules for a Java identifier (“<Id>”), for a Java numeric expression (“<NumExpr>” -- which is presumably similar to the book's Example 2.4, p.46), and that the only boolean operators you want to handle are &&,||,!,== and the numeric predicates >, >=, and ==. (You do not need to worry about enforcing precedence, although you are welcome to.) For this problem, you may use the Extended BNF constructs ? and * (or equivalently, written as opt and …).
hints: Make sure you can derive expressions like!!!!!!falseand((((targetFound)))), in addition to the expression below. Make sure you cannot derive expressions likex false(two expressions not one),2 > true(> can only occur between numeric-expressions, not boolean-expressions), or(the empty string). You might want to ask yourself:For comparison, see that book Example 2.4, and what is allowed on either side of binary operators like “+”, and also what it allowed to follow the unary-negation “-”.
- What is allowed to follow a “!”?
- What is allowed on each side of “||”?
Using your grammar, draw a parse tree (not a derivation) for:
a+2 > 5 || ((!false == x))
In the tree, for children of
<NumExpr>
and
<Id>,
you can just write “⋮” to skip from the non-terminal directly to its children,
since you didn't write the exact rules for those nonterminals.
I recommend drawing your tree freehand3.
This page licensed CC-BY 4.0 Ian Barland Page last generated | Please mail any suggestions (incl. typos, broken links) to ibarland ![]() |