2010-10-26 44 views
6

Tôi đang cố gắng viết một trò chơi đoán số ở Lisp như một dự án giết thời gian. Tuy nhiên, khi tôi cố gắng tải chương trình lên bằng SBCL, tôi nhận được lỗi sau:Lỗi Lisp thường gặp Không được hiểu

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) 

Lỗi này có nghĩa là gì? Mã này là như sau, và báo lỗi xuất hiện khi tải các tập tin và gọi (play) từ 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))) 

(Tôi khá chắc chắn rằng chương trình không hoạt động trừ rằng một lỗi, tôi vẫn một người mới hoàn toàn khi nói đến Lisp. Đây chỉ là lỗi đầu tiên tôi gặp phải mà tôi không thể tự mình hiểu được.)

Ồ, và vấn đề rất có thể liên quan đến prompt-for-guess, read-guesscheck-guess chức năng, bởi vì đó là những cái tôi đã gây rối khi lỗi này bị xén.

Trả lời

6

Có vẻ như bạn không đóng đủ số lần tạm dừng trên số prompt-for-guess của bạn.

Trình đọc sẽ đến cuối tệp và nhận thấy rằng tệp có biểu mẫu vẫn mở và không thể biết được vị trí của nó.

Cách dễ dàng tôi sử dụng để tìm các lỗi như thế này là để trình chỉnh sửa văn bản của tôi thụt lề khu vực và đảm bảo mọi thứ đều giống như tôi nghĩ.

+0

Tuyệt vời, đã khắc phục lỗi đó! Cảm ơn bạn! Bây giờ tôi cần tìm ra cách truyền giá trị trả về của hàm như đối số cho hàm khác. :) – Andy

+2

@Andrew: '(chức năng khác (chức năng đầu tiên))'? –

1

kết thúc tệp trong khi đọc, có dấu ngoặc đơn đóng (hoặc tương tự) bị thiếu. Ký tự 477. Di chuyển con trỏ trong văn bản của bạn đến 477 và kiểm tra biểu thức của nó.

Kiểm tra IDE của bạn để biết lệnh tìm biểu thức không cân bằng.

Trong LispWorks, đây sẽ là M-x Tìm dấu ngoặc đơn không cân bằng.

SLIME cũng cần có một số lệnh cho điều đó.

3

Lệnh trong Emacs là M-x check-parens (nó kiểm tra mọi thứ cần cân bằng, như dấu ngoặc kép). Nó có thể là một chút bí ẩn nếu mọi thứ cân bằng, bởi vì nó không làm gì trong trường hợp đó.

check-parens Lệnh: Kiểm tra dấu ngoặc đơn không cân bằng trong bộ đệm hiện tại. Chính xác hơn, hãy kiểm tra phần thu hẹp của bộ đệm cho các biểu thức không cân bằng ("sexp") nói chung. Việc này được thực hiện theo bảng cú pháp hiện tại và sẽ tìm các dấu ngoặc hoặc dấu ngoặc kép không cân bằng như thích hợp. (Xem nút Thông tin `(emacs) Dấu ngoặc đơn '.) Nếu mất cân bằng là , lỗi được báo hiệu và điểm được để lại ở ký tự không cân bằng đầu tiên .

Các vấn đề liên quan