Common Lisp中的语言问题 - 如何标记文件

时间:2014-10-04 20:06:14

标签: lisp nlp common-lisp tokenize

我一直在尝试使用langutils库(我使用Quicklisp下载)对字符串进行标记,我正在使用SBCL,但我遇到了一些问题。我一直在尝试使用以下代码:

(cl-utilities:split-sequence #\Space (multiple-value-call #'(lambda (a b c d) c) (tokenize-stream (open "hello.txt"))))

输出

("Hello" "," "" "what" "is" "your" "name." "My" "name" "is" "John" "Doe.")

我的问题是:为什么语言标记空间,为什么不标记句点?

顺便说一句,如果说有些错误,那么我可以使用Common Lisp中的其他替代库吗?我曾尝试使用(tokenize-file),但它运行不正常 - 使用(tokenize-file“hello.txt”)返回

The function LANGUTILS-TOKENIZE:TOKENIZE-FILE is undefined.

并使用(标签“string”)返回

The value NIL is not of type HASH-TABLE.

1 个答案:

答案 0 :(得分:1)

好的,让我们看一下,没有特别的顺序:


是的,langutils似乎有些错误。看看它的来源,很多东西仍被标记为“(尚未实施)”。你想用它做什么?具体来说,您期望(tag "string")tokenize-file做什么(文档字符串不是特别清楚)?

如果您要尝试解析Lisp表达式,可以使用内置的read。如果您打算尝试使用自己的语法规则解析任意文件(并使用SBCL),请查看esrap。它是Common Lisp中的PEG解析器实现。 github有一些例子。


如果要忽略split-sequence中的空序列,可以向其传递额外的:remove-empty-subseqs关键字参数。我不完全确定为什么这不是默认值,因为我从未在没有此选项的情况下调用该函数,但它可能在任何主要用例中都有意义。

您的通话应该是

(cl-utilities:split-sequence 
 #\Space (multiple-value-call #'(lambda (a b c d) c)
       (tokenize-stream (open "hello.txt")))
 :remove-empty-subseqs t)

tokenize-stream似乎返回文件的文本内容以及有关它的一些元数据。如果这就是你想要的,那么在不诉诸multiple-value-call的情况下编写自己的代码非常容易。请参阅Files and Directories section of the CL Cookbook


我认为通过执行(tokenize-stream (open "hello.txt")),你会留下悬挂的文件句柄(因为你之后不会关闭它)。这里典型的做法是致电with-open-file

(with-open-file (s "hello.txt")
  (tokenize-stream s))