Вы можете использовать встроенную функцию load
для чтения файла:
(load "/tmp/data.lisp")
Это установит переменную *myfile*
, поэтому вы можете сделать:
* (print *myfile*)
(((KEY 1) (A1 CAN) (A2 4)
(SUR
(((BCZ S) (FEATS NIL)) (DIR FS) (LADOM ALL)
(((NNEW S) (FEATS NIL)) (DIR BS) (LADOM ALL)
((NNEW NP) (FEATS ((BIG NOM)))))))
(SEM (LAM P (P "CAN"))) (PARAM 1.0))
((KEY 2) (A1 KEDIYI) (A2 4)))
(((KEY 1) (A1 CAN) (A2 4)
(SUR
(((BCZ S) (FEATS NIL)) (DIR FS) (LADOM ALL)
(((NNEW S) (FEATS NIL)) (DIR BS) (LADOM ALL)
((NNEW NP) (FEATS ((BIG NOM)))))))
(SEM (LAM P (P "CAN"))) (PARAM 1.0))
((KEY 2) (A1 KEDIYI) (A2 4)))
* (loop for i from 0
for entry in *myfile*
do (format t "Entry #~D: ~S~%" i entry))
Entry #0: ((KEY 1) (A1 CAN) (A2 4)
(SUR
(((BCZ S) (FEATS NIL)) (DIR FS) (LADOM ALL)
(((NNEW S) (FEATS NIL)) (DIR BS) (LADOM ALL)
((NNEW NP) (FEATS ((BIG NOM)))))))
(SEM (LAM P (P "CAN"))) (PARAM 1.0))
Entry #1: ((KEY 2) (A1 KEDIYI) (A2 4))
NIL
* (dolist (entry *myfile*)
(print (assoc 'key entry)))
(KEY 1)
(KEY 2)
NIL
Если вы не доверяете содержимому файла и хотите прочитать исходный код в файле, но не выполнить его (что делает load
), вы должны использовать read
.В этом случае также свяжите *read-eval*
с nil
для защиты от использования #.
, который в противном случае выполнял бы код при чтении:
(with-open-file (f "/tmp/data.lisp")
(let ((*read-eval* nil))
(loop for form = (read f nil nil)
while form
do (print form)))
Содержимое файла выглядит как набор записей, с каждымвведите список пар ключ-значение.В нем нет ничего, что связывало бы его с CLOS, хотя вы могли бы определить структуру или класс с именем entry
с именами слотов key
, bcz
, feats
и так далее, а затем использовать средства доступа, такие как (entry-bcz x)
вместо (second (assoc 'bcz x))
.Это может помочь читабельности и эффективности, но для этого вам нужно создать объекты из этого представления данных на основе списка.