我的任务是让它测试运行:
(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))))
有人可以告诉我如何更改我的功能以使测试成功吗?
提前谢谢。