7

是否可以从 C/C++ 获取 lua 堆栈中的所有错误?这是我尝试过的

C++

int main()
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);

    if (luaL_loadfile(L, "LuaBridgeScript.lua"))
    {
        throw std::runtime_error("Unable to find lua file");
    }

    int error = lua_pcall(L, 0, 0, 0);
    while (error && lua_gettop(L))
    {
        std::cout << "stack = " << lua_gettop(L) << "\n";
        std::cout << "error = " << error << "\n";
        std::cout << "message = " << lua_tostring(L, -1) << "\n";
        lua_pop(L, 1);
        error = lua_pcall(L, 0, 0, 0);
    }
}

路亚:

printMessage("hi")
printMessage2("hi2")

输出:

stack = 1
error = 2
message = LuaBridgeScript.lua:1: attempt to call global 'printMessage' <a nil value>

即使堆栈大小为 0 或负数,我也尝试过循环,但我不明白堆栈如何为负数,并且在几次尝试后程序崩溃。

4

2 回答 2

5

To wrap up my comments into an answer:

According to Lua docs on lua_pcall, pcall returns on either success (end of chunk) or first error thrown. So in the latter case, it will push only one message to the stack. It will never continue execution after the first error.

What you're trying to achieve is checking for possible errors in the file. In statically typed languages like C, every variable has to be defined at compile time, so the compiler can spot instances of calling non existing function.

Lua, however, is a dynamically typed language, in which variables have no types but rather are placeholders for values (which do have types). This means, that Lua cannot tell in advance whether printMessage is a function, a string, a value or if it doesn't exist (nil). It is only at run time when the variable is about to be called that Lua checks its type.

It is therefore not possible to achieve what you want that way. Running the code beyond the first unhandled error is pointless as well, as the error may render assumptions in subsequent fragments invalid (for instance about global variables that the non existing function should have set) - it would be a mess.

As to syntax errors, these are generally caught when compiling the source file, that is while loading. However, Lua parser stops at first encountered syntax error. This is due to the fact that many times syntax errors in one place invalidate everything that follows it. As Etan pointed out in his comment, many parsers report subsequent errors that disappear or change once you've fixed errors that precede them. It is also true for even heavy weight parsers like those in MSVS.

于 2014-08-13T17:47:25.927 回答
1

(按照您在评论中澄清的问题)不可能报告多个语法错误(只报告第一个);所以在下面的片段中只报告了第 1 行的第一个错误:

if true the --<-- first syntax error
end
if false the --<-- second syntax error
end

但是,您可以编写自己的解析器(或修改现有的 Lua 解析器之一),即使在发现错误后仍会继续处理。例如,您可以查看 David Manura 的松散解析器是如何工作的。

不能报告多个运行时错误(只报告第一个);所以在下面的片段中 pcall 只会报告第一个错误:

pcall(function()
  nonExistingFunction1() --<-- only this error will be reported
  nonExistingFunction2()
end)
于 2014-08-13T15:47:56.547 回答