我遇到了导出宏的问题,当它在同一个包中声明时可以正常工作,但是当它被导入时就不能正常工作。我在Windows上使用Emacs、SLIME和Clozure。
包文件
(defpackage :tokenizer
(:use :common-lisp)
(:export :tokenize-with-symbols
:current-token
:advanze-token
:peek-token
:with-token-and-peek
:with-token))
(defpackage :csharp-parser
(:use :common-lisp :tokenizer)
(:import-from :tokenizer :with-token-and-peek :with-token))
分词器文件
(in-package :tokenizer)
(defmacro with-token-and-peek (&body body)
`(let ((token (current-token tokenizer))
(peek (peek-token tokenizer)))
,@body))
解析器文件
(in-package :csharp-parser)
(defun expression (tokenizer node-stack)
(with-token-and-peek
(cond ((is-number? token) (make-value-node "number" token))
((is-bool? token) (make-value-node "bool" token))
((is-identifier? token peek) (make-identifier-node tokenizer node-stack))
(t (make-ast-node :identifier "bla")))))
编译时出现错误:
csharpParser.lisp:265:3:
warning: Undeclared free variable TOKENIZER::TOKENIZER (2 references)
style-warning: Unused lexical variable TOKENIZER::PEEK
style-warning: Unused lexical variable TOKENIZER::TOKEN
csharpParser.lisp:266:14:
warning: Undeclared free variable TOKEN
etc etc etc
如果我在:csharp-parser包中尝试宏展开。
(macroexpand-1 '(with-token-and-peek tok))
(LET ((TOKENIZER::TOKEN (CURRENT-TOKEN TOKENIZER::TOKENIZER))
(TOKENIZER::PEEK (PEEK-TOKEN TOKENIZER::TOKENIZER)))
TOK)
T
现在,就像我说的那样,如果我将宏移动到解析器文件中,它会编译并且运行得非常完美。但是当我尝试将其重构为标记化文件并通过包系统导出时,它会出现这些错误,因为它似乎将符号内部化到调用包中。我已经尝试了多种方法,使用冒号,但无法使其工作。
如果有人能帮助我解决这个问题,我将不胜感激。