compiler-construction - 解决循环导入问题

标签 compiler-construction programming-languages interpreter language-design abstract-syntax-tree

好的,所以我目前正在编写一个解释器(针对我自己设计的语言),并且在处理 import 时遇到问题。 s。

解释器的工作原理如下:

  • 曾经import <somefile>;语句被执行,somefile被加载、解析并执行。
  • 这意味着如果一个函数/类在 somefile 中声明,我们的全局函数表中已经创建了一个条目,以便从那时起可以调用它。
  • 然后我们继续下一个声明。并执行它。

现在这是问题......

问题 1:

  • 假设有一个 doSth文件中的函数file1并导入 file2
  • 如果有 file3导入file2 ,这意味着file1的 Action 也是可以的。这是不可取的。

问题 2:

  • 如果file1进口file2 (因为,假设我们需要使用 file2 中的函数)和 file2进口file1 ,这会导致循环引用(很可能会一直运行到时间结束)

那么,如何解决这些问题呢?有什么想法吗?

我知道这个问题非常专业和复杂,但是如果知道现有解释器/编译器如何处理这个问题,请透露一些信息! ;-)

最佳答案

问题 1

C 和 friend 们所表现出的行为正是您所提示的,这表明无论它有多么令人不快,我们都可以接受:) 但是,许多其他语言也有与您相同的观点。我所知道的所有解决方案都是“申报导出”的某种变体。一般来说,您需要某种机制来指定导出哪些定义(或者导出哪些定义);如果您需要明确地重新导出导入的定义,那么您将不再遭受默认重新导出的困扰。

但是,您现在遇到了一个稍微不同的问题:

file3:
  export cool_definition

file2:
  import file3
  export bland_definition
  /* Use cool_definition */

file1:
  import file2 /* Note: only bland_definition is imported */
  import file3 /* We want cool_definition */

现在您可能必须确保 cool_definitionfile1 中直接使用时与 bland_definition 使用时具有相同的含义文件2。 (取决于您的语言的状态程度,以及您对消除代码重复的关心程度等)

问题 2

假设您同意预处理器导入防护是一个荒谬的黑客,那么您需要记住哪些文件已被导入,并且如果已经或当前正在导入文件,则拒绝导入该文件。这是简单的部分。

使循环导入链发挥作用意味着您需要能够在不知道文件可能依赖的定义的情况下导入文件。例如,如果这些定义是改变程序语法的宏,那么这可能会很棘手。否则,你可以正常收集所有导入的传递闭包;一次处理一个文件以发现定义;然后解析定义(并执行编译所需的任何其他操作)。

Google protobuf 编译器的源代码中有该策略的相当可读的实现(我认为您可以开始浏览 here ,但我已经有一段时间没有查看该代码了。)

关于compiler-construction - 解决循环导入问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23168078/

相关文章:

compilation - 解释器如何翻译 for 循环?

c - 有没有什么合理的方法可以在 C 程序中嵌入 Prolog 解释器?

c - 弹性 Bison : Building C Compiler - Line number in error message

php - 在项目级别而不是文件级别检查 php 中的语法错误

programming-languages - Icon 编程语言的优缺点是什么?

programming-languages - 在语言中不包含 NULL 的含义?

compiler-construction - 内置 AV 的编译器 = 没有病毒开发?

c++ - 在没有 FPU 的情况下 float 会怎样?

java - JVM/CLR 源代码兼容语言选项

clojure - 为 ANTLR 语法编写解释器