【发布时间】:2015-03-29 05:58:56
【问题描述】:
我知道没有两种编程语言是完美匹配的,但我想问一下我是否有一个简单的程序,比如 hello world,我运行编译翻译阶段,比如 lex,解析然后获取 AST 树我可以将它发送到另一个环境说一些 c AST 树并用 Java 解释它
【问题讨论】:
标签: parsing compiler-construction interpreter abstract-syntax-tree lexer
我知道没有两种编程语言是完美匹配的,但我想问一下我是否有一个简单的程序,比如 hello world,我运行编译翻译阶段,比如 lex,解析然后获取 AST 树我可以将它发送到另一个环境说一些 c AST 树并用 Java 解释它
【问题讨论】:
标签: parsing compiler-construction interpreter abstract-syntax-tree lexer
简短的回答:不。
更长的版本:
如果您有两种不同的语言实现记录并导出了它们的 AST 接口,并且这两个接口非常相似,您可以在它们之间进行翻译,那么您可以编译为 AST,然后尝试将 AST 传递给其中一个实现。
我在这里只能假设性地说,因为语言实现包含外部可访问的 AST 接口是非常罕见的。 (一个例外是 Python,它允许您编译为 AST、创建或修改 AST,然后从 AST 编译。这里,“编译”的意思是“编译为 VM 代码”。有关更多信息,请参阅Python docs。)
特别是,我不知道有哪个 Java 实现。 GCC 和 clang 都可以输出类似于 AST 的内容,但它们都不接受,并且输出可能不够完整,无法定义翻译单元的所有方面。
【讨论】:
我不知道有任何标准化的AST 表示格式可以实现这种共享(假设我们正在讨论具有相似语义的语言),但例如在Clang+LLVM 架构中,似乎AST输出可以输入多个代码生成器(编译器)。
就好像有一个通用的 Java 任何语言解释器读取 AST 我猜这样的事情不存在,我怀疑是否有可能构建它,因为不同编程语言中单词的含义是不同。
在澄清 cmets 后编辑 2015-03-30
假设我将
AST序列化为字节流,通过套接字发送,然后在用另一种语言编写的程序中将其反序列化回对象树。使用JSON、YAML、XML,它们是用于序列化和反序列化任意数据的简单、相当标准的语言,然后以所需语言为它们找到解析器。我认为这在技术上是可行的
拥有具体编程语言的具体简单子集,比如说具体的procedural language,例如Tiny C,您可以在一台计算机上构建它的解析树并将它们发送到另一台计算机进行“解释”。谷歌查询ast intermediate representation 可以给你一些提示,比如http://icps.u-strasbg.fr/~pop/gcc-ast.html 或http://lambda-the-ultimate.org/node/716,但它与你原来使用AST 和Java 中的通用解释器的任何语言不同
我正在做一个实验
asm.js 是“在一台机器上用一种语言解析程序并将其发送到另一台机器进行解释”问题的现代版本。另一台机器是任何现代网络浏览器,序列化格式是JavaScript 的子集。全球有数十亿个网络浏览器,使用它的实验既有商业利益又有用,因为这个项目欢迎像你这样的人提供进一步的支持或研究(?)
另见:
【讨论】:
呼应 Rici 的回答:简短回答,不。
这个想法已经尝试过不止一次了。通常它至少会失败,因为您无法为“添加”定义单个 AST 节点,这对所有语言都意味着一件事。 语义完全不同,您必须能够在找到它的特定语言上下文中区分运算符的含义。还有很多其他麻烦,比如就表示(树?DAG?图?)以及携带了多少信息(AST?符号表?控制流?...)
人们不断尝试。
对象管理组有一个Abstract Syntax Tree Model 的规范,它试图定义通用的 AST。 OMG 发现,为了使其实用,除了他们的必杀技“通用 AST 模型”(ick,“GASTM”),他们还需要有所谓的“特定 AST 模型”(“SASM”),例如, .特定于该语言的 AST,甚至是该语言的特定解析器,以便能够准确地解释该解析器生成的运算符和操作数的含义。
[我构建了一个同时处理多种语言的工具。它通过本质上用运算符(例如“+”)和应该解释运算符的“域”(符号系统)标记每个节点来解决节点含义的问题。实际上,这与 SASTM 解决方案相同。我们不相信 GASTM,所以不要理会它。]。
【讨论】: