2

我刚刚完成了 IU 的编译器课程,并试图在我的小“计划”中添加更多形式。我们通过语法糖在我们的语言中添加了几种形式,其中完整的方案通常使用宏扩展(并且和或是主要的)。我遇到的问题是取消 cond 声明。

备注:我在工作时会在 Chez 和 Petite Chez 之间来回走动。

我正在尝试处理所有 cond 子句形式。在处理 (test => expr) 表单时,我似乎遇到了使用 => 的问题。如果没有出现错误放置的 aux 关键字错误或让子句落入匹配语句中的下一行,我似乎无能为力。

关于如何检测此关键字的任何想法?

4

1 回答 1

2

前段时间我写了自己的 Scheme 元循环解释器,支持特殊形式的=>语法。cond本质上,这就是我必须做的:

(define (expand-actions clause)
  (let ((exp (sequence->exp (cond-actions clause))))
    (if (cond-has-then? clause)
        (make-application exp
                          (if (cond-else-clause? clause)
                              #t
                              (list (cond-predicate clause))))
        exp)))

当遍历cond表达式的所有子句(谓词和动作对)时,我展开每个动作并询问=>子句中是否存在令牌(使用cond-has-then?)。如果=>找到,我将子句的动作部分应用于谓词。

这是我的解释器中负责评估表达式的完整代码cond,主要过程(称为 from eval)是cond->if,它将cond表达式转换为一系列嵌套if表达式,并处理=>语法;我希望这对你有帮助:

(define (cond->if exp)
  (expand-clauses (cond-clauses exp)))

(define cond-clauses cdr)

(define (cond-has-then? clause)
  (eq? (cadr clause) '=>))

(define cond-predicate car)

(define (cond-actions clause)
  (if (cond-has-then? clause)
      (cddr clause)
      (cdr clause)))

(define (cond-else-clause? clause)
  (eq? (cond-predicate clause) 'else))

(define (expand-clauses clauses)
  (if (null? clauses)
      (void)
      (let ((first (car clauses))
            (rest  (cdr clauses)))
        (if (cond-else-clause? first)
            (if (null? rest)
                (expand-actions first)
                (error "ELSE clause isn't last -- COND->IF" clauses))
            (make-if (cond-predicate first)
                     (expand-actions first)
                     (expand-clauses rest))))))

(define (expand-actions clause)
  (let ((exp (sequence->exp (cond-actions clause))))
    (if (cond-has-then? clause)
        (make-application exp
                          (if (cond-else-clause? clause)
                              #t
                              (list (cond-predicate clause))))
        exp)))

(define (make-if predicate consequent alternative)
  (list 'if predicate consequent alternative))

(define (sequence->exp seq)
  (cond ((null? seq) '())
        ((last-exp? seq) (first-exp seq))
        (else (make-begin seq))))

(define (last-exp? seq)
  (null? (cdr seq)))

(define first-exp car)

(define (make-application proc . args)
  (cond ((null? args) (list proc))
        ((list? (car args)) (cons proc (car args)))
    (else (cons proc args))))

(define (make-begin seq)
  (cons 'begin seq))
于 2012-05-02T14:17:09.363 回答