Parsing Scala:将combinators解析器中的parseresult(~)展平到列表中?

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"

我从组合库中编写了一些解析器。我想要一个将任意大小的nest~转换为列表的通用函数。如何做到这一点

下面是我使用的解析器示例(我真正的解析器有一个很长的链~所以我想避免使用下面注释中的当前解决方案)

这是一个很好(而且相当简单)的应用程序,适用于中举例说明的那种泛型编程技术

根据你的定义

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