C(或 ML)在创建编译器中的作用是什么?
我相信主要任务是解析数据并创建与其对应的汇编语言指令集(两种逻辑)。 除此以外,这些编译器是否还使用任何其他固有的 C 功能? 我的意思是我可以编写一个程序,可以使用 X 语言将我的程序变成类似 C 的程序,然后使用 gcc 进行编译 - 一切也都发生在后端 - 但这种方法是否明智? 我的问题的图形表示是:
Language X - Compiler made in C using C's string Handling and parsing features to create ASM - RUn on Machine 特点: 使用C的基本机制来生成汇编代码而已——最终使用它自己的汇编逻辑。
X 语言 - 用 C 编写的编译器再次将其重新编码为类似 C 的语法 - 将其提供给像编译器一样的 GCC - ASM - 机器代码
特征 : 愚蠢的系统,因为它最终使用了 C 的设施
I believe the main task is to parse data and create a assembly language instruction set corresponding to it ( both logics ) .
Do these compilers use any other inherent C features other than this ?
I mean I can write a program that can take my program in language X and make it a C like program and then compile using gcc - everything happening in the backend too - but is that approach sensible ?
A graphical representation of my question is :
Language X - Compiler made in C using C's string handling and parsing features to create ASM - RUn on Machine
Features : Using C's basic mechanism to generate assembly code nothing more - uses its own assembly logic in the end .
Language X - Compiler made in C again recodes it to C like syntax - Provides it to GCC like compiler - ASM - Machine code
Features :
Dumb system as it uses C's facilities in the end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您非常错误地认为编译器的两个主要任务是“编写解析器”和“将输出写入汇编器”。最有趣的发生在中间,验证阶段(类型检查)、分析阶段(用于进一步优化的各种信息收集)和转换阶段(从高级语言到不太高级的语言,直到在某个阶段完成某件事之后)看起来像装配)。
即使你设计了一个简单的编译器(不需要第一次与GCC竞争),解析器也不应该是“主要任务”。实际上,解析器如今被认为是一个相当常规的问题,至少如果您的语法相当传统的话(我不是在谈论疯狂的语法可扩展性问题);有一些解析器生成器工作得相对较好,您也可以使用手工制作的解析器来获得更大的灵活性,但总而言之,这绝对不应该成为问题。
编写一个输出 C 或任何其他语言的编译器是完全明智的。许多不同的编译器(例如Haskell 和各种Scheme)都使用C 作为目标语言。但通常(对于有趣语言来说),前期需要做很多工作,将编程语言的抽象编译成可以翻译为 C 的更底层的东西。
现在还有其他方法将自己从低级汇编部分中抽象出来:您可以针对虚拟机(JVM、CLR、Erlang 的 VM、Parrot...),或生成 LLVM 字节码等。
您在问题中提到了 ML。使用代数数据类型(即 SML、OCaml、Haskell 等)的静态类型函数语言是编写编译器的非常好的语言;我认为是最适合的。您可能对ML 中的现代编译器实现这本书感兴趣(有C 和 Java 的变体,但 ML 书是最好的一本)。它在某些地方有点专业,但对于对编译技术有一个良好的整体了解可能是一个不错的选择。当然,如果您想成为编译大师,您还应该使用其他参考资料,例如 Dragon Book,以及可能的与您类似的语言编译的参考资料(我的意思是编译纯函数式语言可能与编译命令式过程语言有很大不同) )。
You are hugely mistaken that the two main tasks of a compiler are "writing a parser" and "writing the output to the assembler". Most interesting happen in the middle, verification passes (type checking), analysis passes (various information collection for further optimizations) and transformation passes (from a high-level to a less high-level language, until after some stage you get done to something looking like assembly).
Even if you design a simple compiler (you don't need to compete with GCC the first time), parsers should not be the "main task". Actually parsers are nowadays considered a fairly routine problem, at least if your syntax is rather conventional (I'm not talking about crazy syntax-extensibility things); there are parser generators which work relatively well, and you may also use hand-crafted parsers for more flexibility, but all in all it definitely shouldn't be the problem.
It is perfectly sensible to write a compiler outputting C, or any other language. Lots of different compilers (for example Haskell and various Scheme) have used C as their target language. But usually (for interesting languages anyway) there is a lot of work upfront, to compile the abstractions of the programming language into something more low-level that can be translated to C.
Nowadays there are also other ways to abstract yourself from the low-level assembly part: you may target a virtual machine (JVM, CLR, Erlang's VM, Parrot...), or produce LLVM bytecode, etc.
You mentioned ML in your question. Statically typed functional languages using algebraic datatypes (that is SML, OCaml, Haskell, etc.) are very good languages to write a compiler in; the best suited ones, I would claim. You may be interested in the book Modern Compiler Implementation in ML (there are variants for C and Java, but the ML book is the best one). It's a bit specialized in some places, but it's a probably a good choice to have a good overall view of the compilation techniques. Of course if you want to become a compilation guru you should also use other references such as the Dragon Book, and possibly references for compilation of languages similar to your (I mean compiling a purely functional language can be very different from compiling an imperative procedural language).
每个编译器都是不同的
编译器编写者可以(并且已经!)完成您能想到的任何事情。旧的“翻译器”f2c 实际上是一个针对 c 的 Fortran 编译器(即在 c 中生成输出)。
这没有什么问题,尽管它会使编译过程变慢(毕竟有一个额外的 lex 和 parse 阶段)。
另一点,对于认真的编译器来说,操作抽象语法树来优化输出需要花费大部分代码和大部分时间。 Crenshaw 教程 中完成的立即代码生成与全功能编译器之间存在巨大差异。
Each compiler is different
Compiler writers can (and have!) done just about anything you can think of. The old "translator" f2c was in fact a Fortran compiler that targeted (i.e. produced output in) c.
There is nothing wrong with that, though it can make the compilation process slower (there is an extra lex and parse stage, after all).
Another point, for serious compilers it is the manipulation of the abstract syntax tree to optimize the output that takes most of the code and most of the time. There is a huge difference between the kind of immediate code generation done in the Crenshaw tutorial and a full featured compiler.