Common Lisp は初めてで、最初のプロジェクトとして単純なパターン マッチャーに取り組んでいます。スター (*) 演算子を使用してリスト内の 0 個以上の要素を表すのに問題があります。したがって、パターン (x * z) とマッチャー (xyyyz) は true を返しますが、パターン (x * z) とマッチャー (xy) は false を返します。
私の最初の考え:
(loop for x in pattern-list
(eq x '*)
;if x is *, pause iterating through this list
(loop for y in matcher-list
;somehow iterate one more value in the pattern list
(eq x y) ;does the value just after the * in the pattern list equal the value in y?
;if they aren't the same symbol, just iterate matcher until they match, then resume incrementing though the pattern list
))
構文と括弧が少しずれている場合は申し訳ありません。
これは、私が取り組んでいた大きなパターン マッチャーの小さな部分です。これが私がこれまでに持っているものです(この場合、list1はパターンリストであり、list2はマッチャーリストです):
このコードの大部分は、この SO 投稿からのものです。
"eq" のみを使用して Common Lisp で equal 関数を設定する
(defun comp-q (list1 list2) ;defun
(if (and (not (null list1)) ;if list1 is not null AND
(not (null list2))) ;if list2 is not null
(let ((a (car list1)) (b (car list2))) ;a is the car (front) of list1 and b is the car of list 2
(cond ((and (listp a) (listp b)) ;cond, evaluate the first thing in the list - are a and b lists?
(and (comp-q a b) ;recursive call on a and b
(comp-q (cdr list1) (cdr list2)))) ;recursive call on the cdr (tail) of a and b
(t ;like an else for cond
(and (or (eq a b) (eq a '?)) ;are a and b equal OR is a a '?'
(comp-q (cdr list1) (cdr list2)))))) ;recursive call on the cdr of a and b
(= (length list1) (length list2)))) ;are the lists equal? only triggered if the null test fails (are they both not null)
マクロを使用するのがloop
最善の策ですか? リストの反復を「一時停止」または追跡することは可能ですか (これは配列風であることはわかっています)。または、 comp-q に実装されている各リストのcar
andを呼び出して、再帰的に作業を続ける必要がありますか?cdr
defun
ありがとう。