bou*_*ekv 4 macros symbols common-lisp
我正在尝试以下列方式定义符号a和b
a + 1 1 b
2
Run Code Online (Sandbox Code Playgroud)
我试图通过使用define-symbol-macro来做到这一点
(define-symbol-macro a '( )
(define-symbol-macro b ') )
Run Code Online (Sandbox Code Playgroud)
但这种方式不起作用.
Jos*_*lor 22
Common Lisp是一种非常灵活的语言,部分原因是它的源代码可以使用语言中使用的相同数据结构轻松表示.最常见的宏扩展形式将这些结构转换为其他结构.这是那种你可以定义宏define-symbol-macro,define-compiler-macro,defmacro,和macrolet.然而,在可以执行任何这种宏扩展之前,系统首先需要从输入流(通常是文件或交互式提示)读取源.这是读者的责任.读者还可以在遇到某些特征时执行某些特殊操作(和'.你想要做的事情可能需要在读者层面发生,如果你想拥有,例如,(read-from-string "a + 1 1 b")返回列表 (+ 1 1),如果你想要(eval (read-from-string "a + 1 1 b"))返回,这就是你想要的2.也就是说,您还可以定义一种特殊的自定义语言(如同loop),a并b在其中进行特殊处理.
set-macro-character,而不是define-symbol-macro这不是您使用符号宏,而是使用宏字符.您可以使用aptly命名设置宏字符set-macro-character.例如,在下面,我将宏字符设置为%读取列表的函数,使用read-delimited-list该函数应该终止^.(使用字符a和b这里将证明非常困难,因为你将无法像(set-macro-character ...)之后写的东西;这就像写作(set-m(cro-ch(r(cter ...),这是不好的.)
CL-USER> (set-macro-character #\% (lambda (stream ignore)
(declare (ignore ignore))
(read-delimited-list #\^ stream)))
T
CL-USER> % + 1 1 ^
2
Run Code Online (Sandbox Code Playgroud)
set-syntax-from-char有一个相关的功能几乎可以满足您的需求set-syntax-from-char.您可以使用它来使一个角色表现得像另一个角色.例如,你可以%表现得像(
CL-USER> (set-syntax-from-char #\% #\()
T
CL-USER> % + 1 1 )
2
Run Code Online (Sandbox Code Playgroud)
但是,由于与之关联的宏字符(不是在寻找具有与实际字符相同的语法)的字符,因此您不能简单地以相同的方式替换: ))^
CL-USER> (set-syntax-from-char #\^ #\))
T
CL-USER> % + 1 1 ^
; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR "unmatched close parenthesis" {1002C66031}>.
Run Code Online (Sandbox Code Playgroud)
set-syntax-from-char当有一个现有的角色本身做你想要模仿的东西时,它会更有用.例如,如果您想创建!一个额外的引用字符:
CL-USER> (set-syntax-from-char #\! #\')
T
CL-USER> (list !a !(1 2 3))
(A (1 2 3))
Run Code Online (Sandbox Code Playgroud)
或者成为%注释字符,就像在LaTeX中一样:
CL-USER> (set-syntax-from-char #\% #\;)
T
CL-USER> (list 1 2 % 3 4
5 6)
(1 2 5 6)
Run Code Online (Sandbox Code Playgroud)
现在,即使你可以做到这一切,对于遇到它的人来说,这似乎是完全令人惊讶的事情.(也许你正在进入一个模糊编码竞赛;))对于上述所示的原因,与常用字符,如这样做a,并b也将使它很难写任何更多的源代码.定义一个全新的readtable可能是一个更好的选择,它可以完成你想要的,或者甚至可以编写一个新的解析器.尽管(Common)Lisp 允许你重新定义语言,但仍然有一些事情可能是单独留下来的.