问题标签 [compiler-construction]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
5 回答
329 浏览

c# - 编译器无法在接口和异常之间选择重载

尝试使用可以为 XML 解析提供位置参考的 excpetion 类,发现了一个有趣的行为 - 当我尝试将 XmlReader 作为参数传递时,编译器无法在使用接口的重载和需要 System.Exception 的重载之间进行选择。

详情如下:

它失败了,因为它无法选择正确的重载。但是为什么呢?我们看到 XmlReader 支持一个接口并且它不是从 System.Exception 继承的

0 投票
2 回答
229 浏览

c# - 在 Visual Studio/C# 的编译时强制使用“this”和“base”

在扩展类时,我发现在访问基类中的方法时使用base(在 VB 中)关键字非常具有描述性。MyBase在访问扩展基类的类中的函数时使用this(在 VB 中) 关键字。Me这也适用于没有继承的“平面”结构。

我觉得读这个更容易:

比这个:

现在,我的问题是:是否可以在 Visual Studio/C# 的编译时强制使用thisand base,以便如果您在代码中不使用这些关键字,编译器会抛出错误或警告?

0 投票
18 回答
11772 浏览

c++ - C / C++ 编译器警告:您是清理所有代码以删除它们还是保留它们?

我参与过许多项目,在这些项目中,其他人给了我要更新的代码。我经常编译它并收到大约 1,000 多个编译器警告。当我看到编译器警告时,它们让我觉得很脏,所以我的首要任务是清理代码并将它们全部删除。通常我会发现十几个问题,比如未初始化的变量。

我不明白为什么人们将它们留在里面并且没有完全干净的编译而没有警告。我错过了什么吗?有什么正当理由让他们离开吗?有什么恐怖故事可以分享吗?

0 投票
18 回答
14914 浏览

compiler-construction - 有趣的编译器项目

我目前正在为未来 8 周内完成的研究生级编译器课程选择一个项目。我想做一些与优化相关的事情,因为我以前在该领域工作不多,但该领域的任何事情都是公平的。

你做过的最有趣的编译器相关项目是什么?你从中学到最多的是什么?


编辑:谢谢大家的好建议。我很抱歉这么久没有更新这个。

我最终做的项目是在 LLVM 上进行简单的自动向量化优化。LLVM 有向量类型,但似乎没有任何方法可以在不支持前端的情况下利用它们。此优化将普通标量代码转换为矢量代码。

由于自动矢量化是一个相当难以实现的优化,我们尽可能地限制了我们的范围。首先,为了在代码中展示指令级并行性,我们寻找符合我们标准的单块循环,然后将它们展开特定次数,以便它们可以方便地向量化。然后,我们实现了Larsen 和 Amarasinghe在Exploiting Superword Level Parallelism with Multimedia Instruction Sets中提出的打包算法。

即使是这种优化的简化版本也相当复杂。有很多限制;例如,您不想向量化一个存在于循环之外的变量,因为程序的其余部分希望它是标量的。在过去的几周里,我们投入了很多时间。不过这个项目很有趣,我们学到了很多东西。

0 投票
7 回答
4129 浏览

parsing - 动态 (?) 解析器

是否存在在运行时生成 AST/解析树的解析器?有点像一个库,可以接受一串 EBNF 语法或类似的东西并吐出一个数据结构?

  • 我知道 antlr、jlex 和他们的同类。他们生成可以做到这一点的源代码。(喜欢跳过编译步骤)
  • 我知道 Boost::Spirit,它使用一些带有 C++ 语法的黑魔法在执行时生成这样的东西(肯定更接近我想要的,但在 C++ 方面我是个无赖。而且它仍然有点限制,因为你的语法是硬编码的)
  • 我不知道 python 或 ruby​​ 中的任何内容,尽管编译器编译器在这种语言中可能非常有效......

现在我知道解析器组合器了。(谢谢,乔纳斯)还有一些图书馆(谢谢 eliben)

顺便说一句,我最近还注意到Parsing Expression Grammars,如果有人实现它听起来很酷(他们说 Perl 6 会有它,但 Perl 回避了我的理解)

0 投票
2 回答
13488 浏览

.net - .NET 中类加载器的等价物

有谁知道是否可以在.NET 中定义等效于“java 自定义类加载器”的内容?

提供一点背景:

我正在开发一种针对 CLR 的新编程语言,称为“Liberty”。该语言的特点之一是它能够定义“类型构造函数”,这是由编译器在编译时执行并生成类型作为输出的方法。它们是泛型的一种概括(该语言中确实有普通的泛型),并允许编写这样的代码(以“Liberty”语法):

“元组”的定义如下:

在这个特定的示例中,类型构造函数tuple提供了类似于 VB 和 C# 中的匿名类型的东西。

但是,与匿名类型不同,“元组”具有名称并且可以在公共方法签名中使用。

这意味着我需要一种方法,让最终由编译器发出的类型可以跨多个程序集共享。例如,我想要

tuple<x as int>在程序集 A 中定义的类型最终与tuple<x as int>程序集 B 中定义的类型相同。

当然,这样做的问题是程序集 A 和程序集 B 将在不同的时间编译,这意味着它们最终都会发出自己不兼容的元组类型版本。

