Lua 解释器

警告⚠️:这将是一个又臭又长的系列教程,教程结束的时候,你将拥有一个除了性能差劲、扩展性差、标准库不完善之外,其他方面都和官方相差无几的 Lua 语言解释器。说白了,这个系列的教程实现的是一个玩具语言,仅供学习,无实用性。请谨慎 Follow,请谨慎 Follow,请谨慎 Follow。

前言

编译原理是计算机科学的一个重要且复杂的知识体系。这个系列教程也只是你入门前的垫脚石。但即使如此,也并不代表这个教程就很简单,如果决定开始,请坚持到底。这是一个认真严肃的教程(咳咳),它不像网络上的其他类似教程,要么实现一个“高级计算器”就完事了,要么语法分析还没讲完,就太监了。也不像其他的 Lua 源码阅读类的指导教程,去教你怎么阅读并理解 Lua 的源码。但我相信完成本教程后再去读 Lua 的源代码,也会轻松很多。

本教程将从零开始,一砖一瓦的构建出一个完整的解释器。不使用任何自动化的工具,也不使用任何第三方库,从词法分析到虚拟机,全部亲力亲为。我们将要实现的语言起名为 SLua,意思是 Simple Lua。

前置要求

本教程并不是面向编程初学者的,你至少需要满足以下要求才可以继续阅读:

  • 本教程使用的编程语言为 Google 出品的 Go 语言。Go 语言上手非常容易,如果你有过其他任何语言的编程经验,请花几个小时阅读这篇教程:墙外多语言版墙内中文版

  • 本教程的定位不是教科书,因此不会过多的提及关于编译原理的理论性的内容,而更加注重实践。所以,这要求你至少要知道编译过程流水线的基本步骤以及每个步骤的作用,比如:词法分析、语法分析、虚拟机等。

  • 既然要实现 Lua 语言的解释器,自然要求你熟悉 Lua 语言,即使没有用它写过项目,至少要熟悉 Lua 语言的语法及语言特性。

面向人群

  • 如果你很想知道脚本语言的解释器的工作原理,请继续阅读。
  • 如果你不仅想知道工作原理,还想亲自实现一个,请继续阅读。
  • 如果你学完学校开设的编译原理课程,除了学会了 LEX 和 YACC,其余的还是一无所知,请继续阅读。

开发方式

我们不准备从一开始就着手实现一个完完整整的解释器,支持所有的 Feature,这样无疑会顾此失彼,也会极大的拉高教程的阅读门槛。所以我们会先抽取 Lua 中一些最最基本的特性,实现一个可以工作的原型。在原型之上,我们再不断添加特性,直到完成为止。

在第一个版本中,我们会将一些比较重要的 Feature 都砍掉,将目光集中在整个流程的实现上。

所以,第一个版本将:

  • 不支持 Table
  • 不支持函数和闭包
  • 不支持 for 循环语句
  • 不支持 repeat...until 循环语句
  • 不支持多行注释和多行字符串

阉割的差不多了,看看还剩下什么:

  • 变量的声明及赋值(全局变量和局部变量)
  • do...end 代码块
  • if...elseif...else...end 分支语句
  • while 循环语句
  • 单行注释
  • 单行形式的字符串
  • 各种单目和双目的运算符

编译流程

SLua 的编译共分为以下几个阶段:

  • 词法分析:将用户输入的文本形式的源代码分解为一个 Token 列表
  • 语法分析:将词法分析的输出作为输入,生成无语义信息的抽象语法树(AST)
  • 语义分析:完善 AST 中的语义相关的信息
  • 代码生成:根据 AST 生成字节码
  • 虚拟机:解释并执行字节码
  • 标准库:提供系统级的实用函数

教程的章节安排也和编译流程保持一致。

获取源代码

代码已托管到 Github 上:SLua,每一个阶段的代码我都会创建一个 release,你可以直接下载作为参照。虽然提供了源代码,但并不建议直接复制粘贴,因为这样学到的知识会很容易忘记。

刚开始玩 Github 和 博客园,所以没有任何粉丝和关注量(哭),如果你觉得这篇教程有帮助,请不要吝啬给文章点个喜欢,给 Github 上的项目点个 Star。如果能 Follow 一下博客园 和 Github 的账号就更好啦,我也会更加有动力将这个系列写下去。:)

