从用户输入评估表达式的问题

时间:2012-02-19 12:26:12

标签: scheme racket

我正在尝试创建一个读取和执行用户表达式的递归定义,例如(3 + 5)。一切都在工作,除了算术符号的一个问题。

我设法在一个更简单的例子中复制错误:

(define v '(1 + 3))

((cadr v) 2 4)

(cadr v)+符号,但由于某种原因,无法对后面的两个参数执行该过程。我错过了什么吗?

4 个答案:

答案 0 :(得分:3)

我认为那是因为

(cadr v)

返回'+而不是+(文字+而不是+函数。)

在将其应用于参数之前,您需要对其进行评估。

这应该有效:

((eval (cadr v)) 2 4)
 ^evaluates the '+ to +

修改 这在交互模式的球拍中起作用。

我不确定区别的是什么,但是在球拍(脚本)中以r5rs模式工作:

#lang r5rs

;required by r5rs
(define user-initial-environment (scheme-report-environment 5))

(define v '(1 + 2))

;eval expects a quoted expression
;(it seems that if it's a function it has to have arguments too)
;and evaluation environment.
((eval (cadr v)  user-initial-environment) 2 4)

答案 1 :(得分:1)

正如其他人所指出的,问题是你构建的列表包含符号加号,而不是函数加号。

从本质上讲,这与'(a)返回两个符号列表的原因相同,而不是发出未绑定标识符错误的信号;引用以“数据语言”开始一个术语,其中合法标识符被解释为符号,而不是变量引用。

当然,问题是你应该怎么做。有些人建议使用'eval';这可能是一个坏主意,因为我认为Matthew Flatt在his blog post on the topic中优雅地抓住了这个原因。

相反,您应该编写一个简单的映射函数。这是我写它的方式。如果您在作业中使用我的代码,请务必相信我:)。

#lang racket

;; a mapping from symbols to operators
(define operator-hash
  (hash '+ +
        '- -
        '* *))
;; ... and whatever other operators you want.

;; example of using it:
(hash-ref operator-hash '+) ;; ==> +

答案 2 :(得分:0)

试试这个:

(define v '(1 + 3))

(let ((operator (eval (cadr v)))
      (operand1 (car v))
      (operand2 (caddr v)))
  (apply operator (list operand1 operand2)))

答案 3 :(得分:0)

您可以通过Guile中的eval这样做:

(define (infix-eval v)
   (eval (list (cadr v)(car v)(caddr v))
         (interaction-environment)))

> (infix-eval '(1 + 2))
3

您可以提供另一个评估环境,而不是使用interaction-environment,您可以在其中定义标准Scheme中找不到的其他符号,以便(7 % 3)(2 ^ 6)这样的表达式也工作。