首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用编程语言实现模块系统

用编程语言实现模块系统
EN

Stack Overflow用户
提问于 2022-08-05 04:29:46
回答 1查看 70关注 0票数 1

我正在编写我自己的编译器,我正在努力实现一个模块系统。有人能指点我吗,该怎么做?其他语言是如何解决这一问题的?此外,我还试图避免使用c和c++ (头文件)。不过,我喜欢Go/Golang中的模块系统。

我不知道这是否相关,但我正在使用LLVM (也许有一种神奇的方法来导入符号)。

我最初的做法是:

  • 读取并解析入口点源文件,即。main.mylang.
  • go通过导入main.mylang
  • for每个导入:读取、解析和解析它的导入.

这就形成了一个树结构:

import3.mylang

  • import1.mylang:

  • main.mylang:1.main.mylang,import4.mylang 2.main.mylang,
    • 4.main.mylang,import5.mylang
    • import2.mylang: import6.mylang

..。等。

然后我会遍历每个节点并复制它的符号(函数、全局变量等)。到父节点的符号表。如果父节点为null,则它是一个入口点文件,编译器可以启动输出对象文件。

为什么我觉得这很糟糕?

collisions

  • you非常慢,即使在编译3-5源文件

  • 时,也很容易导致名称

  • 必须导入整个符号表,因为导入的文件的导出符号依赖于内部符号。例如:假设一个导出的函数修改了内部全局变量

提前感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-08 18:03:42

我觉得你的方法真的很好。编译时间的速度不是那么重要,可用性才是。为了避免名称冲突,您可以使用某种模块名称空间(importname.foo()而不是foo()),并且只要foo不存在,就允许这两种方法。或者,您可以在父符号表中插入占位符,每当用户使用该名称时,就会抛出编译时错误(类似于歧义符号)。应该是这样的: main.mylang

代码语言:javascript
复制
import module1
import module2
int main() {}

module1.mylang

代码语言:javascript
复制
import module2
void foo() {}
void bar() {}

module2.mylang

代码语言:javascript
复制
import module1
void bar() {}
void fun() {}

找到循环之后,树将如下所示:

代码语言:javascript
复制
main
├──module1
│  └──module2
└──module2
   └──module1

像这样的图表:

代码语言:javascript
复制
main
├─>main()
├─>foo() (module1)
├─>bar() (defined twice, throw error when used)
├─>fun() (module2)
├─>module1<───────────┐
│  ├─>foo() (module1) │
│  └─>bar() (module1) │
└─>import2<───────────┘
   ├─>bar() (module2)
   └─>fun() (module2)

我对llvm不太了解,但我很确定普通的表不足以归档这个文件。您至少需要嵌套的表,即使不是像我所描述的那样类似于图的结构。而且,在经典的C/C++体系结构中,这是不可能的,除非您使用唯一标识符作为符号,并且不让用户知道(比如c++函数重载)。例如,您可以调用一个函数__import1_bar和另一个__import2_bar,每当用户使用bar()时,您可以在这个图中查找他想要调用的一个函数。在主函数中,使用import1.bar()将引导您到__import1_bar (如图所示),import2.bar()import1.import2.bar()将引导您到__import2_bar

祝你好运弄明白。但这无疑是一个有趣的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73244684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档