読者です 読者をやめる 読者になる 読者になる

syntax-rulesの仕様を読んで確認した

r7rsのsyntax-rulesのパターンの部分の仕様を読んで確認する。(vectorは省く)

とる形は、以下の4つ(Pはパターンで、[ellipsis]は、0個以上の繰り返し)
1. (P1 ... Pn )
2. (P1 ... Pn . Pn+1)
3. (P1 ... Pk Pe [ellipsis] Pm+1 ... Pn)
4. (P1 ... Pk Pe [ellipsis] Pm+1 ... pn . Px )

つまり、
1.真性リストで[ellipsis]を含まない。
2.非真性リストで[ellipsis]を含まない。
3.真性リストで[ellipsis]を含む。
4.非真性リストで[ellipsis]を含む。
ということか。

1

(define-syntax check-1
  (syntax-rules () ((_ (a b c d e)) (quote (a b c d e)))))


(display (check-1 (1 2 3 4 5)))(newline) ;(1 2 3 4 5)

真性リストで同じ要素数のものだけしかマッチしない。
特になし

2

(define-syntax check-2
  (syntax-rules () ((_ (a b . c))(quote (a b c)))))


(display (check-2 (1 2 )))(newline);(1 2 ())
(display (check-2 (1 2 3 )))(newline);(1 2 (3))
(display (check-2 (1 2 3 4 5)))(newline);(1 2 (3 4 5))
(display (check-2 (1 2 . 3)))(newline);(1 2 3)

非真性、真性どちらでもよく、左から順にマッチさせていき、のこりを最後のcdr部にマッチさせる。
これも、特になし。

3

(define-syntax check-3
  (syntax-rules () ((_ (a b ... c d ))(quote (a b ... c d )))))

(display (check-3 (1 2 3 4 5)))(newline);(1 2 3 4 5)
(display (check-3 (1 2 3)))(newline);(1 2 3)

真性リストで、[ellipsis]の左側と右側をマッチさせて、残りを[ellipsis]の所にマッチさせる。
これも、特になし。

4-1

全部、パターン変数の場合。

(define-syntax check-4a
  (syntax-rules () ((_ (a b ... c . d))(quote (b ...  d  )))))

(display (check-4a (1 2 3  4 5)))(newline);(2 3 4 ())
(display (check-4a (1 2 3 4 . 5)))(newline);(2 3 5)
(display (check-4a (1 2 3)))(newline);(2 ())

処理系によっては、動かなかったり、明らかに間違った結果がでたりした。
saggitarius0.6.11やgauche0.9.5の結果だと、
非真性リストを入れると、末尾cdr同士、それ以外同士でマッチングし、
真性リストを入れると、patternの末尾cdrにnullがマッチして、全部その左側にマッチする。

4-2

定数を入れた場合。

(define-syntax check-4b
  (syntax-rules () ((_ (1 2 ... 3 . d))(quote d ))))

(print (check-4b (1 2 2 2 3 . 4 )));4

真性リストを入力した場合、最後のcdr要素(null)だけが、Pxにマッチするので、
Pnまでうまくマッチできそうなケースでもだめだね。