分享

闭门造脚本语言解释器的一点感想

 quasiceo 2013-11-21
我动手做解释器的原因是多方面的。
0 平时工作搞SSH,没机会接触cool的东西。
1 我不懂汇编,也不懂java字节码,所以只好做解释型的语言,不能做编译型的语言。
2 我工作中遇到的工作流引擎,我越发觉得那个流程图其实也是一个函数而已,只是执行速度慢,逻辑也简单,关键是执行的状态可以持久化。
3 我天天编程,对编程这块特殊的业务,可以说是业务专家。一般情况下,我认为只要需求明确,我又理解深刻,没道理做不出软件来(即使性能差些)。

于是,我开始动手,首先对业务实体进行建模,我要做的是类似java的OO语言,主要的实体就是Package,Class,Object,Method,Field,。。。,这些都是在再普通不过的实体了,参考java的reflect包,基本雷同。
有了这些实体以后,我发现剩下的就是方法内部的逻辑如何建模的问题了。我整理了一下,有2种方法去表示逻辑:
1 流程图
2 指令
我最终选择了流程图,因为我不喜欢顺序的指令集。于是又多了一些实体:FlowChart,Node,StartNode,EndNode,DecisionNode,...
好了,至此所有的静态模型基本完成了。

光有静态模型显然是不够的,激动人心的部分终于要来了。我接下来要写一个执行引擎,去执行流程图。接过我发现要解释执行流程图是很容易的。每个节点都有箭头指向下一个节点,直到EndNode结束。节点类型基本就是顺序,分支。每个节点都有一句指令,最基本的就是赋值,调用。

第三步,我要么写一个图形界面的流程设计器,要么写一个文本代码解析器。结果我选择了后者。设计器我以后也一定要做的。
我没学过编译原理,但也听说要把代码转化为一棵树。我以前用正则表达式解析过html。于是我用还是用正则表达式,把代码解析出来了。语法现在基本参照java。

至此,一个简单的脚本语言解释器成型了,我可以在java里方便的方便的调用脚本语言里的类,并得到返回结果。目前不支持多线程,不支持并发,不支持网络。只支持基本数据类型和数组。对于一般的脚本需求来说,基本能用了。我写了个Finbonacci(int n)函数测了一下,当n=10的时候,共执行了131356个节点,花了13秒, 0.101毫秒/节点。这个速度慢得相当有水平。

心得:
1 其实做语言其实并没有想象中的难。高级语言总是建立在低级语言的基础上。一个高级语言里的指令,在低级语言里也许就是有多个指令来实现。
2 虽然从没用汇编写过程序,但我现在有自信说,最基本的指令其实没几个:赋值,调用,返回,跳转,出,入栈,和数学计算(+-×/)和布尔计算。有了这些指令,理论上就可以写出任意复杂的程序了。
3 其实所谓的语法是最容易实现的部分。在文本解析器完成以后,可以把很cool的语法转化为基本指令。
4 做一个核心的解释器其实工作量不是最大,反而如果要为这个语言写基础包会有巨大的工作量。比如要支持文件系统,图形界面,网络,。。。哪一块都是工作量巨大。

回顾开发的过程,我从以下产品吸取了营养:
smalltalk的纯OO思想,几乎不用关键词,都是用对象和消息的概念来处理。
Delphi以及一个叫FastScript的脚本语言,我曾在某个项目里用过。

将来的打算:
1 我打算把这个东西继续完善,由于是流程图作为逻辑的基本表达方式,也许可以用来替代那些工作流引擎。作为企业业务建模平台。
2 由此对语言不再恐惧和敬畏,打算关注相关开源语言产品,尤其是jvm上的一些脚本语言的实现原理,因为我对c的不熟悉,阻止了我去看ruby,java等的源码。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多