如何使用解析器组合器强制执行失败?

时间:2018-02-12 20:23:51

标签: scala parser-combinators

假设我在一个更大的解析类中有一个解析器def,如下所示:

def thing: Parser[Thing] = stringTerm ^^ { tLabel => repo.getThing(tLabel).get }

repo.getThing返回一个Option [Thing]。好吧,假设找不到tLabel。我宁愿不在一个例外中把我的饼干扔掉。有没有一种更可控的方法可以在解析过程中冒出错误?

理想情况下,它会打到这种顶级电话:

    parse(freq, "johnny 121") match {
        case Success(matched,_) => println(matched)
        case Failure(msg,_) => println("FAILURE: " + msg)
        case Error(msg,_) => println("ERROR: " + msg)
    }

我可以将其冒泡到失败或错误吗?

1 个答案:

答案 0 :(得分:1)

您可以使用^?方法(也称为mapPartial)将PartialFunction应用于解析器结果,并使用Function.unlift转换A => Option[B]进入PartialFunction[A, B]

stringTerm ^? Function.unlift { tLabel => repo.getThing(tLabel) }
// Or equivalently
stringTerm ^? Function.unlift(repo.getThing)

^?也可以使用可选的第二个参数来解释失败:

stringTerm ^? (
  Function.unlift(repo.getThing),
  tLabel => s"Thing with label $tLabel not found"
)

或者,您可以使用>>方法(intoflatMap)根据前一个的结果对解析器进行参数化:

stringTerm >> { tLabel => 
  repo.getThing(tLabel) match {
    // `success` and `failure` create parsers that succeed or fail unconditionally
    // You can also use `err(message)` to fail with an `Error` instead
    case Some(thing) => success(thing)
    case None => failure(s"Thing with label $tLabel not found")
  } 
}