为什么大多数编译器使用 AST,而不是直接生成 IR?

Why most compilers use AST, instead generate IR directly?

听说大部分编译器都是用AST,然后翻译成IR(中间表示)。

但是我觉得编译器可以直接生成IR,比如C4 project

如果我使用 AST,当我完成语法分析和语义分析时,我必须从头扫描 AST 以生成 IR。这是一个额外的步骤,所以我认为它很慢。

使用 AST 有什么好处?更好的可读性还是更好的可移植性?

你能给我一些建议吗?谢谢你的时间。

您可能需要不止一个 AST。您的第一个 AST,即由解析器生成的 AST,可能充满了冗余的东西,以及使您的源语言易于使用的所有语法糖。在开始生成 IR 之前,您需要删除此冗余,否则您的代码生成步骤将变成重复的样板文件。

一个恰当的例子 - if 声明。它有两种形式——一种只有 true 分支,另一种有 truefalse 分支。前者是后者的特例,因此传递 AST 是有意义的,将所有单臂 if 语句替换为带有虚拟 false 分支的双臂语句。那么您的 IR 生成程序将只需要处理一种 if.

另一个重要的考虑因素是打字。对于那里的绝大多数类型系统,在树上做而不是在一些平面 IR 上做起来更容易。

此外,将您的平面 IR 视为另一种形式的 AST,并以相同的方式对待它。以小步骤将复杂的 AST 转换为一些低级和简单的后端 AST(或 IR,随便你怎么称呼它)比在一个巨大的样板通道中完成所有事情要容易得多。