基于Go的Lox语言解释器分析与实现

(整期优先)网络出版时间:2022-08-24
/ 2

基于Go的Lox语言解释器分析与实现

冯伟国, 僧德文

杭州电子科技大学 计算机学院

摘要:主要介绍一个脚本语言解释器的设计与实现。首先对脚本语言和解释器的研究背景进行分析,然后系统拆分为语言解释器和在线编程平台两部分,并对其需求进行具体的分析接着分别语言解释器和在线编程平台各模块进行了划分设计实现该语言解释器在设计上具有小巧精简、低耦合度的特点,能较好地揭示脚本语言和解释器的本质

关键词:Go; Lox; 脚本语言; 解释器; 在线编程

1.研究背景

自计算机发明以来,计算机工程师们一直在构建编程语言,从汇编语言到高级语言,从命令式语言到声明式语言。而如今的软件工程师在工作中也都离不开使用脚本语言和各类特定领域语言。由此看来,编程语言是计算机软件的重要组成部分,它是互联网等计算机相关行业的基石,对于计算机相关产业的发展具有非常重要的意义。而解释器是脚本语言和特定领域语言的主流实现方式,许多编程语言的第一个版本的实现就是一个解释器实现。同时,解释器在一定程度上为我们展示出了编程语言和计算机的作为状态机的本质。

2.系统需求分析

解释器系统的设计与实现包含解释器和在线编程平台两个部分。其中解释器部分是实现脚本语言的核心,而在线编程平台为用户提供了浏览器端编程的服务。

解释器要实现的目标语言是Lox语言的子集,这是一种C-like语法风格的动态脚本语言,它包括numberstringboolnil四种基本数据类型,具备基本的变量声明,表达式运算,程序控制流,函数声明和调用等功能。解释器需要直接解释执行Lox语言代码的文本,输出执行结果,同时支持基本的对语法错误和执行错误的输出报错提示。

在线编程平台需要根据用户提交的Lox语言代码给出执行结果,并且要求解释器和该平台系统实现解耦,即在线编程平台不依赖于某个具体的解释器实现,解释器本身可以脱离在线编程平台单独运行使用。

3系统设计

3.1解释器功能模块划分与实现设计

(1)词法分析器

词法分析是解释器执行过程的第一条路线,词法分析负责从源代码提取有意义的单词,将其分门别类,构造出一系列称为token的块,这些token是构成语言语法的基本单位例如,在Lox语言中var sum = a + b;这段代码通过词法分析将会输出一个长度为7的token序列词法分析器设计使用双指针的算法手写实现,在对代码文本字符迭代的过程中根据left指针和right指针依次提取出每个token结构。

(2)语法解析器

语法解析器负责从线性token序列中分析出语法结构。由于语法结构本身具有的嵌套特性,所以通常使用树这种数据结构来表示它,通常将这种表示语法的数据结构称为抽象语法树AST或语法树syntax-tree,一颗语法树的每个节点通常是一个语句或者组成语句的一个表达式。比如在Lox语言中var sum = a + b;这段代码经过语法解析后应该生成一个以var语句为根节点的语法树结构。语法解析器采用递归下降的算法手写实现,其中表达式的递归-下降本质上就是树的后序遍历算法。

(3)解释执行器

解释执行器将一连串语句也就是一个法树序列作为输入语句的逐条执行本质也就是依次执行每棵语法树及其节点所以执行器的本质就是一个语法树的迭代器它也被叫做tree-walker解释执行器工作也是在对树的迭代过程中作相关的检查同时执行器被赋予了解释执行的任务,正如Ruby的第一个解释器MRI和其他一些教学语言解释器的实现一样,本系统解释器执行器将在语法树迭代过程中给出Lox语言程序的执行结果。所以每一个新的语法规则将对应一个语法树节点结构的定义,而每个语法树节点结构将有一个属于自己执行的方法将语法树节点声明为接口,就可以利用Go语言的多态来实现新的语法定义的扩展,因此执行过程看起来像是每个节点根据自己的语义解释执行自己

3.2在线编程平台的实现设计

在线编程平台基于前后端分离的结构实现,客户端设计使用JavaScript向服务端发起异步的Lox代码执行请求,服务端使用Go语言借助Gin框架实现对客户请求的路由。为解除在线编程平台和解释器之间的耦合,本文设计使用Go语言在Linux平台下支持的插件Plugin加载功能。在服务端本地将解释器编译成为动态链接库文件,而在线平台系统启动时加载该动态链接库文件作为插件引入。当客户端请求被路由到指定接口时,服务端将请求体中的Lox代码文本解析出来作为参数,调用载入的解释器入口函数,得到解释结果,最后封装响应发送回给客户端。

4. 结束语

本文描述了一个小巧精简的解释器的设计与实现。这个Lox语言的解释器具有麻雀虽小五脏俱全的特点,基本的变量声明、表达式运算、语句、控制流、函数。在未来它可能被进一步扩展:可以为它添加数组以及更加好用强大的基本数据结构,为它添加函数闭包以及面向对象的特性。如果要使这门语言更加实用,标准库的支持也是必不可少的。那时候需要真正的语义分析。如果想要更好运行时性能,遍历语法树看起来就显得太慢了,它需要被转化为一个中间表示IR并作静态分析和优化,然后转化为一种字节码,那么解释器就从树的迭代器变成了一个字节码虚拟机,一系列的扁平化能带来更好优化和性能提升。

参考文献

[1]张一帆. 计算机编程语言的发展与应用探究[J].无线互联科技,2020,17(24):112-113.

[2]左书祺. Go语言设计与实现[M]. 北京:人民邮电出版社, 2021.

[3]张军林, 阳富民, 胡贯荣. JavaScript语言解释器的设计与实现[J]. 计算机工程与应用, 2003(30):124-125+140.

[4]刘涛, 贾丽娟, 于峰. 快速掌握编译器设计方法[J].软件, 2018,39(05):114-117.

[5]徐金光. C编译器语法分析的设计与实现[D].成都:电子科技大学,2016.

[6]任洪彩. Go专家编程[M].北京:电子工业出版社, 2020.

[7]谢伟增,金振乾.Java语言在线编译器的设计与实现[J].电子技术与软件工程,2019(20):241-243.