← Архив: Common Lisp

Программная проверка кода

Author: · 08.12.2011 22:54
· original author: Lighten
Встретился с необходимостью проверить, являются ли данные рабочим кодом на lisp. 
Задача. Функция получает на вход строку. Нужно проверить,
является ли эти данные работающим/eval'ируемым в данном контексте кодом lisp, не eval'я его. 
Не нашёл такой встроенной функции. Работаю в eclips, компилятор - sbcl. 
Проверяемый код без макросов и смены пакета.
Не хочется писать компилятор, когда есть уже, или же "подпихивать" в другой процесс-компилятор.
Пробовал просто обрабатывать исключение eval... Пробовал пробегать весь пакет и сравнивать со словами в строке. Но так не нравится.
Если есть eval, compile, eval-when и другие функции, то должна же быть проверка на "работоспособность"!!
Помогите, пожалуйста!!!! и прошу прощения, если что неправильно написал, я ещё новичок...
· original author: Love5an
Без макросов - всмысле без reader-макросов, или что, совсем из одних вызовов функций и специальных операторов?
Ну, ты можешь вызывать READ.READ либо вернет лисповый объект, либо вызовет исключение.
Код на лиспе это в принципе абсолютно любой лисповый объект, а его вычисление зависит от состояния лисп-системы.
В общем случае, проверить корректно ли семантически полученное от READ ast можно только вычислив его.
Оно может стать некорректным прямо в процессе вычисления, потому что.
· original author: elyadow
Компилятором можно проверить так:
(lambda (form)
  (null (nth-value 2 (compile nil `(lambda () ,form))))
)

Хотя это не проверка на "работоспособность", конечно.
· original author: Lighten
Спасибо за ответы!!! Покажу на примере. Строка например будет (setf string1 "(+ 2 3)") мне нужна функция (lisp-p), которая сработает с такой строкой так (lisp-p string1)=>T; если же функция или аргументы будут неизвестными в текущем контексте: (setf string2 "(gkjj bbm 8)") , то (lisp-p string2)=> NIL; Вот "первое приближение" - здесь я просто смотрю есть ли скобки в строке и пробегаю по контексту, сравнивая "слова" в строке и символы. Если все слова в строке присутствуют и скобки есть  - то строка и вправду код лиспа. Для чего это нужно. Чтобы программа могла самостоятельно отличить вводится код лиспа или просто строка. Хотел доделать эту функцию с учётом вложеных скобок, макросов, квазицитирования и тд. Но перед этим решил спросить у более опытных - может такое уже есть.
(defun lisp-p (stringa) (setf wrds (to-words stringa " ():,'\/")) (setf iter 0) (with-package-iterator (next-symbol *package* :internal :external :inherited) (loop (multiple-value-bind (more? symbol) (next-symbol) (if more? (dolist (wrd wrds) (if (not (position #\Newline wrd)) (if (equal symbol (read-from-string wrd)) (incf iter) )) ) (return))))) (if (and (position #\( stringa) (position #\)stringa)) (if (and (< (position #\( stringa) (position #\)stringa)) (> iter 0)) t nil) nil))
· original author: michael.filonenko
Есть, кстати, готовый парсер грамматики s-выражений. Очень удобный на мой взгляд.
https://github.com/nikodemus/esrap/blob/master/example-sexp.lisp
https://github.com/nikodemus/esrap
После составления ast дерева, вам необходимо самостоятельно проверить его корректность. Если у вас "простой лисп", то вроде как не сложно.
· original author: Lighten
Спасибо большое! Да, как раз "простой"!