欢迎关注公众号《后台开发探索之旅》。
上节回顾
上一节介绍了几个Lua EBNF范式,总结如下:
-
chunk可表示为多条statement。
-
statement可表示为两类,一类为if、for、return等控制语句,一类为exprstat(expression statement)表达式语句。
-
exprstat也分为两类,一类为func函数调用,一类为assignment赋值语句。
-
assignment将等号'='左边的作为primaryexp主表达式,将'='右边的作为explist1任意表达式。
-
primaryexp先获取prefixexp前缀表达式,再根据prefixexp后面的符号判断主表达式类型。
考虑到表达式有些复杂,本节主要介绍控制语句,从大家最熟悉的if语句开始。
ifstat
IF cond THEN
block
{ELSEIF cond THEN block}
[ELSE block]
END
范例:
if a >= 80 then
score = 'A'
elseif a >= 60 then
score = 'B'
else
score = 'C'
end
ifstat语法比较直观,一目了然。
-
IF、THEN、ELSEIF、ELSE、END为终结符,对应这5个保留字。
-
cond为条件表达式,等价于 expr。
-
block为代码块,等价于chunk。
cond -> expr
block -> chunk
chunk为多条statement,block实际上也是多条statement,可以将block理解为带判断条件的chunk,所以在lua里block等同于chunk。
whilestat
WHILE cond DO
block
END
范例:
while a > 0 do
a = a - 1
end
WHILE、DO、END为终结符,cond为条件表达式,block为代码块。
repeatstat
REPEAT
block
UNTIL cond
范例:
repeat
a = a - 1
until a <= 0
类似于c语言的do while语句。
由于Lua不支持continue关键字,所以常常需要在循环体内,通过repeat + break来实现continue效果。
dostat
DO block END
范例:
do return end
由于Lua要求return语句必须为当前block的最后一条语句,例如下面语句会报错:
function f()
return
print("call f()")
end
如果需要在中间位置return,必须用do return end语句,dostat生成一个新的block,return为block内的最后一条语句。如下:
function f()
do return end
print("call f()")
end
forstat
FOR { fornum | forlist } END
for语句有两种形式:
-
fornum,类似c语言的计数方式。
-
forlist,类似python的枚举方式。
计数方式
fornum -> NAME =
exp1, exp1[,exp1] forbody
forbody -> DO block
范例:
for i=1, 10 do
a = a + i
end
等号'='左边为计数变量,右边为3个表达式,分别为初始计数、计数上限、递增步长。若没有第3个表达式,默认步长为1。
枚举方式
forlist -> NAME {, NAME}
IN explist1 forbody
范例:
t = {1, 2, 3, }
for i, v in ipairs(t) do
print(i, v)
end
IN为终结符,'IN'左边为枚举函数返回的两个值,右边为枚举表达式。
ipairs是Lua内置的枚举table函数,每次返回一个table元素的key和value,用户可以自定义枚举函数,实现遍历效果。
retstat
RETURN [explist1]
范例:
return
return a, b
return f()
一次可以返回0到多个值,用可选的explist1表示多个返回结果。
本节介绍了控制语句相关的EBNF范式,可以看出控制语句就是expr和block的组合控制,敬请后续,欢迎留言!