加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 通过函数应用程序解析器组合器发出信号失败

发布时间:2020-12-16 18:36:01 所属栏目:安全 来源:网络整理
导读:我需要对解析器匹配进行比标准符号允许的更复杂的语法检查,并且我目前正在函数应用程序中执行它^^.示例简化方案是检查重复的关键字: def keywords: Parser[List[String]] = "[" ~ repsep(keyword,",") ~ "]" ^^ { case _ ~ ks ~ _ = ks.groupBy(x = x).filt
我需要对解析器匹配进行比标准符号允许的更复杂的语法检查,并且我目前正在函数应用程序中执行它^^.示例简化方案是检查重复的关键字:

def keywords: Parser[List[String]] = "[" ~ repsep(keyword,",") ~ "]" ^^ {
  case _ ~ ks ~ _ =>
    ks.groupBy(x => x).filter(_._2.length > 1).keys.toList match {
      case Nil => ks
      case x => throw new DuplicateKeywordsException(x)
    }
}

这是有效的,因为在我的解析器中会抛出异常,但我希望将失败捕获为ParseResult.Failure捕获它发生的位置的输入.我无法弄清楚如何从^^块中发出信号或使用其他构造来实现相同目的.

解决方法

好的,我遵循了Erik Meijer的建议,即沿着幸福的道路走下类型.看看如何在Scala编程中定义^^(与实际代码不同),我意识到它基本上只是一个Map函数:

def ?? [U](f: T => U): Parser[U] = new Parser[U] {
  def apply(in: Input) = p(in) match {
    case Success(x,in1) => Success(f(x),in1)
    case failure => failure
  }
}

基本上它是Parser [T] =>解析器[U].

解析器[T]本身是Input =>的函数. ParseResult [T]和^^只是通过提供apply方法定义一个新的解析器,在调用时要么将Success [T]转换为Success [U],要么只传递Failure.

为了实现在映射期间注入新故障的目标,我需要一个新的映射函数,它具有类似f:T =>的函数. [String,U],所以我可以发出错误信息或成功映射.我选择了Either with string,因为Failure只接受一个字符串消息.然后通过隐式类将此新映射函数添加到Parser [U]:

implicit class RichParser[+T](p: Parser[T]) {
  def ^^? [U](f: T => Either[String,U]): Parser[U] = new Parser[U] {
    def apply(in: Input) = p(in) match {
      case Success(x,in1) => f(x) match {
        case Left(error) => Failure(error,in1)
        case Right(x1) => Success(x1,in1)
      }
      case failure:Failure => failure
      case error:Error => error
    }
  }
}

现在关键字可以定义为:

def keywords: Parser[List[String]] = "[" ~ repsep(keyword,") ~ "]" ^^? {
  case _ ~ ks ~ _ =>
    ks.groupBy(x => x).filter(_._2.length > 1).keys.toList match {
      case Nil => Right(ks)
      case x => Left("found duplicate keywords: "+x.reduce[String] { case (a,b) => s"$a,$b"})
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读