string-replace "O" "E" > string-append "x" > string--6ren">
gpt4 book ai didi

具有多个 ...s 的 Racket 语法模式

转载 作者:行者123 更新时间:2023-12-05 09:35:37 27 4
gpt4 key购买 nike

我正在研究使用类似于 unix 的管道的 Racket 语法,如下所示:

> ("FOO" > string-replace "O" "E" > string-append "x" > string-downcase)
"feex"

这是一个蛮力解决方案,它支持带有 2、1 和 0(额外)参数的过程:

(require (prefix-in racket/base/ racket/base) syntax/parse/define)
(define-syntax-parser #%app
[(_ data (~literal >) proc a b (~literal >) rest ...) #'(#%app (proc data a b) > rest ...)]
[(_ data (~literal >) proc a (~literal >) rest ...) #'(#%app (proc data a) > rest ...)]
[(_ data (~literal >) proc (~literal >) rest ...) #'(#%app (proc data) > rest ...)]
[(_ data (~literal >) proc rest ...) #'(#%app proc data rest ...)]
[(_ rest ...) #'(racket/base/#%app rest ...)])

问题是找到下一个管道,因为语法模式不允许多个 ... 模式。宏需要知道下一个管道在哪里才能关闭第一个管道的表单。除非有办法用不匹配的括号构建部分语法对象?

我可以嵌套省略号,但是我必须使用额外的括号:

(define-syntax-parser #%app
[(_ data (~literal >) (proc params ...) > rest ...) #'(#%app (proc data params ...) > rest ...)]
[(_ data (~literal >) proc rest ...) #'(#%app proc data rest ...)]
[(_ rest ...) #'(racket/base/#%app rest ...)])

> ("FOO" > (string-replace "O" "E") > (string-append "x") > string-downcase)
"feex"

没有额外的括号,有没有办法做到这一点?

我知道 clojure 的线程宏,但如果必须嵌套它们,它们很难遵循。

编辑:此问题的解决方案现在可作为 racket package 使用。和 github

最佳答案

您可以使用 ~seq 模式结合省略号来匹配不带括号的内容。例如:

(define-syntax-parser split
[(_ (~seq a b) ...)
#'(list a ... b ...))

将要求 split 给出偶数个参数,然后这些参数将被重新排列并构建到列表中:

(split 1 2 3 4 5 6)
; =>
(list 1 3 5 2 4 6)

当然,请注意 ~seq 并不神奇,并且在解析时对回溯的支持有限。但原则上你应该能够做这样的事情:

(data (~seq (~literal >) proc args ...) ...)

关于具有多个 ...s 的 Racket 语法模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65740541/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com