parsing – how do i throw exceptions with meaningful messages with a scala combination parser? – Education Career Blog

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: ParserRecord = "-" ~ 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 meaningful 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))
  }
}

Leave a Comment