如何进一步改进基于 Scala 解析器组合器的解析器中的错误消息?

2023-12-27

我编写了一个基于 Scala 解析器组合器的解析器:

class SxmlParser extends RegexParsers with ImplicitConversions with PackratParsers {
    [...]
    lazy val document: PackratParser[AstNodeDocument] =
        ((procinst | element | comment | cdata | whitespace | text)*) ^^ {
            AstNodeDocument(_)
        }
    [...]
}
object SxmlParser {
    def parse(text: String): AstNodeDocument = {
        var ast = AstNodeDocument()
        val parser = new SxmlParser()
        val result = parser.parseAll(parser.document, new CharArrayReader(text.toArray))
        result match {
            case parser.Success(x, _) => ast = x
            case parser.NoSuccess(err, next) => {
                tool.die("failed to parse SXML input " +
                    "(line " + next.pos.line + ", column " + next.pos.column + "):\n" +
                    err + "\n" +
                    next.pos.longString)
            }
        }
        ast
    }
}

通常,生成的解析错误消息相当不错。但有时它会变得只是

sxml: ERROR: failed to parse SXML input (line 32, column 1):
`"' expected but `' found
^

如果引号字符未关闭且解析器到达 EOT,则会发生这种情况。我想在这里看到的是(1)当解析器期望 '"' (我有多个)时,解析器处于什么生成式中,以及(2)此生成式在输入中开始解析的位置(这是一个指示符,其中开头引号在输入中)。有谁知道我如何改进错误消息,并在错误发生时包含有关实际内部解析状态的更多信息(也许可以在此处合理给出生产规则堆栈跟踪或其他任何内容,以便更好地识别顺便说一句,上面的“第 32 行,第 1 列”实际上是 EOT 位置,因此当然在这里没有用。


我还不知道如何处理(1),但当我发现这个网页时我也在寻找(2):

https://wiki.scala-lang.org/plugins/viewsource/viewpagesrc.action?pageId=917624 https://wiki.scala-lang.org/plugins/viewsource/viewpagesrc.action?pageId=917624

我只是复制信息:

一个有用的增强功能是记录重要标记的输入位置(行号和列号)。为此,您必须做三件事:

  • 使每个输出类型扩展 scala.util.parsing.input.Positional
  • 调用 Parsers.positioned() 组合器
  • 使用记录行和列位置的文本源

and

最后,确保源跟踪位置。对于流,您可以简单地使用 scala.util.parsing.input.StreamReader;对于字符串,请使用 scala.util.parsing.input.CharArrayReader。

我目前正在使用它,因此稍后我将尝试添加一个简单的示例

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何进一步改进基于 Scala 解析器组合器的解析器中的错误消息? 的相关文章

随机推荐