P[Node].rep produces P[String] rather than array of nodes

72 Views Asked by At

I would expect the result for plusses to be some kind of array

case class Plus()
val plus: P[Plus] = P ("+") map {_ => Plus()}
val plusses: P[List[Plus]] = P ( plus.rep.! )  // type mismatch; found: Parser[String]  required: Parser[List[Plus]]

but compiler says

type mismatch; found : Parser[String] required: Parser[List[Plus]]

2

There are 2 best solutions below

0
On BEST ANSWER

Answer

First, you don't need to capture something with .! as you already have a result in the plus parser. The .rep then "creates" a parser that repeats the plus parser 0 to n times and concatenates the result into a Seq[Plus].

case class Plus()
val plus: P[Plus] = P ("+") map {_ ⇒ Plus()}
val plusses: P[Seq[Plus]] = P ( plus.rep )

Second, if using the repeat operation rep, Parsers return Seq and not List If you really need a list, use map to convert Seq to List.

val plussesAsList: P[List[Plus]] = P( plus.rep ).map( seq ⇒ seq.toList)
0
On

.! is "to capture the section of the input string the parser parsed" (see http://lihaoyi.github.io/fastparse/#Capture). So the return type of .! is String.

I think what you want is:

val plusses: P[List[Plus]] = P ( plus.rep ) map (_.toList)

Here's what you will get:

@ plusses.parse("+++")
res6: core.Result[List[Plus]] = Success(List(Plus(), Plus(), Plus()),3)