在通用的LISP(SBCL)中,您如何解析文件?

发布于 2025-01-28 17:00:57 字数 1420 浏览 2 评论 0原文

我有一个文件:test.lisp带有此内容:

(+ 3 3)

(let ((n 3)) (+ n 1))

(let ((n 4))
  (+ n 1))

(defun d (f)
  (let ((n 3)
    (f 4)
    (g 3))
    (if (= n 0)
    (+ n f g)
      (* n f g))))

我试图读取这样的文件:

  (let ((in (open dd)))
   (when in 
    (loop for line = (read-line in nil)
     while line do (format t "~a~%" line))
     (close in)))

这给了我明显正确的输出:

(+ 3 3)

(let ((n 3)) (+ n 1))

(let ((n 4))
  (+ n 1))

(defun d (f)
  (let ((n 3)
    (f 4)
    (g 3))
    (if (= n 0)
    (+ n f g)
      (* n f g))))

我想调用我的函数parse-parse-exp parse-exp < /代码>在文件的每一行上,与上面的每个表达式相对应。

从stackoverflow上的另一个答案中,我尝试执行此操作:

* (defun get-file (filename)
   (let ((in (open filename)))
    (loop for line = (read-line in nil)
     while line
     collect line)))
GET-FILE
* (get-file dd)
("(+ 3 3)" "" "(let ((n 3)) (+ n 1))" "" "(let ((n 4))" "  (+ n 1))" ""
 "(defun d (f)" "  (let ((n 3)" "   (f 4)" "    (g 3))" "    (if (= n 0)"
 "  (+ n f g)" "      (* n f g))))")

将每行转换为字符串,而不是我想要的格式。

我也尝试这样做:

(uiop:read-file-lines "file.txt")

但是我获得了与上一个示例相同的输出。

我希望能够将每行/表达式用作parse-exp的输入 - 像这样:

(parse-exp'(+ 3 3))(parse-exp'(let((n 3))(+ n 1))) 等等。

我该怎么做?

谢谢。

I have a file: test.lisp with this content:

(+ 3 3)

(let ((n 3)) (+ n 1))

(let ((n 4))
  (+ n 1))

(defun d (f)
  (let ((n 3)
    (f 4)
    (g 3))
    (if (= n 0)
    (+ n f g)
      (* n f g))))

I am trying to read the file like this:

  (let ((in (open dd)))
   (when in 
    (loop for line = (read-line in nil)
     while line do (format t "~a~%" line))
     (close in)))

which gives me the apparent correct output:

(+ 3 3)

(let ((n 3)) (+ n 1))

(let ((n 4))
  (+ n 1))

(defun d (f)
  (let ((n 3)
    (f 4)
    (g 3))
    (if (= n 0)
    (+ n f g)
      (* n f g))))

I want to call my function parse-exp on each line of the file corresponding to each expression above.

From a different answer here on Stackoverflow I tried to do this:

* (defun get-file (filename)
   (let ((in (open filename)))
    (loop for line = (read-line in nil)
     while line
     collect line)))
GET-FILE
* (get-file dd)
("(+ 3 3)" "" "(let ((n 3)) (+ n 1))" "" "(let ((n 4))" "  (+ n 1))" ""
 "(defun d (f)" "  (let ((n 3)" "   (f 4)" "    (g 3))" "    (if (= n 0)"
 "  (+ n f g)" "      (* n f g))))")

which converts each line to a string and its not in the format that I want.

I also tried doing this:

(uiop:read-file-lines "file.txt")

but I get the same output as the previous example.

I want to be able to use each line/expression as input to parse-exp - like this:

(parse-exp '(+ 3 3)) or
(parse-exp '(let ((n 3)) (+ n 1)))
and so on.

How do I do this?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

噩梦成真你也成魔 2025-02-04 17:00:57

您搜索的是读取而不是read-line读取expression-wise(并由LISP解释器使用)。

(with-open-file (stream "test1.lisp")
  (loop for expr = (read stream nil 'eof)
    until (eq expr 'eof)
    collect expr))
;; ((+ 3 3) (LET ((N 3)) (+ N 1)) (LET ((N 4)) (+ N 1))
;; (DEFUN D (F) (LET ((N 3) (F 4) (G 3)) (IF (= N 0) (+ N F G) (* N F G)))))
;; every element is an expression.

如果您希望表达式为字符串而不是符号列表,请使用(格式nil“ 〜a” ...)

(with-open-file (stream "test1.lisp")
  (loop for expr = (read stream nil 'eof)
    until (eq expr 'eof)
    collect (format nil "~a" expr)))
;; ("(+ 3 3)" "(LET ((N 3)) (+ N 1))" "(LET ((N 4)) (+ N 1))"
;;  "(DEFUN D (F) (LET ((N 3) (F 4) (G 3)) (IF (= N 0) (+ N F G) (* N F G))))")

What you search for is read instead of read-line which reads expression-wise (and is used by lisp interpreters).

(with-open-file (stream "test1.lisp")
  (loop for expr = (read stream nil 'eof)
    until (eq expr 'eof)
    collect expr))
;; ((+ 3 3) (LET ((N 3)) (+ N 1)) (LET ((N 4)) (+ N 1))
;; (DEFUN D (F) (LET ((N 3) (F 4) (G 3)) (IF (= N 0) (+ N F G) (* N F G)))))
;; every element is an expression.

If you want the expressions to be strings instead of list of symbols, use (format nil "~a" ...):

(with-open-file (stream "test1.lisp")
  (loop for expr = (read stream nil 'eof)
    until (eq expr 'eof)
    collect (format nil "~a" expr)))
;; ("(+ 3 3)" "(LET ((N 3)) (+ N 1))" "(LET ((N 4)) (+ N 1))"
;;  "(DEFUN D (F) (LET ((N 3) (F 4) (G 3)) (IF (= N 0) (+ N F G) (* N F G))))")
-柠檬树下少年和吉他 2025-02-04 17:00:57

Common Lisp具有许多功能可以处理的功能:

  • 读取从流中读取S-表达。
  • 读取从字符串读取从字符串
  • printprin1pprint打印S-表达。后者漂亮打印出来。
  • eval评估S-表达。
  • with-open-file是一个宏,它以输入以流以流为“流” 是一个宏来打开并关闭文件
  • ,是一个创建流的宏,以便可以从该字符串中读取

Common Lisp has a bunch of functions to deal with that:

  • read reads an s-expression from a stream.
  • read-from-string reads an s-expression from a string
  • print, prin1 and pprint prints an s-expression. The latter pretty prints it.
  • eval evaluates an s-expression.
  • with-open-file is a macro which opens and closes a file as a stream
  • with-input-from-string is a macro which creates a stream, so that one can read from that string
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文