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"}) } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
热点阅读