Lpeg:如何控制输出树的深度?

时间:2019-03-18 16:43:00

标签: lua peg lpeg

我正在尝试为书的内容列表等编写语法, 我可以简化为以下内容:

给予

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经验的人可以为返回上面给定的输出表提供一些帮助。

0 个答案:

没有答案