首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解析树和字节码是一回事吗?

解析树和字节码是一回事吗?
EN

Stack Overflow用户
提问于 2012-05-02 23:21:31
回答 2查看 664关注 0票数 8

字节码和解析树,特别是Perl使用的解析树到底有什么区别?它们实际上是指同一个概念,还是有区别呢?

我熟悉来自Python和Java的字节码的概念,但在阅读有关Perl的文章时,我了解到它应该在其解释器中执行解析树(而不是字节码)。

如果真的有区别,那么Perl不使用字节码(或Python不使用解析树)的原因是什么?这主要是历史上的,还是语言之间的差异需要不同的编译/执行模型?是否可以使用字节码解释器来实现Perl (具有合理的工作量和执行性能)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-02 23:35:43

Perl使用的不是parse tree,至少不是维基百科对它的定义。这是一个操作码树。

代码语言:javascript
复制
>perl -MO=Concise -E"for (1..10) { say $i }"
g  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 49 -e:1) v:%,{,2048 ->3
f     <2> leaveloop vK/2 ->g
7        <{> enteriter(next->c last->f redo->8) lKS/8 ->d
-           <0> ex-pushmark s ->3
-           <1> ex-list lK ->6
3              <0> pushmark s ->4
4              <$> const[IV 1] s ->5
5              <$> const[IV 10] s ->6
6           <#> gv[*_] s ->7
-        <1> null vK/1 ->f
e           <|> and(other->8) vK/1 ->f
d              <0> iter s ->e
-              <@> lineseq vK ->-
8                 <;> nextstate(main 47 -e:1) v:%,2048 ->9
b                 <@> say vK ->c
9                    <0> pushmark s ->a
-                    <1> ex-rv2sv sK/1 ->b
a                       <#> gvsv[*i] s ->b
c                 <0> unstack v ->d
-e syntax OK

除了,尽管它被称为树,但它并不是真正的树。注意到箭头了吗?这是因为它实际上是一个操作码的列表图形(就像任何其他可执行文件一样)。

代码语言:javascript
复制
>perl -MO=Concise,-exec -E"for (1..10) { say $i }"
1  <0> enter
2  <;> nextstate(main 49 -e:1) v:%,{,2048
3  <0> pushmark s
4  <$> const[IV 1] s
5  <$> const[IV 10] 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      <#> gvsv[*i] s
b      <@> say vK
c      <0> unstack v
           goto d
f  <2> leaveloop vK/2
g  <@> leave[1 ref] vKP/REFC
-e syntax OK

Perl操作码和Java字节码的不同之处在于,Java字节码被设计为可序列化(存储在文件中)。

票数 9
EN

Stack Overflow用户

发布于 2012-05-02 23:25:25

解析树是程序的标记,存储在显示其嵌套的结构中(哪些参数属于哪些函数调用,哪些语句在哪些循环中,等等)。字节码是转换成二进制表示法的程序代码,以便在虚拟机中更快地执行。例如,如果您使用一种假想的语言编写以下代码:

代码语言:javascript
复制
loop i from 1 to 10 {
    print i
}

解析树可能如下所示:

代码语言:javascript
复制
loop
    variable
        i
    integer
        1
    integer
        10
    block
        print
            variable
                i

同时,为面向堆栈的虚拟机编译的原始和符号形式的字节码可能如下所示:

代码语言:javascript
复制
0x01 0x01    PUSH 1
             START:
0x02         DUP
0x03         PRINT
0x05         INCREMENT
0x02         DUP
0x01 0x0a    PUSH 10
0x04         LESSTHAN
0x06 0xf9    JUMPCOND START

在编译程序时,您首先需要解析源代码(通常生成一个解析树),然后将其转换为字节码。跳过第二步,直接从解析树执行会更容易。此外,如果语言语法非常复杂(例如,它允许修改代码),那么生成字节码就会变得更加复杂。如果有一个eval类型的函数来执行任何代码,那么整个编译器必须与应用程序一起分发,以便为这些代码使用虚拟机。只包含一个解析器会更简单。

在perl 6 ( Perl的下一个版本)中,代码被编译成字节码并在Parrot虚拟机上运行。预计它将提高性能。字节码相当简单,可以进一步编译为处理器的本机指令(这称为JIT编译器),以接近编译语言(如C )的速度。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10416727

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档