我已经阅读了整个龙书最近(只是为了好玩,我真的不在计划实施的一个实际compiler),和我留下了这个大问题悬挂在我的头上。

是什么之间的不同实施一个编译和口译?

给我一个编译器是由:

  • 语法分析程序
  • 分析器(其中建立的法树)
  • 产生的中间代码(如3个地址的编码)
  • 做所有这些疯狂的事情以优化如果你想要:-)
  • 产生"组件"或"本机代码"从3个地址的编码。

现在,很明显,解释程序也具有同样的语法分析程序和分析器作为编译器。
但它是做什么之后呢?

  • 它不会"读"的法树并执行它直接?(种喜欢有一个指指针指向目前的树中的节点,而执行是一棵大树穿越加存储管理的呼叫stack)(如果有,它是如何这样做?我希望执行是更好的比一个巨大的开声明,检查是什么类型的节点)

  • 它不会产生3址码和解释呢?(如果有,它是如何这样做?再次,我在找一些更优雅的超过一英里长关的声明)

  • 它不会产生真正的司机代码,它加载到存储器,并使其运行?(在这一点上,我猜这是不翻译了,但更像是一个JIT compiler)

此外,在这一点并概念的"虚拟机"切?你怎么使用一个虚拟的机在一语言?(将清楚我的无知,我的虚拟机VMWare,我没有想法的概念如何VM适用于编程语言/执行程序)。

正如你可以看到,我的问题是相当宽泛的。我主要是找不仅使用哪种方法,但大多是首先了解的大概念,然后得到它是如何工作的详细说明。我想要丑陋的、原始的细节。显然,这更是一个寻求引用的东西读,而不是在等你回答所有这些信息在这里。

谢谢!
丹尼尔


编辑:谢谢你的答案为止。我意识到我的标题是误导性的。我理解的"功能"差异之间的一个编译和口译员。
我在寻找什么区别如何你 实施 一名翻译,与一个编译器。
我现在理解了如何以一个编译器是实现,问题是如何翻译的不同之处。

例如:维生素b6显然是两个编译和口译员。我现在明白了编译器的一部分。然而,我不能掌握如何、何时运行的内部IDE,它可能让我阻止该程序在任何任意一点,改变编码,并恢复执行的新的编码。这只是一个小小的例子,这不是回答我在寻找。我想要明白,因为我解释一下,会发生什么之后我有一个分析树。一个编译器将产生新的代码中的"目标"的语言。什么一个解释?

谢谢你的帮助!

有帮助吗?

解决方案

简短的回答:

  • 一个编译器将源代码成为可执行的格式,用于以后执行
  • 口译员估算的源代码,用于立即执行

有一个很大的回旋余地,在如何正在实施。它是可能的口译员产生本机代码然后执行,虽然一个编译器虚拟机可能产生的p-代码,而不是机器码。螺纹理解的语言,如提出查找关键词在字典和执行它们的相关机代码的功能。

编译器一般可以优化更好,因为他们有更多的时间来研究码和产生的文件对于后来的执行;口译员有时间减少到最优化,因为他们往往执行代码"是"在一见钟情

一名翻译,优化的背景下,学习更好的方法来执行代码也是可能的

摘要:的差别归结为'准备的代码,用于以后执行'或'执行代码现在

其他提示

编译是一个程序,意味着一个程序在一种编程语言编写的程序在另一种编程语言。这就是它-简单明了的。

一解释意味着一种编程语言纳入其语的含义。

X86的芯片是一个解释为x86机语言。

Javac是一个编译器java java虚拟机。java、可执行的申请,是一个翻译jvm。

一些口译人员分享的一些要素的汇编,他们可以翻译成一种语文到另一种内部的语言,是容易解释。

口译人员通常,但并不总是能读eval印循环。

一个 程序 是描述工作你想做的。

一个 编译器 转换为一个高级别描述成一个更简单的描述。

一个 口译员 读说明该怎么做 不会的工作.

  • 一些口译员(例如Unix弹)阅读的说明的一小块的时间和行为上的每一块,因为他们看到它;一些(例如Perl,Python)阅读整个描述中,在内部将其转换为一个较简单的形式然后采取行动。
  • 一些口译员(例如Java的JVM,或者一个奔腾芯片4)只了解一个非常简单的语言描述,太繁琐的对人类的工作直接,所以人类使用的编译器转换成他们的高级说明,以这种语言。

编译器 从来没有 做的工作。口译员 总是 做的工作。

这两个有许多共同之处(例如词汇parser)有不同意见上的差异。我看看是这样的:

经典的定义 将编译器分析和翻译的符号流入流的字节,可以由CPU运行,而口译员做同样的事情,但将它们转换一种形式,必须执行的一个软件(例如JVM,CLR)。

但人们叫'javac'一个编译器,所以 非正式定义 一个编译器是什么,必须做到源代码作为一个单独的步骤,而口译员没有'建立'的步骤(例如PHP,Perl).

