Plai多个值

时间:2016-09-26 11:43:26

标签: scheme racket plai

我的任务是让它测试运行:

(test (run "{+ {2 1} {3 4}}") '(5 6 4 5))
(test (run "{+ {- {+ 1 3} 2} {10 -10}}") '(12 -8))

到目前为止我的源代码看起来像

#lang plai

(require (for-syntax racket/base) racket/match racket/list racket/string
         (only-in mzlib/string read-from-string-all))

;; build a regexp that matches restricted character expressions, can use only
;; {}s for lists, and limited strings that use '...' (normal racket escapes
;; like \n, and '' for a single ')
(define good-char "(?:[ \t\r\na-zA-Z0-9_{}!?*/<=>:+-]|[.][.][.])")
;; this would make it awkward for students to use \" for strings
;; (define good-string "\"[^\"\\]*(?:\\\\.[^\"\\]*)*\"")
(define good-string "[^\"\\']*(?:''[^\"\\']*)*")
(define expr-re
  (regexp (string-append "^"
                         good-char"*"
                         "(?:'"good-string"'"good-char"*)*"
                         "$")))
(define string-re
  (regexp (string-append "'("good-string")'")))

(define (string->sexpr str)
  (unless (string? str)
    (error 'string->sexpr "expects argument of type <string>"))
    (unless (regexp-match expr-re str)
      (error 'string->sexpr "syntax error (bad contents)"))
    (let ([sexprs (read-from-string-all
                 (regexp-replace*
                  "''" (regexp-replace* string-re str "\"\\1\"") "'"))])
    (if (= 1 (length sexprs))
      (car sexprs)
      (error 'string->sexpr "bad syntax (multiple expressions)"))))

(test/exn (string->sexpr 1) "expects argument of type <string>")
(test/exn (string->sexpr ".") "syntax error (bad contents)")
(test/exn (string->sexpr "{} {}") "bad syntax (multiple expressions)")

;; WAE abstract syntax trees
(define-type WAE
  [num  (listof number?)]
  [add  (left WAE?) (right WAE?)]
  [sub  (left WAE?) (right WAE?)]
  [with (name symbol?) (init WAE?) (body WAE?)]
  [id   (name symbol?)])

; parse-sexpr : sexpr -> WAE
;; to convert s-expressions into WAEs
(define (parse-sexpr sexp)
  (match sexp
    [(? number?) (num sexp)]
    [(list '+ l r) (add (parse-sexpr l) (parse-sexpr r))]
    [(list '- l r) (sub (parse-sexpr l) (parse-sexpr r))]
    [(list 'with (list x i) b) (with x (parse-sexpr i) (parse-sexpr b))]
    [(? symbol?) (id sexp)]
    [else (error 'parse "bad syntax: ~a" sexp)]))

将包含WAE表达式的字符串解析为WAE AST     (define(parse str)       (parse-sexpr(string-&gt; sexpr str)))

根据替换规则用第一个参数中的第三个参数替换第二个参数;结果表达式不包含第二个参数的自由实例

(define (subst expr from to)
  (type-case WAE expr
    [num (n)   expr]
    [add (l r) (add (subst l from to) (subst r from to))]
    [sub (l r) (sub (subst l from to) (subst r from to))]
    [id (name) (if (symbol=? name from) (num to) expr)]
    [with (bound-id named-expr bound-body)
          (with bound-id
                (subst named-expr from to)
                (if (symbol=? bound-id from)
                    bound-body
                    (subst bound-body from to)))]))

通过将WAE表达式减少为数字

来评估它们
(define (eval expr)
  (type-case WAE expr
    [num (n) n]
    [add (l r) (+ (eval l) (eval r))]
    [sub (l r) (- (eval l) (eval r))]
    [with (bound-id named-expr bound-body)
          (eval (subst bound-body
                       bound-id
                       (eval named-expr)))]
    [id (name) (error 'eval "free identifier: ~s" name)]))

; run : string -> listof number
;; evaluate a WAE program contained in a string
(define (run str)
  (eval (parse str)))

bin-op :(号码号码 - &gt;号码)(号码或号码列表)(号码或号码列表) - &gt; (数量清单)) 对来自两个输入列表或数字的所有数字组合应用二进制数值函数,并返回所有结果的列表

(define (bin-op op ls rs)
  (define (helper l rs)
    ;; f : number -> number
    (define (f n) (op l n))
    (map f rs))
  (if (null? ls)
    null
    (append (helper (first ls) rs) (bin-op op (rest ls) rs))))

有人可以告诉我如何更改我的功能以使测试成功吗?

提前谢谢。

0 个答案:

没有答案