解释器原理

来源:互联网 发布:淘宝商家编码怎么填 编辑:程序博客网 时间:2024/04/27 22:14

 

文字解码完后,你可以想象有一条纸带,上面写着代码。从左侧向左拉动纸带,用剪刀将程序

纸带剪成纸片,在内存中依次摆放这些纸片,然后才可以执行内存中的这些纸片。

 

 

执行内存中代码的时侯,会用到一种名为堆栈(stack的数据结构(也就是数据的组织处理

方式)。堆栈像个容器,放东西与取东西都在同一端,越晚放进去的东西,越早被取出来(后

进先出)。用通俗一点的比喻:堆栈就像是停车场,越早停进去的车,会停在越里面的位置,

要等到比它晚进的车都开走之后,才能开走。

为什么需要堆栈?因为程序在执行的过程中,有时候需要把某些事暂时保留不做(因为条件不

成熟),等到后面的事做完才能回头去做之前保留的事,这时候用堆栈是最适合的。

从下一页开始连续有好几个范例,你会看到这些范例在执行的过程中堆栈如何变化,而且屏幕

上的输出如何变化。通过这些范例,你应该可以理解解释器的运行原理。

 

 

对于abs -1这段代码来说,会被剪成两个值:abs-1,然后开始执行。

在状态A,堆栈与屏幕都是空的。然后把abs放进堆栈中,abs 是求绝对值的函数,它后面

需要跟着一个数字,但堆栈中目前只有abs自己,所以执行不了,这是状态B

到了状态C-1也被放进堆栈。有了这一个参数,abs终于可以计算了,计算方式是把这两

个值都从堆栈中取出,计算之后得到的值是1,再把1放回堆栈,现在是状态D

内存中的代码已经执行完毕,堆栈中也没有任何进一步的计算要进行,这表示程序要结束了。

结束时,堆栈中剩下的1就是返回值。所以在状态E 中,我们看到堆栈被清空,但屏幕上出

== 1

 

 

 

对于power 2 6这段代码来说,会被剪成power26这三个值,然后开始执行。

在状态A,堆栈与屏幕都是空的。然后把power放进堆栈中,成为状态Bpower是求幂的

函数,它后面需要跟着两个数字,分别是底数与指数,所以目前计算不了。状态C,把2放进

堆栈,依然无法执行。

状态D,把6放进堆栈,现在power 的两个参数都到齐了,可以计算了。方式是把三个值都

取出来计算,结果得到64,再把结果放回堆栈,进入状态E

内存中的代码已经执行完毕,堆栈中也没有任何进一步的计算要进行。这表示程序要结束了。

结束时,堆栈中剩下的64就是返回值。所以在状态F 中,我们看到堆栈被清空,但屏幕上出

== 64

 

 

对于print add 3 -4这段代码来说,会被剪成printadd3-4这四个值,然后

解释其原理

 

开始执行。

先把print放进堆栈,进入状态Aprint需要一个参数,所以此时无法计算。再把add

进堆栈,进入状态Badd现在无法当做print 的参数,因为add 自己就是一个函数,必须

add计算完毕的值才能当print参数。add 需要两个参数。

3 -4 被依次放进堆栈,进入状态C。这个时候,add的两个参数已经到齐,可以计算了。

把这三个值取出来,计算之后得到结果-1,把-1放回堆栈,现在是状态D

这个时候,print需要的参数(-1)已经出现了,取出这两个值,计算(执行)的结果是屏

幕上出现-1print是没有返回值的。没有返回值也就是说返回值是一个特殊值unset(未

设)。unset放进堆栈中。现在状态是E

内存中的代码已经执行完毕,堆栈中也没有任何进一步的计算要进行。这表示程序要结束了。

结束时,堆栈中剩下的特殊值unset就是返回值,返回值为特殊值unset相当于没有返回值。

所以在状态F 中,我们看到堆栈被清空,屏幕中没有出现==

 

 

对于power 2 6 abs add 3 -4这段代码来说,会被剪成power26absadd3

-4 这7 个值,然后开始执行。

power26依次放进堆栈,进入状态A。终于可以计算了,计算之后进入状态B。堆栈

中已经没有任何进一步的计算要进行,但内存中还有后续的代码,所以尚未结束。

把内存中的absadd3-4依次放进堆栈,进入状态C。终于可以计算了,取出最上面的

三个值,计算之后把结果-1放回堆栈,进入状态D。状态D 也可以计算,取出两个值,计算

结果1放回堆栈,进入状态E

内存中的代码已经执行完毕,堆栈中也没有任何进一步的计算要进行。这表示程序要结束了。

结束时,堆栈中若有多个值,最上层的值就是返回值。所以在状态F中,我们看到堆栈被清空,

屏幕中出现== 1,而64直接被扔了。

 

 

这个例子其实有两个段落,所以最后堆栈会有两个值。段落之间彼此独立,因此写代码时,我

们喜欢让段落之间换行,可以帮助阅读理解。

每次发生计算,其实就是找到一个段落。堆栈最后的值分别由powerabs 产生,所以它们

两个就是段落的起点。

既然每次发生计算就是一个段落,那么add应该也是段落的起点。但因为add只是abs 的一

部分(也就是说它是abs段落的子段落),而且add 没有兄弟段落(power abs在这里就

是兄弟关系,是平级的),再说abs太简单,让abs add 摆一起比较好。把add段落拆出

去没有太大必要。

最后一个例子。对于power 26 print add 3 -4这段代码来说,这个例子和前一个例子

差不多,只是abs换成了print。这导致状态E的堆栈中有两个值,而最上面的值是特殊值

unset

尽管最后堆栈中存在一个有效值64,但只有最上面的值才是返回值。unset表示没有返回值。

本文节选自《编程ING:人人都能学会程序设计》一书

蔡学镛 著

电子工业出版社出版

图书详细信息:http://blog.csdn.net/broadview2006/article/details/7768124

 

原创粉丝点击