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
语法混淆了? 如何修复它以对 when
和 if
使用相同的 ?
?
我发现了,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))
此代码运行良好:
(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
语法混淆了? 如何修复它以对 when
和 if
使用相同的 ?
?
我发现了,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))