Common Lisp 错误:预期类型:REAL 数据:NIL

发布于 2024-10-19 17:45:48 字数 1825 浏览 5 评论 0原文

我正在尝试用 Common Lisp 自己写一些东西,实现调车场算法。我认为它进展顺利,即使它结果相当丑陋并且如果我怀疑它的 Lispy 性,但在 REPL 中测试该函数时,我在标题中得到了错误。

代码如下,测试用例为(shunting-yard '(3 + 5))

(defparameter *output-queue*   nil)
(defparameter *operator-stack* nil)

(defun determine-precedence (operator)
  (case operator
    (('+ '-) 2)
    (('* '/) 3)
    ('^      4)))

(defun shunting-yard (stmt)
  (loop until (null stmt) do
       (let ((token (car stmt)))
         (cond ((or (numberp token)
            (eq token '\())
            (setf *output-queue* (cons token *output-queue*)))
               ((mapcar #'(lambda (x) (eq token x)) '(+ - * / ^))
            (let* ((token-precedence (determine-precedence token))
                   (stack-topmost (car *operator-stack*))
                   (stack-precedence (determine-precedence stack-topmost)))
              (when (< token-precedence stack-precedence)
                (setf *output-queue* (cons stack-topmost *output-queue*))
                (setf *operator-stack* (cdr *operator-stack*)))
              (setf *operator-stack* (cons token *operator-stack*))))
               ((eq token '\))
            (loop for stack-topmost in *operator-stack*
               until (eq stack-topmost '\()
               do (progn
                (setf *output-queue* (cons stack-topmost *output-queue*))
                (setf *operator-stack* (cdr *operator-stack*)))
               finally (setf *operator-stack* (cdr *operator-stack*)))))
         (setf stmt (cdr stmt))))
  (loop while (not (null *operator-stack*))
     do (progn
      (setf *output-queue* (cons (car *operator-stack*) *output-queue*))
      (setf *operator-stack* (cdr *operator-stack*))))
  (nreverse *output-queue*))

错误是在代码本身中(我的猜测)还是在我的测试用例中?

预先非常感谢,写这篇文章真的很有趣,我迫不及待地想做其他事情,但只有在我开始工作之后。

I'm working on actually writing something on my own in Common Lisp for once, implementing the Shunting-yard Algorithm. I thought it went okay, even if it came out rather ugly and if I doubt its Lispy-ness, but upon testing out the function in the REPL, I get the error in the title.

The code is as follows, with the test case being (shunting-yard '(3 + 5)).

(defparameter *output-queue*   nil)
(defparameter *operator-stack* nil)

(defun determine-precedence (operator)
  (case operator
    (('+ '-) 2)
    (('* '/) 3)
    ('^      4)))

(defun shunting-yard (stmt)
  (loop until (null stmt) do
       (let ((token (car stmt)))
         (cond ((or (numberp token)
            (eq token '\())
            (setf *output-queue* (cons token *output-queue*)))
               ((mapcar #'(lambda (x) (eq token x)) '(+ - * / ^))
            (let* ((token-precedence (determine-precedence token))
                   (stack-topmost (car *operator-stack*))
                   (stack-precedence (determine-precedence stack-topmost)))
              (when (< token-precedence stack-precedence)
                (setf *output-queue* (cons stack-topmost *output-queue*))
                (setf *operator-stack* (cdr *operator-stack*)))
              (setf *operator-stack* (cons token *operator-stack*))))
               ((eq token '\))
            (loop for stack-topmost in *operator-stack*
               until (eq stack-topmost '\()
               do (progn
                (setf *output-queue* (cons stack-topmost *output-queue*))
                (setf *operator-stack* (cdr *operator-stack*)))
               finally (setf *operator-stack* (cdr *operator-stack*)))))
         (setf stmt (cdr stmt))))
  (loop while (not (null *operator-stack*))
     do (progn
      (setf *output-queue* (cons (car *operator-stack*) *output-queue*))
      (setf *operator-stack* (cdr *operator-stack*))))
  (nreverse *output-queue*))

Is the error in the code itself (my guess) or is it in my test case?

Thanks so much in advance, this was REALLY fun to write and I can't wait to work on something else, but only after I get this working.

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

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

发布评论

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

评论(1

老娘不死你永远是小三 2024-10-26 17:45:48

有几个错误:

第一:

(defun determine-precedence (operator)
  (case operator
    (('+ '-) 2)
    (('* '/) 3)
    ('^      4)))

引号需要去掉。全部。

第二:

(mapcar #'(lambda (x) (eq token x)) '(+ - * / ^))

上面并不是按照你的想法做的。将其替换为对 MEMBER 的调用。

第三:

 (when (< token-precedence stack-precedence)

您需要确保变量确实与数字绑定。
使用像

 (check-type token-precedence number)
 (check-type stack-precedence number)

以前一样的东西作为支票。

愉快的进一步调试...

There are several errors:

First:

(defun determine-precedence (operator)
  (case operator
    (('+ '-) 2)
    (('* '/) 3)
    ('^      4)))

The quotes need to go. All.

Second:

(mapcar #'(lambda (x) (eq token x)) '(+ - * / ^))

Above is not doing what you think. Replace it with a call to MEMBER.

Third:

 (when (< token-precedence stack-precedence)

You need to make sure that the variables are really bound to numbers.
Use something like

 (check-type token-precedence number)
 (check-type stack-precedence number)

before as a check.

Happy further debugging...

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