我有一个以 (defparameter *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)
...........开头的文件并继续这样做 .
我猜这是一个CLOS但它存储在一个文件中 . 我需要能够在关联列表中获取此数据以达到A1或A2等作为后续获取其值的键 . 我现在做的是逐行读取文件并对其进行字符串操作 . 但我认为这是一个不好的做法 . 这是我现在的代码;
(defun open_ded (path)
(defvar last_id 0)
(let ((in (open path :if-does-not-exist nil)))
(when in
(loop for line = (read-line in nil)
while line
do
(if (setq key_id (findkeyid line)) ;search "KEY" and return its id value
(setq last_id key_id)) ;if it is not nil, set it to last_id
而且我知道我可以使用(defparameter * s (打开“路径”))获取整个文件但是我想要的时候(关联'A1(读 s ))或(关联'KEY(读 s) *)它让我无处可去 . 你对如何实现这个有什么想法吗?
2 回答
@zut很好地展示了如何在不评估内容的情况下阅读文件 .
我正在使用它并向您展示如何从第一个表达式中获取键值对 .
~/Dropbox/cl/test-file.lisp
的内容是:您可以使用内置函数
load
来读取文件:这将设置变量
*myfile*
,这样你就可以这样做:如果您不信任文件内容,并且想要读取文件中的源代码但不执行它(
load
),则使用read
. 在这种情况下,还要将*read-eval*
绑定到nil
以防止使用#.
,否则会在读取时执行代码:文件内容看起来像一个条目集合,每个条目都是一个键值对列表 . 虽然您可以使用插槽名称
key
,bcz
,feats
等来定义名为entry
的结构或类,然后使用诸如(entry-bcz x)
之类的访问器而不是(second (assoc 'bcz x))
,但它中没有任何内容将其连接到CLOS . 这可能有助于提高可读性和效率,但要做到这一点,您需要从这个基于列表的数据表示中创建对象 .