如何生成从虚构语言解析的AST树代码?

时间:2012-02-28 04:27:04

标签: ruby parsing compiler-construction

我在http://parsingintro.sourceforge.net/阅读了这篇文章,并决定尝试将其重写为Ruby中的练习。有两个原因使我这样做,我想了解更多关于如何编写Ruby(Java,PHP,C和一些Python的背景)的知识,我想了解更多关于解析器/编译器的知识。

我在https://github.com/parse/boatcaptain发布了所有代码。正在生成AST树,不幸的是,本文的作者没有涉及代码生成和优化等概念。

任何人都可以通过指导我如何将这个AST树变成“代码”来帮助我吗? This is the AST tree that is generated

几年前我用Java编写了一个计算器,它使用了很多类似于我在解析器中使用的术语和技术。但是在计算器中,我有eval()的方法 - 我的“类”,因此得到输出,我应该在这里做类似的事情吗?计算器来源:https://github.com/parse/Uppsala-University-Courses/blob/master/ImpOOP-Calculator/src/Calculator.java

我也很喜欢我编写Ruby的方式的反馈,我相信我仍然会编写Ruby,就像编写Python一样,缺少Ruby的一些优点。

1 个答案:

答案 0 :(得分:2)

最基本形式的代码生成只是遍历您的中间形式 - AST - 并以您的目标语言发出相应的指令。

首先,您需要选择目标语言。您希望输入文件在哪个平台上运行?您可以选择的主要选项是:

  • 源到源转换器
  • 编译器到本机代码
  • 编译器到字节码(在VM上即时运行)

目标语言的选择可以决定您在语言之间进行映射所需的工作量。例如,将面向对象的类映射到ASM可能/将是棘手的。将固有的过程代码映射到基于堆栈的代码也可能是一个挑战。

无论您选择哪种语言,问题无疑都归结为以下过程:访问树的节点,并根据其类型发出相应的指令。

假设您遇到AST中的以下节点(与您链接的节点相同):

        =
delta       /
      alpha   beta

看到它是一个“赋值”节点,然后代码生成器知道它必须在将该值粘贴到LHS之前评估树的RHS; '三角洲'。所以我们按下RHS节点,看它是一个除法运算。然后我们知道在划分它们之前我们必须评估该节点的LHS和RHS,并将结果粘贴在“delta”中。

所以现在我们向下移动LHS,看它是一个变量,然后我们发出'load'指令。我们回到RHS然后再下来,同样为'beta'发出'负载'。然后我们回到树上(同时带上alpha和beta),在两个操作数上发出除法指令,存储结果,将树传递给赋值发射器,然后将它存储在'delta'中。

因此,此代码段的结果代码可能是:

load alpha
load beta
tmp = div alpha beta
store delta tmp

对于已有的Ruby Code Generator库,我不知道,对不起。我希望这个答案对你来说不是太笼统或简单。