1

这里有一个口齿不清的问题。在过去的几个月里,我一直在慢慢学习 lisp,并且在尝试从 Web 浏览器获取输入与从 REPL 获取输入时遇到了问题。

具体问题是在尝试评估此代码时:

假设sexp'(look north)

(member (car sexp) '(look walk pickup drop))

从 SBCL 中的 REPL 来看,这可以正常工作并且符合预期。但是,当sexp从 hunchentoot 中获取时,即使“看起来”与 REPL 中的相同,sexp它似乎永远无法考虑(car sexp).'(look walk pickup drop)

我认为这可能是文件的字符编码与sexp从网络浏览器抓取时的字符编码,但我不知道如何检验这个假设。任何指针将不胜感激!

编辑

我输入的方式是基于 Conrad Barski 的“Land of Lisp”中的文字冒险游戏,详情如下。

(defun game-read (string-to-read)
  (let ((cmd (read-from-string
               (concatenate 'string "(" string-to-read ")"))))
    (describe cmd)
    (flet ((quote-it (x)
                     (list 'quote x)))
      (cons (car cmd) (mapcar #'quote-it (cdr cmd))))))

然后将其包裹在:

(defun game-eval (sexp)
  (if (member (car sexp) *allowed-commands*) ;Offending line                                                                          
      (eval sexp)
      '(i do not know that command.)))

哪里*allowed-commands*是:

(defparameter *allowed-commands* '(look walk pickup inventory))

我标记为冒犯了正常工作的行,但是当string-to-read它来自作为请求的一部分从 hunchentoot 获取的请求参数(car sexp) ,无论我知道如何查看它但在*allowed-commands*.

4

2 回答 2

4

你需要确定你得到的是什么输入。它是一个符号吗?Common Lisp 具有 TYPE-OF、INSPECT 和 DESCRIBE 等功能,可以获取有关数据的更多信息。

* (describe 'north)

COMMON-LISP-USER::NORTH
  [symbol]


* (type-of 'north)

SYMBOL

下一个问题是:如果它是一个符号,它在哪个包中?

* (symbol-package 'north)

#<PACKAGE "COMMON-LISP-USER">

您的其他符号是否在同一个包中?

下一个问题是:如果是符号或字符串,那么大写呢?

* (symbol-name 'north)

"NORTH"

默认情况下,符号是大写的。从输入读取的符号不一定是这种情况。

现在您还可以使用 MEMBER 进行纯字符串比较:

* (member (symbol-name '|Foo|)
          '(foo bar baz)
          :key #'symbol-name :test #'equalp)

(FOO BAR BAZ)   ; this is the usual return value,
                ; the rest list with first item found
于 2011-07-18T20:08:16.377 回答
1

我从未使用过 sbcl 或 Common Lisp,但这听起来像是一个实习问题。试试这个查询:

(member (intern (car sexp)) '(look walk pickup drop)))
于 2011-07-18T19:59:19.107 回答