在编译的哪个阶段,语法糖通常会“脱糖”

Posted

技术标签:

【中文标题】在编译的哪个阶段,语法糖通常会“脱糖”【英文标题】:At what stage in compiling does syntactic sugar generally become "desugared" 【发布时间】:2021-07-09 23:02:46 【问题描述】:

我很好奇编译器如何以及何时将语法糖“脱糖”成最终形式。语法糖的一个例子是增量语句 i++ 变成了赋值语句 i=i+1,或者支持运算符重载的语言。

我知道许多不同的编译器会在不同的阶段以不同的方式和不同的阶段实现“脱糖”过程,所以我对任何语言的粗略示例都很满意。

我指的是编译过程的各个不同阶段,例如解析、语义分析、中间、代码生成等。

我对 AST 的影响(如果有的话)以及它可能发生的任何潜在转换特别感兴趣。

【问题讨论】:

这肯定发生在代码生成之前 :-)。除此之外,我认为没有比“这取决于”更好的答案了。至少,我不会尝试一个。 (后缀++ 比简单的替换为(x = x + 1) 更复杂,因为替换表达式的返回值是x 的新值,但后缀递增的语义要求返回值是旧值。 ) @rici 虽然我理解您为什么回复评论,但在这种情况下,因为问题比客观更主观,我认为您应该将其发布为答案,以便其他人可以看到问题一个答案。如果我是 OP,我会支持它作为答案并接受它。 【参考方案1】:

我将采取不同的方法来回答这个问题。我不会专注于阶段,而是专注于中间语言。

正如@rici 在 cmets 中提到的那样,这确实取决于。在许多现代编译器中,使用了不同的中间表示:

    HIR(高级中间表示)(前端和“中端”) MIR(中级中间表示)(中端和后端) LIR(低级中间表示)(后端)

这些不同的中间表示可以依次细分,例如,HIR-1(加糖)HIR-2(加糖)

当我们在不同的中间表示之间进行转换时,我们的中间语言变得不那么特定于语言而更加特定于目标。中级中间表示通常类似于低级与机器无关的语言,而 LIR 通常非常接近目标机器。通常,HIR 的不同变体使循环和数组访问等内容保持显式,例如,它用于检查自动并行化代码的机会或进行与循环结构相关的其他优化。有时还可以在那里找到更多特定于语言的优化(或检查)。

在句法糖的情况下,它要么在解析后保留,因此成为某些 HIR 表示的一部分,要么设计者可能选择直接对其进行去糖化。在解析后保留它的好处是,它可以用于为用户提供提示的工具中,或者可以在某些 HIR 优化中使用一些语法糖。保留它的缺点是需要对糖进行编码,并且可能会在编译器中引入更多代码和更多检查。

【讨论】:

以上是关于在编译的哪个阶段,语法糖通常会“脱糖”的主要内容,如果未能解决你的问题,请参考以下文章

Java语法糖1:可变长度参数

脱糖与DXD8R8

脱糖与DXD8R8

脱糖与DXD8R8

脱糖与DXD8R8

重新认识ES6中的语法糖