Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
II. recursively specified programs (EOPL 3e, Section 1.2)
A. tips for reducing time
What were the tips for reducing time on recursive list problems?
------------------------------------------
MORE TIPS FOR SAVING TIME
WHEN DOING RECURSIVE PROBLEMS
6. Assume a parser handles syntax errors
in input.
7. Use helping procedures to access
parts of the syntax.
8. One procedure per nonterminal.
Don't mix 2 recursions in a procedure.
9. Use these tips for each procedure
you write
------------------------------------------
B. multiple alternatives, helpers
------------------------------------------
ASSUME A PARSER
::=
hot
| warm
| cold
Parsing
(parse-temperature 'hot) ==> hot
(parse-temperature 'warm) ==> warm
(parse-temperature 'cold) ==> cold
(parse-temperature 'tepid) ~~> error
(parse-temperature 23) ~~> error
------------------------------------------
So, when you have a procedure that takes a input,
what can you assume about that input?
------------------------------------------
USE HELPING PROCEDURES
The code for temperature-mod.scm is at the end of these lecture notes.
Use the instructions from homework 1, problem 4 to add this module to your
lib342 directory.
(require (lib "temperature-mod.scm" "lib342"))
Constructors:
hot : (-> () temperature)
warm : (-> () temperature)
cold : (-> () temperature)
Tests (discriminators):
hot? : (-> (temperature) boolean)
warm? : (-> (temperature) boolean)
cold? : (-> (temperature) boolean)
Comments to aid memory
::=
hot "hot ()"
| warm "warm ()"
| cold "cold ()"
------------------------------------------
------------------------------------------
FOLLOW THE STRUCTURE/GRAMMAR OF INPUT
Problem:
(make-warmer
(parse-temperature 'cold)) = (warm)
(make-warmer
(parse-temperature 'warm)) = (hot)
(make-warmer
(parse-temperature 'hot)) = (hot)
------------------------------------------
What's the type?
What's the outline?
Can you write it?
C. multiple nonterminals, no recursion (skip if low on time)
------------------------------------------
PHONE NUMBER GRAMMAR
::=
( . ) "phone-number (exchange subscriber)"
::= "exchange (number)"
::= "subscriber (number)"
------------------------------------------
------------------------------------------
HELPING PROCEDURES
In phone-number-mod.scm:
phone-number : (-> (exchange subscriber) phone-number)
exchange : (-> (number) exchange)
subscriber : (-> (number) subscriber)
phone-number->exchange : (-> (phone-number) exchange)
phone-number->subscriber : (-> (phone-number) subscriber)
exchange->number : (-> (exchange) number)
subscriber->number : (-> (subscriber) number)
------------------------------------------
------------------------------------------
FOR YOU TO DO
Write
to-string : (-> (phone-number) string)
(to-string
(parse-phone-number (555 . 1212)))
==> "555-1212"
------------------------------------------
D. multiple alternatives
------------------------------------------
LAMBDA-1-EXP GRAMMAR
::=
"var-exp (id)"
| ( lambda ( ) ) "lambda-exp (id body)"
| ( ) "app-exp (rator rand)"
------------------------------------------
Does this look like anything familiar?
------------------------------------------
HELPING PROCEDURES FOR LAMBDA-1
var-exp? : (-> (lambda-1-exp) boolean)
lambda-exp? : (-> (lambda-1-exp) boolean)
app-exp? : (-> (lambda-1-exp) boolean)
var-exp->id : (-> (lambda-1-exp) symbol)
lambda-exp->id : (-> (lambda-1-exp) symbol)
lambda-exp->body : (-> (lambda-1-exp) lambda-1-exp)
app-exp->rator : (-> (lambda-1-exp) lambda-1-exp)
app-exp->rand : (-> (lambda-1-exp) lambda-1-exp)
var-exp : (-> (symbol) lambda-1-exp)
lambda-exp : (-> (symbol lambda-1-exp) lambda-1-exp)
app-exp : (-> (lambda-1-exp lambda-1-exp) lambda-1-exp)
------------------------------------------
Which are tests? Constructors? Observers?
------------------------------------------
RECURSION OVER LAMBDA-1
(count-var-exps (parse-lambda-1-exp 'x))
==> 1
(count-var-exps
(parse-lambda-1-exp '(x y)))
==> 2
(count-var-exps
(parse-lambda-1-exp '((x z) y)))
==> 3
(count-var-exps
(parse-lambda-1-exp '(lambda (x) x)))
==> 1
(count-var-exps
(parse-lambda-1-exp '(f (lambda (x) x))))
==> 2
(deftype count-var-exps
(define count-var-exps
(lambda (exp)
------------------------------------------
Would more examples help?
What other questions should we ask?
------------------------------------------
FOR YOU TO DO (IN PAIRS)
Using the helping procedures
var-exp?, lambda-exp?, var-exp->var,
lambda-exp->body, app-exp->rator,
app-exp->rand, set, and set-union
write a procedure for:
all-var-exps : (-> (lambda-1-exp)
(set-of symbol))
(all-var-exps (parse-lambda-1-exp 'x))
= (set x)
(all-var-exps
(parse-lambda-1-exp '(x y)))
= (set x y)
(all-var-exps
(parse-lambda-1-exp '(lambda (x) y)))
= (set y)
(all-var-exps
(parse-lambda-1-exp
'(f (lambda (x) (x (f x))))))
= (set f x)
------------------------------------------
How would this change if we added quote to the grammar?
E. combinations
------------------------------------------
STATEMENTS AND EXPRESSIONS
::=
"exp-stmt (exp)"
| (set! ) "set-stmt (id exp)"
::=
"var-exp (id)"
| "num-exp (num)"
| (begin {}* ) "begin-exp (stmts exp)"
where is a Scheme
------------------------------------------
What are the helping procedures?
How does this recurse?
How many procedures would we use to solve a problem over
this grammar?
------------------------------------------
EXAMPLE PROBLEM
targets : (-> (statement) (set-of symbol))
(targets (parse-statement 'x))
= (set )
(targets (parse-statement '(set! x 3)))
= (set x)
(targets
(parse-statement
'(set! x (begin (set! y 4) y))))
= (set x y)
------------------------------------------
What are the base cases?
What other examples would be useful?
Any related simpler examples?
How many procedures?
What are examples for the other procedure?
;;;----------------------------------------------------------------------
;;; temperature-mod.scm
;;; Follow the instructions for HW 1, problem 4 to add this module to your
;;; lib342 directory.
;;;
;;; ::= hot "hot"
;;; | warm "warm"
;;; | cold "cold"
(module temperature-mod mzscheme
(provide temperature? hot? warm? cold? hot warm cold parse-temperature)
;; type predicate
; (deftype temperature? (type-predicate-for temperature))
;; case testers (discriminators)
; (deftype hot? (-> (temperature) boolean))
; (deftype warm? (-> (temperature) boolean))
; (deftype cold? (-> (temperature) boolean))
;; constructors
; (deftype hot (-> () temperature))
; (deftype warm (-> () temperature))
; (deftype cold (-> () temperature))
;; parsing/bless input correctness
; (deftype parse-temperature (-> (datum) temperature))
(define temperature?
(lambda (d)
(or (eq? d 'hot) (eq? d 'warm) (eq? d 'cold))))
(define hot?
(lambda (temp)
(eq? temp 'hot)))
(define warm?
(lambda (temp)
(eq? temp 'warm)))
(define cold?
(lambda (temp)
(eq? temp 'cold)))
(define hot
(lambda ()
'hot))
(define warm
(lambda ()
'warm))
(define cold
(lambda ()
'cold))
(define parse-temperature
(lambda (d)
(cond
((eq? d 'hot) (hot))
((eq? d 'warm) (warm))
((eq? d 'cold) (cold))
(else (error "parse-temperature: bad syntax:" d)))))
) ; end module
;;;----------------------------------------------------------------------