Perl 是编译的还是解释的?
9 回答
你不会得到一个明确的答案,因为你没有提供一个明确的问题。
Perl 总是处于以下两种状态之一:要么正在编译,要么正在执行。这就是为什么你会看到“在编译时”与“在运行时”的讨论。通常,您会得到一个编译短语,然后是一个执行阶段,但不必如此。
这两个阶段也可以来回交易。Aneval STRING
是解释器调用编译器的一种方式(因此也是do FILE
and require
)。块是编译器调用解释器的一种BEGIN
方式(因此也是use
and no
)。
当你运行时perl -c
,你省略了运行时阶段。有多种方法可以跳过编译时阶段,但没有一种是特别方便或常见的。Apachemod_perl
只编译一次脚本,但会执行多次。如果您使用 Byteloader,您也可以这样做。等等。
Perl 是编译还是解释的正确答案是肯定的。
好吧,这取决于您所说的编译语言是什么意思。也许这就是谷歌搜索没有为您的问题带来明确答案的原因。
一种观点认为,编译意味着从一个源代码描述编译到另一个,即代码生成。
如果我们接受这些前提,那么 Perl 6 可以编译,而 Perl 5 和更早的版本是解释型语言。
Perl 6 专门编译为Parrot 字节码。因此 Perl 6 是一种正确编译的语言,就像Java 是.
Perl 5 和更早版本将 Perl 源代码解析为内部列表或树,但我认为它不应该被称为适当的编译器,除非在理论上。它不输出任何通常与编译器相关的字节码、汇编或真实机器码。Perl 用于检查 Perl 语法的解析阶段曾经被称为“编译”源代码。它用于在不运行 Perl 源文件的情况下检查其语法有效性。
它被调用为:
perl -c myprog.pl
但是,如果您查看 Perl 选项的帮助,-c 实际上代表“检查”。
-c check syntax only (runs BEGIN and CHECK blocks)
(更复杂的是,Perl 5 支持写出内部字节码,但它在 5.10 版本中被删除。大概是因为它有问题,我不知道。)
另一方面,如果您认为编译是将源代码树解析为任何其他类型的表示的行为,那么,这种解析使 Perl 成为一种编译语言。Perl 必须完全解析源文件才能开始执行它。根据这个定义,任何可以在解析之前立即开始执行源文件的语言都是解释语言。
第三种看待这一点的方法是从这些词“解释”和“编译”是该领域专业人士最常使用的。我敢打赌,如果在考虑 Perl 时要求程序员的随机子集选择“编译”或“解释”,大多数人会选择“解释”。不是因为关于 Perl 本质的一些理论争论,而是因为“已编译”通常会引发“编译”、“链接”、“目标代码”等思想,而“解释”则意味着“编写代码,尝试一下” ”。对或错,在试图确定 Perl 是真的解释还是编译时,这可能是件好事。你会在你的追求中遇到很多争论。
两个都。Perl5 将源代码编译成 OPCODE 对象,然后解释 OPCODE 对象。长答案如下。
来自维基百科,
编译器是一种计算机程序(或程序集),它将以编程语言(源语言)编写的源代码转换为另一种计算机语言(目标语言,通常具有称为目标代码的二进制形式)。
Perl5 是一个编译器。它采用 Perl5 源代码并生成 OPCODE 对象图。
$ perl -MO=Concise,-exec -E'for (1..3) { say "Hello, World!" }'
1 <0> enter
2 <;> nextstate(main 48 -e:1) v:%,2048
3 <0> pushmark s
4 <$> const(IV 1) s
5 <$> const(IV 3) s
6 <$> gv(*_) s
7 <{> enteriter(next->c last->f redo->8) lKS/8
d <0> iter s
e <|> and(other->8) vK/1
8 <;> nextstate(main 47 -e:1) v:%,2048
9 <0> pushmark s
a <$> const(PV "Hello, World!") s
b <@> say vK
c <0> unstack v
goto d
f <2> leaveloop vK/2
g <@> leave[1 ref] vKP/REFC
-e syntax OK
但是,Perl5 编译器不生成机器代码。那么OPCODE图是如何执行的呢?来自维基百科,解释器的一个定义是
显式执行由编译器生成的存储的预编译代码,该编译器是解释器系统的一部分
这意味着 OPCODE 图被解释。
正在开展工作以提供将 Perl5 编译为 LLVM 字节码的选项。反过来,这可以被 jit 编译成机器代码。这与 Java 使用的方法相同。
Raku (Perl 6) 与 Perl 5 具有兼容模式,因此可以使用 Rakudo 将 Perl 5 编译为 JVM 和 Parrot。我想要 LLVM 来做这个!
Perl 是一种解释型语言。但是,它确实在内部编译成 p 代码以提高效率。
两个都。首先,Perl 6 脚本被编译成字节码(并优化)。然后它被执行(但是,你仍然需要 Perl 解释器)。字节码是一种可执行代码,它独立于它运行的环境(相同的字节码可以在 ARM 处理器的 Unix 环境、x86 的 Windows 系统和 x64 的 Haiku 环境中运行)。
Perl 6 可以编译成 Parrot VM(虚拟机)字节码。Python 和 Ruby 也使用 Parrot VM。
这就是使 Perl、Ruby 和 Python 比 PHP 更快的原因,PHP 只是解释(也可以编译,但你需要 3rd 方组件)。
它是一个虚拟机,也可以在不需要 C 的情况下进行编译。但是它的虚拟机比 Java 快几光年,所以真的没有任何东西可以与之相比。
坏处 - 就像 C++ 推动成为一把万能的瑞士军刀一样可怕。在 Perls 案例中,它移除了训练轮、安全性和边界。例如,在大多数 OOP 语言中,您必须先声明一个类,然后才能使用对象,而在 Perl 中,您可以混合和匹配任何东西,从而将任何东西变成对象或将对象变成任何东西,对类型没有任何限制。如果您已经了解 OOP,那么这个概念会非常混乱,缺乏限制既是强大的,也是 Perl 的一个缺点。因此,语言是否被编译并不是问题,因为你可以在不影响世界的情况下有效地推理某些事情。另一个问题是 Perl 是只写的,所以一旦写完,一切看起来都像胡言乱语,变得难以剖析甚至调试。
最常被解释,但也可能被编译。 关于 perl 编译器