从LISP读取/解析常见的LISP文件,没有所有软件包或加载所有内容



我正在进行一个项目,其中涉及解析常见LISP存储库的历史。我需要将它们解析为列表或类似的名单。理想情况下,我想以某种方式保留尽可能多的原始源文件语法。例如,在文本#+sbcl <something>的情况下,我认为这意味着"如果我们当前的LISP为SBCL,请阅读<something>,否则跳过它",我想得到类似(#+ 'sbcl <something>)的东西。

我最初在python上写了一个Lalr解析器,这有点有效,但由于许多原因,这并不理想。我很难获得正确的输出,而且我有很多特殊情况要添加。

我认为我真正应该做的是使用LISP本身,因为它已经内置了Lisp解析器。如果我只能将文件读取到SEXPS中,我可以将其倒入某些东西(Cl-Json会做(为了进一步处理线路。

不幸的是,当我尝试阅读https://github.com/fukamachi/woo/woo/blob/master/src/src/woo.lis.lisp时,我会得到错误

There is no package with the name WOO.EV.TCP

当然来自该文件的80行,因为该软件包是在src/ev/tcp.lisp中定义的,我们还没有阅读。

基本上,是否有可能仅将文件阅读到SEXPS而不关心包裹是否定义或包含相关符号的情况下?如果是这样,怎么样?我已经尝试查看HypersPEC读取器文档,但我看不到任何听起来相关的内容。

我实际上写了常见的LISP,但似乎可能通过创建带有该名称的空白包并处理否来处理未定义的软件包条件来解决此问题 - 仅通过介绍给定符号来符合包装条件。我想。我不知道该怎么做,我不知道它是否有效,我不知道会涉及多少个特殊情况。副手,第一个条件称为no-such-package,但第二个条件(至少在SBCL中(称为simple-error,所以我什至不知道如何确定此特定的simple-error是否是无套件,错误,更不用说如何从条件中提取相关名称,修复并重新启动。我真的很想听到一位普通的LISP专家,这是在我沿着尝试这样做的道路之前要做的正确的事情,因为它将涉及很多学习。

在我看来,我可以通过在阅读文件之前进行修复。例如。将woo.ev.tcp:start-listening-socket变成woo.ev.tcp===start-listening-socket。我并不特别喜欢这种解决方案,而且尚不清楚我不会遇到更多丑陋的特殊情况,但是如果没有更好的答案,它可能会起作用。

我几乎确定没有简单的便携式方法出于多种原因。

(暂时将事物限制在不存在的包装问题上。(

首先,没有便携式访问读取器的访问权限,该读者认为令牌将是符号,然后查找包装标记&amp; c:这只是根据2.3中规则发生的。因此,您无法轻易干预此事。

其次,在读者可能能够处理它们的任何条件下,没有足够的信息。

从这个问题中有几种可能的方法。

如果您感到足够英雄,您可能可以教读者,所有令牌启动的字符实际上都是您控制的东西,然后写一个令牌阅读器,以某种方式通过返回某些对象来处理整个软件包,不是象征。但是要做到这一点,您需要处理数字,如果您认为这很简单,那不是。

如果您觉得英雄不那么英雄,您可以写一个更原始的令牌阅读器,它甚至没有试图处理任何东西,除了抓住所需的所有字符并返回某种包装字符串的对象。这将避免以失去大量功能为代价的整数问题。

如果您不关心可移植性,找到实现,了解其读者的工作方式,并努力解决。我可以轻松计数的开源或源可用的实现更多(也许我擅长计数(,所以这是一种很好的方法。当然是我要做的。


这只是问题的开始。CL读取器是毛茸茸的,并且以其标准配置(除非其他人进行安排,否则用于compile-file之类的配置(可以在阅读时间运行完全任意的代码,包括修改读者本身的代码,其中一些可能会这样做以实现的方式。人们使用此方法:LISP被称为"可编程编程语言"是有原因的,就是人们对其进行编程。

我决定使用sed(实际上是Python的re.sub,但是谁在计数?(,因为它适用于我的实际用例,并且很容易。

对于未来的读者:各种各样的人说这是不可能的,这可能是正确的。@Svante发布的其他问题看起来像是解决部分问题的好方法。通过替换#.#+#-等的读取器宏的其他部分,可以更优雅地解决问题的其他部分,而这些读者的含义与@TFB的建议相比,这听起来只有一个列表,但我没有时间来看,但是我没有时间那屎。

最新更新