lua - 为什么下面这段 Lua 代码完全有效?

标签 lua luajit

从我的 Lua 知识(以及根据我在 Lua 手册中读到的内容)来看,我一直认为 Lua 中的标识符仅限于 A-Z & a-z & _ & 数字(并且不能开始使用数字也不能是保留关键字,即 local local = 123)。

现在我遇到了一些(混淆的)Lua 程序,它使用各种奇怪的字符作为标识符:

/image/tiuKs.png

-- Most likely, copy+paste won't work. Download the file from https://tknk.io/7HHZ
print(_VERSION .. " " .. (jit and "JIT" or "non-JIT"))

local T = {}

T.math = T.math or {}
T.math.​â®â€‹âŞâ®â€‹­ď»żâ€Śâ€­âŽ­ = math.sin
T.math.â¬â€‹â­â¬â­â«â®â€­â€¬ = math.cos

for k, v in pairs(T.math) do print(k, v) end

输出:

Lua 5.1 JIT
â¬â€‹â­â¬â­â«â®â€­â€¬ function: builtin#45
​â®â€‹âŞâ®â€‹­ď»żâ€Śâ€­âŽ­ function: builtin#44

我不清楚为什么允许使用这组字符作为标识符?
换句话说,为什么它是一个完全有效的Lua程序呢?

最佳答案

与某些语言不同,Lua 并不是由正式规范真正定义的,该规范涵盖了所有偶然情况并完全解释了 Lua 的所有行为。像“Lua 文件编码的字符集是什么”这样简单的事情在 Lua 文档中并没有真正解释。

全部the docs say about identifiers是:

Names (also called identifiers) in Lua can be any string of letters, digits, and underscores, not beginning with a digit and not being a reserved word.

但没有任何东西真正说明什么是“字母”。 Lua 使用的字符集甚至没有定义。因此,它本质上取决于实现。 “字母”是......无论实现想要它是什么。

那么,假设您正在编写一个 Lua 实现。并且您希望用户能够提供 Unicode 编码的字符串(即 Lua 文本中的字符串)。 Lua 5.3 需要这个。但您也不希望他们必须对其文件使用 UTF-16 编码(也是因为 lua_load 获取字节序列,而不是 Shorts)。因此,您的 Lua 实现假设它在 lua_load 中获取的字节序列是用 UTF-8 编码的,以便用户可以编写使用 Unicode 字符的字符串。

在编写此实现的词法分析器/解析器部分时,您如何处理?处理 UTF-8 最简单、最容易的方法是...不处理 UTF-8。事实上,这就是该编码的全部意义。由于Lua用特定符号定义的所有内容都是用ASCII编码的,并且ASCII文本也是具有相同含义的UTF-8文本,因此您基本上可以将UTF-8字符串视为ASCII字符串。对于 Lua 中的字符串,您只需复制字符串的起始字符和结束字符之间的字节序列即可。

那么如何处理标识符的词法分析呢?嗯,你可以问上面的问题。或者您可以问一个更简单的问题:该字符是空格、控制字符、数字还是符号? “信件”只不过是不属于其中之一的东西。

Lua 定义了它认为什么是“符号”。 ASCII 可以告诉您什么是控制字符、空格和数字。在这样的实现中,任何具有 ASCII 之外的值的 UTF-8 代码单元都是一个字母。即使从技术上讲,这些代码单元解码为 Unicode 认为的“符号”,您的词法分析器也只是将其视为字母。

这种简单形式的 UTF-8 词法分析可为您提供快速的性能和较低的内存开销。您不必将 UTF-8 解码为 Unicode 代码点,也不需要巨大的 Unicode 表来告诉您代码点是“符号”还是“空格”或其他什么。当然,这也是许多基于 ASCII 的 Lua 实现中自然会出现的情况。

所以大多数 Lua 实现都会这样做,即使只是偶然。做更多的事情需要刻意的努力。

它还允许用户使用 Unicode 字符序列作为标识符。这意味着某人可以轻松地用他们的母语(关键字之外)编写代码。

但这意味着混淆器有很多方法来创建“标识符”,而这些“标识符”只是无意义的字节字符串。事实上,由于 Unicode 中有多种方法可以“拼写”同一个明显的 Unicode 字符串(除非您直接检查字节),混淆器可以将在文本编辑器中呈现时出现的标识符设置为全部相同的文本,但实际上是不同的字符串。

关于lua - 为什么下面这段 Lua 代码完全有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55671742/

相关文章:

c - 从 lua 调用 c 函数比从 c 调用更快吗?

sockets - 如何检查 luasocket 库中的套接字是否关闭?

lua环境和模块

c++ - ffi.C 缺少所有符号的所有声明

lua - 如何在 Linux 上超过 64 位 LuaJIT 的 1gb 内存限制?

lua - 如何修改aerospike中ttl为-1的所有记录集的TTL?

c - 协程恢复上的 Lua 段错误

lua - 如何在 Windows 上将 LuaJIT 与 LuaRocks 集成?

c++ - 如何静态构建和链接 LuaJIT (VS 2013)

LuaJIT,如何将cdata转换为userdata?