我编写了一个基于 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 位置,因此当然在这里没有用处。