Perl是编译还是解释?
答案 0 :(得分:56)
你不会得到明确的答案,因为你没有提出明确的问题。
Perl始终处于以下两种状态之一:它正在编译,或者正在执行。这就是为什么你看到“在编译时”和“在运行时”的谈话。通常,您会得到一个编译短语,后跟一个执行阶段,但不一定是这样。
这两个阶段也可以来回交易。 eval STRING
是解释器调用编译器的一种方式(因此do FILE
和require
也是如此。 BEGIN
块是编译器调用解释器的一种方式(因此use
和no
也是如此。
运行perl -c
时,省略运行时阶段。有多种方法可以跳过编译时阶段,但没有一种方法特别方便或常见。 Apache的mod_perl
只编译一次脚本,但多次执行它们。如果您使用Byteloader,您也可以这样做。等等。
编译或解释Perl的正确答案只是 YES。
答案 1 :(得分:22)
那么,这取决于编译语言的含义。也许这就是为什么谷歌搜索没有给出你的问题的明确答案。
一种观点认为,编译意味着从源代码描述编译到另一个,即code generation。
如果我们接受这些前提,那么可以编译Perl 6,Perl 5及更早版本是解释语言。
Perl 6专门编译为Parrot bytecode。因此Perl 6是一种正确编译的语言,就像Java is一样。
Perl 5和更早版本将Perl源代码解析为内部列表或树,但我不认为它应该被称为正确的编译器,除非在理论意义上。它不输出通常与编译器相关的任何字节码,汇编或真实机器代码。用于检查Perl语法的Perl的解析阶段曾被称为“编译”源。它用于检查Perl源文件的语法有效性,而无需运行它。
它被调用为:
perl -c myprog.pl
但是如果你看看Perl选项的帮助,-c实际上代表“检查”。
-c check syntax only (runs BEGIN and CHECK blocks)
(为了进一步复杂化,Perl 5支持写出内部字节码,但它是removed in version 5.10。大概是因为它是错误的,我不知道。)
另一方面,如果您认为编译是将源树解析为任何其他类型的表示的行为,那么解析使Perl成为编译语言。 Perl必须完全解析源文件才能开始执行它。通过这个定义,任何可以在解析之前立即开始执行源文件的语言都是解释语言。
第三种方式来看看这个词,“解释”和“编译”这些词最常用于该领域的专业人士。我敢打赌,如果在考虑Perl时,如果一个随机的程序员子集被要求选择“编译”或“解释”,那么大多数人会选择“解释”。不是因为对Perl本质的一些理论论证,而是因为“编译”通常会调用“编译”,“链接”,“目标代码”等的思想,而“解释”则意味着“编写代码,试一试” ”。对或错,在尝试确定Perl是否,真正,解释或实际上是编译时,可能会有所了解。你将在你的任务中遇到很多争论。
答案 2 :(得分:11)
两者,真的。 Perl5将源代码编译成OPCODE对象,然后解释OPCODE对象。接下来是答案。
来自维基百科,
编译器是一种计算机程序(或程序集),它将用编程语言(源语言)编写的源代码转换为另一种计算机语言(目标语言,通常具有称为目标代码的二进制形式)。 / p>
根据该定义,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使用的方法相同。
答案 3 :(得分:0)
Perl是一种解释性语言。但是,它会在内部编译成p代码以提高效率。
答案 4 :(得分:0)
答案 5 :(得分:0)
Raku(Perl 6)具有与Perl 5的兼容模式,因此可以使用Rakudo将Perl 5编译为JVM和Parrot。我要为此使用LLVM!
答案 6 :(得分:-1)
两者。首先,将Perl 6脚本编译为字节码(并进行优化)。然后它被执行(但是,你仍然需要Perl解释器)。 字节码是一种可执行代码,它独立于其运行的环境(相同的字节码可以在ARM处理器上的Unix环境中运行,Windows系统使用x86和Haiku在x64上运行)。
Perl 6可以编译为Parrot VM(虚拟机)字节码。 Parrot VM也被Python和Ruby使用。
这使得Perl,Ruby和Python比PHP更快,这只是被解释的(也可以编译,但你需要第三方组件)。
答案 7 :(得分:-1)
这是一个无需使用C也可以进行编译的VM。但是,它的VM比Java快几年,因此实际上没有什么可以比拟的。
不好的-它以C ++一样的方式令人难以置信地成为所有瑞士军刀。在Perls的情况下,它会除去训练轮,安全装置和边界。例如,在大多数OOP语言中,必须先声明一个类,然后才能使用对象。在Perl中,对可以混合和匹配任何内容的类型没有任何限制,从而可以将任何内容转换为对象或将对象转换为任何内容。如果您已经了解OOP,那么这个概念就很混乱,在Perl中缺少限制既强大又不利。因此,不管语言是否经过编译,都不是问题,您可以在不影响世界的前提下有效地推理出某些东西。另一个问题是,Perl仅是写的,因此一旦写完,一切看起来就像乱七八糟的东西,变得难以剖析甚至调试。
答案 8 :(得分:-2)
最常被解释但也可能被编译。 about perl compiler