Scheme/Racket 数学表达式的解释器

Scheme/Racket interpreter for math expressions

我正在尝试为一个项目制作一个数学表达式解释器,但我很难解析不寻常的(一元)表达式,如 '(- -1), '(- (- -1)), '(* 10), '(/ 10) 和其他类似表达式。

(define (math-eval expr)
  (define (helper op expr)
    (cond [(and (or (eqv? + op) (eqv? - op)) (null? expr)) 0]
          [(and (or (eqv? * op) (eqv? / op)) (null? expr)) 1]
          [(eqv? '+ (car expr)) (helper + (cdr expr))]
          [(eqv? '- (car expr)) (helper - (cdr expr))]
          [(eqv? '* (car expr)) (helper * (cdr expr))]
          [(eqv? '/ (car expr)) (helper / (cdr expr))]
          [(atom? (car expr))
           (op (car expr) (helper op (cdr expr)))]
          [else (+ (helper + (car expr)) (helper + (cdr expr)))]))
  (helper + expr))

这个函数接受列表,我认为问题出在原子上?选项,但我不确定如何修复它。 如果您能帮助我或指导我如何解决我的问题,我将不胜感激。

尝试递归构建math-eval

  • 如果 expr 是数字,return 那个数字。
  • 如果expr是函数的符号,return就是那个函数。
  • 如果 expr 是列表,评估列表的每个元素,然后使用 apply 调用函数(列表的第一个元素,car)数字(其余元素,cdr).

这里是辅助函数,returns 给定符号的函数:

(define (fetch-function expr)
  (second
   (assoc expr (list (list '+ +)
                     (list '- -)
                     (list '* *)
                     (list '/ /)))))

示例:

> (fetch-function '+)
#<procedure:+>
> (fetch-function '-)
#<procedure:->

这里是递归的 math-eval,按描述工作:

(define (math-eval expr)
  (cond ((number? expr) expr)
        ((symbol? expr) (fetch-function expr))
        (else (let ((op (car expr))
                    (args (cdr expr)))
                (apply (math-eval op)
                       (map math-eval args))))))

示例:

> (math-eval '(- -1))
1
> (math-eval '(- (- -1)))
-1
> (math-eval '(* 10))
10
> (math-eval '(/ 10))
1/10