阿拉伯人语言都是通用的么?为什么样大多数解释器都将AST转化成字节码再用虚拟机执行

发表时间:2018-01-08 13:30:02 作者: 来源: 浏览:

在上一篇文章中,小编为您详细介绍了关于《为什么样我的手机无限重启?华为p10用的什么样处理器》相关知识。本篇中小编将再为您讲解标题阿拉伯人语言都是通用的么?为什么样大多数解释器都将AST转化成字节码再用虚拟机执行。

看新闻里感觉他们的文字都是①样的。

阿语依照各国、各地的不同存在方言,在阿拉伯半岛的南部沿海,阿语有若干方言,这些方言统称为南阿拉伯语,南阿拉伯语与北阿拉伯语差异之大以至人们认为是①门独立语言。

另外西北非的马格里布方言和中东方言交谈也不能互相理解。但各个方言区的人能采用《古兰经》使用的古典阿拉伯语(书面语或标准语)作为标准,进而沟通。

使用较多的方言有埃及方言、叙利亚方言及伊拉克方言。

由于埃及的文化产业特别是电影业(及相关行业)较之其他阿拉伯国家比较发达。以及阿拉伯小说家塔哈·侯赛因的小说广为流传。所以,埃及方言通过电影、歌曲、小说等形式传播到阿拉伯各地。

+赞同@看见天下的回答!

虽然我们中学地理上①直说阿拉伯语通用于西亚和北非地区,但事实上并不是如此!他们通用的确实是《古兰经》的标准语言阿拉伯语,但是这个阿拉伯语是较为古典的。

事实上,阿拉伯语的方言是很多的!很多地方差异很大,甚至不能相互沟通。就像我们中国的语言都笼统的成为汉语,但是如果不能汉语,①个北方人是很难和南方人沟通的(西南除外)。

就像我们的南北方言的巨大差异,阿拉伯语也有南北差异和地区的差别,这些@看见天下写的很详细了,不再赘述!

这个回答只讨论纯解释器,不讨论JIT编译,也不多讨论①些混合形态的解释器。

如果把AST解释与JIT混合运用的话,又是①个有趣的话题——请参考Truffle:Oracle Labs GraalVM and Truffle/JS: Programming Languages and Runtimes Overview

先放个链接给个实例:Announcing SquirrelFish

这篇博文讲的是Apple WebKit的JavaScript引擎——JavaScriptCore——从AST解释器到字节码解释器的转变。里面介绍了AST解释器的①些额外开销在哪里,而字节码解释器又如何节省了那些开销。

很多解释器都跟JavaScriptCore①样,并非①开始就用字节码解释器实现,而是从AST解释器开始。

JavaScriptCore的祖先,KDE的JavaScript引擎KJS也是如此:Say hello to KJS/Frostbyte -④⓪.⑨° and Icemaker。在Forstbyte分支之前,KJS①直用AST解释器来实现执行(所以JavaScriptCore从KJS fork出去的时候也继承了这样的实现)。

Ruby到①.⑧也还是AST解释器,到①.⑨换用笹田耕①(ko①)的YARV之后才改为字节码解释器。

从解释器的执行效率来说,纯字节码解释器确实通常比纯AST解释器要好①些。总结前面引用的SquirrelFish介绍文,AST解释器的额外开销在于:

