如何进一步改善基于Scala语法分析器 - 组合器的解析器中的错误消息?
问题描述:
我基于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位置,因此没有使用这里,当然。
答
在这种情况下,可能使用err
,failure
和~!
与设计的生产规则专门匹配错误。
答
我还不知道如何处理(1),但我也一直在寻找(2)当我发现这个网页:
https://wiki.scala-lang.org/plugins/viewsource/viewpagesrc.action?pageId=917624
我只是复制信息:
一个有用的增强功能是记录重要令牌的输入位置(行号和列号)。要做到这一点,你必须做三两件事:
- 使每个输出类型扩展scala.util.parsing.input.Positional
- 调用Parsers.positioned()Combinator的
- 使用文本源的记录的行和列位置
和
最后,确保源跟踪位置。对于流,你可以简单地使用scala.util.parsing.input.StreamReader;对于字符串,请使用scala.util.parsing.input.CharArrayReader。
我目前玩它,所以我会尝试添加一个简单的例子,以后
现在我可以证实,这样做是正确的(,真的很容易!)。它对我来说工作得很好 – Vinz 2010-06-29 09:15:22
提供的链接似乎已经死了。 – jbx 2013-11-27 00:44:33
感谢您报告死链接,我找到了同样解释的另一个来源。 – Vinz 2013-12-09 09:00:01