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位置であるため、もちろんここでは役に立ちません。