I'd like to throw an exception when the language doesn't conform to the grammar for a scala combination parser. Here's an example of a rule:
def record: Parser[Record] = "-" ~ opt(recordLabel) ~ repsep(column, ",") ^^ {
case "-" ~ label ~ columns => new Record(label, columns)
}
Let's say in the repsep(column, ",") part, they accidently make a string like this
a, b, c, d,
This is not valid because it ends with a "," that isn't suppose to be there. Rather than the parser just stopping when you call parseAll(), how do you make this throw a m开发者_Python百科eaningful exception that is human readable? (Custom text, line number, etc.)
EDIT: Okay, I found something that works, but I am not satisfied with it's customizability:
def loadFrom(filename: String) {
val source =
Source.fromFile(filename).getLines.mkString("\n")
val parseResult = parseAll(tables, source)
if(!parseResult.successful) {
throw new TestDataParseException(parseResult.toString)
}
}
The toString prints an okay message, but it prints weird stuff like wanting "\z" when it found a space instead (which sometimes looks like a block/square in my IDE). I'd rather say, "Hey, you forgot a comma!"
The line numbers/columns do print out in the form of [x.y]. I'd actually like to show [Line: x, Column: y] because people will know what that is more intuitively.
Thanks
parseAll(tables, source) match {
case Success(ast, _) => //do something
case NoSuccess(msg, next) => {
println("Failed at line %s, column %s: %s".format(
next.pos.line, next.pos.column, msg))
}
}
精彩评论