如何进一步改进Scala语法分析器中的错误消息
我编写了一个基于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
我只是复制这些信息:
有用的增强功能是记录重要令牌的输入位置(行号和列号)。 要做到这一点,你必须做三件事:
和
最后,确保源跟踪位置。 对于流,你可以简单地使用scala.util.parsing.input.StreamReader; 对于字符串,请使用scala.util.parsing.input.CharArrayReader。
我现在正在玩它,所以我会稍后尝试添加一个简单的示例
在这种情况下,您可能会使用err
, failure
和~!
生产规则专门用于匹配错误。
上一篇: How to further improve error messages in Scala parser
下一篇: CRXIR2 doesn't work with VS2010 on Windows 7 nor on Vista