Парсер lisp на lisp - Lisp

Формулировка задачи:

Здравствуйте! Решил написать компилятор racket (диалект lisp) на racket, для того, чтобы легко можно было проверить его полноценность (компилирует сам себя - все хорошо, нет - нужно пилить дальше). До этого писал компилятор для маленького lisp на с++, так что (примерно) представляю, что нужно делать. Это первая большая программа на lisp, так что пока тяжело. Например: вот такую простую функцию:
function ast(tokens, from, to)
{
  if(from == undefined)
    from = 0;
 
  if(to == undefined)
    to = tokens.length
 
  var ret = [];
 
  for(var i=from; i<to; i++)
  {
    if(tokens[i] == "(")
    {
      var level = 1;
      var start = i;
      while(level!=0)
      {
        i++;
 
        if(tokens[i] == "(")
            level++;
 
         if(tokens[i] == ")")
            level--;
      }
 
      ret.push(ast(tokens, start+1, i));
    }
    else
        ret.push(tokens[i])
  }
 
  return ret; 
}
Я попытался написать вот так (код страшный и нерабочий):
(define (parse tokens from to)
  (cond
    [(>= from to) '#()]
    [(not (and (vector-has tokens "(") (vector-has tokens ")"))) tokens]
     [else (let* [(fb (vector-index tokens "("))
                (lb (end tokens 1 (+ fb 1)))]
            (println (string-append "fb = " (number->string fb)))
            (println (string-append "lb = " (number->string lb)))
 
            (cond
              [(and (= fb 0) (= lb (- (vector-length tokens) 1))) (parse tokens (+ fb 1) (- lb 1))]
              [(= fb 0) (vector-append (parse tokens (+ fb 1) lb) (parse tokens (+ lb 1) (- (vector-length tokens) 1)))]
              [(= lb (- (vector-length tokens) 1)) (vector-append (parse tokens 0 (- fb 1)) (parse tokens (+ fb 1) (- (vector-length tokens) 1)))]
              [else (vector-append (parse tokens 0 (- fb 1)) (parse tokens (+ fb 1) (- lb 1)) (parse tokens (+ lb 1) (- (vector-length tokens) 1)))]
              )
            )]) )
Помогите, пожалуйста, переписать.

Код к задаче: «Парсер lisp на lisp - Lisp»

textual
(define (delimiter? ch)
  (or (equal? ch #\()
      (equal? ch #\))
      (char-whitespace? ch)))
 
(define (match-token src)
  (let loop ((src src) (acc null))
    (if (delimiter? (first src))
        (values (list->string (reverse acc)) (rest src))
        (loop (rest src) (cons (first src) acc)))))
 
(define (match-list src)
  (cond ((and (list? src) (null? src)) src)
        ((equal? (first src) #\()
         (let ((src (rest src)))
           (cond ((null? src) src)
                 ((equal? (first src) #\)) null)
                 (else (let-values (((token rest) (match-token src)))
                         (cons token (match-list rest)))))))
        ((equal? (first src) #\)) null)
        (else (let-values (((token rest) (match-token src)))
                         (cons token (match-list rest))))))
 
(match-list (string->list "(defun foo nil)"))
'("defun" "foo" "nil")

9   голосов, оценка 3.778 из 5


СОХРАНИТЬ ССЫЛКУ