Lua 解释器的更多相关文章

  1. 从零开始的Lua宅[1]:编译Lua解释器

    Lua是一门神奇的脚本语言,游戏宅必备,懒人必备.Lua差多不是学起来用起来最简单的语言了,以至于简单到自身就是文档,自身就是配置文件.但是Lua的运行效率却是众多脚本中非常高的,据说仅次于V8爹下的 ...

  2. Nginx详解二十二:Nginx深度学习篇之Lua解释器安装及基础语法

    解释器 Lua:Lua是一个简洁.轻量.可扩展的脚本语言 Nginx+Lua优势充分的结合Nginx的并发处理epoll优势的Lua的轻量实现简单的功能切高并发的场景 安装Lua 1.安装解释器:yu ...

  3. 一个简单的Lua解释器

    #include "stdafx.h" #include<stdarg.h> #include<stdlib.h> #include<stdio.h& ...

  4. VS2008 集成Lua解释器

    1. 登陆官网下载源代码 -> www.lua.org -> get started ->  installing  选择系统类型(这里是Windows的,所下面载 luaDist) ...

  5. [Lua]50行代码的解释器,用来演示lambda calculus

    嗯,来写写经过: 在知乎上看见用Belleve牛用javascript写了一个精简的lisp解释器 => 我也想写一个,用lua写,能多简单呢? => 写了一个阉割的scheme解释器,包 ...

  6. 用VS2005编译生成Lua库文件和解释器

    TMD,本来很简单的东西,网上说的乱七八糟,说的也不明白,大家抄来抄去,估计都不自己实践的..花了半个下午研究了一下,总结一下. 1)下载lua工程文件,地址为http://www.lua.org/f ...

  7. 使用Nginx+Lua代理Hadoop HA

    一.Hadoop HA的Web页面访问 Hadoop开启HA后,会同时存在两个Master组件提供服务,其中正在使用的组件称为Active,另一个作为备份称为Standby,例如HDFS的NameNo ...

  8. StackExchange.Redis加载Lua脚本进行模糊查询的批量删除和修改

    前言 使用StackExchange.Redis没有直接相关的方法进行模糊查询的批量删除和修改操作,虽然可以通过Scan相关的方法进行模糊查询,例如:HashScan("hashkey&qu ...

  9. Lua和C++交互详细总结

    转自:http://cn.cocos2d-x.org/tutorial/show?id=1474 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信 ...

随机推荐

  1. service入门—电话监听器

    1.继承Service类 2.在清单文件进行配置(因为Service属于四大组件之一) <service android:name=".PhoneStatusService" ...

  2. VC++编程之字符串解惑--Unicode & MBCS

    VC++中的字符串用起来着实让人难受,LPTSTR.LPCTSTR.LPCSTR.LPCWSTR.LPSTR.WCHAR.CString._T()和L彼此之间的互相转换更是头痛.根据使用经验和MSDN ...

  3. FMXUI - UI.Dialog 示例

    在 FMXUI 开源库,增加了 UI.Dialog 单元.此单元实现了跨平台的基础对话框组件.使用时引用 UI.Dialog 即可.如果需要自定义对话框的样式, 可以添加一个 TDialogStyle ...

  4. LWP::UserAgent - Web user agent class Web 用户agent 类:

    LWPUserAgent: LWP::UserAgent - Web user agent class Web 用户agent 类: 概述: require LWP::UserAgent; my $u ...

  5. Swift - String与NSString的区别,以及各自的使用场景

    String是Swift里新增加的类型,它与原来的NSString可以很方便地互相转换.但在实际开发中,我们该如何选择? 1,能使用String类型就尽量使用String类型,原因如下: (1)现在C ...

  6. 基于MFC简单图片裁剪工具

    话说这几天又没干啥正事,看书没效率,游戏也没怎么玩,尼玛时间都去哪儿了! --------------------------------------------------------------- ...

  7. Android下QQ空间查看大图特效

    近期在做一个项目,里面有一个功能是实现Android QQ好友动态里面的缩略图放大,查看大图的效果.用过都知道,这个特效非常赞的,没用过的下载个玩玩吧.我刚開始以为放大的那个大图是一个Activity ...

  8. 【thinking in java】读书笔记(一)

    近期開始读tij,好记性不如烂笔头,所以还是记录一下,方便以后查阅. 一.各种初始化问题: 方法重载的问题: 方法的重载,差别是靠传入方法的參数,而不是返回值.比方f(),假设是返回值的话,easy产 ...

  9. 几本不错的CPU设计以及VLSI的书籍

    1. Microprocessor Design Principales and Practrices with VHDL  特点:电路与VHDL一一对应,比较清楚,而且还用MAX+plus进行仿真 ...

  10. 序列化TList of objects(摘自danieleteti的网站)

    Some weeks ago a customer asked to me if it is possibile serialize a TList of objects. “Hey, you sho ...