我有以下解析器:
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)).
我想添加尽可能多的列表,因为有新行的单词。 请不要过分关注列表中只有一个单词的事实。这只是我的问题的简化版本。 那么,我应该在解析器或案例类中更改什么?
答案 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]]
:_*
根据您的输入,它输出:
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]
解析器的映射是多余的,您可以将其删除。