理解 Scala 解析器组合器中的波浪号 [英] Understanding the tilde in Scala's parser combinators

查看:35
本文介绍了理解 Scala 解析器组合器中的波浪号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Scala 的新手,在阅读有关解析器组合器的内容时​​(背后的魔法解析器组合器Scala 中的特定领域语言)我遇到了这样的方法定义:

I'm fairly new to Scala and while reading about parser combinators(The Magic Behind Parser Combinators, Domain-Specific Languages in Scala) I came across method definitions like this:

def classPrefix = "class" ~ ID ~ "(" ~ formals ~ ")"

我一直在阅读 scala.util.parsing.Parsers 的 API 文档,它定义了一个名为 (波浪号) 的方法,但我仍然不太了解它在上面的示例中的用法.在那个例子中(波浪号)是一个在 java.lang.String 上调用的方法,它没有那个方法并导致编译器失败.我知道(波浪号)被定义为

I've been reading throught the API doc of scala.util.parsing.Parsers which defines a method named (tilde) but I still dont't really understand its usage in the example above. In that example (tilde) is a method which is called on java.lang.String which doesn't have that method and causes the compiler to fail. I know that (tilde) is defined as

case class ~ [+a, +b] (_1: a, _2: b)

但这对上面的例子有什么帮助?

but how does this help in the example above?

如果有人能给我提示以了解这里发生的事情,我会很高兴.预先非常感谢您!

I'd be happy if someone could give me a hint to understand what's going on here. Thank you very much in advance!

一月

推荐答案

这里的结构有点棘手.首先,请注意您总是将这些东西定义在内部某个解析器的子类中,例如class MyParser 扩展了 RegexParsers.现在,您可能会注意到 RegexParsers 中的两个隐式定义:

The structure here is a little bit tricky. First, notice that you always define these things inside a subclass of some parser, e.g. class MyParser extends RegexParsers. Now, you may note two implicit definitions inside RegexParsers:

implicit def literal (s: String): Parser[String]
implicit def regex (r: Regex): Parser[String]

这些将做的是获取任何字符串或正则表达式并将它们转换为与该字符串或正则表达式匹配的解析器作为标记.它们是隐式的,所以它们会在任何需要的时候被应用(例如,如果你在 Parser[String] 上调用一个方法,那个 String(或 正则表达式)没有).

What these will do is take any string or regex and convert them into a parser that matches that string or that regex as a token. They're implicit, so they'll be applied any time they're needed (e.g. if you call a method on Parser[String] that String (or Regex) does not have).

但是这个 Parser 是什么东西?它是在 Parsers 中定义的内部类,RegexParser 的超特征:

But what is this Parser thing? It's an inner class defined inside Parsers, the supertrait for RegexParser:

class Parser [+T] extends (Input) ⇒ ParseResult[T]

看起来它是一个接受输入并将其映射到结果的函数.嗯,有道理!你可以看到它的文档 这里.

Looks like it's a function that takes input and maps it to a result. Well, that makes sense! And you can see the documentation for it here.

现在我们可以只查找~方法:

Now we can just look up the ~ method:

def ~ [U] (q: ⇒ Parser[U]): Parser[~[T, U]]
  A parser combinator for sequential composition
  p ~ q' succeeds if p' succeeds and q' succeeds on the input left over by p'.

所以,如果我们看到类似的东西

So, if we see something like

def seaFacts = "fish" ~ "swim"

发生的情况是,首先,"fish" 没有 ~ 方法,所以它被隐式转换为 Parser[String]做.~ 方法需要一个 Parser[U] 类型的参数,所以我们隐式地将 "swim" 转换为 Parser[String]](即U == String).现在我们有一些东西可以匹配输入 "fish",输入中剩下的东西应该匹配 "swim",如果两者都是这样,那么 seaFacts 将在匹配中取得成功.

what happens is, first, "fish" does not have the ~ method, so it's implicitly converted to Parser[String] which does. The ~ method then wants an argument of type Parser[U], and so we implicitly convert "swim" into Parser[String] (i.e. U == String). Now we have something that will match an input "fish", and whatever is left in the input should match "swim", and if both are the case, then seaFacts will succeed in its match.

这篇关于理解 Scala 解析器组合器中的波浪号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