使用语法分析的球拍无尽背景扩展

时间:2013-11-19 20:48:47

标签: macros racket

所以我正在尝试编写一个宏来为类声明提供一些我更喜欢的语法。

(define-syntax (defclass stx)
  (syntax-parse stx #:literals ((*...* ...))
    ;=============================
    [(defclass (name:id inits ... rest:id *...*) opts ...)
    #'(defclass (name inits ... rest *...*) (opts ...))]

    [(defclass (name:id inits ... rest:id *...*) (opts ...))
    #'(defclass (name inits ... rest *...*) object% ((super-new) opts ...))]

    [(defclass (name:id inits ... rest:id *...*) super (opts ...))
    #'(define name (class super (init inits ...) (init-rest rest) opts ...))]

    [(defclass (name:id inits ... rest:id *...*) super supers ... (opts ...))
    #'(define name (class* super (supers ...) (init inits ...) (init-rest rest) opts ...))]
    ;=============================
    [(defclass (name:id inits ...) opts ...)
    #'(defclass (name inits ...) (opts ...))]

    [(defclass (name:id inits ...) (opts ...))
    #'(defclass (name inits ...) object% ((super-new) opts ...))]

    [(defclass (name:id inits ...) super (opts ...))
    #'(define name (class super (init inits ...) opts ...))]

    [(defclass (name:id inits ...) super supers ... (opts ...))
    #'(define name (class* super (supers ...) (init inits ...) opts ...))]
    ;=============================
    [(defclass name:id opts ...)
    #'(defclass name (opts ...))]

    [(defclass name:id (opts ...))
    #'(defclass name object% ((super-new) opts ...))]

    [(defclass name:id super (opts ...))
    #'(define name (class super opts ...))]

    [(defclass name:id super supers ... (opts ...))
    #'(define name (class* super (supers ...) opts ...))]
    ;=============================
))

所以(defclass (foo bar baz) (method X ...))最终转换为(define foo (class object% (super-new) (init bar baz) (method x ...)))

问题是DrRacket的背景扩张似乎正在不断扩大。更糟糕的是,当DrRacket告诉我它已经扩展了很长时间并且我想看到目前为止的步骤时,单击按钮显示步骤并没有显示步骤。我正在使用行(defclass (char atts inventory level-atts))对其进行测试,该行应生成(define char (class object% (init atts inventory level-atts) (super-new))),但正如我所说,我无法检查扩展过程并查看实际发生的情况。我还尝试将语法分析的所有#'(defclass ...)模板更改为(defclass ...),以防语法分析不扩展它返回的表单,但后来我遇到无法引用nameinits等,因为它们不在模板中。

1 个答案:

答案 0 :(得分:1)

获取“后台扩展等待......”的最简单方法可能就是:

(define-syntax-rule (infinite)
  (infinite))

(infinite)

infinite扩展为infinite,扩展为infinite ...您明白了。

您的defclass有许多模式可扩展为defclass。其中一种模式必须扩展到自身。

这里有六个模式扩展到defclass。乍一看,我无法发现哪个人有这个问题。如果你不能,我建议一步一步地进行工作:注释掉所有的模式。接下来,从最具体的开始 - “已经扩展最多”,扩展为defclass。逐个添加它们,每个都有一个示例用法,直到再次达到无限扩展。然后仔细看看这个模式,直到你发现它。

(从与他们中的一些人谈话,我得到的印象是,即使是在Scheme和Racket宏专家的人也会一步一步地解决问题。非平凡的宏并不是整个结构通常从大脑到大脑出现的地方。手指正确地在一个大模糊中。)