首页 文章

球拍宏 - 制作对

提问于
浏览
2

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

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

进入这样的事情:

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

因此,原始表达式的cddr被转换为表达式对(用于语法规则体),并且id被插入到这些对中的每一对的汽车中 .

当仅使用语法规则提供的模式匹配时,我无法递归地思考(我一直想要操纵表达式,就像它是普通的列表一样) . 我应该使用什么样的模式?或者,我可以以某种方式将其作为普通列表进行操作,然后取消引用结果以用于扩展吗?

非常感谢

Edit - tentative solution, informed by Taymon's answer

我在这里好奇的一部分是关于摆脱那些配对的括号 . 我研究了语法案例,但有点困惑,所以试图用模式匹配的子语言来完成它 . 我最终使用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 ...))))

2 回答

  • 6

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

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

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

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

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

    Taymon是对的,但是也可以使用省略号来完成它而不用括号中的模式替换对,使用 ~seq 来自 syntax/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)
    

相关问题