3.1 – 词法约定

Lua 语言的格式自由。它会忽略语法元素(符记)间的空格(包括换行)和注释,仅把它们看作为名字和关键字间的分割符。

Lua 中的 名字(也被称为 标识符)可以是由非数字打头的任意字母下划线和数字构成的字符串。标识符可用于对变量、表的域、以及标签命名。

下列 关键字 是保留的,不可用于名字:

  1. and break do else elseif end
  2. false for function goto if in
  3. local nil not or repeat return
  4. then true until while

Lua 语言对大小写敏感:and 是一个保留字,但 AndAND则是两个不同的有效名字。作为一个约定,程序应避免创建以下划线加一个或多个大写字母构成的名字(例如 _VERSION)。

下列字符串是另外一些符记:

  1. + - * / % ^ #
  2. & ~ | << >> //
  3. == ~= <= >= < > =
  4. ( ) { } [ ] ::
  5. ; : , . .. ...

字面串 可以用单引号或双引号括起。字面串内部可以包含下列 C 风格的转义串: '\a' (响铃),'\b' (退格),'\f' (换页),'\n' (换行),'\r' (回车),'\t' (横项制表),'\v' (纵向制表),'\' (反斜杠),'\"' (双引号),以及 '\'' (单引号)。在反斜杠后跟一个真正的换行等价于在字符串中写一个换行符。转义串 '\z' 会忽略其后的一系列空白符,包括换行;它在你需要对一个很长的字符串常量断行为多行并希望在每个新行保持缩进时非常有用。

Lua 中的字符串可以保存任意 8 位值,其中包括用 '\0' 表示的 0 。一般而言,你可以用字符的数字值来表示这个字符。方式是用转义串 \xXX,此处的 XX 必须是恰好两个字符的 16 进制数。或者你也可以使用转义串 \ddd ,这里的 ddd 是一到三个十进制数字。(注意,如果在转义符后接着恰巧是一个数字符号的话,你就必须在这个转义形式中写满三个数字。)

对于用 UTF-8 编码的 Unicode 字符,你可以用转义符 \u{XXX} 来表示(这里必须有一对花括号),此处的 XXX 是用 16 进制表示的字符编号。

字面串还可以用一种 长括号 括起来的方式定义。我们把两个正的方括号间插入 n 个等号定义为 n 级开长括号。就是说,0 级开的长括号写作 [[ , 一级开长括号写作 [=[ ,如此等等。闭长括号也作类似定义; 举个例子,4 级反的长括号写作 ]====] 。一个 长字面串 可以由任何一级的开长括号开始,而由第一个碰到的同级的闭长括号结束。这种方式描述的字符串可以包含任何东西,当然特定级别的反长括号除外。整个词法分析过程将不受分行限制,不处理任何转义符,并且忽略掉任何不同级别的长括号。 其中碰到的任何形式的换行串(回车、换行、回车加换行、换行加回车),都会被转换为单个换行符。

字面串中的每个不被上述规则影响的字节都呈现为本身。然而,Lua 是用文本模式打开源文件解析的,一些系统的文件操作函数对某些控制字符的处理可能有问题。因此,对于非文本数据,用引号括起来并显式按转义符规则来表述更安全。

为了方便起见,当一个开长括号后紧接一个换行符时,这个换行符不会放在字符串内。举个例子,假设一个系统使用 ASCII 码(此时 'a' 编码为 97 ,换行编码为 10 ,'1' 编码为 49 ),下面五种方式描述了完全相同的字符串:

  1. a = 'alo\n123"'
  2. a = "alo\n123\""
  3. a = '\97lo\10\04923"'
  4. a = [[alo
  5. 123"]]
  6. a = [==[
  7. alo
  8. 123"]==]

数字常量 (或称为 数字量)可以由可选的小数部分和可选的十为底的指数部分构成,指数部分用字符 'e' 或 'E' 来标记。Lua 也接受以 0x0X 开头的 16 进制常量。16 进制常量也接受小数加指数部分的形式,指数部分是以二为底,用字符 'p' 或 'P' 来标记。数字常量中包含小数点或指数部分时,被认为是一个浮点数;否则被认为是一个整数。下面有一些合法的整数常量的例子:

  1. 3 345 0xff 0xBEBADA

以下为合法的浮点常量:

  1. 3.0 3.1416 314.16e-2 0.31416E1 34e1
  2. 0x0.1E 0xA23p-4 0X1.921FB54442D18P+1

在字符串外的任何地方出现以双横线 () 开头的部分是 注释 。如果 后没有紧跟着一个开大括号,该注释为 短注释,注释到当前行末截至。否则,这是一段 长注释 ,注释区一直维持到对应的闭长括号。长注释通常用于临时屏蔽掉一大段代码。