2010-10-26 26 views
6

Ich versuche, ein Zahlen Ratespiel in Lisp als Time-Tötung Projekt zu schreiben. Allerdings, wenn ich versuche, das Programm zu laden, bis mit SBCL, ich die folgenden Fehlermeldung erhalten:Common Lisp Fehler nicht verstanden

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) 

Was bedeuten diese Fehler? Der Code ist wie folgt, und der Fehler wird angezeigt, wenn die Datei geladen und (play) aus dem REPL Aufruf:

;;;; 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))) 

(ich ziemlich sicher bin, dass das Programm nicht minus eins nicht funktioniert, dass Fehler, ich bin immer noch ein kompletter Neuling, wenn es um Lisp geht.Dies ist nur der erste Fehler, den ich erlebt habe, den ich alleine nicht herausfinden kann.)

Oh, und das Problem hat wahrscheinlich mit der prompt-for-guess, read-guess zu tun und check-guess Funktionen, denn das waren diejenigen, mit denen ich zu tun hatte, als dieser Fehler auftauchte.

Antwort

6

Es sieht so aus, als ob Sie nicht genug Parens auf Ihrem prompt-for-guess defun geschlossen haben.

Der Leser wird an das Ende der Datei und merkt, dass es ein Formular noch geöffnet hat, und kann nicht herausfinden, wo es herkommt.

Ein einfacher Weg, den ich verwende, um Fehler wie diesen zu finden, besteht darin, dass mein Texteditor die Region einrastet, und stelle sicher, dass alles so ausgerichtet ist, wie ich denke.

+0

Super, das hat diesen Fehler behoben! Vielen Dank! Jetzt muss ich herausfinden, wie man den Rückgabewert einer Funktion als Argument an eine andere Funktion übergibt. :) – Andy

+2

@Andrew: '(andere Funktion (erste Funktion))'? –

1

Ende der Datei während lesen, gibt es eine geschlossene Klammer (oder ähnlich) fehlt. Zeichen 477. Bewegen Sie den Cursor in Ihrem Text auf 477 und prüfen Sie, um welchen Ausdruck es sich handelt.

Überprüfen Sie Ihre IDE auf einen Befehl, um unsymmetrische Ausdrücke zu finden.

In LispWorks wäre dies M-x Finden Sie unsymmetrische Klammern.

SLIME sollte auch einen Befehl dafür haben.

3

Der Befehl in Emacs ist M-x check-parens (es prüft alles, was ausgeglichen werden muss, wie z. B. Anführungszeichen). Es kann ein bisschen verwirrend sein, ob alles in Balance ist, weil es in diesem Fall nichts tut.

check-parens Befehl: Auf unbalancierte Klammern im aktuellen Puffer prüfen. Genauer gesagt, überprüfen Sie den verengten Teil des Puffers für unsymmetrische Ausdrücke ("sexps") im Allgemeinen. Dies geschieht gemäß der aktuellen Syntaxtabelle und findet unsymmetrische Klammern oder Anführungszeichen als geeignet. (Siehe Info-Knoten `(Emacs) Klammern.) Wenn das Ungleichgewicht gefunden wird, wird ein Fehler gemeldet und der Punkt bleibt am ersten unsymmetrischen Zeichen .