Common Lisp-模式匹配

尼尔维格

我正在尝试编写一个函数来比较Common Lisp中的两个列表。

符号“&”表示任何元素序列,符号“ $”表示任何单个元素。

(defun match (filter data)
     (cond
        ((atom filter) (eq filter data))
        ((atom data) NIL)
        ((eq (car filter) '|$|)
           (match (cdr filter) (cdr data)))
        ((eq (car filter) '|&|)
           (cond
             ((match (cdr filter) data))
             (data (match filter (cdr data)))))
        ((match (car filter) (car data))
            (match (cdr filter) (cdr data)))))

运作良好:

(match '(a b c) '(a b c)) ; => T
(match '(a $ c) '(a b c)) ; => T
(match '(a ff c) '(a b c)) ; => NIL
(match '(a & c) '(a z b c)) ; => T

我想添加一个新的过滤器(带有%符号),该过滤器允许在不同的可能元素之间进行选择,例如

(match '(a %(b 1) c) '(a b c)) ; => T
(match '(a %(b 1) c) '(a 1 c)) ; => T
(match '(a %(b 1) c) '(a z c)) ; => NIL
狮子座

您必须尝试%之后的子列表中的所有元素,以查看是否有任何元素与过滤器的其余部分相结合,是否与数据匹配:

(defun match (filter data)
     (cond
        ((atom filter) (eq filter data))
        ((atom data) NIL)
        ((eq (car filter) '|$|)
           (match (cdr filter) (cdr data)))
        ((eq (car filter) '|&|)
           (cond
             ((match (cdr filter) data))
             (data (match filter (cdr data)))))
        ((eq (car filter) '|%|)
          (some #'(lambda (f) (match (cons f (cddr filter)) data)) (cadr filter)) )
        ((match (car filter) (car data))
            (match (cdr filter) (cdr data)))))

您还应该添加一些检查步骤,以确保过滤器的格式正确,例如,%之后的元素是列表等。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章