【问题标题】:Can a Abstract Syntax Tree be Compile by multiple Compiler or Interpreter?抽象语法树可以由多个编译器或解释器编译吗?
【发布时间】:2015-03-29 05:58:56
【问题描述】:

我知道没有两种编程语言是完美匹配的,但我想问一下我是否有一个简单的程序,比如 hello world,我运行编译翻译阶段,比如 lex,解析然后获取 AST 树我可以将它发送到另一个环境说一些 c AST 树并用 Java 解释它

【问题讨论】:

    标签: parsing compiler-construction interpreter abstract-syntax-tree lexer


    【解决方案1】:

    简短的回答:不。

    更长的版本:

    如果您有两种不同的语言实现记录并导出了它们的 AST 接口,并且这两个接口非常相似,您可以在它们之间进行翻译,那么您可以编译为 AST,然后尝试将 AST 传递给其中一个实现。

    我在这里只能假设性地说,因为语言实现包含外部可访问的 AST 接口是非常罕见的。 (一个例外是 Python,它允许您编译为 AST、创建或修改 AST,然后从 AST 编译。这里,“编译”的意思是“编译为 VM 代码”。有关更多信息,请参阅Python docs。)

    特别是,我不知道有哪个 Java 实现。 GCC 和 clang 都可以输出类似于 AST 的内容,但它们都不接受,并且输出可能不够完整,无法定义翻译单元的所有方面。

    【讨论】:

    • 谢谢 rici,但我要创建一个参数,假设我将 AST 序列化为字节流,通过套接字发送,然后将其反序列化回用另一个编写的程序中的对象树语言。使用 JSON、YAML 和 XML 这些简单、相当标准的语言来序列化和反序列化任意数据,然后以所需语言为它们找到解析器。我认为这在技术上是可行的吗?让我听听你的看法
    • @user22092:你当然可以尝试在这些骨头上放些肉。 理论上是可能的,是的,尽管您的描述涉及许多问题。正如我在回答中所说,大多数语言都没有定义一组标准的 AST 对象,更不用说让它们在标准运行时中可用了。此外,AST 不会捕获整个解析——例如,还有一个符号表——并且不能保证处理的输入的整体是一棵树。 (您提到的任何交换格式都不能处理图表。)但就像我说的那样,去吧!
    • 好的,我试试,目前还在努力
    • @user22092:考虑为“x+y”以及“(+ x y)”构建一个 Java AST,其中 x 和 y 是字符串类型。没有什么能阻止您将该树发送给愿意接受它的 C 编译器。但是 C 对 "(+ ....)" 的解释只允许数值算术。因此,原封不动地运送树木是造成语义灾难的秘诀。语言对运算符的解释差异很大,因此当运算符具有相同名称时,这几乎不起作用。更糟糕的是,接收方语言如何处理它接收到的运算符,而不是它的语言? (Java 中的“setjmp”?)
    【解决方案2】:

    我不知道有任何标准化的AST 表示格式可以实现这种共享(假设我们正在讨论具有相似语义的语言),但例如在Clang+LLVM 架构中,似乎AST输出可以输入多个代码生成器(编译器)。

    就好像有一个通用的 Java 任何语言解释器读取 AST 我猜这样的事情不存在,我怀疑是否有可能构建它,因为不同编程语言中单词的含义是不同。

    在澄清 cmets 后编辑 2015-03-30

    假设我将AST 序列化为字节流,通过套接字发送,然后在用另一种语言编写的程序中将其反序列化回对象树。使用JSONYAMLXML,它们是用于序列化和反序列化任意数据的简单、相当标准的语言,然后以所需语言为它们找到解析器。我认为这在技术上是可行的

    拥有具体编程语言的具体简单子集,比如说具体的procedural language,例如Tiny C,您可以在一台计算机上构建它的解析树并将它们发送到另一台计算机进行“解释”。谷歌查询ast intermediate representation 可以给你一些提示,比如http://icps.u-strasbg.fr/~pop/gcc-ast.htmlhttp://lambda-the-ultimate.org/node/716,但它与你原来使用ASTJava 中的通用解释器的任何语言不同

    我正在做一个实验

    asm.js 是“在一台机器上用一种语言解析程序并将其发送到另一台机器进行解释”问题的现代版本。另一台机器是任何现代网络浏览器,序列化格式是JavaScript 的子集。全球有数十亿个网络浏览器,使用它的实验既有商业利益又有用,因为这个项目欢迎像你这样的人提供进一步的支持或研究(?)

    另见:

    【讨论】:

    • 感谢 xmojmr,但我将创建一个参数,假设我将 AST 序列化为字节流,通过套接字发送,然后将其反序列化回用另一个编写的程序中的对象树语言。使用 JSON、YAML 和 XML 这些简单、相当标准的语言来序列化和反序列化任意数据,然后以所需语言为它们找到解析器。我认为这在技术上是可行的吗?让我听听你的看法
    • @user22092 我明白了。我的答案又增加了一章。如果您对此感到满意并且没有人在合理的时间范围内提供更好的东西,那么建立 Stack Overflow 表达“谢谢”的方式是通过投票或accepting the answer
    【解决方案3】:

    呼应 Rici 的回答:简短回答,不。

    这个想法已经尝试过不止一次了。通常它至少会失败,因为您无法为“添加”定义单个 AST 节点,这对所有语言都意味着一件事。 语义完全不同,您必须能够在找到它的特定语言上下文中区分运算符的含义。还有很多其他麻烦,比如就表示(树?DAG?图?)以及携带了多少信息(AST?符号表?控制流?...)

    人们不断尝试。

    对象管理组有一个Abstract Syntax Tree Model 的规范,它试图定义通用的 AST。 OMG 发现,为了使其实用,除了他们的必杀技“通用 AST 模型”(ick,“GASTM”),他们还需要有所谓的“特定 AST 模型”(“SASM”),例如, .特定于该语言的 AST,甚至是该语言的特定解析器,以便能够准确地解释该解析器生成的运算符和操作数的含义。

    [我构建了一个同时处理多种语言的工具。它通过本质上用运算符(例如“+”)和应该解释运算符的“域”(符号系统)标记每个节点来解决节点含义的问题。实际上,这与 SASTM 解决方案相同。我们不相信 GASTM,所以不要理会它。]。

    【讨论】:

    • 好的,我已经学会了,但我现在所做的是创建一个源文本,带有我自己的规则和语法。然后,当我为我编写的新语言创建树时,我用 python 和 Java 解释器来评估树给我结果。伙计,我希望这棵通用树成为标准。这样我们就可以对代码进行基准测试,甚至无需重新编写代码或从简单的语言转移
    • 定义具有明确含义的“特定抽象语法树(模型)”[SASM!] 是一回事,这样两个不同的应用程序就可以读取并正确解释该特定模型。相信您可以构建通用语法是另一回事。你正在向风车倾斜。
    • 好的,谢谢,但作为 CS 的人,我从不说不行
    • 我已经这样做了大约 40 年。还没有答案。祝你好运。