(我正在使用 Lua 5.2 和 LPeg 0.12)
假设我有一个模式P
可以产生一些不确定数量的捕获(如果有的话),并且我想编写一个模式Q
来捕获P
以及之后的P
位置 -- 但要在. 本质上,如果结果为,那么我想要结果为。P
lpeg.match(P * lpeg.Cp(), str, i)
v1, v2, ..., j
lpeg.match(Q, str, i)
j, v1, v2, ...
P
这是否可以在每次匹配时都不必创建新表来实现?
大多数情况下,我想这样做是为了简化一些产生迭代器的函数。Lua 的无状态迭代器函数只获取一个控制变量,它需要是迭代器函数返回的第一个值。
在一个允许人们命名可变参数函数的最后一个参数的世界中,我可以这样写:
function pos_then_captures(pattern)
local function roll(..., pos)
return pos, (...)
end
return (pattern * lpeg.Cp()) / roll
end
唉。简单的解决方案是明智地使用lpeg.Ct()
:
function pos_then_captures(pattern)
-- exchange the order of two values and unpack the first parameter
local function exch(a, b)
return b, unpack(a)
end
return (lpeg.Ct(pattern) * lpeg.Cp()) / exch
end
或让来电者进行lpeg.match
打包/删除/插入/解包舞蹈。尽管后者听起来很恶心,但我可能会这样做,因为lpeg.Ct()
可能会对pos_then_captures
.
每次pattern
成功匹配时,其中任何一个都会创建一个新表,诚然这在我的应用程序中并不重要,但是有没有办法在没有任何打包解包魔法的情况下做到这一点?
我对 Lua 的内部不太熟悉,但感觉我真正想做的是从 Lua 的堆栈中弹出一些东西并将其放回其他地方,这似乎不是一个直接或有效的操作支持,但也许 LPeg 在这种特定情况下可以做的事情。