用"read"解析字符串.并忽略包名称空间 [英] Parse string with "read" and ignore package namespaces

查看:96
本文介绍了用"read"解析字符串.并忽略包名称空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个程序,该程序打开一个lisp文件,在流上调用"read",直到流为空,并对其收集的列表进行处理.

I am writing a program that opens a lisp file, calls "read" on the stream until the stream is empty, and does things with the lists it collects.

这一直很好,直到我发现读取"将执行程序包查找,例如,如果遇到some-package:foo,它将抱怨Package SOME-PACKAGE does not exist.

This was working quite nicely until I discovered that "read" will perform package lookup, for instance if it encounters some-package:foo it will complain that Package SOME-PACKAGE does not exist.

这是一个说明我的意思的例子:

Here is an example showing what I mean:

(read (make-string-input-stream "(list 'foo :foo some-package:foo)"))

所以我现在想要三件事之一:

So I now I would like one of three things:

  1. 将其设置为读取"将忽略程序包名称空间,以便我可以将任意源文件转换为符号列表.
  2. 使用其他行为与读取"类似的解析库,但只能通过修饰:或忽略冒号及其之前的所有内容而获得纯符号.
  3. 对该文件进行预处理,并使用正则表达式等将查找包打包并用纯名称替换,例如将"some-package:foo"转换为简单的"foo"
  1. Make it so "read" will ignore package namespaces so I can convert arbitrary source files to lists of symbols.
  2. Use some other parsing library with similar behavior to "read" but that only gets plain symbols, either by mangling the : or ignoring the colon and everything before it.
  3. Pre-processing the file and use regex or such to package lookups and replace them with plain names, such as converting "some-package:foo" to simply "foo"

首先,所有这些操作的目的是制作一个函数调用依赖关系图.我知道存在的事物具有更高质量的本质,但是我想自己做些乐趣/学习.但是,我遇到了这个问题,不知道如何进行.

The purpose of all of this in the first place was to make a function call dependency graph. I'm aware there exists things of that nature of much higher quality that exist, but I wanted to do it myself for fun/learning. However, I have hit a snag with this problem and don't know how to proceed.

推荐答案

最简单的答案是告诉Lisp阅读器按原样读取冒号#\::

The simplest answer is to tell the Lisp reader to read colon #\: as is:

(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:BARFOO :BAR,但是您可能可以解决该问题.

The obvious problem is that this will read FOO:BAR and FOO :BAR identically, but you might be able to work around that.

这篇关于用"read"解析字符串.并忽略包名称空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