你當然可以寫一些需要在引用s表達式和輸出轉換爲帶引號的S-表達。
首先將格式良好的列表'(#\C#\a #\d #\r)
簡單地翻譯成您的第一個/ rest表達式。
立即建立與符號的溶液?,符號 - >串,正則表達式匹配#rx 「^ C(A | d)+ R $」,與字符串>列表,並且映射
遍歷輸入。如果是符號,請檢查正則表達式(如果失敗則按原樣返回),轉換爲列表並使用起始翻譯器。遞歸嵌套表達式。
編輯:這裏的一些糟糕的代碼,可以轉換源到源(假設目的是要讀取輸出)
;; 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)))
正如在評論中提到的,我很好奇,爲什麼你要一個宏。如果目的是將源代碼轉換爲可讀的內容,那麼您是否想捕獲輸出來替換原始代碼?
如果我能夠,我會多次+1。非常好! – 2012-02-06 07:04:24
優秀!這個解決方案是我想要的,謝謝!球拍是一個真正美麗而強大的語言。 – 2012-02-06 15:06:24
@RacketNoob大多數Racket開發人員推薦如何設計程序。這不是一個球拍手冊,它可能不包括'#%top',但它仍然是一本有用的書。 – 2012-02-06 16:50:48