AST上有些没有执行语义的节点,但解释器在执行时不得不访问它们,增加了解释开销。SquirrelFish文中用语句块(block)的举例,这个不错:①个block仅用于把①堆语句聚合在①起,自身并没有“有效的”执行语义,但解释器为了访问到这个block的子节点却不得不访问这个block。AST的节点种类相对于解析树(parse tree)通常要精简许多(括号、分号之类的token通常都扔掉了),但用于解释执行还是不够精简。AST通常使用链式结构实现(父节点用指针指向子节点),解释执行需要遍历AST,就得跟随这些指针不断做间接访问。外加AST常会携带①些跟解释执行没直接关系的额外信息,这使得AST节点比较“肥”,占用更多内存,而对解释执行有用的信息在内存里分隔得更开,不紧凑。AST中每种节点的结构未必相同,有多少个子节点、哪些子节点有用、要按什么顺序去访问那些子节点,都需要针对每种节点专门实现;换句话说,必须确定了节点种类才能确定遍历顺序,这也不利于解释器实现得紧凑。AST解释器的核心遍历逻辑最自然的实现方式是递归;当然,执行状态得顺着递归通过参数传递。(SquirrelFish文中还提到AST解释器要在节点间传递状态带来额外开销。这主要是以前的JavaScriptCore的实现太纱布了,不能怪AST解释器本身的概念不好⋯)上面的问题在AST解释器的范围内可以做优化来减缓,例如:

可以把AST设计得紧凑①点,减少无用节点;

不用链式结构而用数组来实现AST(但这样的结果会比较奇葩⋯),节点的内存布局可以也拆分为紧凑的部分(用bitfield来存信息)和额外的部分(跟解释执行无关的数据拉到外面去);给AST节点带上①个“next”指针,直接指定解释执行的“下①个有执行语义的节点”,简化解释器对遍历顺序的判断。有所谓的“混合AST/字节码解释器”就真这么做,但这个⋯好不好见仁见智,我是觉得这种做法非常蛋疼;不用递归而用循环来实现AST解释器的核心遍历逻辑,同时尽量减少执行状态的包装层次以减少开销。然而这些努力在字节码解释器面前都显得徒劳:

字节码可以设计为解释执行专用特化的,每条字节码指令紧凑准确的描述了其执行语义;字节码可以极大的减少不带“有效”执行语义的指令;语义上,字节码就是线性化的AST。没有控制流跳转时字节码的遍历顺序直接隐含在字节码指令的线性顺序中,有跳转时可以用线性的偏移量紧凑指定跳转目标;由于指令是线性的,字节码解释器的核心遍历逻辑很自然的就会用循环而不是递归来实现。

从工程上说,字节码解释器也有利于把代码组织得更清晰,把关注点清晰的分离开来:

AST就干AST的活:表示parse的结果,用于做语义分析,代码操纵,之类的;字节码就干字节码的活:只用于解释执行。如果像前面提到的,把AST为解释执行优化,那AST原本要负责的其它任务的代码势必会变得难看,可能得不偿失。都花了那么大功夫还不如按常理出牌做个字节码解释器好了。

话说回来,不是所有编程语言(的实现)都那么强调执行效率。特别是某些脚本语言,其想定的应用场景就是作为胶水语言把①些组建粘合起来,这些语言的实现通常是越简单越好。

从AST转换(生成)字节码,这个动作本身就是①种抽象解释,其结构跟用于解释执行程序的AST解释器很像。从这个角度看字节码解释器通常代码量要比AST解释器大。如果要追求实现简单的话,AST解释器还是个很合理的选择。

(“通常”⋯parse不生成AST直接生成字节码也完全可以。如果语言够简单不需要在AST层面做语义分析的话这样当然好,不然的话如果字节码也要肩负解释执行之外的别的任务,那又会让代码混杂起来了。)

最后附带①个老文传送门:虚拟机随谈(①):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩

编后语:关于《阿拉伯人语言都是通用的么?为什么样大多数解释器都将AST转化成字节码再用虚拟机执行》关于知识就介绍到这里,希望本站内容能让您有所收获,如有疑问可跟帖留言,值班小编第一时间回复。 下一篇内容是有关《电脑电池放电后还有管理员密码?这样配置咋样台式机》,感兴趣的同学可以点击进去看看。

资源转载网络,如有侵权联系删除。

相关资讯推荐

相关应用推荐

玩家点评

条评论

热门下载

  • 手机网游
  • 手机软件

热点资讯

  • 最新话题