本篇在讲什么 Lua的词法分析 本篇需要什么 对Lua语法有简单认知 对C++语法有简单认知 依赖Visual Studio工具 本篇的特色 具有全流程的图文教学 重实践,轻理论,快速上手 提供全流程的源码内容 |
★提高阅读体验★ 👉 ♠ 一级标题 👈👉 ♥ 二级标题 👈👉 ♣ 三级标题 👈👉 ♦ 四级标题 👈 |
♠ 前言
♠ luaL_dofile
在C++中我们通过luaL_dofile
宏来加载一个lua文件,如下述代码所示
int main()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
luaL_dofile(L, "lua_src/test.lua");
lua_close(L);
}
其实际上执行了两个函数,分别是luaL_loadfile
和lua_pcall
,二者包括宏均定义在lauxlib.h
脚本内
本篇重点去认识和了解luaL_loadfile
函数,在该函数内去对一个Lua文件进行词法分析
♠ 保留字
我们先了解一下Lua的一些保留字,其定义在llex.h
脚本当中,每一个保留字都对应了Lua中某个关键字或类型,比如TK_AND
代指的就是and
关键字
保留字定义为int类型,从257
开始,以此递增,原因是Lua识别字符的时候通过Ascii
码来标记,防止二者有冲突
♠ token
我们先了解一下什么是token
,其代指的保留字相关的枚举类型,每一个都是一个token类型
Lua在做词法分析的时候会根据不同的token类型去执行不同的方法,词法分析的过程可以理解成对每一个token分析的过程
举个例子,我们在脚本test.lua
中定义了一句Lua代码,如下图所示,其解析过程如下:
1、local ——> TK_LOCAL(268)
2、空格 ——> 32(空格ascii码)
3、num ——> TK_NAME(285)(自定义变量)
4、空格 ——> 32(空格ascii码)
5、等号 ——> 61(=的ascii码)
6、空格 ——> 32(空格ascii码)
7、1 ——> TK_NUMBER(数字1,ascill码61)
♠ 关键函数
我们了解一下个词法分析相关的重要函数和作用
- luaL_loadfile
解析Lua脚本,获取脚本内的二进制或字节流
- luaY_parser
词法分析的核心函数
- luaX_next
解析字节流中的下一个token块
- chunk
解析token的函数
简单的概括下对一段Lua代码进行词法分析都经历了哪些步骤
♠ 实例详解
我们直接通过断点调试和堆栈信息查看,来看看解析一段Lua代码的过程,这里直接从luaY_parser
函数开始,Lua代码如下所示
local num = 1
1、运行代码后第一个断点卡在了chunk
函数,我们可以通过堆栈信息看到&lexstate
中获取的第一个token是268,对应的正是Lua中的local
2、第二个断点我们打在了statement
函数里,可以看到因为获取的token是TK_LOCAL
所以执行到了对应的case里面
3、第三个断点我们打在了luaX_next
函数里,从堆栈中看到新获取的token是285,对应的是TK_NAME
,因为lua中的num
是我们自定义的变量
4、放开断点继续执行,依然卡到了luaX_next
里面,这里可一看获取到的token
是61,对应的就是=
的ascii码
5、放开断点继续执行,依然卡到了luaX_next
里面,这里可一看获取到的token
是284,对应的类型是TK_NUMBER
,因为我们在Lua中给变量num赋值是数字1,
6、继续执行,获取的最后一个token是287,对应的类型是TK_EOS
,该token类型代表着解析结束
至此,我们对该Lua代码的词法解析就全部结束了
♠ 推送
- Github
https://github.com/KingSun5
♠ 结语
若是觉得博主的文章写的不错,不妨关注一下博主,点赞一下博文,另博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。