Я кодировал парсер на основе комбинаторов парсера 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 и, следовательно, здесь, конечно, бесполезна.