将“Simply Scheme”语言添加到DrRacket

5
我想学习这本书:http://www.eecs.berkeley.edu/~bh/ss-toc2.html。但我在使用“Simply Scheme”语言时遇到了问题,代码无法运行。
    #lang planet dyoo/simply-scheme:2
    (parse ’(4 + 3 * 7 - 5 / (3 + 4) + 6))

我一直收到以下错误消息:“parse: unbound identifier in module in: parse”。这是一条与模块相关的未绑定标识符的解析错误。

再强调一下:您没有定义parse,因此错误信息是正确的:它尚未“绑定”,因为parse没有内建定义。因此,您使用语言是正确的:语言不是问题的根源。 - dyoo
3个回答

6

请查看此页面,上面有完整的说明。只需按照以下步骤进行:

#lang racket
(require (planet dyoo/simply-scheme:2:2))

请注意,用于引用的字符是不正确的,应该使用'。这可能是因为您复制粘贴了格式不正确的代码。
当然,在完成上述步骤之后,您还需要定义第18章中所解释的过程,因为它们在您刚刚导入的包中没有定义!确保执行以下操作:
(define (parse expr)
  (parse-helper expr '() '()))

(define (parse-helper expr operators operands)
  (cond ((null? expr)
     (if (null? operators)
         (car operands)
         (handle-op '() operators operands)))
    ((number? (car expr))
     (parse-helper (cdr expr)
               operators
               (cons (make-node (car expr) '()) operands)))
    ((list? (car expr))
     (parse-helper (cdr expr)
               operators
               (cons (parse (car expr)) operands)))
    (else (if (or (null? operators)
              (> (precedence (car expr))
             (precedence (car operators))))
          (parse-helper (cdr expr)
                (cons (car expr) operators)
                operands)
          (handle-op expr operators operands)))))

(define (handle-op expr operators operands)
  (parse-helper expr
        (cdr operators)
        (cons (make-node (car operators)
                 (list (cadr operands) (car operands)))
              (cddr operands))))

(define (precedence oper)
  (if (member? oper '(+ -)) 1 2))

(define (compute tree)
  (if (number? (datum tree))
      (datum tree)
      ((function-named-by (datum tree))
         (compute (car (children tree)))
         (compute (cadr (children tree))))))

(define (function-named-by oper)
  (cond ((equal? oper '+) +)
    ((equal? oper '-) -)
    ((equal? oper '*) *)
    ((equal? oper '/) /)
    (else (error "no such operator as" oper))))

(parse '(4 + 3 * 7 - 5 / (3 + 4) + 6))
=> '(+ (- (+ (4) (* (3) (7))) (/ (5) (+ (3) (4)))) (6))

(compute (parse '(4 + 3 * 7 - 5 / (3 + 4) + 6)))
=> 30 2/7

@JimBoy,我在问题的代码中发现了第二个错误,你使用了而不是'进行引用。除此之外,你只需要像我在更新的答案中所示的那样复制第18章中的定义即可。 - Óscar López
1
我没有注意到引用的错误。现在它可以工作了! :) 谢谢。 - JimBoy

2
这里还有一个模块可以让你运行"Simply Scheme": https://gist.github.com/alexgian/5b351f367169b40a4ad809f0bb718e1f 你可以直接运行它,然后交互式地输入你的代码,无需像上面提到的Planet/dyoo代码一样进行安装。 不过,如果你希望这样做,也可以进行安装,然后只需在任何程序前加上#lang simply-scheme即可正常工作。 如何进行安装的说明可以在这里看到: https://groups.google.com/forum/#!topic/racket-users/jHPtw3Gzqk4 其中Matthew Butterick在2018年6月4日发布的消息中提供了指导。
这个版本解决了dyoo代码没有处理的一些问题。
> (first 'american)
'a
> (first 'American)
"A"
> (every butfirst '(AmericAn Legacy CODE))
'("mericAn" egacy "ODE")

即,字符串和符号的不正确混合,而不是
> (first 'american)
a
> (first 'American)
A
> (every butfirst '(AmericAn Legacy CODE))
(mericAn egacy ODE)    

应该如此。

然而,正如上面的答案所指出的那样,您仍然需要自己输入解析函数的代码,因为这是作者的意图。


1
PS. 上述模块在Racket 6.3上运行良好,无需回滚! - Alex Gian

0

我不得不回到DrRacket 5.4.1才能让Simply Scheme和SICP都正常工作。


1
我看到你在2014年3月回答了这个问题,所以可能已经有所改变,但是我正在运行DrRacket 6.12,并且对于上述代码没有任何问题。(只是提供信息,以防有人认为存在向后兼容性问题。目前一切都很好。) - Alex Gian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接