list - 用“read”解析字符串并忽略包命名空间
问题描述
我正在编写一个程序,它打开一个 lisp 文件,在流上调用“读取”直到流为空,然后对它收集的列表进行处理。
这工作得很好,直到我发现“读取”将执行包查找,例如,如果遇到some-package:foo
它会抱怨Package SOME-PACKAGE does not exist.
这是一个显示我的意思的示例:
(read (make-string-input-stream "(list 'foo :foo some-package:foo)"))
所以我现在想要三件事之一:
- 让它如此“读取”将忽略包名称空间,因此我可以将任意源文件转换为符号列表。
- 使用其他一些具有类似行为的解析库来“读取”,但只能通过修改
:
或忽略冒号及其前面的所有内容来获取普通符号。 - 预处理文件并使用正则表达式等来打包查找并用普通名称替换它们,例如将“some-package:foo”转换为简单的“foo”
首先,所有这些的目的是制作一个函数调用依赖图。我知道存在质量更高的那种性质的东西,但我想自己做这件事是为了好玩/学习。但是,我遇到了这个问题,不知道如何继续。
解决方案
最简单的答案是告诉 Lisp 阅读器按#\:
原样阅读冒号:
(defun read-standalone-char (stream char)
(declare (ignore stream))
char)
(defun make-no-package-prefix-readtable (&optional (rt (copy-readtable)))
"Return a readtable for reading while ignoring package prefixes."
(set-syntax-from-char #\: #\Space rt)
(set-macro-character #\: #'read-standalone-char nil rt)
rt)
(let ((*readtable* (make-no-package-prefix-readtable)))
(read-from-string "(list 'foo :foo some-package:foo)"))
==> (LIST 'FOO #\: FOO SOME-PACKAGE #\: FOO) ; 33
明显的问题是它的读取方式FOO:BAR
相同FOO :BAR
,但您也许可以解决这个问题。
推荐阅读
- protractor - 使用 Protractor 在不同版本的 chrome 上运行测试
- asp.net-core - Html Beginform with button click 在.net core mvc中不起作用
- reactjs - React JS API Post 抛出 ERR_ABORTED 415
- javascript - 迭代 Typescript 中的对象以查找属性及其值
- javascript - 我正在尝试在 localhost 中测试我的实时 Facebook 之类的聊天应用程序
- sql - 检查 SYS_REFCURSOR 是否为空
- node.js - 组件EmployeeCreateComponent的模板出现错误
- java - 无法在存储android 10中打开PDF文件
- go - 将字符串切片作为选项发送到期望接口{}的可变参数函数
- telegram - 如何在 Telegram Bot 网络服务器关闭时获取未发送的消息?