Jör*_*tag
16
这里有几个例子:
- 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编译器是不可能的. HTML或HTML中的HTML编译器.
另一方面:用专门的编译器编写语言编写编译器可能会使它更容易理解,但同时它需要你学习一门新语言.
请注意,这三个类不是不相交的:编译器可以属于多个类.例如,编写一个专门的编译器编写语言的编译器本身就属于类别1(自己编写)和3(用编写编译器的语言编写).
在某些情况下,你实际上能够达到最佳位置.例如,F#是一种在CLI上具有原生速度的本机语言,它非常擅长编写编译器.因此,在F#中编写F#编译器会给你#1(自己编写),#2(用本地快速语言编写)和#3(用编写编译器的语言编写).这同样适用于Scala.