问题标签 [compiler-theory]

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 投票
6 回答
1662 浏览

c# - 函数式语言编译器相对于命令式语言编译器的优势

作为这个问题的后续行动,F# 的内置不变性相对于 C# 有哪些优势?——我是否正确假设 F# 编译器可以进行某些优化,因为它知道它正在处理大部分不可变的代码?我的意思是,即使开发人员编写了“函数式 C#”,编译器也不知道开发人员试图编写的所有不变性,因此无法进行相同的优化,对吧?

一般来说,函数式语言的编译器是否能够进行命令式语言无法实现的优化——即使是用尽可能多的不变性编写的语言?

0 投票
1 回答
551 浏览

.net - 我正在尝试使用 System.Reflection.Emit 编写一个 .NET 编译器,我该如何进行类型解析?

我有一个从引用的 dll 解析类型的策略。我一直在尝试解析正在编译的程序集中定义的类型。我正在使用没有第三方库的 System.Reflection.Emit api。

例如:

解决 B 对 A 的引用的最佳方法是什么?

那这个呢:

其中类包含彼此的实例。

有没有最佳实践方法来做到这一点?我应该实施任何设计模式吗?我宁愿只使用 System.Reflection.Emit 库,但如果有更好的方法可以做到这一点,或者这不能用它们完成,那么使用其他库是可以接受的。

谢谢

0 投票
2 回答
114 浏览

c - “类型和大小说明符” - 术语

采取以下代码段:

第 3 行中“char [6]”的正确技术术语是什么?我称之为“类型和大小说明符”,它仅描述了编译器的用途。

我用来调用“函数的调用堆栈签名”或简称为“函数签名”的整行 3。“函数声明”或“函数原型”也是正确的,而不是“函数实现”。

注意:您不需要向我解释有关调用堆栈、帧、调用约定等的所有内容。人。我只是在那里寻找正确的术语。不是整个第 3 行,只是如何调用单个说明符,例如“char [6]”。

0 投票
3 回答
5787 浏览

yacc - yacc:从浮点数中区分整数

我应该编写一个执行 2 + 2 = 4 和 2.2 + 2 = 4.2 的程序。

我已经这样做了,因此它将所有内容都视为浮点数,但这是“错误的”。我必须区分它们。这是我到目前为止所拥有的:

我遇到的问题是每个表达式只能有一种类型。现在一切基本上都是浮动的,所以虽然操作是正确的,但这不是正确的解决方案。

我想过定义更多的表达式,基本上有factor_int和factor_float,然后替换其中的所有内容,但这似乎真的错了。我不知道如何完成这项工作,而且我看到的教程并没有真正帮助我。

0 投票
3 回答
3904 浏览

terminology - 运行时定义

什么是运行时?而且我的意思不是“在运行时”=程序/脚本正在运行。我是说

<your-interpreted-language-here> 运行时

0 投票
2 回答
35739 浏览

compiler-theory - S-attributed 和 L-attributed 语法是什么意思?

我正在阅读一本编译器书籍,当它说“S 属性语法也是 L 属性语法”时有点困惑。无法理解。有人可以说清楚(一个例子应该很好)。谢谢。

0 投票
2 回答
869 浏览

assembly - P6 架构 - 除了寄存器重命名之外,有限的用户寄存器是否会导致更多的操作花费在溢出/加载上?

我正在研究有关动态语言 VM 实现的 JIT 设计。自从 8086/8088 天以来,我没有做太多的组装,只是在这里或那里做了一点,所以如果我心情不好,那就太好了。

据我了解,x86 (IA-32) 架构今天仍然具有与以往相同的基本受限寄存器集,但内部寄存器数量已大幅增长,但这些内部寄存器通常不可用,并与寄存器重命名一起使用实现代码的并行流水线,否则无法并行化。我非常理解这种优化,但我的感觉是,虽然这些优化有助于提高整体吞吐量和并行算法,但我们仍然坚持使用的有限寄存器集会导致更多的寄存器溢出开销,如果 x86 有两倍或四倍的寄存器对我们可用,典型指令流中的推送/弹出操作码可能会显着减少?或者是否有其他处理器优化也可以优化这一点,我不知道?基本上如果我

任何关于研究的参考,或者更好的是,个人经历?

编辑:x86_64 有 16 个寄存器,是 x86-32 的两倍,感谢您的更正和信息。

0 投票
2 回答
413 浏览

language-features - 语言和虚拟机:难以优化的功能及其原因

我正在为一个研究项目做准备。

说出一种难以优化的主流语言或语言特性,以及为什么该特性值得或不值得付出的代价,或者只是用轶事证据来揭穿我的理论。在有人将此标记为主观之前,我要求提供语言或功能的具体示例,以及优化这些功能的想法,或者我没有考虑过的重要功能。此外,任何对证明我的理论正确或错误的实现的引用。

