重磅来袭
来源:互联网 发布:网络延时和rtt的关系 编辑:程序博客网 时间:2024/05/16 19:57
欢迎关注公众号《Lua探索之旅》。
Lua语法短小精悍,简单易学,非开发人员也可以编写一些简单的脚本,有开发经验的人更是分分钟上手。但麻雀虽小五脏俱全,要探索lua内部实现,必须全面掌握其语法。
推荐阅读《lua5.1参考手册》,该手册为官方文档,由云风(游戏圈的大神,梦幻西游技术负责人)翻译。
Lua EBNF范式
代码是程序设计思想的落地,核心在于设计思想,如非必要,不贴源码。
lua的语法规则是通过EBNF范式定义的,理解了EBNF,也就理解了lua的语法分析,事实上lua的语法分析模块就是lua EBNF的代码实现。
lua EBNF如下图所示,从本节开始将完整介绍各个推导式的含义。
chunk -> { stat [`;`] }
{}表示0个或多个, []表示0个或1个,chunk可推导为
chunk -> stat
chunk -> stat; stat; ...
lua的一个执行单元称为chunk(数据块),一个chunk可包含多条语句,比如
a = 1
b = a + 1
每一行表示一条statement(语句),若一行有多条statement,用分号分隔
a = 1; b = a + 1;
chunk可以保存在一个文件里,也可以存入字符串。当一个 chunk 被执行,首先它会被预编译成虚拟机中的指令序列,然后被虚拟机解释运行这些指令。
stat -> ifstat | whilestat | dostat | forstat | repeatstat | funcstat | localstat | retstat | breakstat | exprstat
|表示或,一条statement可以有多种表达形式,比如赋值语句、if语句、for语句、return语句等
每条statement根据第一个token类型决定使用哪种产生式。比如 "a=1" 的第一个token为TK_NAME, "if a>1 then ... end" 的第一个token为TOKEN_IF。
token类型和产生式的对应关系如下:
exprstat -> func | assignment
除去if、while、local、return等控制语句,exprstat表示一条执行语句,包含赋值和函数调用两类,如 "a=1" 和 "print()"
lua将表达式分为 主表达式 primaryexp 和 任意表达式 explist1。
主表达式必须可以作为左值存在,能够被赋值,比如 "a.b=1+2",其中 "a.b"为主表达式,"1+2"不能为主表达式。
在exprstat里,等号'='左边为一个主表达式,用primaryexp解析,有4种表达形式:
exp; exp(exp); exp[exp]; exp.exp
比如: a; a(1+2); a["b"]; a.b
其他复杂形式为这4种形式的递归实现,如
a.b.c = a.exp1
exp1 = b.c
再比如
a(b.c).d() = exp1.exp2
exp1 = a(exp3)
exp2 = d()
exp3 = b.c
primaryexp先获取一个前缀表达式 prefixexp,如 "a()" 分解为 "a" 和 "()",其中 "a" 即为前缀。
然后根据第2个token决定使用上面4种表达形式的哪一种,如 "a()" 使用 exp(exp) 形式解析。
primaryexp解析完后,判断当前expr是否为函数调用,如:
"a()" 是函数调用
"a().b" 不是函数调用
"a().b()" 是函数调用
若为函数调用,exprstat使用 func 产生式,否则使用 assignment 产生式,作为赋值语句处理。
primaryexp -> prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs }
对应上面的4种表达形式
prefixexp.NAME 用于table取key值,如 "a.b" 等同于 "a['b']",这是lua的语法糖
prefixexp[exp] 用于table取key值,key可以为一个表达式
prefixexp:NAME() 用于table的成员函数调用,另一个语法糖,如 "a:b(c)" 等同于"a.b(a,c)",自动将当前table对象作为第一个参数插入,类似c++的this指针
prefixexp() 用于函数调用,如 "a()"
prefixexp -> NAME | `(` expr `)`
前缀表达式可以为标识符,也可以一个表达式
如 "a()" ,prefixexp使用 NAME 产生式
如 "(a+1).d=1",prefixexp使用 expr 产生式
不要怀疑, "(a+1).d=1",在lua里可以这样写,比如a为table,table又可以定义元方法,重载+运算符返回一个新table就可以了。
本节先介绍这几个EBNF,敬请后续!
- 重磅来袭
- CityPickerViewV2.0重磅来袭
- 奖品 | OMG ! 圣诞节超强活动重磅来袭
- Augmented World Expo(AWE)重磅来袭!
- 家驹再唱海阔天空,金立首个朋友圈广告重磅来袭
- R7重磅来袭,OPPO这次玩什么?
- 设计成就中国高峰论坛重磅演讲嘉宾来袭
- Github上的1000多本免费电子书重磅来袭!
- 物联网硝烟四起:谷歌、阿里重磅来袭
- 重磅来袭!CMA新会员的福利来了
- 重磅来袭,使用CRL实现大数据分库分表方案
- 马哥python培训实战班2016重磅来袭
- 网易云捕1.5版本已经上线,重磅功能来袭
- Activiti权威指南 书重磅来袭,工作流开发者的福音
- 课程、干货任你选,Strata技术会重磅来袭!
- 2017中国产业园区大会即将重磅来袭!
- 《设计模式的艺术——软件开发人员内功修炼之道》重磅来袭!
- 程序化购买:浪潮来袭 悠易互通重磅推出DSP2.0平台
- base.css
- 6.1
- I/O复用--select函数源码剖析
- mysql表行列互换
- 我就是想发一下我的小站 哈哈哈
- 重磅来袭
- 动态规划问题数字三角形的(递归程序)
- Android开发-数据存储方式一
- HAProxy常用配置介绍,ACL详解
- css知识点
- codeforces C. Solution for Cube
- mysql游标循环的使用
- 导航框架的应用
- 多关键词匹配个人解决方案