我对 Scala 相当陌生,在阅读解析器组合器( The Magic Behind Parser Combinators 、 Domain-Specific Languages in Scala )时,我遇到了这样的方法定义:
def classPrefix = "class" ~ ID ~ "(" ~ formals ~ ")"
我一直在阅读 scala.util.parsing.Parsers 的 API 文档,它定义了一个名为 (tilde) 的方法,但我仍然不太理解它在上面示例中的用法。 在该示例中 (波浪号) 是在 java.lang.String 上调用的方法,但该方法没有该方法并导致编译器失败。 我知道 (波浪线) 被定义为
case class ~ [+a, +b] (_1: a, _2: b)
但是这对上面的例子有什么帮助呢?
如果有人能给我提示以了解这里发生的情况,我会很高兴。 预先非常感谢您!
一月
最佳答案
这里的结构有点棘手。首先,请注意,您总是在某些解析器的子类中定义这些内容,例如MyParser 类扩展了 RegexParsers
。现在,您可能会注意到 RegexParsers
中的两个隐式定义:
implicit def literal (s: String): Parser[String]
implicit def regex (r: Regex): Parser[String]
它们要做的就是获取任何字符串或正则表达式,并将它们转换为与该字符串或正则表达式作为标记匹配的解析器。它们是隐式的,因此会在需要时随时应用(例如,如果您在 Parser[String]
上调用 String
(或 正则表达式
)没有)。
但是这个Parser
是什么东西?它是在 Parsers
中定义的内部类,是 RegexParser
的 super 特征:
class Parser [+T] extends (Input) ⇒ ParseResult[T]
看起来它是一个接受输入并将其映射到结果的函数。嗯,这是有道理的!你可以看到它的文档 here .
现在我们可以查找 ~
方法:
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'.
所以,如果我们看到类似的东西
def seaFacts = "fish" ~ "swim"
首先,"fish"
没有 ~
方法,因此它被隐式转换为 Parser[String]
,做。然后,~
方法需要一个 Parser[U]
类型的参数,因此我们将 "swim"
隐式转换为 Parser[String ]
(即 U
== String
)。现在我们有了与输入 "fish"
匹配的内容,输入中剩下的任何内容都应与 "swim"
匹配,如果两者都是这种情况,则 seaFacts
将成功匹配。
关于scala - 理解 Scala 解析器组合器中的波形符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6818390/