gpt4 book ai didi

recursion - 在 Racket 中,我可以像处理 s 表达式一样递归处理语法对象吗?

转载 作者:行者123 更新时间:2023-12-05 04:15:17 46 4
gpt4 key购买 nike

假设我正在使用 s 表达式作为我正在编写的语言的 IR。然后我可能有一个看起来像的 AST

'(add (times (3 : int)
(add (4 : int)
(5 : int)))
(1 : int))

我可以毫不费力地递归处理。例如,要删除类型注释,我可以这样做

(define (erase-types term)
(match term
[`(,val : ,type)
val]
[`(,binop ,arg1 ,arg2)
`(,binop ,(erase-types arg1) ,(erase-types arg2))]))

现在假设我想做同样的事情,但不是在编译时使用包含与顶部 AST 相同数据的语法对象。我尝试使用某种基于模式的宏,但似乎无法使用 (define-syntax erase-types-or-whatever ...)以递归的方式。

我也试过放一个普通的 match在一个单独的模块中运行 (require (for-syntax ...))做一个大syntax->datum在一开始,甚至做类似的事情

(define (erase-types-or-whatever stx)
(match (syntax-e stx)
[...]))

但是我有 syntax->datum无处不在,我必须用 datum->syntax 再次重组它而且我真的不知道如何使用它(我只是把 #f 作为第一个参数吗?)感觉这一切都是绝对错误的方法。

进行这种语法树处理的正确方法是什么?在涉及宏和语法时,这些文档也不是很有启发性。

最佳答案

#lang racket
(require syntax/parse)

(define-syntax : (λ (stx) (raise-syntax-error ': "used out of context" stx)))

(define (erase-types term)
(syntax-parse term
#:literals (:)
[(val : type) #'val]
[(binop arg1 arg2) (with-syntax ([arg1 (erase-types #'arg1)]
[arg2 (erase-types #'arg2)])
#'(binop arg1 arg2))]))

(erase-types #'(add (times (3 : int)
(add (4 : int)
(5 : int)))
(1 : int)))

关于recursion - 在 Racket 中,我可以像处理 s 表达式一样递归处理语法对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32791480/

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