【问题标题】:Common Lisp Error Not Understood不理解的常见 Lisp 错误
【发布时间】:2011-04-30 21:40:14
【问题描述】:

我正在尝试用 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 时,我仍然是一个完全的新手。这只是我遇到的第一个我无法理解的错误我自己出去。)

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

【问题讨论】:

    标签: lisp common-lisp sbcl


    【解决方案1】:

    您的prompt-for-guess defun 似乎没有关闭足够多的括号。

    读者读到文件末尾,注意到它有一个表单仍然打开,但不知道它来自哪里。

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

    【讨论】:

    • 太棒了,修复了那个错误!谢谢!现在我需要弄清楚如何将函数的返回值作为参数传递给另一个函数。 :)
    • @Andrew: (other-function (first-function))?
    【解决方案2】:

    Emacs 中的命令是 M-x check-parens(它也会检查所有需要平衡的东西,比如引号)。如果一切都是平衡的,这可能会有点神秘,因为在这种情况下它什么都不做。

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

    【讨论】:

      【解决方案3】:
      读取期间

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

      检查您的 IDE 以查找不平衡表达式的命令。

      在 LispWorks 中,这将是 M-x 查找不平衡括号

      SLIME 也应该有一些命令。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 2016-10-25
        • 1970-01-01
        • 1970-01-01
        • 2012-12-10
        • 2011-02-04
        • 1970-01-01
        相关资源
        最近更新 更多