使用 hygenic 宏展平语法树

Flatten syntax tree using hygenic macros

是否可以编写一个 R5RS 宏来“展平”任意深度的语法树?
示例:

(flatten-syntax (a (b (c d)) e)) => (a b c d e)

我的最终目标是拥有另一个像这样工作的宏:

(declare-tree (a (b (c d)) e))
 => 
(begin (define a #f) (define b #f) (define c #f) (define d #f) (define e #f))

但如果 flatten-syntax 可用,应该很容易定义。

这里对我来说最具挑战性的部分是 syntax-rules-only 限制,但如果您有 syntax-case 解决方案,请也 post 它。

我在这个问题上的进展停滞在这一点上:

(define-syntax flatten-syntax-helper
  (syntax-rules ()
    ((_ buf (x . xs))
     (flatten-syntax-helper
      (flatten-syntax-helper buf x) xs))
    ((_ buf ())
     buf)
    ((_ buf x)
     (x . buf))))
(define-syntax-rule (my-flatten-syntax T)
  (flatten-syntax-helper () T))

guile 中,,expand (my-flatten-syntax (a (b (c d)) e)) 导致语法错误“无法匹配 my-flatten-syntax 形式的任何模式”。

这是我的快速尝试:

#lang racket

(define-syntax reverse-macro
  (syntax-rules ()
    [(_ () (result ...)) '(result ...)]
    [(_ (x xs ...) (result ...)) (reverse-macro (xs ...) (x result ...))]))

(define-syntax flatten-syntax-aux
  (syntax-rules ()
    [(_ ((xs ...) ys ...) (result ...))
     (flatten-syntax-aux (xs ... ys ...) (result ...))]
    [(_ (x xs ...) (result ...))
     (flatten-syntax-aux (xs ...) (x result ...))]
    [(_ () (result ...))
     (reverse-macro (result ...) ())]))

(define-syntax-rule (flatten-syntax xs)
  (flatten-syntax-aux xs ()))

(flatten-syntax (a (b (c d)) e)) ;=> '(a b c d e)

确实,您可以通过稍微调整 flatten-syntax 来创建 declare-tree,但您可能会感到惊讶,直接定义 declare-tree 实际上要容易得多:

#lang racket

(define-syntax declare-tree
  (syntax-rules ()
    [(_ ((xs ...) ys ...))
     (begin (declare-tree (xs ...))
            (declare-tree (ys ...)))]
    [(_ (x xs ...))
     (begin (define x #f)
            (declare-tree (xs ...)))]
    [(_ ())
     (begin)]))

(declare-tree (a (b (c d)) e))
(list a b c d e) ;=> '(#f #f #f #f #f)

这是因为declare-tree其实不需要展平结构。它可以生成嵌套的begin,如:

(begin
  (begin (define a #f)
         (define b #f))
  (begin (define c #f)
         (define d #f)))