打印带有中缀符号的列表

时间:2019-06-13 17:43:15

标签: lisp common-lisp

我想使用format将s表达式转换为带有前缀符号的字符串。如何使用format完成此操作?

示例;

(format t "<insert format controls here>" (1 2 3) '*)
=> "1 * 2 * 3"

4 个答案:

答案 0 :(得分:7)

此答案包含错误代码。

容易,只需使用custom formatters

(format t "~/acquire/~/disseminate/" '(1 2 3) '*)

它们的定义如下:

(let ((memory))
  (defun cl-user::acquire (stream list &optional colonp atsignp)
    (declare (ignore colonp atsignp stream))
    (setf memory list))
  (defun cl-user::disseminate (stream operator &optional colonp atsignp)
    (declare (ignore colonp atsignp))
    (format stream (concatenate 'string "~{~a~^ " (string operator) " ~}") memory)
    (setf memory nil)))

例如:

CL-USER> (format t "~/acquire/~/disseminate/" '(1 2 3) '*)
1 * 2 * 3

memory变量在两个函数的词法范围内,这使它们可以通信数据。第一个存储列表,第二个使用列表。如果您从不调用第二个函数(或第一个函数为nil),则memory被永久绑定到最后一个列表,这可能是一个问题。另请注意,您可能会遇到并发问题。 坦白说,这不是您想要做的最好的方法,但是它可以完成工作。您的要求。

答案 1 :(得分:5)

(format t "~{~A~^ * ~}" '(1 2 3))
;; 1 * 2 * 3
;; NIL
  • ~{~}:遍历列表。
  • ~A:打印易于理解的( a 美观的)
  • ~^:仅当列表中有后继元素时才打印以下内容。
  • *:在周围的空白处加缀。

我曾经问过类似的问题。您在末尾添加了'*-因此,您还希望控制应使用join列表元素的分隔符。查看以下链接- @Sylwester给出了可接受的答案:Nicer pythonic `join` in common-lisp

(他通过将第二个格式表达式注入格式表达式来做到这一点-非常优雅!- 这样就可以致电(join '(1 2 3) :sep " * "))。

答案 2 :(得分:4)

使用str库*:

(str:join " * " '(1 2 3))
;; "1 * 2 * 3"

join函数的定义如下:

(defun join (separator strings)
  (let ((separator (replace-all "~" "~~" separator)))
    (format nil
            (concatenate 'string "~{~a~^" separator "~}")
            strings)))

*无耻的晋升。

答案 3 :(得分:1)

这是我想出的解决方案。

(defun compile-arith (expr)
  (format nil (concatenate 'string "~{~(~a~)~^ " (string (car expr)) " ~}")
    (cdr expr)))

(compile-arith '(* 1 2 3))

=> "1 * 2 * 3"