Lua语法分析(4)- 表达式

欢迎关注公众号《后台开发探索之旅》。

 

 

上一节介绍了二元操作符,本节以Lua EBNF为基础,介绍Lua表达式的各种表现形式。

 

Lua支持逗号分隔的表达式列表 explist,在多重返回值、多重赋值、参数列表等场景使用,示例如下:

return a,b,c
a,b,c=1,2,3
local a,b,c=1,2,3
f = function (a,b,c) end
print(1,2,3)

从 explist 开始介绍表达式。

 

 

explist1 

explist1 -> expr {`,` expr}

 

根据上面示例很好理解,逗号分隔的每一项为一个expr。

 

 

expr

expr -> subexpr(limit=0)

 

上一节介绍了运算符优先级,也就是 subexpr 的实现。初始优先级 limit=0,逐个读取运算符,根据优先级递归解析,可参考《二元操作符》一节。

 

 

subexpr

subexpr -> 
  (simpleexp | unop subexpr) 
  { binop subexpr }

 

一个表达式由运算符和子表达式组成,运算符分为一元运算符(unary operator)和二元运算符(binary operator)。

  • simpleexp 表示子表达式。

  • unop subexpr 表示一元运算符和子表达式。

  • binop subexpr 表示二元运算符和子表达式。

 

以 "-9+10*5/(a+10) == #t1" 为例,推导如下:

"-9"   -> unop subexpr
"+10"  -> binop subexpr
"*5"   -> binop subexpr

"/(a+10)" -> binop subexpr
"(a+10)"  -> simpleexp

"== #t1"  -> binop subexpr
"#t1"     -> unop subexpr

 

Lua里一元操作符有:

  • '#' 取字符串长度,或table数组元素数量。

  • '-' 负号。

  • 'not' 取反,相当于c语言的'!'取反。

 

 

simpleexp

simpleexp -> NIL 
  | false | true | NUMBER 
  | STRING | ... | FUNCTION body 
  | primaryexp | constructor

 

前面6个产生式比较简单,分别对应nil、false、true、数字、常量字符串、可变参数...。

  • FUNCTION body 表示函数定义。

  • constructor 表示table初始化。

  • primaryexp 表示主表达式。

 

 

FUNCTION body

body -> `(`parlist`)` chunk END
parlist -> [param {`,' param}]
param -> NAME | `...'

 

范例:

f = function (a,b,c) 
  return a+b+c 
end

 

  • FUNCTION和END 为两个终结符。

  • chunk 表示函数体。

  • parlist 表示参数列表。

 

在Lua里函数是第一类型,和普通变量有相同的用法,可以作为参数、值传递,这一点类似python。

 

 

constructor

constructor -> `{`[fieldlist]`}`
fieldlist -> 
    field { fieldsep field } 
    [ fieldsep ]
field -> 
    `[` expr `]` `=` expr |
    name `=` expr |
    expr
fieldsep -> `,` | `;`

 

范例:

a = {}
a = {1,2,3}
a = {x=1,["y2"]=2}
a = {1,2;x=1,[y1]=2;["y2"]=2,3;}

 

table是Lua里唯一的数据结构,可以理解为array和hash的组合。

  • {1,2,3} 存在数组部分。

  • {x=1} 存在哈希部分。

  • 元素之间可以用 ',' 或 ';' 分隔。

  • {x=1} 等价于 {["x"]=1}。

 

 

语法分析总结

通过对Lua语法分析的一系列介绍,虽然没有接触实际源码,相信对Lua语法分析也有了一定的了解。这一块应该属于Lua源码相当难啃的一部分内容,通过先理论后实践的方法,避免陷入源码实现的黑洞,从而提升信心。

 

Lua的词法分析、语法分析、指令生成模块耦合在一起,并且Lua是基于寄存器的虚拟机。在生成指令的时候,已经指定每个指令所操作的寄存器位置,所有这些逻辑都要在lua脚本的一次遍历分析完成。

 

关于语法分析的介绍到此为止,后续将介绍指令生成部分,敬请期待!

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值