语言解释器的实现

出于个人情怀和早期对语言实现的兴趣,最近业余时间写了个简化版语言解释器,性能是python的3倍左右,几乎包含语言所有的特性,下面主要讲一下核心实现,感兴趣的可以直接看golang源码:https://github.com/song2010040402102/cy

词法分析

词法分析主要对一个表达式进行分词,把各个变量和运算符拆分到一个array中,遇到()或function,把它当成子表达式递归处理即可

语法分析

语法分析相对词法分析较为复杂,首先需要把词法array中的运算符中同名不同含义的进行转化,例如,-既可以作为一元运算符负号也可以作为二元运算符减号,++要分析是先赋值还是先自增,然后根据运算符的优先级构造语法树,其中叶子节点存储变量,其它节点存储运算符,而每个子节点的数量取决于运算符的元数,对于一元运算符要根据结合方向来选择左边还是右边的表达式作为子节点。为了通用起见,可以定义运算符的优先级、结合性、元数等

语义分析

语义分析对于自然语言非常复杂,对于计算机语言可以简单理解为像c语言编译器在编译过程报的错误或警告,即处理变量类型是否可转换或运算符是否可操作当前的变量类型等等。为了通用起见,可以定义一个变量和运算符的语义表

符号表

符号表用来表示每个变量的名称和类型,在程序运行时,用于申请堆栈的大小

符号表又分为全局符号表和函数符号表,在符号查找时,优先查找函数符号表,查找失败再查找全局符号表

由于函数可能会嵌套一些条件和循环语句,所以函数符号表是个树形结构,应该沿着当前节点往树根方向查找

指令生成

程序运行时,不可能沿着语法树来执行,会大大降低执行效率,因此需要把语法树转换成线性指令,转换过程只需要深度优先遍历即可

控制语句

像if、while、continue、break、return等都可抽象成运算符来处理,if运算符逻辑决定执行哪个语句块,while运算符逻辑决定是否要循环执行语句块,continue、break、return通过改变程序计数器来控制当前执行哪个指令

以上六个部分是解释器的核心,其他像变量、函数声明,堆栈空间申请与释放,ebp、esp、eax、pc等寄存器使用都相对比较简单,不再赘述

标签: none

添加新评论