![]() |
![]() |
|
Tentative/to-be-determined
some problems due Mar.21 (Thu), and the remainder
due
by
Mar.26 (Tue) in class, hardcopy and D2L.
(I personally recommend
completing at least #3 and either #9 or #10
by class on Thursday,
to help ensure you're on the right track.)
Submit a single pdf file named hw06.pdf:
I suggest using a text-editor like Word (or LibreOffice or DrRacket or similar): The derivations are best written in a text-editor where you can copy/paste one line and replace a single non-terminal to create the next line. But for parse-trees, I recommend drawing them freehand.
Your hardcopy should include your answers, and your (presumably-hand-drawn) trees. Including images is optional for the pdf; I will use your hardcopy to grade the trees.
If you do want to incorporate your images (in the single pdf), you can of course do so via Word/LibreOffice/etc.; you may also do so via DrRacket's Insert » Insert Image…, and then printing to pdf.
Your name and the assignment-number must be in a comment at the start of the file, along with a link to this assignment page.
I encourage you to actually put all the nonterminals in upper-case (or at least first-letter-upcased), just to make it easier to tell terminals from non-.
<JsFunc> → function <JsIdent>( <JsIdents> ) { <JsBody> } |
For the grammar rules, write them as in class: in basic BNF
using “→” (and “
(2pts)
As we consider how to define
Working towards a solution, the programmer MC Carthy comes up with the following attempt for a nonterminal that generates comma-separated lists of “x”s (albeit still ending in a semicolon, unlike our part (c) next):
<XS> → ; | x; | x, <XS> |
Prove that this grammar is not correct, by giving a derivation2 of some string which is not a valid comma-separated list (ending in a semicolon).
(6pts) Generating a grammar
Give a grammar for Java's boolean expressions.
(That is: a grammar describing exactly what you are allowed to put
inside the parentheses of a Java
For this problem, assume that you already have grammar rules for
a Java numeric expression
(“
Using your grammar, give a parse tree (not a derivation) for:
In the tree, for children of
(4pts)
Write
data def'n: A natural-number is:
The predicates
- 0, OR
- (+ 1 [natural-number])
zero? andpositive? are often used to distinguish the two branches, though of course= and> could be used equally-well.
For a longer discussion of the same, see natnum-defn-taster.rkt for thinking ofsub1 as the “getter” to pull out the “natural-number field, which a positive is built out of”. For mathematically-inclined, here's “if your language provided neither numbers nor `+`, how would you do addition?”.
Note: Note that being tail-recursive is a property of a function’s source-code. The fact that a tail-recursive function can be optimized to not unnecessarily-allocate stack space is a compiler-implementation issue — albeit it’s what makes the concept of tail-recursion important.
Reading: Scott also discusses recursion and tail-recursion, in §6.6.1 (both 3rd and 4th eds).
#| /** Return the smallest number in a list. * @pre <code>!nums.isEmpty()</code> * @return the smallest number in `nums`. */ static Double myMin( List<Double> nums ) { // initialize our loop-variables: double minSoFar = nums.get( ); List<Double> numsRemaining = nums.subList( ,nums.size()); while ( ) { double a = numsRemaining.get(0); // corresponding to Scott’s variable `a` minSoFar = ( ? : ); numsRemaining = ; } return minSoFar; } |# |
Btw: The book’s starting-code calls(empty? (rest l)) — something not in the template. It’s a bit of a hack to stray from the template: Scott wants to avoid making a helper-function, but still return a sentinel-value answer for empty-lists.
However, when converting to tail-recursion, this difference ends up being moot: as you make a helper/wrapper function for the tail-recursion, that extra check disappears.
scheme vs racket: The book’s scheme code uses:car ,cdr ,null? , and#t . In racket, these names are (respectively):first ,rest ,empty? , and#true .
This looks familiar: Yes, this problem is nearly identical to the “my-max ” function in the notes that we went over in class. Oh well. I figure if you understand that example, then this problem won take long, and if you come across difficulties then it's still a good problem to work through.
(check-expect (natnum->string/binary 0) "") (check-expect (natnum->string/binary 1) "1") (check-expect (natnum->string/binary 2) "10") (check-expect (natnum->string/binary 3) "11") (check-expect (natnum->string/binary 4) "100") (check-expect (natnum->string/binary 5) "101") (check-expect (natnum->string/binary 15) "1111") (check-expect (natnum->string/binary 16) "10000") (check-expect (natnum->string/binary (+ 1024 8 4)) "10000001100") (check-expect (natnum->string/binary #x0A) "1010") ; hex literal "0A" (check-expect (natnum->string/binary #xFFFF) "1111111111111111") (check-expect (natnum->string/binary #xFeedBee) "1111111011101101101111101110") ; natnum->string/binary : natnum -> string ; Return the binary-numeral representing n (without any leading zeroes). ; Note that the numeral for zero, without leading zeros, is the empty-string! ; (define (natnum->string/binary n) (cond [(zero? n) ""] [(positive? n) (string-append (natnum->string/binary (quotient n 2)) (if (even? n) "0" "1"))])) |
Btw: This code doesn’t quite follow the design-recipe for natural-numbers, because it recurs on(quotient n 2) rather than(sub1 n) . But it still works fine because it “reduces” the natnum to a smaller one. To reason about this code, you wouldn’t use straight-up mathematical induction; instead you’d call it “strong induction”.
This page licensed CC-BY 4.0 Ian Barland Page last generated | Please mail any suggestions (incl. typos, broken links) to ibarland ![]() |