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

  1. Здравствуйте! Решил написать компилятор racket (диалект lisp) на racket, для того, чтобы легко можно было проверить его полноценность (компилирует сам себя - все хорошо, нет - нужно пилить дальше). До этого писал компилятор для маленького lisp на с++, так что (примерно) представляю, что нужно делать. Это первая большая программа на lisp, так что пока тяжело. Например: вот такую простую функцию:Javascript1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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; }Я попытался написать вот так (код страшный и нерабочий):


textual

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

(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



Похожие ответы
  1. После года самостоятельного изучения Python в качестве первого и основного ЯП, пришел я в университет в магистратуру, где в качестве функционального ЯП предлагается писать задачи на Scheme. Привыкнув писать по императивной парадигме, спотыкаться начал практически сразу же. Например. Требуется написать программу, которая вычисляет день недели по дате. Пусть процедура принимает год-месяц-день и возвращает числа от 0 (понедельник) до 6 (воскресенье). Покопавшись по вопросу реализации подобного алгоритма, набрёл на интересное решение на Python:Python1 2 3 4 5 6 7 def whatDay(day, month, year):     days = ["пн","вт","ср","чт","пт","сб","вс"]     a = (14 - month) // 12     y = year - a     m = month+12 * a-2     result = ((7000 + (day + y + y//4 - y//100 + y//400 + (31*m) // 12)) % 7) - 1     return days[result]Не получается перестроить данное решение под, собственно, Scheme. Пробовал так:

  1. Напишите программу, которая строит СДНФ и СКНФ для заданной булевой формулы. Формула может быть задана прямо в исходном тексте программы.

  1. Турист в первый день прошел 30 км, на каждый следующий день прошел на 3 км меньше, чем в предыдущий. Какое расстояние он прошел за 11 дней?

  1. Не получается написать функцию, которая принимает на вход список, и преобразует его следующим образом: после каждого неотрицательного элемента добавляет звездочку. Например: исходный список: (0 b a -2 4) преобразованный список: ((0 *) b a -2 (4 *)) Помогите, пожалуйста!Добавлено через 22 минуты Ошибку выдает компилятор: sh-4.4$ clisp main.lisp *** - >: NIL is not a real number

  1. В SICP сказанно что после предиката в cond может быть последовательность выражений, а в if - только одно. Я собственно не пойму, что за "последовательность выражений"?

  1. При отладке показывает на кусок кода:

  1. 1. Например "3497" в "7943" ... 2. Например "4" в число 4 ...