0

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 に実装されている各リストのcarandを呼び出して、再帰的に作業を続ける必要がありますか?cdrdefun

ありがとう。

4

1 に答える 1