Lisp 带有assoc和函数测试的堆栈溢出

Lisp 带有assoc和函数测试的堆栈溢出,lisp,stack-overflow,Lisp,Stack Overflow,我编写了这个函数,如果给定的参数匹配,则返回t,否则返回nil (defun match (input-form pattern) (cond ((and (not input-form) (not pattern)) t) ((not pattern) nil) ((eq (car pattern) '*) (or (match input-form (cdr pattern)) (match (cdr input-form) pattern))) ((no

我编写了这个函数,如果给定的参数匹配,则返回t,否则返回nil

(defun match (input-form pattern)
  (cond
    ((and (not input-form) (not pattern)) t)
    ((not pattern) nil)
    ((eq (car pattern) '*) (or (match input-form (cdr pattern)) (match (cdr input-form) pattern)))
    ((not input-form) nil)
    ((and (> (length (string (car pattern))) 1) (eq (char (string (car pattern)) 0) '#\?))
            (match (cdr input-form) (cdr pattern)) )
    ((eql (car input-form) (car pattern)) (match (cdr input-form) (cdr pattern))) ) )
当我这样做时:

(setq patterns 
    '(((bonjour *) bonjour) ((salut *) salut)) )

(assoc '(bonjour Eliza) patterns :test #'match)
它运行良好并返回:
((bonjour*)bonjour)

(assoc'(hello Eliza)模式:测试匹配)
工作也很好,返回零

但当我向变量模式添加模式时,如下所示:

(setq patterns 
'(((bonjour *) bonjour) ((salut) salut) ((* mere * pere *) parlez-moi de vos parents) ((mere *) la mere de qui) ((* mere) parlez-moi de votre mere)) )
当我请求匹配的东西时,它会工作,但当我请求不匹配的东西时,我会收到一条堆栈溢出错误消息

我做错了什么?

如果您愿意,您将立即得到答案(请记住快速按Ctrl-C:-):

也就是说,您需要先测试
(空输入表单)
,然后再单步执行模式:

(defun match (input-form pattern)
  (cond
    ((and (null input-form) (null pattern)) t)
    ((or (null pattern) (null input-form)) nil)
    ((eq (car pattern) '*) 
     (or (match input-form (cdr pattern)) 
         (match (cdr input-form) pattern)))
    ((and (> (length (string (car pattern))) 1) 
             (char= (char (string (car pattern)) 0) #\?))
     (match (cdr input-form) (cdr pattern)))
    ((eql (car input-form) (car pattern))
     (match (cdr input-form) (cdr pattern)))))

请注意我对代码所做的缩进和空白更改,以及在检查空列表时使用,而不是考虑(也可以考虑)。谢谢您的响应;首先感谢您对缩进和使用null的建议。我也尝试过跟踪匹配,但我不想跟踪和使用assoc进行测试。不幸的是,它仍然不起作用,因为(Hello Eliza)与(Hello*)不匹配,但我正在尝试修复它。好的,我添加了这个测试:((和(eq(汽车模式)*)(eq(cdr模式)nil))t)以避免模式使用*完成时出现问题,并且它可以工作,多谢各位

(defun match (input-form pattern)
  (cond
    ((and (null input-form) (null pattern)) t)
    ((or (null pattern) (null input-form)) nil)
    ((eq (car pattern) '*) 
     (or (match input-form (cdr pattern)) 
         (match (cdr input-form) pattern)))
    ((and (> (length (string (car pattern))) 1) 
             (char= (char (string (car pattern)) 0) #\?))
     (match (cdr input-form) (cdr pattern)))
    ((eql (car input-form) (car pattern))
     (match (cdr input-form) (cdr pattern)))))