添加导入或包含对编程语言的支持的方法有哪些?

时间:2017-07-19 09:29:02

标签: compiler-construction python-import abstract-syntax-tree interpreter

我现在正在使用教程实现一个解释器作为业余爱好项目。基本上,我是lex,解析代码并生成一个抽象语法树并对其进行评估。从一个源代码文件,我生成一个树。现在我想添加类似于Python的import或C #include语句的功能。我的方法是什么?其他语言如何克服这个问题?他们是创建两个单独的树并将它们组合在一起,还是仅将文件的内容复制到实际文件中并创建一棵大树?你能给我一些解释可能方法的教程或论文吗?

2 个答案:

答案 0 :(得分:1)

解决方案取决于includes是函数(如C等)或源体(如Java)的签名还是标题。

包含为标题或签名

  • Lex并检查任何include语句
  • 加载任何包含并为每个包含一个符号表并放入堆栈(主观实现警告)。无需为每个创建完整的AST,因为只有符号对于解析引用很重要。
  • 在解析和AST发出期间,使用符号表堆栈进行查找

假设是:构成include的假设已经过解析,验证并从其来源发出代码。

包括作为来源

当您包含源代码时,您正在扩展编译单元,导入的源代码将被视为in scope。这将需要:

  • Lex the base source
  • 识别,加载和列出包含的来源。这应该pre-pend你的lex令牌列表,除非你有特定的行为作为你的语言语义的一部分
  • 继续生成您的一(1)AST。它会更大。

答案 1 :(得分:1)

编译器至少有两种通用方法可以解决“包含”问题。

  1. 字面上包含文件的文本。这就是方法C和增强的FORTRAN 77编译器使用的方法。

  2. 单独编译“include”并只包含定义。这就是Ada采取的方法。

  3. 有些编译器同时使用它们。有一些编译器(例如一些帕斯卡)支持这两种方法。