关于编译原理:几百行代码实现一个脚本解释器

29次阅读

共计 969 个字符,预计需要花费 3 分钟才能阅读完成。

前言

最近又在重新学习编译原理了,其实两年前也温习过,当初是为了能实现通过 MySQLDDL 生成 Pythonsqlalchemymodel


相干文章在这里:手写一个词法分析器

尽管实现了相干性能,但当初看来其实实现的比拟糙的,而且也只使用到了词法剖析;所以这次我的目标是能够通过词法剖析 -> 语法分析 -> 语义剖析 最终能实现一个功能完善的脚本 ” 语言 ”。

成果

当初也有了一些阶段性的成绩,如下图所示:

目前具备以下基本功能:

  • 变量申明与赋值(只反对 int)
  • 二次运算(优先级反对)
  • 语法查看
  • debug 模式,能够打印 AST

感兴趣的敌人能够在这里查看源码:
https://github.com/crossoverJie/gscript

本地有 go 环境的话也能够装置运行。

go get github.com/crossoverJie/gscript
gscript -h

或者间接下载二进制文件运行:https://github.com/crossoverJie/gscript/releases

实现

以后版本是应用 go 编写的,的确也如题目所说,外围代码还不到 1k 行代码,当然这也和目前性能简陋无关。

不过麻雀虽小五脏俱全,从以后版本还是使用到了编译原理中的局部常识:词法、语法分析。

根本实现流程如上图:

  • 通过词法分析器将源码中解析出 token
  • 再通过对 token 推导生成出形象语法树(AST)

    • 如果语法语法呈现谬误,这一步骤便会抛出编译失败,比方 2*(1+ 少了一个括号。

因为没有应用相似于 ANTLR 这样工具来辅助生成代码(不然性能也不会只有这么点),所以其中的词法、语法分析都是手写的,代码量并不大,对于想要调试的敌人能够间接查看源码。

词法分析器:token/token.go:39
语法分析器:syntax/syntax.go

其中会波及到一些概念,比方无限状态机、递归降落算法等知识点就没在本文探讨了,后续这个我的项目性能更加欠缺后也会重头整顿。

布局

最初是画饼阶段了,不出意外后续会持续新增如下性能:

  • 更多的根底类型,string/long 之类的。
  • 变量作用域、函数。
  • 甚至是闭包。
  • OOP 必定也少不了。

这些个性都实现后那也算是一个 ” 古代 ” 的脚本语言了,后续我也会持续更新学习和实现过程中的乏味内容。

源码地址:
https://github.com/crossoverJie/gscript

正文完
 0