I have following 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)
}
}
}
The result of this execution will be List(mike, john, sara)
but it isn't what i want.
I'd like to have the following case class:
case class SomeEntity(list: List[String])
And the result will be the following:
SomeEntity(List(mike), List(john), List(sara)).
I want to add as much Lists as there are words with new lines. Please, don't put a big attention on the fact that there is just one word in a list. It is just a simplified version of my issue. So, what should i change in the parser or in case class?
The case class definition does not match your expected output. You're looking for this:
Now if, you want to get back a
SomeEntity
instance, the type of the Parser will beParser[SomeEntity]
.As
repsep
will give you back aList[String]
, you need to map each element in the list into a singleton list (so that you get aList[List[String]]
) and then you forces it to see it as a varargs type with:_*
Given your input, it outputs:
Your case class could also take a
List[List[String]]
as parameter. Although aList[String]
would be the most correct type in my opinion, but you certainly have reasons to require this.Note that your mapping with the
word
parser is redundant, you could remove it.