【问题标题】:Programming language and compiler编程语言和编译器
【发布时间】:2009-07-23 18:55:16
【问题描述】:

我正在和我的朋友讨论这个问题,并意识到这可能是问这个问题的最佳地点?

一门新语言是如何诞生的?这种新语言 NEW 必须用一些旧语言 OLD 编写(例如 C++ 在初始阶段是用 C 编写的),或者这是如何创建的? 而且,如果没有编译器,这种语言 NEW 怎么能自己工作呢?那么,必须有一些编译器吗?谁为其编写编译器?

那么,新语言及其编译器、新语言与其旧基础语言的关系如何协同工作?

【问题讨论】:

  • 感谢大家这么快的回复。我想,我需要一门编译器设计课程。但是,我想知道/好奇你们怎么能这么快回复,我的意思是在 1-2 分钟之内,这太神奇了?
  • 我们都在为声望点而死。请为我们点赞! :-)
  • @Norman :我是 SO 新手,对声誉知之甚少。当我有空时,必须检查所有这些。我猜你现在很幸福。 :)

标签: compiler-construction programming-languages


【解决方案1】:

您使用一种实现语言编写编译器,直到编译器可以开始编译足够多的新语言以用于实现新语言的其余部分。

这就是它的工作原理。

编辑:澄清一下,对此答案的评论也是正确的。除非您愿意,否则编译器不必用新语言编写。如前所述,有些人并没有走这条路,而是继续使用原始的实现语言。

【讨论】:

  • 是的,简而言之就是这样。有些人不相信它是一种真正的语言,除非它可以用来编写自己的编译器:)
  • 补充 Scyllinice 的回答:当然,并非所有语言都可以走这条路——很多 LISP 变体都是纯解释器,本身无法创建可执行文件,可以编写 LISP 编译器几乎任何语言。 OLD 和 NEW 语言之间实际上不必有任何真正的联系。
  • 不过,您不一定要迁移出原始实现语言。例如,Tcl 和许多(大多数?)脚本语言在新语言变得成熟和稳定很久之后才使用 C 或 C++ 实现语言。
【解决方案2】:

Bootstrapping 是计算机科学中使用的一个术语,用于描述以要编译的目标编程语言编写编译器(或汇编器)所涉及的技术。这种技术也称为自托管。

【讨论】:

    【解决方案3】:

    您可能想了解编程语言设计和编译器设计:

    http://dragonbook.stanford.edu/
    Bootstrapping (compilers)
    http://en.wikipedia.org/wiki/Programming_language
    http://www.paulgraham.com/langdes.html

    或者,在当地大学学习一门或三门课程。

    【讨论】:

      【解决方案4】:

      任何语言的核心是链接器和编译器,编译器将源代码转换为中介,非常接近机器代码,代码。从这一点开始,链接器用于将其附加到其他二进制文件,如库等。在二进制文件链接到所有逻辑片段后,它们成为机器代码中的可执行文件(或 .NET/Java 中的可翻译中间代码) )。

      “人类”英语的大部分翻译发生在编译器中,并且有很多关于如何完成的文章......但其中大部分是在超自然领域,因为编写所需的组织技能一个工作编译器是巨大的。

      您可以通过查看语言定义(Bjarne Stroustrup 的“The C++ Programming Language”、Microsoft Press 的“The C# Programming Language”)来查看表面级别的各种翻译,并仔细了解编译器的工作原理,其中两个附录并且贯穿始终的是词汇片段或规则,编译器将使用它们以非常合乎逻辑的方式将您的单词翻译成机器代码。

      如果您想了解更多,我强烈建议您阅读您最喜欢的编程语言的语言定义,关于编译器的维基百科文章也会让您有更广泛的了解。

      【讨论】:

      • 我不同意“编写一个工作编译器所需的组织技能是巨大的”的说法。早在我刚毕业几年并且从未上过编译器课程的时候,我就能够使用 lex 和 yacc 创建一种特殊用途的语言。虽然很困难,但远非非常困难。这实际上是相当有益的。
      • @Bryan:这取决于。使用现代编译器生成工具可以相当容易地创建一种小型语言(如许多特定领域的语言),但@Sprague 假设一些更丰富的东西。一旦添加了 Python、Java 或 C# 等主要编程语言所需的所有优化、代码生成等,工作就会变得非常苛刻。然后是虚拟机设计、GC 算法、标准库等辅助任务......
      【解决方案5】:

      好问题!

      • 有时新语言的编译器是用旧语言编写的。

      • 如果新语言N的编译器是用N编写的,有很多策略,所有这些都涉及找到某种方法来运行语言的程序N 当你还没有编译器时。

        1. 为语言 N 编写一个解释器,比如用 C 语言(实际上是您选择的语言),然后使用解释器来解释编译器自己编译。

          • N 编写一个非常可怕的编译器,比如用 C 语言,然后用它来编译第一个版本的编译器。

          • 将编译器的第一个版本编译成汇编代码或 C 代码,通常是手动的。

      我最喜欢的是策略 #1,但它们都有效。

      如果您想深入了解该问题的解决方案,请查看 Andrew Appel 的简短论文 Axiomatic Bootstrapping: A Guide for Compiler Hackers,可从普林斯顿网站免费获得。这篇论文非常数学化,但在相关工作部分,您会找到对旧论文的参考,包括使用 T 图显示自举过程的论文,许多人认为这非常直观。

      【讨论】:

        【解决方案6】:

        一种语言(通常)只是一种规范。一种语言的编译器或解释器可以用您选择的任何语言编写。第一个是机器代码,因为这就是我们所拥有的。然后是汇编程序,然后是 C 等其他语言。从那时起,C(和 C++)一直是实现语言的流行选择。然而,C 和 C++ 是唯一的选择。

        还值得指出的是,一种语言通常可以使用一种(或多种语言)专用语言(例如 yacc 和 lex)来实现。这些是特定于领域的语言,专门设计用于轻松创建基于规范的编译器。这使得手工编码许多可以很容易地由计算机生成的东西不再是苦差事。您获取规范,通过这些工具运行它,然后弹出代码来实现您的语言。 Yacc 代表 Yet Another Compiler-Compiler。它为编译器编译规范并生成编译器。

        其他海报建议,一旦一种语言足够健壮,编译器就可以移植到它自己,但这不是必需的。许多语言是在十年或更久以前用 C 语言编写的,今天仍在继续用 C 语言实现。

        【讨论】:

          猜你喜欢
          • 2010-12-24
          • 1970-01-01
          • 2011-02-21
          • 2011-03-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-09
          相关资源
          最近更新 更多