Scala组合器解析器,什么是>?意思是? [英] Scala combinator parser, what does >> mean?
问题描述
我对scala中的">>"感到困惑. Daniel在 Scala解析器组合器解析xml中说过说,它可以用于参数化解析器基于先前解析器的结果.有人可以给我一些例子/提示吗?我已经阅读了scaladoc,但仍然不明白.
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.
谢谢
推荐答案
正如我所说,它用于对解析器进行参数化,但是让我们通过一个例子来阐明它.
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:
def numberAndWord = number ~ word
def number = "\\d+".r
def word = "\\w+".r
在下RegexParsers ,这将解析"3个水果"之类的内容.
Under RegexParsers, this will parse stuff like "3 fruits".
现在,假设您还想要这些"n事物"的清单.例如,"3个水果:香蕉,苹果,橙子".让我们尝试对其进行分析,以了解其进展.
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.
首先,我该如何解析"N"个东西?碰巧的是,有一个repN
方法:
First, how do I parse "N" things? As it happen, there's a repN
method:
def threeThings = repN(3, word)
这将解析香蕉苹果橙",而不是香蕉,苹果,橙".我需要一个分隔符.有repsep
可以提供该功能,但不能让我指定所需的重复次数.因此,让我们自己提供分隔符:
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:
def threeThings = word ~ repN(2, "," ~> word)
好吧,那句话.现在,我们可以为三个示例编写整个示例,如下所示:
Ok, that words. We can write the whole example now, for three things, like this:
def listOfThings = "3" ~ word ~ ":" ~ threeThings
def word = "\\w+".r
def threeThings = word ~ repN(2, "," ~> word)
这种工作方式,除了我要在3中固定"N"外,我想让用户指定数量.这就是>>
的地方,也称为into
(是的,对于Parser
是flatMap
).首先,让我们更改threeThings
:
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 as into
(and, yes, it is flatMap
for Parser
), comes into. First, let's change threeThings
:
def things(n: Int) = n match {
case 1 => word ^^ (List(_))
case x if x > 1 => word ~ repN(x - 1, "," ~> word) ^^ { case w ~ l => w :: l }
case x => err("Invalid repetitions: "+x)
}
这比您预期的要复杂一些,因为我强迫它返回Parser[List[String]]
.但是,如何将参数传递给事物呢?我的意思是,这行不通:
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:
def listOfThings = number ~ word ~ ":" ~ things(/* what do I put here?*/)
但是我们可以这样重写:
But we can rewrite that like this:
def listOfThings = (number ~ word <~ ":") >> {
case n ~ what => things(n.toInt)
}
那几乎够了,除了我现在丢失了n
和what
:它只返回列表(香蕉,苹果,橙子)",而不是应该有多少,以及它们是什么.我可以这样:
That is almost good enough, except that I now lost n
and what
: it only returns "List(banana, apple, orange)", not how many there ought to be, and what they are. I can do that like this:
def listOfThings = (number ~ word <~ ":") >> {
case n ~ what => things(n.toInt) ^^ { list => new ~(n.toInt, new ~(what, list)) }
}
def number = "\\d+".r
def word = "\\w+".r
def things(n: Int) = n match {
case 1 => word ^^ (List(_))
case x if x > 1 => word ~ repN(x - 1, "," ~> word) ^^ { case w ~ l => w :: l }
case x => err("Invalid repetitions: "+x)
}
最后一条评论.您可能会想问自己您是什么意思flatMap
?这不是单子/理解性吗?" 为什么,是的,是的! :-)这是另一种编写listOfThings
的方法:
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 writing listOfThings
:
def listOfThings = for {
nOfWhat <- number ~ word <~ ":"
n ~ what = nOfWhat
list <- things(n.toInt)
} yield new ~(n.toInt, new ~(what, list))
我没有做n ~ what <- number ~ word <~ ":"
,因为它在Scala中使用了filter
或withFilter
,而Parsers
并未实现.但是这里还有另一种写法,它不具有完全相同的语义,但是产生相同的结果:
I'm not doing n ~ what <- number ~ word <~ ":"
because that uses filter
or withFilter
in Scala, which is not implemented by Parsers
. But here's even another way of writing it, that doesn't have the exact same semantics, but produce the same results:
def listOfThings = for {
n <- number
what <- word
_ <- ":" : Parser[String]
list <- things(n.toInt)
} yield new ~(n.toInt, new ~(what, list))
这甚至可能使人们认为,也许单子无处不在" 的说法可能有所帮助. :-)
This might even give one to think that maybe the claim that "monads are everywhere" might have something to it. :-)
这篇关于Scala组合器解析器,什么是>?意思是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!