【问题标题】:Storing Lua script in Lua在 Lua 中存储 Lua 脚本
【发布时间】:2018-11-20 04:39:37
【问题描述】:

我有一个用 C++ 编写的应用程序,它可以显示、编辑和运行 Lua 脚本。此应用程序存储所有内容,包括项目文件中的完整 Lua 脚本。

这里的问题是项目文件的格式也是一个Lua文件,用C++写的(不是Lua引擎写项目文件)。

编辑器中的示例 Lua 脚本:

-- Message
local message =
[["First" line
Second line
Last line]]

现在,我想将上面的脚本保存在一个 lua 文件中。 示例项目文件:

-- Project file
projectName = "test"
options = {}
options.autoRun = false

-- Lua source
luaScript =
[=[
-- Message
local message =
[["First" line
Second line
Last line]]
]=]

我当然可以将 Lua 脚本包含在 [=[ ... ]=] 中(如示例中所示),但如果脚本也包含相同的序列,则它将不起作用。由于脚本是用户编写的任意脚本,我不能只是假设某个序列没有被使用。

有没有办法在 XML 中包含“原始”数据,例如 CData? 我会尽量避免对脚本进行编码,因为我希望它在项目文件中是可读的。

最简单的方法是 [ 和 ] 字符可以转义,但显然不能。

我可以将脚本分解为单独的字符串,将其转义并将它们连接起来:

-- Project file
projectName = "test"
options = {}
options.autoRun = false

-- Lua source
luaScript = "-- Message\n"..
            "local message =\n"..
            "[[\"First\" line\n"..
            "Second line\n"..
            "Last line]]\n"..

但这种解决方案并不容易直接在项目文件中阅读和编辑。

如果这是不可能的,那么最好得到确认,我很可能会使用编码方案而不是 B 计划。

解决方案
在探索了一些选项和 indeas 之后,我根据 lhf 的建议采用了解决方案。我已经为 Lua 编写器类编写了一些 C++,所以当我编写一个字符串时,我会检查它是否是一个多行字符串。如果是我只需在前面插入[====================================================================[ -- MULLTILINE BEGIN\r\n 并在字符串后面附加\r\n]====================================================================] -- MULLTILINE END,无需转义字符串。如果它是单行字符串,我不添加任何内容,只转义它。

添加 CR/LF 对和 cmets 的原因是为了方便用户直接在项目文件中编辑脚本。

script =
[====================================================================[ -- MULLTILINE BEGIN
-- Lua script engine 5.3.4
function onData(data,ch)
  print("A 'String' within a \"string\" within a [===[string]===]")
end

-- Multiline within Multiline
a = [=[
Spicy jalapeno bacon ipsum dolor amet ground round eu chicken,
venison turkey corned beef dolore exercitation pastrami nostrud
prosciutto in drumstick deserunt meatloaf. Pastrami jowl beef
ribs minim eu pariatur est et lorem kielbasa shoulder. Dolore
officia cupidatat, biltong tempor ut ham kielbasa magna bacon
salami. Turducken tri-tip tail reprehenderit tenderloin aliquip.
]=]

print(a)
]====================================================================] -- MULLTILINE END

读回字符串时,我只需在第一行查找-- MULTILINE BEGIN\r\n。如果它在那里,我只需删除包含 CR/LF 对和最后一个 CR/LF 对的行。由于-- MULLTILINE END 是多行之外的注释,因此它不会是字符串的一部分,也不需要删除,只需要在结束序列之前添加 CR/LF 对。

【问题讨论】:

    标签: c++ lua escaping raw-data


    【解决方案1】:

    您可以根据需要在长字符串引用[====[ 中使用任意数量的=。只需在字符串中找到最长的= 并添加一个=

    您也可以在 string.format 中使用%q,它将引用所有需要引用的字符。

    【讨论】:

    • 正如我所说,用户可能也会觉得这样做很有趣。这不能保证 100% 有效。
    • 长字符串机制旨在实现这一点。为什么示例不起作用?请添加到您的问题中。
    • 我已经在问题中解释过,用户可以编写任意 Lua 脚本,这意味着他可以在某处使用完全相同的“长”引用序列。我无法控制 Lua 脚本包含的内容。
    • 我忘了提到我正在用 C++ 编写 lua 配置文件,所以 string.format %q 将不起作用:/ 我已经更新了问题。要找到最长的 = 我需要解析整个脚本。但是我想如果不先分析 Lua 脚本就没有简单的解决方案。
    • 在探索了一些替代方案之后,这是最好的折衷方案。请参阅我更新的问题。
    猜你喜欢
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 2017-01-20
    • 2016-03-05
    • 1970-01-01
    • 2015-02-19
    相关资源
    最近更新 更多