我正在尝试为书的内容列表等编写语法, 我可以简化为以下内容:
给予
input = [[
* A
** B
*** C
** D
*** E
* F
]]
然后输出应为此表:
{ "A" { "B", { "C" }, "D", { "E" } } "F" }
以下尝试是无效的(存在多个问题),但到目前为止,我仍然提供了大致思路。
local C, Cb, Cc, Cg, Cmt, Ct, P, R, V = lpeg.C, lpeg.Cb, lpeg.Cc, lpeg.Cg, lpeg.Cmt, lpeg.Ct, lpeg.P, lpeg.R, lpeg.V
function is_child(str, i, depth, new_depth)
return new_depth > depth
end
grammar = P {
'Begin';
Begin = Cg(Cc(0), 'depth') * V'Array',
Array = Ct(V'Element'^0),
Element = V'IsChild' * V'Array' + V'Letter',
IsChild = Cmt(Cb('depth') * Cg(V'Depth', 'new_depth'), is_child),
Depth = P'*'^1 / string.len,
Letter = P' ' * C(R'AZ') * P'\n',
}
我的想法是必须存储某种状态depth
(初始化为零),以确定输入的下一行代表同级节点还是子节点。因此,规则IsChild
会将新深度与旧深度进行比较并做出决定。
但是那是我所知道的。我不清楚如何将深度状态从depth
正确更新为new_depth
。深度只能增加1,但可以减少任何数量(例如E-> F减少2)。还存在一个问题,用于存储Cg
的{{1}}不返回任何值(除非包装在new_depth
中,在这里似乎不合适)。
因此,我很有可能认为这是错误的方法。也许有更多lpeg经验的人可以为返回上面给定的输出表提供一些帮助。