Compiler construction 口译员应该如何“翻译”呢;工作“;当翻译一种语言时?

Compiler construction 口译员应该如何“翻译”呢;工作“;当翻译一种语言时?,compiler-construction,programming-languages,code-generation,interpreter,Compiler Construction,Programming Languages,Code Generation,Interpreter,作为一个自我项目,我正在为我“编写”的一种编程语言创建一个解释器(它实际上只是JavaScript编程语言的一个小小扩展),但我对解释器的实际工作方式以及应该如何执行用我的语言编写的程序有点迷茫。我的问题是: 1:因为这是一个解释器,所以我应该在遍历解析树时执行语句,还是应该用另一种语言(比如python)生成代码,然后使用子进程调用编译并运行生成的python文件 2:我是否应该在阅读时执行每条语句?或者在遍历树并生成/执行代码之前,我应该在内存中构建整个程序的parse tree->AST吗

作为一个自我项目,我正在为我“编写”的一种编程语言创建一个解释器(它实际上只是JavaScript编程语言的一个小小扩展),但我对解释器的实际工作方式以及应该如何执行用我的语言编写的程序有点迷茫。我的问题是:

1:因为这是一个解释器,所以我应该在遍历解析树时执行语句,还是应该用另一种语言(比如python)生成代码,然后使用子进程调用编译并运行生成的python文件


2:我是否应该在阅读时执行每条语句?或者在遍历树并生成/执行代码之前,我应该在内存中构建整个程序的parse tree->AST吗?(取决于问题1的答案)

实现解释器的一种直观方法是创建一个可执行的AST:

  • 解析源文件:您可以自己编写解析器,也可以使用许多可用的编译器生成器之一(例如)。如果您使用编译器生成器,那么“低级内容”的麻烦就会少很多,并且可以更专注于实现语言语义。但是,您也将错失一次学习如何自己实现解析器的机会
  • 生成可执行AST:在执行函数/方法的一个节点中本地实现每个操作。例如,添加节点将执行其左子节点、右子节点,然后自己返回结果。if节点将首先执行其条件,然后根据条件执行其if分支子节点或其右分支子节点。您还必须考虑将运行时数据(如变量)存储在何处
  • 执行AST:如果要执行动态类型化语言(如JavaScript),则必须考虑变量可以具有不同类型的值。您可以拥有适应执行状态的节点,也可以实现处理所有情况的单个节点
  • 一种方法是在JavaTruffle框架的顶部实现它。如果您以正确的方式实现解释器,您将获得良好的性能。还有几种语言实现;还包括使用Cocoa编译器生成器的。一些论文解释了如何实现局部变量或处理动态类型语言的不同类型的值


    我建议您先看看truffle.sl的实现,然后看看从那里可以得到什么

    请看我的SO答案,其中显示了如何执行构造的AST:我发誓,您是SO上最有帮助的用户。@kjh,JavaScript太可爱了,不容易被临时AST walker评估。值得先把它简化成一种更简单的语言,或者更好地说,简化成一个简单的字节码,然后由一个普通的解释器执行。@SK logic,这意味着什么?你的意思是我应该在我的解释器实现中省略该语言的某些功能吗?@kjh,不,我的意思是你可以先编译或翻译源语言,然后再进行解释。您可以删除语法sugar,将多个结构化编程语句降低为一个简单的通用语句(例如,
    goto
    ),尽可能地枚举变量,而不是使用它们的符号名,等等。非常有趣的答案,我一定会研究一下。我们今天在操作系统课上讨论了这个概念,当时我们的教授正在讨论虚拟机是如何工作的。很酷的话题。