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-s开发者_Go百科tack* (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.
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...
精彩评论