Lua虚拟机之语法分析(二)

本文是作者在项目发布前的忙碌中抽出时间撰写的Lua虚拟机系列文章的第二篇,主要聚焦于语法分析。通过分析lua虚拟机源代码,特别是luaX_init方法在lstate.c和llex.c中的作用,阐述了如何生成关键字到全局状态的字符串表,为理解Lua虚拟机的工作原理提供了深入见解。
摘要由CSDN通过智能技术生成

      最近实在是忙,项目就快要发布了,加班加点在所难免。继上一篇关于lua基本数据类型的简单分析后,我将继续写阅读lua虚拟机的源代码笔记,这是第一次接触虚拟机工作原理,lua虚拟机代码量不大,是个很好的学习的例子,应当坚持下去。关于语法分析,我觉得只需要弄清楚从哪分析,怎么分析以及最终的生成结果就差不多了。

      当通过调用lstate.c:lua_newstate()方法生成一个新的lua_State时,其内部又会调用llex.c:luaX_init方法,该方法的作用是生成lua的关键字(保留字)到global_State的字符串表中(stringtable,以哈希表的形式保存),关于lua的保留字,在llex.c中可看到下面这段:

/* ORDER RESERVED */
static const char *const luaX_tokens [] = {
    "and", "break", "do", "else", "elseif",
    "end", "false", "for", "function", "goto", "if",
    "in", "local", "nil", "not", "or", "repeat",
    "return", "then", "true", "until", "while",
    "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
    "<number>", "<name>", "<string>"
};
      而真正让虚拟机开始分析源代码,则是通过lapi.c:lua_load函数,lauxlib.c中则封装了对lua_load的调用,其中包括从文件加载源码的分析lauxlib.c:luaL_loadfilex,以及从内存加载lauxlib.c:luaL_loadbufferex。在lua_load中,除了必要的初始化,比如生成一个ZIO对象(流对象)负责处理文件或字符串的输入,还调用了ldo.c:luaD_protectedparser函数,而在这个函数中,又最终调用了lparser.c:luaY_parser函数,好了,虚拟机开始进入源码的分析阶段了,代码如下:

Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
                      Dyndata *dyd, const char *name, int firstchar) {
  LexState lexstate; // 扫描状态机,单词读取、步进等操作
  FuncState funcstate; // 函数状态机,每输入一个源代码文件或者是一段源代码字符串,都将有一个状态机对应
  Closure *cl = luaF_newLclosure(L, 1);  /* create main closure */
  /* anchor closure (to avoid being collected) */
  setclLvalue(L, L->top, cl);
  incr_top(L);
  funcstate.f = cl->l.p = luaF_newproto(L);
  funcstate.f->source = luaS_new(L, name);  /* c
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值