问题
I'm working on a code formatter for Lisp, which is using the reader to read code into S-expression format.
This works fine for plain symbols.
It doesn't work so well for qualified symbols. foo:bar
is only readable if the package foo
has been defined, but of course as far as the formatter is concerned, it has not, because unlike the compiler, the formatter is only reading the code, not executing it.
How can I tell the reader to either go ahead and automatically create a package foo
on the fly, or failing that, don't sweat it, just read foo:bar
, not as a symbol per se, but in some unambiguous format I can deal with as a special case?
回答1:
I believe that you should not use the reader for that, because that is lossy (you lose comments, and anything that gets changed through reader macros, e. g. read-time-values, read-time references etc.).
But if you want, you can automatically create the package and maybe also export the symbol by handling the error, e. g. on SBCL:
(handler-bind ((sb-int:simple-reader-package-error
(lambda (e)
(let ((p (sb-int::package-error-package e)))
(ctypecase p
(string
(make-package p)
(invoke-restart 'retry))
(package
(export (intern (first (simple-condition-format-arguments e)) p) p)
(invoke-restart 'retry)))))))
(with-simple-restart (retry "Retry")
(read-from-string "foo:bar")))
This is a bit hacky, and we have no guarantee that the format of the condition stays like that.
来源:https://stackoverflow.com/questions/52405865/reading-qualified-symbols