导出符号上的SBCL错误



我在SBCL中使用"pregexp"包进行正则表达式操作。因为函数不是在包中定义的,所以我使用下面的代码来包装:

---------------在文件"foo。口齿不清 " -----------------

(defpackage :pregexp
   (:use :common-lisp)
   (:documentation "Portable Regular Expression Library")
   (:nicknames :pre))
(in-package :pregexp)
(load (merge-pathnames "libs/pregexp/pregexp" CL-USER:*x-code-path*))
(export '(pregexp
           pregexp-match-positions
           pregexp-match
           pregexp-split
           pregexp-replace
           pregexp-replace*
           pregexp-quote))

我把代码放在初始化文件"~/"中。Sbclrc",以加载"foo. exe"。lisp"开始。到目前为止,这是可以的,并且当我启动SBCL时没有错误。

然后我注意到每次我重新加载"foo。Lisp",有警告说函数已经导出,所以我更改代码:

---------------在文件"foo。口齿不清 " -----------------

#-pregexp
(progn
(defpackage :pregexp
   (:use :common-lisp)
   (:documentation "Portable Regular Expression Library")
   (:nicknames :pre))
(in-package :pregexp)
(load (merge-pathnames "libs/pregexp/pregexp" CL-USER:*x-code-path*))
(export '(pregexp
           pregexp-match-positions
           pregexp-match
           pregexp-split
           pregexp-replace
           pregexp-replace*
           pregexp-quote))
(pushnew :pregexp *features*)
)

我只把代码包装在' program '块中,但每次我启动SBCL时,都在那里错误:

debugger invoked on a SB-KERNEL:SIMPLE-PACKAGE-ERROR in thread
#<THREAD "main thread" RUNNING {23EF7A51}>:
  These symbols are not accessible in the PREGEXP package:
    (COMMON-LISP-USER::PREGEXP COMMON-LISP-USER::PREGEXP-MATCH-POSITIONS
     COMMON-LISP-USER::PREGEXP-MATCH COMMON-LISP-USER::PREGEXP-SPLIT
     COMMON-LISP-USER::PREGEXP-REPLACE COMMON-LISP-USER::PREGEXP-REPLACE*
     COMMON-LISP-USER::PREGEXP-QUOTE)
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE] IMPORT these symbols into the PREGEXP package.
  1: [RETRY   ] Retry EVAL of current toplevel form.
  2:            Ignore error and continue loading file "C:\test\bar.lisp".
  3: [ABORT   ] Abort loading file "C:\test\bar.lisp".
  4:            Retry EVAL of current toplevel form.
  5:            Ignore error and continue userinit file "C:\user\Dropbox\.sbclrc".
  6:            Abort userinit file "C:\user\Dropbox\.sbclrc".
  7:            Skip to toplevel READ/EVAL/PRINT loop.
  8: [EXIT    ] Exit SBCL (calling #'EXIT, killing the process).
((FLET SB-IMPL::THUNK :IN EXPORT))
0] 

那么,我现在该怎么办呢?

PS,环境:SBCL x86 1.1.4 Windows Server 2003 32位

阅读器将PROGN表单作为当前包中的单个表单读取。符号来自那个包。

所以尝试从PREGEXP包中导出COMMON-LISP-USER::PREFEXP符号。

您需要确保您导出了正确的符号(它在正确的包中)

Rainer Joswig的回答提到了在读取、实习和导出过程中发生的一些事情,但我想知道,如果使用defpackage:export子句,您遇到的问题是否不会更容易避免。如果您使用它,您可以将defpackage表单写成:

(defpackage :pregexp
   (:use :common-lisp)
   (:documentation "Portable Regular Expression Library")
   (:nicknames :pre))
   (:export #:pregexp                 ; or :pregexp, or "PREGEXP"
            #:pregexp-match-positions 
            #:pregexp-match 
            #:pregexp-split
            #:pregexp-replace
            #:pregexp-replace*
            #:pregexp-quote))

即使这些符号命名为函数,也不需要在导出与它们关联的符号之前定义这些函数。(我之所以提到这一点,是因为问题中的代码定义了包,然后加载(大概)函数定义,然后导出符号。事情不需要按这个顺序发生。例如,定义包,导出符号,然后定义函数。

最新更新