如何使用scala组合解析器抛出有意义消息的异常?

ege*_*ari 6 grammar parsing scala

当语言不符合scala组合解析器的语法时,我想抛出一个异常.这是一个规则的例子:

def record: Parser[Record] = "-" ~ opt(recordLabel) ~ repsep(column, ",") ^^ {
    case "-" ~ label ~ columns => new Record(label, columns)
}
Run Code Online (Sandbox Code Playgroud)

让我们说在repsep(列,",")部分,他们意外地创建一个像这样的字符串

a, b, c, d,
Run Code Online (Sandbox Code Playgroud)

这是无效的,因为它以","结束,而不是假设存在.当你调用parseAll()时,而不是解析器只是停止,你如何使这个抛出一个人类可读的有意义的异常?(自定义文本,行号等)

编辑:好的,我发现了一些有用的东西,但我对它的可定制性不满意:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

toString打印一个好的消息,但是当它找到一个空格时(它有时看起来像我的IDE中的块/方块)它打印出奇怪的东西,比如想要"\ z".我宁愿说,"嘿,你忘了逗号!"

行号/列以[xy]的形式打印出来.我实际上想要显示[Line:x,Column:y],因为人们会更直观地知道这是什么.

谢谢

Mar*_*amy 7

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))
  }
}
Run Code Online (Sandbox Code Playgroud)