一步步写lua解释器--语法分析

当我们从源码中读取到一个个单词token之后,就需要将这些token转换为实际的语句了。一门语言的产生是有一定的道理,是用来解决实际问题的,没人会吃饱了没事干发明一门语言。例如在学数学时要求一个一元一次方程的结果即解方程ax + b = c,我们可以写如下代码:

local f = funciton(a,  b, c)
  if a ~= 0 then 
    local x = (c - b ) / a
    return x
  else
    ...
  end
end
t = {a=5, b = 6, c = 7}
f(t.a, t.b, t.c)

除了循环,以上代码基本上包含了一门简单语言必有的语句:变量声明,赋值,if else语句,运算,函数调用等等。当解析器遇到这么多各不相同的语句时,是怎样管理这些语句,这些语句最终又是怎么样变成可执行的代码的呢?一台既可以打游戏又可以上网听歌的电脑是怎么生产出来的呢?答案是由一个个零件组装起来的。

代码也是,再大再复杂的代码也可以分解成为基本的模块。例如赋值语句x = (c-b)/a可以分解为赋值左边变量x和右边表达式(c-b)/a;表达式又是两种基本运算的组合:减法和除法;if语句有逻辑判断部分和要选择执行的模块代码;函数的构成部分为:函数名,参数列表和函数体模块。总之,再复杂的语句都可以分解为几个基本的语句,再复杂的代码都可以转化为赋值,运算,逻辑比较等指令。

我们再来分析如何解析这些代码语句。拿函数来举例,一个函数有函数名,函数参数,函数体。这些可以看做是函数语句的子语句。而函数体又有语句,且语句的数量不确定。我们把函数体语句当做函数体的子语句也可以,但是由于不知道有多少个子语句,处理起来不太好,而且这样细分子语句会导致越来越复杂。一个较好的方法是将函数体的子语句就当做函数体,也就是说函数体就是函数子语句列表的形式。举个简单例子:

f = function(a, b)
  local x = a + b
  x = x * 2
  reurn x 
end

分解后类似于如下结构:

函数  :
  名字 :f
  参数 :a -> b
  函数体 :local x=a+b ->  x=x* 2 -> return x

函数体就是这三个语句的列表,而不是他再有三个子语句。我们把这三个语句叫做兄弟语句,而函数体相对函数来说是子语句。

所以我们要构造一个结构,即能包含几个子结构,也能拥有兄弟结构。所有结构我们可以用一个base结构的指针来表示。相信有c语言基础的朋友都能构建出来:

class {
protected:
   TreeNodeBase* _child[Child_Num_Const];
   TreeNodeBase* _pParent;
   TreeNodeBase* _pNext;
...

其他语句也基本这样来构造,再举个多值赋值的语句:

local a, b, c = 1, 2+3, f()
赋值语句:
  变量左值列表: a -> b -> c
  表达式右值列表: 1 -> 2+3 -> f()

还有几种语句需要特别的处理,例如:

t.a.b.c = 1

那究竟t.a.b.c该如何来解析呢?先说简单的t.a,我们可以把他看做是一个表访问语句,子语句分别为t和a。t.a.b.c可以看做是有3个嵌套的语句:
t.a.b和c,t.a.b又分为t.a,b,t.a分为t,a。为什么不反过来分为t,a.b.c呢?这个后面讲table的时候专门会讲到。

同理if elseif elseif ... else 也是这样类似的嵌套解析,这个后面也会讲到。

好了,相信大家明白怎么样来进行语法分析了,所有的语句都可以按照以上的方法来进行解析。一个lua文件的所有代码可以看做是一个大的块,块包含语句列表。最终,一个lua文件会生成一个树状的大型结构体。

解析完语句下一步就要生成代码了,我们拭目以待。有问题可以在后面留言,或者加入QQ群 858791125 讨论。

项目地址:
https://github.com/shonm520/mlua

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值