I am little bit confusing about ">>" in scala. Daniel said in Scala parser combinators parsing xml? that it could be used to parameterize the parser base on result from previous parser. Could someone give me some example/hint ? I already read scaladoc but still not understand it.
thanks
As I said, it serves to parameterize a parser, but let's walk through an example to make it clear.
Let's start with a simple parser, that parses a number follow by a word:
Under RegexParsers, this will parse stuff like "3 fruits".
Now, let's say you also want a list of what these "n things" are. For example, "3 fruits: banana, apple, orange". Let's try to parse that to see how it goes.
First, how do I parse "N" things? As it happen, there's a
repN
method:That will parse "banana apple orange", but not "banana, apple, orange". I need a separator. There's
repsep
that provides that, but that won't let me specify how many repetitions I want. So, let's provide the separator ourselves:Ok, that words. We can write the whole example now, for three things, like this:
That kind of works, except that I'm fixing "N" in 3. I want to let the user specify how many. And that's where
>>
, also known asinto
(and, yes, it isflatMap
forParser
), comes into. First, let's changethreeThings
:This is slightly more complicated than you might have expected, because I'm forcing it to return
Parser[List[String]]
. But how do I pass a parameter to things? I mean, this won't work:But we can rewrite that like this:
That is almost good enough, except that I now lost
n
andwhat
: it only returns "List(banana, apple, orange)", not how many there ought to be, and what they are. I can do that like this:Just a final comment. You might have wondered asked yourself "what do you mean
flatMap
? Isn't that a monad/for-comprehension thingy?" Why, yes, and yes! :-) Here's another way of writinglistOfThings
:I'm not doing
n ~ what <- number ~ word <~ ":"
because that usesfilter
orwithFilter
in Scala, which is not implemented byParsers
. But here's even another way of writing it, that doesn't have the exact same semantics, but produce the same results:This might even give one to think that maybe the claim that "monads are everywhere" might have something to it. :-)
The method
>>
takes a function that is given the result of the parser and uses it to contruct a new parser. As stated, this can be used to parameterize a parser on the result of a previous parser.Example
The following parser parses a line with
n + 1
integer values. The first valuen
states the number of values to follow. This first integer is parsed and then the result of this parse is used to construct a parser that parsesn
further integers.Parser definition
The following line assumes, that you can parse an integer with
parseInt: Parser[Int]
. It first parses an integer valuen
and then uses>>
to parsen
additional integers which form the result of the parser. So the initialn
is not returned by the parser (though it's the size of the returned list).Valid inputs
Invalid inputs