2012-05-02 46 views
2

我刚刚完成了IU的编译器课程,并试图在我的小“计划”中添加更多的表单。我们通过语法糖将多种形式添加到我们的语言中,其中完整的计划通常使用宏观扩展(和和或者是主要的扩展)。我遇到的问题是解除cond声明。Scheme - 检测aux关键字

作为说明:我正在工作时在Chez和Petite Chez之间来回走动。

我想处理所有的cond子句形式。处理(test => expr)表单时,我似乎遇到了使用=>的问题。我似乎无法做任何事情,没有得到一个错位的辅助关键字错误或让子句落在我的匹配语句中的下一行。

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

+0

如果你可以发布一些代码或者解释一些你已经做过的事情,这可能会有帮助。 –

回答

2

前段时间我写了我自己的Scheme metacircular interpreter,支持=>语法的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表达式的代码的完整片,主过程(一个从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)) 
+1

谢谢!由于某种原因,我的模式匹配器给我如何使用eq的问题?第一次。重做它时,eq?像魅力一样工作。 –