Scala 组合器解析器,>> 是什么意思?

2024-02-26

我对 scala 中的“>>”有点困惑。丹尼尔说在Scala 解析器组合器解析 xml? https://stackoverflow.com/questions/5271010/scala-parser-combinators-parsing-xml它可用于根据先前解析器的结果参数化解析器。有人能给我一些例子/提示吗?我已经读过 scaladoc 但仍然不明白。

thanks


正如我所说,它用于参数化解析器,但让我们通过一个示例来清楚地说明这一点。

让我们从一个简单的解析器开始,它解析一个数字后跟一个单词:

def numberAndWord = number ~ word
def number        = "\\d+".r
def word          = "\\w+".r

Under 正则表达式解析器 http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#scala.util.parsing.combinator.RegexParsers,这将解析“3 个水果”之类的内容。

现在,假设您还想要这些“n 件事”的列表。例如,“3种水果:香蕉、苹果、橙子”。让我们尝试解析它,看看它是如何进行的。

首先,我如何解析“N”个东西?碰巧的是,有一个repN method:

def threeThings = repN(3, word)

这将解析“香蕉苹果橙”,但不能解析“香蕉,苹果,橙子”。我需要一个分隔符。有repsep这提供了这一点,但这不会让我指定我想要的重复次数。因此,让我们自己提供分隔符:

def threeThings = word ~ repN(2, "," ~> word)

好吧,这句话。我们现在可以为三件事编写整个示例,如下所示:

def listOfThings = "3" ~ word ~ ":" ~ threeThings
def word         = "\\w+".r
def threeThings  = word ~ repN(2, "," ~> word)

这种方法是可行的,只是我在 3 中修复了“N”。我想让用户指定有多少个。这就是地方>>,也称为into(而且,是的,它是flatMap for Parser),进入。首先,我们来改变一下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]]。但是如何将参数传递给事物呢?我的意思是,这行不通:

def listOfThings = number ~ word ~ ":" ~ things(/* what do I put here?*/)

但我们可以这样重写:

def listOfThings = (number ~ word <~ ":") >> {
  case n ~ what => things(n.toInt)
}

这几乎已经足够了,只是我现在输了n and what:它只返回“列表(香蕉,苹果,橙子)”,而不是应该有多少,以及它们是什么。我可以这样做:

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:

def listOfThings   = for {
  nOfWhat  <- number ~ word <~ ":"
  n ~ what = nOfWhat
  list     <- things(n.toInt)
}  yield new ~(n.toInt, new ~(what, list))

我没有做n ~ what <- number ~ word <~ ":"因为那使用filter or withFilter在 Scala 中,这不是由Parsers。但这里还有另一种编写方式,它不具有完全相同的语义,但会产生相同的结果:

def listOfThings   = for {
  n    <- number
  what <- word
  _    <- ":" : Parser[String]
  list <- things(n.toInt)
}  yield new ~(n.toInt, new ~(what, list))

这甚至可能让人认为也许这样的说法“单子无处不在”可能有什么关系。 :-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 组合器解析器,>> 是什么意思? 的相关文章

随机推荐