Parsing Scala:将combinators解析器中的parseresult(~)展平到列表中?
我从组合库中编写了一些解析器。我想要一个将任意大小的nest~转换为列表的通用函数。如何做到这一点 下面是我使用的解析器示例(我真正的解析器有一个很长的链~所以我想避免使用下面注释中的当前解决方案) 这是一个很好(而且相当简单)的应用程序,适用于中举例说明的那种泛型编程技术 根据你的定义Parsing Scala:将combinators解析器中的parseresult(~)展平到列表中?,parsing,scala,combinators,Parsing,Scala,Combinators,我从组合库中编写了一些解析器。我想要一个将任意大小的nest~转换为列表的通用函数。如何做到这一点 下面是我使用的解析器示例(我真正的解析器有一个很长的链~所以我想避免使用下面注释中的当前解决方案) 这是一个很好(而且相当简单)的应用程序,适用于中举例说明的那种泛型编程技术 根据你的定义 object CombinatorParser extends RegexParsers { lazy val a = "a" lazy val b = "b" lazy val c = "c"
object CombinatorParser extends RegexParsers {
lazy val a = "a"
lazy val b = "b"
lazy val c = "c"
lazy val content = a ~ b ~ c
}
我们可以递归地定义一个类型类,它将按如下方式展平它的结果
import CombinatorParser._
首先,我们定义一个特征,它(抽象地)将任意匹配的M
展平为列表[字符串]
trait Flatten[M] extends (M => List[String]) {
def apply(m : M) : List[String]
}
然后我们为我们感兴趣的M
的所有形状提供类型类实例:在本例中,String
、A~B
和ParseResult[T]
(其中A
、B
和T
都是有flatte
实例的类型)
最后,我们可以定义一个方便的函数来简化应用Flatten
实例来解析结果
def flatten[P](p : P)(implicit flatten : Flatten[P]) = flatten(p)
现在我们准备好出发了
val testChar = "abc"
val output = parseAll(content, testChar)
println(output) // ((a~b)~c) but I want List(a, b, c)
val flattenedOutput = flatten(output)
println(flattenedOutput) // List(a, b, c)
如果您喜欢没有泛型编程的解决方案
def flatten(res: Any): List[String] = res match {
case x ~ y => flatten(x) ::: flatten(y)
case None => Nil
case Some(x) => flatten(x)
case x:String => List(x)
}
val testChar = "abc"
val output = CombinatorParser.parseAll(CombinatorParser.content, testChar).getOrElse(None)
println(flatten(output))
我认为那是不可能的。你不能把你的链条分成小块吗?你到底想干什么?也许如果你多给点背景,别人会有更好的解决办法。
val testChar = "abc"
val output = parseAll(content, testChar)
println(output) // ((a~b)~c) but I want List(a, b, c)
val flattenedOutput = flatten(output)
println(flattenedOutput) // List(a, b, c)
def flatten(res: Any): List[String] = res match {
case x ~ y => flatten(x) ::: flatten(y)
case None => Nil
case Some(x) => flatten(x)
case x:String => List(x)
}
val testChar = "abc"
val output = CombinatorParser.parseAll(CombinatorParser.content, testChar).getOrElse(None)
println(flatten(output))