解析案例类列表

时间:2014-10-08 19:32:15

标签: list class scala parsing

我对scala相当新,我想解析一个案例类列表:

abstract class D
case class D0(a: Int, b: Int) extends D
case class D2(c: String, d: Int) extends D
case class D3(e: Int, f: String) extends D
case class D4(e: String, f: String, g: Int) extends D

我想解析List [D]的一个实例。 列表中有一个特殊的顺序,可以用类似BNF的表示法来解释:

rep(D0 -> D4 -> rep(D2 -> opt(rep(d3))))

D0之后是D4,然后是1-n D2,每个D2后跟1-n D3等等......

我想创建一个类型列表:

type T0 = (D0, D4, List[(D2, List[D3])])

到目前为止,我发现的所有解决方案都是丑陋且有状态​​的。 经验丰富的scala开发人员将如何实现这一目标?

谢谢

1 个答案:

答案 0 :(得分:4)

对我来说这看起来并不太丑(假设我正确理解了这个问题,这通常不称为解析):

type T1 = (D2, List[D3])

// MatchError if the list doesn't look the way you expected
def matchList(l: List[D]): List[T0] = l match {
  case (d0: D0) :: (d4: D4) :: tail => 
    val (d2d3s, tail1) = matchD2D3s(tail)
    (d0, d4, d2d3s) :: matchList(tail1)
  case Nil => Nil
}

def matchD2D3s(l: List[D]): (List[T1], List[D]) = l match {
  case (d2: D2) :: tail =>
    val (d3s, tail1) = tail.span(_.isInstanceOf[D3])
    val (otherD2D3s, tail2) = matchD2D3s(tail1)
    ((d2, d3s) :: otherD2D3s, tail2)
  case l => (Nil, l) // no d2s
}