tch*_*ist 56

你不会得到明确的答案,因为你没有提出明确的问题.

Perl总是处于以下两种状态之一:它要么正在编译,要么正在执行.这就是为什么你看到"在编译时"和"在运行时"的谈话.通常,您会得到一个编译短语,后跟一个执行阶段,但不一定是这样.

这两个阶段也可以来回交易.一个eval STRING是解释调用编译器(因此也因此是一种方法do FILErequire).阿BEGIN块是一个用于编译器调用解释器(因此也因此是一种方法useno).

运行时perl -c,省略运行时阶段.有多种方法可以跳过编译时阶段,但没有一种方法特别方便或常见.Apache mod_perl只编译一次脚本,但多次执行它们.如果您使用Byteloader,您也可以这样做.等等.

是否编译或解释Perl的正确答案是YES.

  • 你得到我的+1! (2认同)

Pro*_*ica 23

那么,这取决于编译语言的含义.也许这就是为什么谷歌搜索没有给你的问题一个明确的答案.

一种观点是编译意味着从源代码描述到另一代码编译,即代码生成.

如果我们接受这些前提,则可以编译Perl 6,Perl 5及更早版本是解释语言.

Perl 6专门编译为Parrot字节码.因此,Perl 6是一种正确编译的语言,就像Java一样.

Perl 5和更早版本将Perl源代码解析为内部列表或树,但我不认为它应该被称为适当的编译器,除非在理论意义上.它不输出通常与编译器相关的任何字节码,汇编或真实机器代码.用于检查Perl语法的Perl的解析阶段曾被称为"编译"源.它用于检查Perl源文件的语法有效性而不运行它.

它被调用为:

perl -c myprog.pl
Run Code Online (Sandbox Code Playgroud)

但是如果你看看Perl选项的帮助,-c实际上代表"检查".

-c                check syntax only (runs BEGIN and CHECK blocks)
Run Code Online (Sandbox Code Playgroud)

(为了进一步复杂化,Perl 5支持写出内部字节码,但在版本5.10删除了.大概是因为它有错误,我不知道.)

另一方面,如果您认为编译是将源树解析为任何其他类型的表示的行为,那么解析使Perl成为编译语言.Perl必须完全解析源文件才能开始执行它.通过这个定义,任何可以在解析之前立即开始执行源文件的语言都是解释语言.

第三种看待这个问题的方法是这些"解释"和"编译"这些词最常用于该领域的专业人士.我敢打赌,如果在考虑Perl时,如果一个随机的程序员子集被要求选择"编译"或"解释",那么大多数人会选择"解释".不是因为在Perl的性质一些理论上的说法,但由于"编译"通常调用"编译","链接","目标代码"等,而"释"被认为是指"写代码的思想,试试吧".对或错,在尝试确定Perl是真实的,解释的还是实际上编译的时候,可能会有所了解.你将在你的任务中遇到很多争论.

  • 这不是很准确.如果没有编译Perl,那么解析树会从哪里出来?如果没有解析器,你就无法得到一个解析树 - 这就是所有编译的.也许如果问题谈到了本机机器语言的代码生成,那么你的答案会更合适.但事实并非如此,因为代码生成与编译完全不同. (10认同)
  • @tchrist,OTOH,然后几乎所有语言都被编译,因为几乎所有语言都有解析器. (5认同)
  • @tchrist不,解析使语法树不编译.如果你是dsiagree,那么你必须相信不存在任何解释的Lisp,因为Lisps会读取诸如`(let((ab))c)`之类的内容并将其转换为内存中的树.但是,通过遍历树运行该语句与生成代码之间存在差异. (4认同)
  • 关于“*Perl (5) 似乎是一种以某种方式难以达成共识的语言。*”,Perl“显式执行由编译器生成的存储预编译代码,编译器是解释器系统的一部分”。这是解释器的定义,所以 Perl 是一个包含编译器的解释器。缺乏共识源于人们错误地认为它必须是其中之一。 (3认同)
  • 回复“*一个观点是编译意味着从源代码描述编译到另一个源代码描述,即代码生成。如果我们接受这些前提,那么 Perl 6 可以编译,而 Perl 5 及更早版本是解释语言*”,是吗?根据该定义,Perl 5 已编译。它生成由高级操作码组成的汇编程序。/// Re“*它不会输出任何通常与编译器相关的字节码、汇编或真实机器代码*”,它会输出;它只是不费心将其写入磁盘。有一个工具可以做到这一点,但没有得到维护。所以根据你的两个定义,Perl5 已编译 (2认同)

ike*_*ami 11

两个,真的.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
Run Code Online (Sandbox Code Playgroud)

但是,Perl5编译器不会生成机器代码.那么OPCODE图是如何执行的呢?从维基百科,解释器的一个定义就是这样

显式执行由编译器生成的存储的预编译代码,该编译器是解释器系统的一部分

这意味着解释了OPCODE图.

正在努力提供将Perl5编译为LLVM字节码的选项.反过来,这可以被jit编译成机器代码.这与Java使用的方法相同.

  • @tchrist,我不希望专业人士根据他们的解释或编译来讨论语言. (3认同)