【问题标题】:What is the language of compilers? Are they written with different languages?编译器的语言是什么?它们是用不同的语言编写的吗?
【发布时间】:2011-02-14 00:31:17
【问题描述】:
【问题讨论】:
标签:
compiler-construction
【解决方案1】:
编译器通常是用所述编译器的语言编写的。例如,C 编译器通常是用 C 编写的。
...这提出了“第一次如何编译它?”的问题。我听到了两个答案:要么是手工编译的(听起来很吓人),要么是作弊并使用该语言的现有编译器。
正如@jball 所评论的,请阅读Bootstrapping 上的维基百科文章以获取完整的详细信息。
【解决方案2】:
任何事物的语言是什么? gcc 例如写在 C.
曾经有一个关于Lisp 解释器的故事是用 Lisp 写的。
这带来了以下问题——如果 C 编译器是用 C 编写的,那么第一个 C 编译器是由什么编译的?为此,read here。
【解决方案3】:
compiler 可能用任何语言编写。在其最基本的形式中,编译器只是将代码从一种语言转换为另一种语言。在当今大多数人使用“编译器”一词的意义上,他们指的是接收某种高级语言的源代码并将其转换为汇编或某种低级中间语言的东西(CIL)。
【解决方案4】:
有时是,有时不是。习惯上会尽快尝试用该语言本身为一种新语言实现编译器,部分是为了证明它可以做“繁重的工作”。
当然,您首先需要一个编译器或者至少是解释器来运行那个编译器并让它自己编译——所以你首先必须用不同的语言来实现它。
对于许多专门的语言,用该语言本身编写编译器是不切实际的,因为该语言不适用于编译器之类的东西。
【解决方案5】:
这里有几个例子:
- Rubinius Ruby 编译器是用 Ruby 编写的,
- YARV Ruby 编译器是用 C 语言编写的,
- XRuby Ruby 编译器是用 Java 编写的,
- Ruby.NET Ruby 编译器是用 C# 编写的,
- MacRuby Ruby 编译器是用 Objective-C 编写的,
- IronJS ECMAScript 编译器是用 F# 编写的,
- MS Visual F# 编译器是用 F# 编写的,
- MS Visual C# 编译器是用 C++ 编写的,目前正在用 C# 重写,
- MS Visual Basic.NET 编译器是用 C++ 编写的,目前正在用 Visual Basic.NET 重写,
- GCC C 编译器是用 C 语言编写的,
- Clang C 编译器是用 C++ 编写的,
- 大多数 Pascal 编译器都是用 Pascal 编写的,
- 大多数 Oberon 编译器都是用 Oberon 编写的,
- 6g/8g 和 gccgo Go 编译器都是用 C 编写的。
一般来说,编译器可以用任何语言编写,只要语言足够强大,就可以编写编译器。这显然包括任何图灵完备的语言。但甚至可以用非图灵完备的语言编写编译器。 (例如,我看不出编译器不能成为总函数的任何明显原因,但总函数显然不是图灵完备的。)
然而,在实践中,编译器大多是用三种具有不同优缺点的特定语言编写的:
- 编译器实现的语言相同(优点:更大的社区,因为知道该语言的每个人都可以在编译器上工作,否则他们需要了解两种语言;缺点:引导问题)
- 编译器应该在其上运行的平台的主要低级系统编程语言,例如Unix 上的 C,JVM 上的 Java,CLI 上的 C#(优点:非常快;缺点:通常这些语言根本不适合编写编译器,而且我实际上并不认为性能优势是真实的)
- 一种非常适合编写 ML、Haskell、Lisp、Scheme 等编译器的语言(优点:这些编译器往往很容易理解和破解;缺点:您仍然需要了解两种语言)
- 上述特殊情况:用于编写编译器的特定领域语言,如 OMeta 或用于解析前端 ANTLR、YACC(优点:与上述相同,但更重要;缺点:与上述相同)
所有这些本质上都是权衡:用相同的语言编写编译器更容易理解,因为您不必学习另一种语言。它还可能使其更难理解,因为该语言实际上并不擅长编写编译器。 (例如,想象一下,用 SQL 编写一个 SQL 编译器。)甚至可能不可能编写一个编译器,例如(对于“语言”和“编译器”的一个相当松散的定义)它是不可能用 CSS 编写 CSS 编译器或用 HTML 编写 HTML 编译器。
另一方面:用专门的编译器编写语言编写编译器可能更容易理解,但同时它需要你学习一门新语言。
请注意,这三个类并不是不相交的:一个编译器可以分为多个类。例如,一个专门编写编译器的语言的编译器,它本身就属于第 1 类(自己编写)和第 3 类(用擅长编写编译器的语言编写)。
在某些情况下,您实际上可以达到最佳状态。例如,F# 是 CLI 上原生速度的原生语言,非常擅长编写编译器。因此,在 F# 中编写 F# 编译器会给您带来 #1(自己编写)、#2(使用原生、快速的语言编写)和 #3(使用适合编写编译器的语言编写)。这同样适用于 Scala。