Схема макроса, что соответствует чему? - PullRequest
0 голосов
/ 21 мая 2018

С https://www.gnu.org/software/guile/manual/html_node/Syntax-Rules.html#Syntax-Rules Я получил следующий пример макроса:

(define-syntax simple-let
  (syntax-rules ()
    ((_ (head ... ((x . y) val) . tail)
        body1 body2 ...)
     (syntax-error
      "expected an identifier but got"
      (x . y)))
    ((_ ((name val) ...) body1 body2 ...)
     ((lambda (name ...) body1 body2 ...)
      val ...))))

Я пытаюсь понять, как работает этот макрос.Поэтому я немного прокомментировал это:

;; EXAMPLE 7
;; Reporting errors at macro-expansion time (read time, compile time).
(define-syntax simple-let
  (syntax-rules ()
    [(simple-let (head ... ((x . y) val) . tail)
                                        ; (1) head ... can also be zero times?
                                        ; (2) what is `. tail` matching?
                                        ; (3) can I not use two ellipsis on the
                                        ; same level instead of `. tail`?
                 body1
                 body2 ...)
     (syntax-error "expected an identifier but got"
                   (x . y))]
    ;; if there ((a . b) val) is not matched
    [(simple-let ((name val) ...)
                 body1
                 body2 ...)
     ((lambda (name ...)
        body1
        body2 ...)
      val ...)]))

Единственное, что я не совсем понимаю с точки зрения того, как это работает, - это первое выражение соответствия:

(simple-let (head ... ((x . y) val) . tail)

Поэтому я попробовал несколькопримеры:

;; simply working
(simple-let ([a 3])
            (+ a 4))

;; caught
(simple-let ([(a . b) 3])  ; Q: What is `. tail` matching in this one?
            (+ a 4))
(simple-let ([a 3] [(b . c) 3])  ; Q: What is `. tail` matching in this one?
            (+ a b))

;; not caught
(simple-let ([a 3] [(b . c) 3] [d 4])  ; Q: Why is `. tail` not matching `[d 4]`?
            (+ a b))

Мне сложно понять, какая часть соответствует . tail и почему.Я попытался использовать ... вместо . и поставить его позади tail, чтобы поймать пример, где синтаксическая ошибка не улавливается, потому что она не входит в первый случай совпадения, но она не работает иговорит мне, что это неправильное использование многоточия.Я предполагаю, что нельзя иметь два многоточия на одном и том же уровне вложенности, потому что было бы трудно понять, какой многогранник соответствует чему.В некоторых случаях подобные регулярные выражения становятся вычислительно дорогими.

Так что же соответствует . tail в примерах и почему этот пример не уловлен?

1 Ответ

0 голосов
/ 23 мая 2018

обычно хвост соответствует остальной части списка, например,

для '(1 2 3 4) соответствует шаблону (1. X), x соответствует' (2 3 4).

Результат сбивает с толку, поэтому нужно обратиться к источникам, чтобы увидеть реализацию (см. Ice-9 / psyntax.scm)

Там можно увидеть, что многоточие переводится в (каждый + xyz) с z вэтот случай - tail и соответствует последнему cdr, который во всех ваших случаях равен '().

В примере ... это gready and.хвоста нет.Если вы недовольны тем, как это поведение документировано, или хотите изменить реализацию, вы можете обратиться в список рассылки guile-devel: guile-devel@gnu.org

Guile также имеет синтаксический анализ в качестве загружаемой библиотеки.(ищите guile-syntax-parse), который является портом синтаксического синтаксического анализа ракетки пару лет назад (см. документацию racket, если вам интересно) Я кодировал ваш пример с синтаксическим синтаксическим анализом, и он должен выполняться так, как вы ожидали.

...