首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用LPeg发出解析错误的信号?

如何用LPeg发出解析错误的信号?
EN

Stack Overflow用户
提问于 2016-07-30 01:55:06
回答 1查看 390关注 0票数 2

我正在编写一个基于LPeg的解析器。如何才能使解析错误返回nil, errmsg

我知道我可以使用error(),但据我所知,这会产生一个正常的错误,而不是nil, errmsg

代码是pretty long,但相关部分如下:

代码语言:javascript
复制
local eof = lpeg.P(-1)
local nl = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n" + eof -- \r for winblows compat
local nlnoeof = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n"
local ws = lpeg.S(" \t")
local inlineComment = lpeg.P("`") * (1 - (lpeg.S("`") + nl * nl)) ^ 0 * lpeg.P("`")
local wsc = ws + inlineComment -- comments count as whitespace
local backslashEscaped
= lpeg.P("\\ ") / " " -- escaped spaces
+ lpeg.P("\\\\") / "\\" -- escaped escape character
+ lpeg.P("\\#") / "#"
+ lpeg.P("\\>") / ">"
+ lpeg.P("\\`") / "`"
+ lpeg.P("\\n") -- \\n newlines count as backslash escaped
+ lpeg.P("\\") * lpeg.P(function(_, i)
    error("Unknown backslash escape at position " .. i) -- this error() is what I wanna get rid of.
  end)
local Line = lpeg.C((wsc + (backslashEscaped + 1 - nl))^0) / function(x) return x end * nl * lpeg.Cp()

当出现无效转义时,我希望Line:match(...)返回nil, errmsg

EN

回答 1

Stack Overflow用户

发布于 2016-09-03 13:30:41

LPeg本身并不提供特定的函数来帮助您进行错误报告。您的问题的一个快速解决方案是创建一个protected call (pcall)来匹配,如下所示:

代码语言:javascript
复制
local function parse(text)
  local ok, result = pcall(function () return Line:match(text) end)
  if ok then
    return result
  else
    -- `result` will contain the error thrown. If it is a string
    -- Lua will add additional information to it (filename and line number).
    -- If you do not want this, throw a table instead like `{ msg = "error" }`
    -- and access the message using `result.msg`
    return nil, result
  end
end

但是,这也会捕获任何其他错误,这可能不是您想要的。更好的解决方案是使用LPegLabel。LPegLabel是LPeg的扩展,它添加了对标记故障的支持。只需将require"lpeg"替换为require"lpeglabel",然后使用lpeg.T(L)抛出标签,其中L是1-255之间的整数(0用于常规的PEG失败)。

代码语言:javascript
复制
local unknown_escape = 1
local backslashEscaped = ... + lpeg.P("\\") * lpeg.T(unknown_escape)

现在,如果抛出了标签,Line:match(...)将返回nil, label, suffix (suffix是剩余的未处理的输入,您可以使用它通过其长度来计算错误位置)。这样,您就可以根据标签打印出相应的错误消息。对于更复杂的语法,您可能需要一种更系统的方式来映射错误标签和消息。请查看LPegLabel存储库的自述文件中的文档,了解如何做到这一点的示例。

LPegLabel还允许您顺便捕捉语法中的标签(通过标签选择);这对于实现错误恢复之类的东西很有用。有关标记的故障和示例的更多信息,请查看文档。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38664815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档