添加重复作为列表以防 class(scala 解析器)

Add repitition as list in case class (scala parser)

我有以下解析器:

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),但这不是我想要的。

我想要以下案例class:

case class SomeEntity(list: List[String])

结果如下:

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

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

大小写 class 定义与您预期的输出不匹配。您正在寻找这个:

case class SomeEntity(list: List[String]*) {
    override def toString = this.getClass.getSimpleName+"("+list.mkString(", ")+")"
}

现在,如果您想取回一个 SomeEntity 实例,解析器的类型将为 Parser[SomeEntity]

因为repsep会给你一个List[String],你需要将列表中的每个元素映射到一个单例列表中(这样你就得到一个List[List[String]])然后你强制它将其视为具有 :_*

的可变参数类型
 def freq: Parser[SomeEntity] = 
     repsep(word, eol) ^^ (list => new SomeEntity(list.map(List(_)) : _*))

根据您的输入,它输出:

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

您的案例 class 也可以使用 List[List[String]] 作为参数。尽管 List[String] 在我看来是最正确的类型,但您当然有理由要求它。

请注意,您与 word 解析器的映射是多余的,您可以将其删除。