您当然可以编写一些内容,接收带引号的 s 表达式并将翻译输出为带引号的 s 表达式。
从简单地将格式良好的列表'(#\c #\a #\d #\r)
转换为您的第一个/其余 s 表达式开始。
现在用 symbol?、symbol->string、regexp-match #rx"^c(a|d)+r$"、string->list 和 map 构建解决方案
遍历输入。如果它是一个符号,请检查正则表达式(如果失败则按原样返回),转换为列表,然后使用您的起始翻译器。递归嵌套表达式。
编辑:这里有一些写得不好的代码,可以将源代码转换为源代码(假设目的是读取输出)
;; translates a list of characters '(#\c #\a #\d #\r)
;; into first and rest equivalents
;; throw first of rst into call
(define (translate-list lst rst)
(cond [(null? lst) (raise #f)]
[(eq? #\c (first lst)) (translate-list (rest lst) rst)]
[(eq? #\r (first lst)) (first rst)]
[(eq? #\a (first lst)) (cons 'first (cons (translate-list (rest lst) rst) '()))]
[(eq? #\d (first lst)) (cons 'rest (cons (translate-list (rest lst) rst) '()))]
[else (raise #f)]))
;; translate the symbol to first/rest if it matches c(a|d)+r
;; pass through otherwise
(define (maybe-translate sym rst)
(if (regexp-match #rx"^c(a|d)+r$" (symbol->string sym))
(translate-list (string->list (symbol->string sym)) rst)
(cons sym rst)))
;; recursively first-restify a quoted s-expression
(define (translate-expression exp)
(cond [(null? exp) null]
[(symbol? (first exp)) (maybe-translate (first exp) (translate-expression (rest exp)))]
[(pair? (first exp)) (cons (translate-expression (first exp)) (translate-expression (rest exp)))]
[else exp]))
'test-2
(define test-2 '(cadr (1 2 3)))
(maybe-translate (first test-2) (rest test-2))
(translate-expression test-2)
(translate-expression '(car (cdar (list (list 1 2) 3))))
(translate-expression '(translate-list '() '(a b c)))
(translate-expression '(() (1 2)))
正如评论中提到的,我很好奇你为什么想要一个宏。如果目的是将源代码转换为可读的东西,您不想捕获输出以替换原始内容吗?