这不是明确的,因为它用来进行。它使用的是建立一个分析树,结合,并执行它(往往结合在最后一秒)。

基本是这样做的方式。

你可以要求这东西跑码(java/.净)没有做JIT是interpriters-但不是传统意义上的因为你还有为'汇编'到码。

老同学差别是:如果它所产生的CPU码它是一个编译器。如果你碰它直接在你的编辑的环境,并可以与它进行交互编辑时,这是一个interpriter.

这是远远不那么正式的比实际龙的书-但是我希望它的信息。

如果我的经验表明任何东西;

  1. 口译员的不要尝试以减少/处理AST此外,每个时间代码块所引用的、相关的AST节点走过和执行。编译器横框在最多次产生可执行代码在一定的地方,并用它来完成。
  2. 口译员符号表保持价值和引用,同时执行,汇编人员的符号表保留地点的变量。有没有这样的事情符号表,同时执行。

在拍摄的差别可能是作为简单的

case '+':
    symtbl[var3] = symtbl[var1] + symtbl[var2];
    break;

之间,

case '+':
    printf("%s = %s + %s;",symtbl[var3],symtbl[var1],symtbl[var2]);
    break;

(不论你的目标的另一种语言或(虚拟的)机的说明。)

关于这一部分的问题,这对其他的答案没有真正解决:

此外,在这一点上没有概念 "虚拟机"切?什么做 你使用一个虚拟的机中的一个 语言?

虚拟机JVM或CLR是一个抽象层,让你重复使用JIT编译器化,垃圾收集等实施细节完全不同的语言编制的运行上的虚拟机。

他们还帮助你做的语言规范更加独立,从实际的硬件。例如,虽然C码在理论上是便携式的,你不断地需要担心的东西喜欢字节序、类型大小和变量的取向如果你真的要生产的携带的代码。而Java,JVM是非常清楚地规定在这些方面,因此语言的设计师及其用户不必担心他们;它的工作JVM实施者实施所指定的行为实际的硬件。

一次一分析的树可用,有几个战略:

1)直接解释AST(红宝石、其原来的解释) 2)代码转化->入字节的代码或机器码

实现编辑并继续,该程序计数或指令的指令已经被重新计算和移动。这要求合作,从IDE,因为代码可能已经插入之前或之后的黄色小箭头。

一个办法可以这样做是嵌入位置的程序计数的分析树。例如,可能有一种特殊的声明,称为"突破"。该计划反只需要定位之后的"突破"的指令,以继续运行。

此外,你必须决定什么你想要做的关于当前叠框架(和变量的stack)。也许是弹出现叠和复制的变量,或保持堆,但在GOTO和返回到目前的编码。

给你名单的步骤:

  • 语法分析程序
  • 分析器(其中建立的法树)
  • 产生的中间代码(如3个地址的编码)
  • 做所有这些疯狂的事情以优化如果你想要:-)
  • 产生"组件"或"本机代码"从3个地址的编码。

一个非常简单的解释(如早期的基础知识或TCL)只会执行步骤一和步骤二一行的时间。然后扔掉大多数结果同时进行到下一个线以执行。其他3个步骤决不会被执行。

如果你在找一本书, 结构和解释计算机程序 ("向导书")是一个良好的开端与解释的概念。你只是没有处理方案的代码,可穿越,进行评估,并通过如果它是一个AST.

此外, 彼得Norvig 有一个简短的例子来说明的主要思想使用Python(与许多例子中的评论意见),在这里是另一个 小例子 在维基百科上。

就像你说的,这是一个树历,并至少对话的价值,它是一个简单的一种:每当你看到一个经营者,评估的操作数的拳头,然后应用操作人员。最终返回值结果的程序(或声明给予REPL).

注意,你不总是做的树穿越明确:你可能会产生你AST在这样一种方式,接受访问者(我认为SableCC这不会),或者用于非常小的语言,如小小的运算法用于证明析发电机,你就可以评估的结果在分析。

为了支持声明和任务分配,则需要保持周围的环境.只是为你会评估",加上"通过添加的操作数,你会评估的姓名的一个功能,可变的,等等, 通过寻找它在环境。支助范围意味着处理环境就像一堆和推动和出现的事情在适当的时间。在一般情况下,如何复杂的解释是取决于哪种语言功能,你是故意的支持。例如,口译员使垃圾收集和反省可能的。

Vm:底座和j_random_hacker描述的计算机硬件作为一种解释。反过来也是如此--译员是机器;他们的指示发生在较高级别的比那些一个真正的ISA。VM-风格的口译员,该程序实际上类似于机器码,尽管对于一个非常简单的机。 Java码 只使用一些"寄存器"之一,它拥有一个程序计数器。这样一个虚拟机译员更像是硬件模拟器于口译员的例子,我相联系上。

但需要注意的是,速度原因,默认Oracle JVM作品翻译运行的Java码指令转x86指令("及时汇编").

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top