2012-03-25 57 views
2

我刚开始潜入球拍宏,并试图制作一个简洁的宏 - 宏定义宏。我想扩大这样的表达式:球拍宏 - 制作对

(macro id 
    (param) replacement1 
    (params ...) replacement2) 

弄成这个样子:

(define-syntax id 
    (syntax-rules() 
     ((id param) replacement1) 
     ((id params ...) replacement2))) 

所以原始表达式的CDDR变成表达对(用于语法规则身体),并且id被插入每个这些对的汽车中。

当我仅使用由语法规则提供的模式匹配(我一直希望像处理普通列表一样操纵表达式)时,我在递归思考时遇到了麻烦。我应该使用什么样的模式?或者,我可以以某种方式将其作为普通列表进行操作,然后取消在扩展中使用的结果?

非常感谢

编辑 - 试探性的解决方案,通过Taymon的回答

在这里我的好奇心部分通知给即将摆脱那些配对括号。我研究了语法情况,但有点困惑,所以试图纯粹使用模式匹配子语言。最后我用Taymon宏观与另一宏“pairize”给定的模板(它的作用有点像一个蓄电池功能)合并:

(define-syntax-rule (macro-aux id ((param ...) expr) ...) 
    (define-syntax id 
    (syntax-rules() 
     ((id param ...) expr) 
     ...))) 

(define-syntax pairize 
    (syntax-rules() 
    ((pairize id (pairs ...) p b) (macro-aux id pairs ... (p b))) 
    ((pairize id (pairs ...) p b rest ...) (pairize id (pairs ... (p b)) rest ...)))) 

(define-syntax macro 
    (syntax-rules() 
    ((macro id tpl-expr ...) (pairize id() tpl-expr ...)))) 

回答

6

这是不可能建立操纵的语法表达作为常规宏扩展球拍数据。但是,在这种情况下,这并不是真的必要。

我建议的一件事是稍微改变你的语法,以便每个模式替换对括在括号中。像这样:

(macro id 
    [(param) replacement1] 
    [(params ...) replacement2]) 

一旦完成,您可以使用常规的模式匹配宏。这是我对此采取:

(define-syntax-rule (macro id [(param ...) replacement] ...) 
    (define-syntax id 
    (syntax-rules() 
     [(id param ...) replacement] ...))) 
+0

谢谢!在看到你的例子之前,我并没有完全意识到elipses是如何工作的,并且已经在暂时的解决方案中使用了你的规则。 – twf 2012-03-25 19:50:23

1

Taymon是正确的,但它也可以用省略号做才不至于包裹在括号中的模式替换对,使用~seqsyntax/parse

(require syntax/parse/define) 
(define-simple-macro (macro id (~seq (param ...) replacement) ...) 
    (define-syntax id 
    (syntax-rules() 
     [(id param ...) replacement] ...))) 

可以像你最初想要的那样使用:

(macro id 
    (param) replacement1 
    (params ...) replacement2)