Common Lisp 错误无法理解

发布于 2024-09-29 08:31:52 字数 4230 浏览 8 评论 0原文

我正在尝试用 Lisp 编写一个猜数字游戏作为一个消磨时间的项目。但是,当我尝试使用 SBCL 加载程序时,出现以下错误:

debugger invoked on a SB-C::INPUT-ERROR-IN-COMPILE-FILE in thread #<THREAD
                                                                    "initial thread" RUNNING
                                                                    {AA14959}>:
  READ failure in COMPILE-FILE at character 477:
    end of file on #<SB-SYS:FD-STREAM
                     for "file /home/andy/Dropbox/Programming/Common Lisp/number-game.lisp"
                     {B4F45F9}>

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE] Ignore runtime option --load "number-game.lisp".
  1: [ABORT   ] Skip rest of --eval and --load options.
  2:            Skip to toplevel READ/EVAL/PRINT loop.
  3: [QUIT    ] Quit SBCL (calling #'QUIT, killing the process).

(SB-C::READ-FOR-COMPILE-FILE
 #<SB-SYS:FD-STREAM
   for "file /home/andy/Dropbox/Programming/Common Lisp/number-game.lisp"
   {B4F45F9}>
 477)

此错误是什么意思?代码如下,加载文件并从 REPL 调用 (play) 时出现错误:(

;;;; number-game.lisp
;;;;
;;;; Andrew Levenson
;;;; 10/25/2010
;;;;
;;;; Simple number guessing game. User has
;;;; five guesses to determine a number between
;;;; one and one hundred, inclusive (1-100).

;;; Set global variable for the target number:
(defparameter *target* nil) 

;;; Set the iterator so we may check the number of guesses
(defparameter *number-of-guesses* 0)

;;; Welcome the user
(defun welcome-user ()
    (format t "Welcome to the number guessing game!~%"))

;;; Prompt for a guess
(defun prompt-for-guess ()
    (format t "Please enter your guess (1-100): ")
    (finish-output nil) ; nil directs finish-output to standard IO
    (check-guess((read-guess)))

;;; Read in a guess
(defun read-guess ()
    (let ((guess (read)))
        (if (numberp guess) ; If true, return guess. Else, call prompt-for-guess
            (progn
                (setq *number-of-guesses* (+ *number-of-guesses* 1))
                guess)
            (prompt-for-guess))))

;;; Check if the guess is higher than, lower than, or equal to, the target
(defun check-guess (guess)
    (if (equal guess *target*)
        (equal-to)
        (if (> guess *target*)
            (greater-than (guess))
            (if (< guess *target*)
                (less-than (guess))))))

;;; If the guess is equal to the target, the game is over
(defun equal-to ()
    (format t "Congratulations! You have guessed the target number, ~a!~%" *target*)
    (y-or-n-p "Play again? [y/n] "))

;;; If the guess is greater than the target, inform the player.
(defun greater-than (guess)
    (format t "Sorry, ~a is greater than the target.~%" guess)
    (if (< *number-of-guesses* 6)
        (prompt-for-guess)
        (game-over)))

;;; If the guess is less than the target, inform the player.
(defun less-than (guess)
    (format t "Sorry, ~a is less than the target.~%" guess)
    (if (< *number-of-guesses* 6)
        (prompt-for-guess)
        (game-over)))

;;; If the player has run out of guesses, give them the option
;;; of playing the game again.
(defun game-over ()
    (y-or-n-p "You have run out of guesses. Play again? [y/n] "))


;;; Play the game
(defun play ()
    ;; If it's their first time playing this session,
    ;; make sure to greet the user.
    (unless (> *number-of-guesses* 0)
        (welcome-user))
    ;; Reset their remaining guesses
    (setq *number-of-guesses* 0)
    ;; Set the target value
    (setq *target*
        ;; Random can return float values,
        ;; so we must round the result to get
        ;; an integer value.
        (round
            ;; Add one to the result, because
            ;; (random 100) yields a number between
            ;; 0 and 99, whereas we want a number
            ;; from 1 to 100 inclusive.
            (+ (random 100) 1)))
    (if (equal (prompt-for-guess) "y")
        (play)
        (quit)))

我相当肯定,除了那个错误之外,程序无法工作,我'对于 Lisp 来说,我还是一个完全的新手。这只是我遇到的第一个我自己无法解决的错误。)

哦,这个问题很可能与提示有关 - for-guess、read-guesscheck-guess 函数,因为当这个错误出现时,我正在处理这些函数。

I'm trying to write a number guessing game in Lisp as a time-killing project. However, when I try to load up the program using SBCL, I get the following error:

debugger invoked on a SB-C::INPUT-ERROR-IN-COMPILE-FILE in thread #<THREAD
                                                                    "initial thread" RUNNING
                                                                    {AA14959}>:
  READ failure in COMPILE-FILE at character 477:
    end of file on #<SB-SYS:FD-STREAM
                     for "file /home/andy/Dropbox/Programming/Common Lisp/number-game.lisp"
                     {B4F45F9}>

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE] Ignore runtime option --load "number-game.lisp".
  1: [ABORT   ] Skip rest of --eval and --load options.
  2:            Skip to toplevel READ/EVAL/PRINT loop.
  3: [QUIT    ] Quit SBCL (calling #'QUIT, killing the process).

(SB-C::READ-FOR-COMPILE-FILE
 #<SB-SYS:FD-STREAM
   for "file /home/andy/Dropbox/Programming/Common Lisp/number-game.lisp"
   {B4F45F9}>
 477)

What does this error mean? The code is as follows, and the error appears when loading the file and calling (play) from the REPL:

;;;; number-game.lisp
;;;;
;;;; Andrew Levenson
;;;; 10/25/2010
;;;;
;;;; Simple number guessing game. User has
;;;; five guesses to determine a number between
;;;; one and one hundred, inclusive (1-100).

;;; Set global variable for the target number:
(defparameter *target* nil) 

;;; Set the iterator so we may check the number of guesses
(defparameter *number-of-guesses* 0)

;;; Welcome the user
(defun welcome-user ()
    (format t "Welcome to the number guessing game!~%"))

;;; Prompt for a guess
(defun prompt-for-guess ()
    (format t "Please enter your guess (1-100): ")
    (finish-output nil) ; nil directs finish-output to standard IO
    (check-guess((read-guess)))

;;; Read in a guess
(defun read-guess ()
    (let ((guess (read)))
        (if (numberp guess) ; If true, return guess. Else, call prompt-for-guess
            (progn
                (setq *number-of-guesses* (+ *number-of-guesses* 1))
                guess)
            (prompt-for-guess))))

;;; Check if the guess is higher than, lower than, or equal to, the target
(defun check-guess (guess)
    (if (equal guess *target*)
        (equal-to)
        (if (> guess *target*)
            (greater-than (guess))
            (if (< guess *target*)
                (less-than (guess))))))

;;; If the guess is equal to the target, the game is over
(defun equal-to ()
    (format t "Congratulations! You have guessed the target number, ~a!~%" *target*)
    (y-or-n-p "Play again? [y/n] "))

;;; If the guess is greater than the target, inform the player.
(defun greater-than (guess)
    (format t "Sorry, ~a is greater than the target.~%" guess)
    (if (< *number-of-guesses* 6)
        (prompt-for-guess)
        (game-over)))

;;; If the guess is less than the target, inform the player.
(defun less-than (guess)
    (format t "Sorry, ~a is less than the target.~%" guess)
    (if (< *number-of-guesses* 6)
        (prompt-for-guess)
        (game-over)))

;;; If the player has run out of guesses, give them the option
;;; of playing the game again.
(defun game-over ()
    (y-or-n-p "You have run out of guesses. Play again? [y/n] "))


;;; Play the game
(defun play ()
    ;; If it's their first time playing this session,
    ;; make sure to greet the user.
    (unless (> *number-of-guesses* 0)
        (welcome-user))
    ;; Reset their remaining guesses
    (setq *number-of-guesses* 0)
    ;; Set the target value
    (setq *target*
        ;; Random can return float values,
        ;; so we must round the result to get
        ;; an integer value.
        (round
            ;; Add one to the result, because
            ;; (random 100) yields a number between
            ;; 0 and 99, whereas we want a number
            ;; from 1 to 100 inclusive.
            (+ (random 100) 1)))
    (if (equal (prompt-for-guess) "y")
        (play)
        (quit)))

(I'm fairly certain that the program doesn't work minus that one error, I'm still a complete novice when it comes to Lisp. This is just the first error I've encountered that I can't figure out on my own.)

Oh, and the issue most likely has to do with the prompt-for-guess, read-guess and check-guess functions, because those were the ones I was messing with when this error cropped up.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

段念尘 2024-10-06 08:31:52

看来您在 prompt-for-guess defun 上没有关闭足够的括号。

读者正在读到文件的末尾,并注意到它有一个仍然打开的表单,并且无法弄清楚它来自哪里。

我用来查找此类错误的一个简单方法是让我的文本编辑器缩进该区域,并确保所有内容都按照我的想法排列。

It looks like you didn't close enough parens on your prompt-for-guess defun.

The reader is getting to the end of the file and noticing that it has a form still open, and can't figure out where it's from.

An easy way I use to find errors like this is to have my text editor indent the region, and make sure everything lines up like I think it should.

魂归处 2024-10-06 08:31:52

Emacs 中的命令是 Mx check-parens(它检查需要平衡的所有内容,例如引号)。如果一切都平衡,这可能会有点令人困惑,因为在这种情况下它什么也不做。

检查括号
命令:检查当前缓冲区中是否有不平衡的括号。
更准确地说,检查缓冲区变窄的部分是否不平衡
一般表达式(“sexps”)。这是根据
当前语法表,会发现不平衡的括号或引号
合适的。 (请参阅信息节点“(emacs)Parentheses”。)如果不平衡是
发现,发出错误信号,并将点留在第一个不平衡处
特点。

The command in Emacs is M-x check-parens (it checks everything that needs to balance, like quotes, as well). It can be a bit mystifying if everything balances, because it does nothing in that case.

check-parens
Command: Check for unbalanced parentheses in the current buffer.
More accurately, check the narrowed part of the buffer for unbalanced
expressions ("sexps") in general. This is done according to the
current syntax table and will find unbalanced brackets or quotes as
appropriate. (See Info node `(emacs)Parentheses'.) If imbalance is
found, an error is signaled and point is left at the first unbalanced
character.

余生共白头 2024-10-06 08:31:52

读取期间的文件结尾,缺少右括号(或类似的)。字符 477。将文本中的光标移到 477 并检查它是哪个表达式。

检查 IDE 中是否有命令来查找不平衡的表达式。

在 LispWorks 中,这将是 Mx Find Unbalanced Parentheses

SLIME 也应该有一些命令。

end of file during read, there is a closing parenthesis (or similar) missing. Character 477. Move the cursor in your text to 477 and check which expression it is.

Check your IDE for a command to find unbalanced expressions.

In LispWorks this would be M-x Find Unbalanced Parentheses.

SLIME should have some command for that, too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文