在案例类(scala解析器)中添加repitition作为列表

时间:2015-06-14 12:01:16

标签: scala parser-combinators

我有以下解析器:

import scala.util.parsing.combinator.RegexParsers

class SimpleParser extends RegexParsers {

  override val skipWhitespace = false

  private val eol = sys.props("line.separator")

  def word: Parser[String] = "[a-z]+".r ^^ { _.toString }

  def freq: Parser[List[String]] = repsep(word, eol) ^^ {
    case word => word
  }

}

object TestSimpleParser extends SimpleParser {
  def main(args: Array[String]) = {
    parse(freq,
      """mike
        |john
        |sara
      """.stripMargin) match {
      case Success(matched,_) => println(matched)
      case Failure(msg,_) => println(msg)
      case Error(msg,_) => println(msg)
    }
  }
}

此执行的结果将是List(mike, john, sara),但它不是我想要的。

我想要以下案例类:

case class SomeEntity(list: List[String])

结果如下:

SomeEntity(List(mike), List(john), List(sara)).

我想添加尽可能多的列表,因为有新行的单词。 请不要过分关注列表中只有一个单词的事实。这只是我的问题的简化版本。 那么,我应该在解析器或案例类中更改什么?

1 个答案:

答案 0 :(得分:3)

案例类定义与预期输出不匹配。你正在寻找这个:

reset()

现在,如果您想要返回case class SomeEntity(list: List[String]*) { override def toString = this.getClass.getSimpleName+"("+list.mkString(", ")+")" } 实例,则解析器的类型将为SomeEntity

由于Parser[SomeEntity]会返回repsep,您需要将列表中的每个元素映射到单个列表中(以便获得List[String]),然后强制它使用List[List[String]]

将其视为varargs类型
:_*

根据您的输入,它输出:

 def freq: Parser[SomeEntity] = 
     repsep(word, eol) ^^ (list => new SomeEntity(list.map(List(_)) : _*))

您的案例类也可以将SomeEntity(List(mike), List(john), List(sara)) 作为参数。虽然我认为List[List[String]]是最正确的类型,但你肯定有理由要求这样做。

请注意,使用List[String]解析器的映射是多余的,您可以将其删除。