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 ;;;----------------------------------------------------------------------