我研究了使用某种“类型擦除”来做到这一点,这样我就可以拥有一个包含一堆这样的类型的共享库(这是“Liberty”语法):

然后将访问从 i、j 和 k 元组字段重定向到Field1Field2Field3.

然而,这并不是一个真正可行的选择。这意味着在编译时tuple<x as int>最终tuple<y as int>会成为不同的类型,而在运行时它们将被视为相同的类型。这会给诸如平等和类型标识之类的事情带来很多问题。这对我的口味来说太抽象了。

其他可能的选择是使用“状态包对象”。但是,使用状态包会破坏语言中支持“类型构造函数”的全部目的。想法是启用“自定义语言扩展”以在编译时生成新类型,编译器可以使用这些新类型进行静态类型检查。

在 Java 中,这可以使用自定义类加载器来完成。基本上可以发出使用元组类型的代码,而无需在磁盘上实际定义类型。然后可以定义一个自定义的“类加载器”,它将在运行时动态生成元组类型。这将允许在编译器内部进行静态类型检查,并将跨编译边界统一元组类型。

然而不幸的是,CLR 不提供对自定义类加载的支持。CLR 中的所有加载都是在程序集级别完成的。可以为每个“构造类型”定义一个单独的程序集,但这会很快导致性能问题(有许多只有一种类型的程序集会使用太多资源)。

所以,我想知道的是:

是否可以在 .NET 中模拟 Java 类加载器之类的东西,我可以在其中发出对不存在类型的引用,然后在需要使用它的代码运行之前在运行时动态生成对该类型的引用?

笔记:

*我实际上已经知道这个问题的答案,我在下面提供了答案。然而,我花了大约 3 天的时间进行研究,并进行了大量的 IL 黑客攻击,以便提出解决方案。我认为在这里记录它是一个好主意,以防其他人遇到同样的问题。*

0 投票
5 回答
593 浏览

delphi - Delphi 是否有将版本作为输入参数的 FOSS 批量编译解决方案?

Delphi 是否有将版本作为输入参数的 FOSS 批量编译解决方案?

我正在使用 Delphi 7,这仍然是最繁琐的操作。是否有任何其他解决方案,解决方法可以使这变得容易。

0 投票
11 回答
20191 浏览

windows - 为什么 GCC-Windows 依赖于 cygwin?

我不是 C++ 开发人员,但我一直对编译器很感兴趣,而且我对修补一些 GCC 的东西(尤其是 LLVM)很感兴趣。

在 Windows 上,GCC 需要 POSIX 仿真层(cygwin 或 MinGW)才能正确运行。

这是为什么?

我使用许多其他软件,用 C++ 编写并针对不同平台(Subversion、Firefox、Apache、MySQL)进行交叉编译,它们都不需要 cygwin 或 MinGW。

我对 C++ 最佳实践编程的理解是,您可以编写合理的平台中立代码并处理编译过程中的所有差异。

那么与 GCC 有什么关系呢?为什么它不能在 Windows 上本地运行?


编辑:

好的,到目前为止,这两个回复基本上说,“GCC 使用 posix 层,因为它使用 posix 标头”。

但这并不能真正回答问题。

假设我已经为我最喜欢的标准库准备了一组头文件。为什么我仍然需要 posix 标头?

GCC 是否需要 cygwin/mingw 才能实际运行

还是只需要头文件和库的仿真层?如果是这样,为什么我不能只给它一个包含所需资源的“lib”目录?


再次编辑:

好的,我会再次尝试澄清问题...

我还用D 编程语言编写代码。官方编译器名为“dmd”,并且有适用于 Windows 和 linux 的官方编译器二进制文件。

Windows 版本不需要任何类型的 POSIX 仿真。Linux 版本不需要任何类型的 Win32 仿真。如果编译器对其环境有假设,它会很好地隐藏这些假设。

当然,我必须告诉编译器在哪里可以找到标准库以及在哪里可以找到静态或动态链接的库。

相比之下,GCC 坚持假装它在 posix 环境中运行,它要求我通过设置一个仿真层来满足这些假设。

但是,在 GCC 中,究竟是什么依赖于该层?它只是在寻找 stdlib 标头,并假设它会在“/usr/lib”中找到这些标头吗?

如果是这样的话,我不应该告诉它在“C:/gcc/lib”中查找那些头文件吗?

或者 GCC 本身是否依赖 POSIX 库来访问文件系统(以及做其他低级的事情)?如果是这样的话,那么我想知道为什么他们不只是静态链接到他们最喜欢的 windows POSIX 库。当用户可以将这些依赖项直接构建到应用程序中时,为什么还要要求用户设置依赖项?

0 投票
9 回答
46969 浏览

c++ - 递归函数可以内联吗?

在阅读本文时,发现如果编译器未正确处理上述代码,将导致“无限编译”。

编译器如何决定是否内联函数?

0 投票
14 回答
41878 浏览

compiler-construction - 用自己的语言编写编译器

直观地说,似乎语言的编译器Foo本身不能用 Foo 编写。更具体地说,语言的第一个编译器Foo不能用 Foo 编写,但任何后续编译器都可以用Foo.

但这真的是真的吗?我对阅读第一个编译器是用“自身”编写的语言有一些非常模糊的回忆。这可能吗,如果可以,怎么办?