gpt4 book ai didi

clojure - Lisp/Clojure DSL 的中间表示

转载 作者:太空宇宙 更新时间:2023-11-03 18:36:27 24 4
gpt4 key购买 nike

我正在用 Clojure 设计一个 DSL,它用于驱动代码生成器(在本例中用于程序图像合成 - clisk),但我无法找出中间值的最佳表示形式。

最初,DSL 由返回一种或多种形式的函数组成,例如(说明性的)

(v+ 1.0 [1.0 'y])
=> ['(+ 1.0 1.0) '(+ 1.0 y)]

然后可以组合这些函数来构建更大的代码块。

这很简单,生成的表单可以直接输入代码生成器。然而,我现在已经确定了这种方法的一些弱点,例如,如果需要传递一些辅助数据(例如,不能以 BufferedImages 等形式编码的对象、对优化有用的元数据等)。

我确定这是 Lisp 世界中已解决的问题 - 这种 DSL 的最佳中间表示通常是什么?

最佳答案

每当您需要用于生成代码的中间表示时,我想到的最明显的事情就是抽象语法树 (AST)。您的示例表示是列表,根据我的经验,它的形式不那么灵活。对于除了琐碎的代码生成以外的任何事情,我都不会拐弯抹角,而只是使用完整的 AST 表示。通过使用列表,您可以将更多工作推给生成端来解析信息,例如类型和第一项的含义。转移到 AST 表示会给你更多的灵 active ,并解耦更多的系统,代价是解析端的更多工作(或生成表单的函数的更多工作)。生成端也将做更多工作,但其中许多组件可以解耦,因为它们的输入将更加结构化。

就 AST 应该是什么样子而言,我会复制 Christophe Grand 的 enlive,他在其中使用 {:tag <tag name> :attrs <map of attrs> :content <some collection>}

或 clojure 脚本使用的内容,{:op <some operator> :children <some collection>} .

这使得它非常通用,因为您可以定义任意 walker 来查看 :children并且可以在不知道 :op 是什么的情况下遍历任何结构的或:tag是。

然后对于原子组件,您可以将其包装在映射中并为其提供一些独立于对象的实际类型的类型信息(关于 DSL 的语义)。 {:atom <the object> :type :background-image} .

在代码生成方面,遇到原子时,您的代码可以在 :type 上调度,然后,如果需要,进一步分派(dispatch)对象的实际类型。从集合表单生成也很容易,在 :op/:tag 上分派(dispatch),然后与 child 一起重复。对于 child 使用什么收藏,我会阅读更多关于谷歌群组的讨论。他们的结论对我很有启发。

https://groups.google.com/forum/#!topic/clojure-dev/vZLVKmKX0oc/discussion

总而言之,对于 child ,如果存在语义排序重要性,例如在 if 语句中,则使用 map {:conditional z :then y :else x} .如果它只是一个参数列表,那么您可以使用向量。

关于clojure - Lisp/Clojure DSL 的中间表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10763223/

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