Scheme/Racket: 语法分析器匹配混淆

Scheme/Racket: Syntax parser matching confused

此代码运行良好:

(require syntax/parse/define (only-in racket [#%app racket:#%app]))
(define-syntax-parser #%app
    [(_ Cond {~datum ?} Form1 ...) 
    #'(when Cond Form1 ...)]
    [(_ Cond {~datum ??} Form1 ... {~datum :} Form2 ...) 
    #'(if Cond (begin Form1 ...) (begin Form2 ...))]
    [(_ Xs ...) 
    #'(racket:#%app Xs ...)]
)

(#t ? (displayln 1))
(#t ?? (displayln 1) : (displayln 2))

但是,我希望将 ?? 更改为单个 ?。 Racket 显示错误,为什么 Racket 不匹配第二种语法?

:: undefined;
 cannot reference an identifier before its definition

Racket 是否将 if 语法与右上方的 when 语法混淆了? 如何修复它以对 whenif 使用相同的 ?

我发现了,when 是在 define-syntax-parser 中的 if 之前首先定义的,它的语法包括省略号 ... 匹配它后面的所有内容,包括 if-else 中的 :

修复如下,将 if 的语法放在第一位:

(require syntax/parse/define (only-in racket [#%app racket:#%app]))
(define-syntax-parser #%app
    [(_ Cond {~datum ?} Form1 ... {~datum :} Form2 ...) 
    #'(if Cond (begin Form1 ...) (begin Form2 ...))]
    [(_ Cond {~datum ?} Form1 ...) 
    #'(when Cond Form1 ...)]
    [(_ Xs ...) 
    #'(racket:#%app Xs ...)]
)

(#t ? (displayln 1))
(#t ? (displayln 1) : (displayln 2))