首选语言:C/ c++、Java、Ruby。
我正在寻找一些关于如何编写自己的编译器的有用书籍/教程,只是为了教育目的。我最熟悉C/ c++、Java和Ruby,所以我更喜欢包含这三者之一的资源,但任何好的资源都是可以接受的。
首选语言:C/ c++、Java、Ruby。
我正在寻找一些关于如何编写自己的编译器的有用书籍/教程,只是为了教育目的。我最熟悉C/ c++、Java和Ruby,所以我更喜欢包含这三者之一的资源,但任何好的资源都是可以接受的。
当前回答
如果你没有时间,我推荐Niklaus Wirth的“编译器构造”(Addison-Wesley)。1996年),一本你一天就能读完的小册子,但它解释了基础知识(包括如何实现词法分析器、递归下降解析器和你自己的基于堆栈的虚拟机)。在那之后,如果你想深入了解,就像其他评论者建议的那样,没有办法绕过龙的书。
其他回答
I think Modern Compiler Implementation in ML is the best introductory compiler writing text. There's a Java version and a C version too, either of which might be more accessible given your languages background. The book packs a lot of useful basic material (scanning and parsing, semantic analysis, activation records, instruction selection, RISC and x86 native code generation) and various "advanced" topics (compiling OO and functional languages, polymorphism, garbage collection, optimization and single static assignment form) into relatively little space (~500 pages).
我更喜欢《现代编译器实现》而不是《Dragon》,因为《现代编译器实现》对该领域的调查较少——相反,它确实涵盖了编写一个严肃、体面的编译器所需的所有主题。在你读完这本书之后,如果你需要的话,你就可以直接深入研究论文了。
I must confess I have a serious soft spot for Niklaus Wirth's Compiler Construction. It is available online as a PDF. I find Wirth's programming aesthetic simply beautiful, however some people find his style too minimal (for example Wirth favors recursive descent parsers, but most CS courses focus on parser generator tools; Wirth's language designs are fairly conservative.) Compiler Construction is a very succinct distillation of Wirth's basic ideas, so whether you like his style or not or not, I highly recommend reading this book.
您可以使用Apache软件基金会的BCEL。使用这个工具,您可以生成类似汇编程序的代码,但它是带有BCEL API的Java。您可以学习如何生成中间语言代码(在本例中是字节代码)。
简单的例子
用这个函数创建一个Java类: maxAsString(int a, int b) { If (a > b) { 返回Integer.valueOf(一).toString (); } if (a < b) { 返回Integer.valueOf (b) .toString (); }其他{ 返回“=”; } }
现在用这个类运行BCELifier
BCELifier bcelifier = new BCELifier("MyClass", System.out);
bcelifier.start();
您可以在控制台上看到整个类的结果(如何构建字节代码MyClass.java)。该函数的代码如下:
private void createMethod_1() {
InstructionList il = new InstructionList();
MethodGen method = new MethodGen(ACC_PUBLIC, Type.STRING, new Type[] { Type.INT, Type.INT }, new String[] { "arg0", "arg1" }, "maxAsString", "MyClass", il, _cp);
il.append(InstructionFactory.createLoad(Type.INT, 1)); // Load first parameter to address 1
il.append(InstructionFactory.createLoad(Type.INT, 2)); // Load second parameter to adress 2
BranchInstruction if_icmple_2 = InstructionFactory.createBranchInstruction(Constants.IF_ICMPLE, null); // Do if condition (compare a > b)
il.append(if_icmple_2);
il.append(InstructionFactory.createLoad(Type.INT, 1)); // Load value from address 1 into the stack
il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
il.append(_factory.createInvoke("java.lang.Integer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
il.append(InstructionFactory.createReturn(Type.OBJECT));
InstructionHandle ih_13 = il.append(InstructionFactory.createLoad(Type.INT, 1));
il.append(InstructionFactory.createLoad(Type.INT, 2));
BranchInstruction if_icmpge_15 = InstructionFactory.createBranchInstruction(Constants.IF_ICMPGE, null); // Do if condition (compare a < b)
il.append(if_icmpge_15);
il.append(InstructionFactory.createLoad(Type.INT, 2));
il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
il.append(_factory.createInvoke("java.lang.Integer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
il.append(InstructionFactory.createReturn(Type.OBJECT));
InstructionHandle ih_26 = il.append(new PUSH(_cp, "equals")); // Return "equals" string
il.append(InstructionFactory.createReturn(Type.OBJECT));
if_icmple_2.setTarget(ih_13);
if_icmpge_15.setTarget(ih_26);
method.setMaxStack();
method.setMaxLocals();
_cg.addMethod(method.getMethod());
il.dispose();
}
来自comp.compiler常见问题解答:
《个人电脑编程》作者:Per Brinch Hansen Prentice-Hall 1982 ISBN 0-13-730283-5
这本书名很不幸的书 解释单用户编程环境的设计和创建 用于微电脑,使用一种类似pascal的语言,叫做Edison。作者介绍 一个的逐步实现的所有源代码和解释 爱迪生编译器和简单的支持操作系统,全部写在 爱迪生本身(除了一个小的支持内核写在符号 PDP 11/23汇编程序;完整的源代码也可以为IBM订购 个人电脑)。
这本书最有趣的地方是:1)它的能力 演示如何创建一个完整的,独立的,自我维护的, 有用的编译器和操作系统,以及2)有趣的讨论 语言设计和规范的问题和权衡。
“Brinch Hansen on Pascal Compilers” by Per Brinch Hansen 普伦蒂斯-霍尔 1985 ISBN 0-13-083098-4
Another light-on-theory heavy-on-pragmatics here's-how-to-code-it book. The author presents the design, implementation, and complete source code for a compiler and p-code interpreter for Pascal- (Pascal "minus"), a Pascal subset with boolean and integer types (but no characters, reals, subranged or enumerated types), constant and variable definitions and array and record types (but no packed, variant, set, pointer, nameless, renamed, or file types), expressions, assignment statements, nested procedure definitions with value and variable parameters, if statements, while statements, and begin-end blocks (but no function definitions, procedural parameters, goto statements and labels, case statements, repeat statements, for statements, and with statements).
编译器和解释器都是用Pascal* (Pascal " * ")编写的 Pascal子集扩展了一些爱迪生风格的创建功能 软件开发系统。用于IBM个人电脑的Pascal编译器由 但是很容易将这本书的Pascal编译器移植到任何作者 方便的Pascal平台。
本书使编译器的设计和实现看起来很简单。我 尤其是作者对质量的关注, 可靠性和测试。编译器和解释器可以很容易地使用 作为一个更复杂的语言或编译器项目的基础,特别是 如果你被要求快速启动并运行一些东西。
如果你像我一样,没有受过正规的计算机科学教育,并且对 构建/想知道编译器是如何工作的:
我推荐“Java编程语言处理器:编译器和解释器”, 对于自学成才的计算机程序员来说,这是一本令人惊叹的书。
在我看来,理解那些基本的语言理论、自动化机器和集合理论并不是什么大问题。问题是如何把这些东西转换成代码。上面的书告诉您如何编写解析器、分析上下文和生成代码。如果你不能理解这本书,那么我不得不说,放弃构建编译器吧。这本书是我读过的最好的编程书。
还有一本书,也很好,《c语言编译器设计》,里面有很多代码,告诉你如何构建编译器和词法分析器工具。
构建编译器是一种有趣的编程实践,可以教会您许多编程技能。
不要买龙的书。这是浪费金钱和时间,不适合从业者。
你可能想看看Lex/Yacc(或Flex/Bison,随便你怎么称呼它们)。Flex是一个词法分析器,它将解析和识别语言的语义组件(“标记”),而Bison将用于定义解析每个标记时发生的情况。这可以是,但绝对不限于,打印出C代码,供编译器编译成C,或者动态运行指令。
这个常见问题应该对你有帮助,这个教程看起来很有用。