如何在不运行 Lua 脚本的情况下识别未初始化的变量

我想编写一些 Lua 代码,像这样:

y=x+1

并能够获取所有变量的名称(在本例中为 xy),以便我在调用的 C++ 程序中从它们中读取/写入。问题在于 x 未初始化,因此此块将不会执行,因此两个变量都不会出现在全局表中。我的当前解决方法是要求用户明确声明它们想要在外部初始化 x(以及如何初始化它),然后我将 Lua 脚本前置以适当的 x 声明,以便最终脚本如下:

x= /*在 Lua 脚本之外计算的一些值*/
y=x+1

虽然这可以工作,但我真的希望有一种方法可以自动列出 Lua 代码中的所有未初始化变量并将其呈现给用户,而不是用户自己去记得明确声明。解析 Lua 代码而不执行它的函数可能是我想要的。我尝试了函数 luaL_loadstring,但 xy 没有出现在全局表中。

由于这有点模糊,我将给出一个使用案例。我的 C++ 代码基本上对函数执行优化,例如找到根或最大值。我希望用户能够定义自定义函数(以 Lua 脚本的形式),通常将具有一个或多个输入和一个或多个输出。用户将定义优化器应该操作哪些参数。例如,用户可能想要找到 y = x^2 的最小值。我希望它的工作方式是用户编写一个由 y = x^2 组成的 Lua 脚本,然后告诉优化器变化 x 以最小化 y。在优化器的每个迭代中,当前对 x 的猜测将自动粘贴到用户脚本中,然后执行该脚本,然后从 Lua 状态中获取 y 的值以反馈给优化器。这是我目前的实现方式,但从用户体验的角度来看有些笨拙,因为用户必须手动声明 x 是 Lua 变量。当有许多需要手动声明的变量时,这变得繁琐。如果我能自动扫描脚本并向用户显示其未声明的变量列表,然后让他们使用拖放和其他 GUI 辅助功能进行手动声明,那就好多了。

点赞
用户734069
用户734069

Lua 不是用来这样工作的。Lua/C 的互操作是要 协作 的;它不应该是 C 可以随意做任何想做的事情。

在你的例子中,如果你有一个 Lua 脚本,它应该从 C 取一个值并将该值加 1 返回,然后你在 Lua 中这样写:

local x = ... -- 获取块的第一个参数。
return x + 1  -- 将值加上 1 并返回它。

你将这个字符串编译成一个 Lua 块,像调用 Lua 函数一样调用它。你将要操作的值传递给它,然后从 Lua 栈中获取返回值。

这个想法 不是 C 代码可以随意地进入 Lua 脚本并将数据随意插入。上面的代码块从用户那里获得参数,并向用户提供返回值。这通常是 C 与 Lua 交互的方式。

是的,你可以向全局变量中写入值,并让 Lua 脚本读取它们,并将其“结果”写入外部代码读取的全局变量中。但这不是与脚本交互的最有效的方式。

我真的很想有一种自动列出所有未初始化变量的方法。

在 Lua 中没有“未初始化的变量”。不是你所想的那样。

是的,有全局变量。但该全局变量是否具有值 不是 Lua 脚本可以控制的。全局变量毕竟是 全局 的;你可以从 外部 的脚本中设置全局变量(例如 lua_setglobal)。如果你这样做了,那么从它读取的脚本将读取你设置的值。但它并不知道任何有关此的信息。

2018-12-17 18:38:00
用户8291949
用户8291949

你需要的是一个静态代码分析器/Lua 语言的检查工具。可以看看 Luacheck:

Luacheck 是一个针对 Lua 语言的静态分析器和检查工具。它能检测出使用未定义全局变量、未使用变量和值、访问未初始化变量、无法到达的代码等各种问题。大多数检查方面都可以配置:可以定义自定义项目相关的全局变量、选择 Lua 标准库的版本的一组标准全局变量、根据相关变量的类型和名称过滤警告等。这些选项可以在命令行上使用,也可以作为 Lua 注释直接放入检查的文件中,或放在配置文件中。

还有 Lualint,以及类似的 Lua 语言检查工具,适用于 AtomVSCode 或你喜欢的 IDE。

2018-12-18 01:13:46