【问题标题】:How can I force a Failure with parser combinators?如何使用解析器组合器强制失败?
【发布时间】:2018-02-13 05:34:51
【问题描述】:

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

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)
    }

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

【问题讨论】:

    标签: scala parser-combinators


    【解决方案1】:

    您可以使用^? 方法(也称为mapPartial)将PartialFunction 应用于解析器结果,同时使用Function.unliftA => 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")
      } 
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      相关资源
      最近更新 更多