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

Ral*_*all 7 error-handling scala parser-combinators

我编写了一个基于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
    }
}
Run Code Online (Sandbox Code Playgroud)

通常,生成的解析错误消息相当不错.但有时它变得公正

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

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

Dan*_*ral 1

在这种情况下,您可以使用err,failure和 以及~!专门为匹配错误而设计的生产规则。