繁体   English   中英

球拍宏-配对

[英]Racket macros - making pairs

我刚刚开始研究Racket宏,并试图制作一个简洁的宏,定义宏。 我想扩展一个这样的表达式:

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

进入这样的事情:

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

因此,将原始表达式的cddr转换为成对的表达式(供语法规则主体中使用),并将id插入每对表达式的car中。

仅使用语法规则提供的模式匹配时,我很难进行递归思考(我一直想像对待普通列表一样操纵表达式)。 我应该使用哪种模式? 或者,我可以以某种方式将其作为普通列表进行操作,然后取消引用结果以供扩展使用?

非常感谢

编辑-临时解决方案,由Taymon的答案提供

我在这里的好奇心部分在于摆脱那些配对括号。 我研究了语法情况,但有点困惑,因此尝试仅使用模式匹配子语言来完成。 我最终将Taymon的宏与另一个宏结合使用来“配对”给定的模板(其作用类似于累加器函数):

(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 ...))))

可以构建一个宏扩展器,将语法表达作为常规的Racket数据进行操作。 但是,在这种情况下,这并不是必须的。

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

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

完成后,您就可以使用常规的模式匹配宏。 这是我的看法:

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

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM