lisp - 口齿不清错误 : Expected-type: REAL datum: NIL

标签 lisp common-lisp sbcl shunting-yard

我正在努力用 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*))

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

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

最佳答案

有几个错误:

首先:

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

报价需要去。全部。

第二个:

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

以上不是你想的那样。将其替换为对 MEMBER 的调用。

第三:

 (when (< token-precedence stack-precedence)

您需要确保变量确实绑定(bind)到数字。 使用类似的东西

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

之前作为检查。

愉快的进一步调试...

关于lisp - 口齿不清错误 : Expected-type: REAL datum: NIL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5163302/

相关文章:

LISP:如何获得列表的总和? (没有全局变量)

struct - Lisp 中的嵌套结构

common-lisp - SBCL 内置可执行文件 : "When attempting to set the slot' s value to XXX (SETF of SLOT-VALUE), 对象中缺少插槽 YYY”?

lisp - Lisp 中的 "Stack overflow (deep)"错误

multithreading - 在 SBCL 中进行多线程计算的正确方法

lisp - 从终端命令提示符运行 Common Lisp 函数

global-variables - def参数的使用

macros - Lisp:在宏中扩展属性名称

lisp - defstruct - :read-only is not read only

lisp - 我可以将 lambda 与即时 lambda 列表(没有宏)一起使用吗?