首选语言:C/ c++、Java、Ruby。

我正在寻找一些关于如何编写自己的编译器的有用书籍/教程,只是为了教育目的。我最熟悉C/ c++、Java和Ruby,所以我更喜欢包含这三者之一的资源,但任何好的资源都是可以接受的。


当前回答

我记得大约七年前问过这个问题,当时我对编程还是个新手。

我问的时候非常小心,令人惊讶的是,我没有像你们在这里受到那么多批评。然而,他们确实给我指出了“龙书”的方向,在我看来,这是一本真正伟大的书,解释了编写编译器所需知道的一切(当然,你必须掌握一两种语言)。你懂的语言越多越好。

是的,很多人说读那本书是疯狂的,你不会从中学到任何东西,但我完全不同意这种说法。

许多人还说编写编译器是愚蠢和毫无意义的。编译器开发之所以有用,原因有很多:

因为它很有趣。 它是有教育意义的,当你学习如何编写编译器时,你会学到很多计算机科学和其他技术,这些技术在编写其他应用程序时很有用。 如果没有人编写编译器,现有的语言就不会变得更好。

我没有立即编写自己的编译器,但在询问之后,我知道从哪里开始。现在,在学习了许多不同的语言和阅读了龙书之后,写作并不是什么大问题。(我也在学习计算机工程,但我对编程的大部分知识都是自学的。)

总之,《龙之书》是一个很棒的“教程”。但是在尝试编写编译器之前,先花些时间掌握一两种语言。不过,不要指望在未来十年左右成为编译器大师。

如果你想学习如何编写解析器/解释器,这本书也是不错的选择。

其他回答

The Dragon Book is too complicated. So ignore it as a starting point. It is good and makes you think a lot once you already have a starting point, but for starters, perhaps you should simply try to write an math/logical expression evaluator using RD, LL or LR parsing techniques with everything (lexing/parsing) written by hand in perhaps C/Java. This is interesting in itself and gives you an idea of the problems involved in a compiler. Then you can jump in to your own DSL using some scripting language (since processing text is usually easier in these) and like someone said, generate code in either the scripting language itself or C. You should probably use flex/bison/antlr etc to do the lexing/parsing if you are going to do it in c/java.

我记得大约七年前问过这个问题,当时我对编程还是个新手。

我问的时候非常小心,令人惊讶的是,我没有像你们在这里受到那么多批评。然而,他们确实给我指出了“龙书”的方向,在我看来,这是一本真正伟大的书,解释了编写编译器所需知道的一切(当然,你必须掌握一两种语言)。你懂的语言越多越好。

是的,很多人说读那本书是疯狂的,你不会从中学到任何东西,但我完全不同意这种说法。

许多人还说编写编译器是愚蠢和毫无意义的。编译器开发之所以有用,原因有很多:

因为它很有趣。 它是有教育意义的,当你学习如何编写编译器时,你会学到很多计算机科学和其他技术,这些技术在编写其他应用程序时很有用。 如果没有人编写编译器,现有的语言就不会变得更好。

我没有立即编写自己的编译器,但在询问之后,我知道从哪里开始。现在,在学习了许多不同的语言和阅读了龙书之后,写作并不是什么大问题。(我也在学习计算机工程,但我对编程的大部分知识都是自学的。)

总之,《龙之书》是一个很棒的“教程”。但是在尝试编写编译器之前,先花些时间掌握一两种语言。不过,不要指望在未来十年左右成为编译器大师。

如果你想学习如何编写解析器/解释器,这本书也是不错的选择。

“…让我们构建一个编译器……”

我认为@sasb是http://compilers.iecc.com/crenshaw/的第二名。暂时忘掉买更多的书吧。

为什么?工具和语言。

所需的语言是Pascal,如果我没记错的话,是基于Turbo-Pascal的。如果你去http://www.freepascal.org/并下载Pascal编译器,所有的例子都可以直接从页面上运行~ http://www.freepascal.org/download.var Free Pascal的好处是,你可以使用它几乎任何你喜欢的处理器或操作系统。

一旦你掌握了课程,然后尝试更高级的“龙书”~ http://en.wikipedia.org/wiki/Dragon_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();
}

你可能想看看Lex/Yacc(或Flex/Bison,随便你怎么称呼它们)。Flex是一个词法分析器,它将解析和识别语言的语义组件(“标记”),而Bison将用于定义解析每个标记时发生的情况。这可以是,但绝对不限于,打印出C代码,供编译器编译成C,或者动态运行指令。

这个常见问题应该对你有帮助,这个教程看起来很有用。