macros - Racket 宏 - 配对

标签 macros scheme racket define-syntax

我刚刚开始深入研究 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] ...)))

关于macros - Racket 宏 - 配对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9860634/

相关文章:

scheme - Guile计划-引用期间?

scheme - 如何使用 DrRacket 5.2.1 在 Emacs 中编辑和运行 PLAI 代码

racket - 如何控制 DrRacket 中 Enter 的行为?

scheme - 方案中的二叉树

c - 使用 3D 数组到线性索引宏进行三维泊松乘法时出现段错误

visual-studio-2010 - 如何删除选定代码部分中的所有注释?

c - 如何将 __DATE__ 和 __TIME__ 预定义宏用作两个整数,然后进行字符串化?

c++ - C++代码中的#if语句

scheme - 你如何在 Scheme 中返回一个过程的描述?

scheme - 我似乎无法全神贯注于Scheme中的call/cc