2012-05-02 32 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?像魅力一樣工作。 –