在我的难以优化的特性和我的理论列表中名列前茅(我的一些理论未经测试,基于思想实验):

1)运行时方法重载(又名多方法分派或基于签名的分派)。与允许运行时重新编译或方法添加的功能结合使用时是否难以优化。还是只是很难,无论如何?调用站点缓存是许多运行时系统的常见优化,但多方法增加了额外的复杂性,并且使得内联方法不太实用。

2)类型变形/变体(也就是基于值的类型,而不是基于变量的类型)当您不知道某些类型是否可以在基本块中更改时,根本无法应用传统的优化。结合多方法,内联必须小心地完成,并且可能只针对给定的被调用者大小阈值。IE。很容易考虑内联简单的属性获取(getter / setter),但内联复杂的方法可能会导致代码膨胀。另一个问题是我不能只将变量分配给寄存器并将其 JIT 到本机指令,因为我必须携带类型信息,或者每个变量都需要 2 个寄存器而不是 1 个。在 IA-32 上这很不方便,即使使用 x64 的额外寄存器进行了改进。这可能是我最喜欢的动态语言特性,因为它从程序员的角度简化了很多事情。

3)头等舱延续- 有多种实现它们的方法,我在两种最常见的方法中都这样做了,一种是堆栈复制,另一种是实现运行时以使用连续传递样式、仙人掌堆栈、写时复制堆栈帧,和垃圾收集。一流的延续有资源管理问题,即。我们必须保存所有内容,以防继续继续,而且我不知道是否有任何语言支持留下“意图”的延续(即“我不会回到这里,所以你可以丢弃这个世界的副本” )。在线程模型和延续模型中编程后,我知道两者都可以完成同样的事情,但延续' 优雅给运行时带来了相当大的复杂性,并且还可能影响缓存效率(堆栈的位置随着使用延续和协同程序而改变更多)。另一个问题是它们只是不映射到硬件。优化延续就是针对不太常见的情况进行优化,正如我们所知,常见的情况应该很快,而不太常见的情况应该是正确的。

4)指针算术和屏蔽指针的能力(以整数存储等)必须把它扔进去,但实际上我可以很容易地没有它。

我的感觉是,许多高级特性,尤其是动态语言中的特性,并没有映射到硬件. 微处理器实现在芯片优化背后进行了数十亿美元的研究,但语言特性的选择可能会边缘化其中许多特性(如缓存、堆栈顶部到寄存器的别名、指令并行性、返回地址缓冲区、循环缓冲区和分支预测)。微特征的宏应用不一定像一些开发人员想的那样成功,在 VM 中实现多种语言最终会将本机操作映射到函数调用中(即,语言越动态,我们必须查找的次数越多/在运行时缓存,什么都不能假设,所以我们的指令组合比传统的由更高比例的非本地分支组成,静态编译的代码),我们唯一能真正做到 JIT 的就是对非动态类型的表达式求值以及对常量或立即类型的操作。我的直觉是字节码虚拟机和 JIT 内核可能并不总是因此而适用于某些语言。

我欢迎你的回答。

0 投票
7 回答
1520 浏览

compiler-construction - 现代和旧的编译器是用什么编写的?

作为编译器,而不是解释器,只需要翻译输入而不运行它,它本身的性能应该不会像解释器那样有问题。因此,您不会在 Ruby 或 PHP 中编写解释器,因为它太慢了。

但是,编译器呢?

如果您使用脚本语言编写编译器,甚至可能具有快速开发的特点,您可能会将源代码和初始开发时间减少一半,至少我认为是这样。

可以肯定的是:对于脚本语言,我的意思是解释性语言具有使编程更快、更容易和更有趣的典型特征,通常至少是这样。示例:PHP、Ruby、Python,也许是 JavaScript,尽管这对于编译器来说可能是一个奇怪的选择

  • 编译器通常是用什么编写的?我想你会用 C、C++ 甚至汇编程序等低级的东西来回应,为什么?

  • 是否有用脚本语言编写的编译器?

  • 使用低级或高级编程语言编写编译器有什么(缺点)优点?

0 投票
2 回答
1341 浏览

compiler-construction - 二元运算的IR树表示

我有一个简单的操作,如下所示:

它的 IR 树表示是什么?
到目前为止,我想出了:

但我不确定我是否需要 MEM 作为 NAME。欢迎任何帮助。

我们使用的符号与此 pdf 中的符号完全相同:http: //www.computing.dcu.ie/~hamilton/teaching/CA449/notes/translate.pdf

它来自java书中的现代编译器实现。