如何对 Scala 解析器组合器结果进行模式匹配
我们有一个多线程 RPC 服务器来解析输入字符串。我们遇到了 Scala 的解析器组合器库不是多线程安全的问题: Parsers.scala 用于任何解析。我们在这一行中得到一个 NullPointerException
if (!(lastNoSuccess != null && next.pos < lastNoSuccess.next.pos))
通过创建一个扩展解析器之一的对象来实现解析器的默认方法,但我想按需构造一个解析器,以便每个解析器都有自己的内部状态,所以我使用一个类来代替一个物体的。但是,我无法编译它,因为我需要对结果进行模式匹配:
import scala.util.parsing.combinator.RegexParsers
class SqlParserImpl
extends RegexParsers
{
val term: Parser[String] = """(?i)term\b""".r
}
object Test
{
def main(args: Array[String]): Unit =
{
val parser = new SqlParserImpl
parser.parseAll(parser.term, "term") match {
// How do I match?
case SqlParserImpl#Success(result, _) => true
case SqlParserImpl#NoSuccess => false
}
}
}
失败
t.scala:16: error: '=>' expected but '#' found.
case SqlParserImpl#Success(result, _) => true
^
t.scala:17: error: '=>' expected but '#' found.
case SqlParserImpl#NoSuccess => false
^
two errors found
We have a multithreaded RPC server that parses input strings. We've run into an issue where Scala's parser combinator library is not multithreaded safe: the var lastNoSuccess in Parsers.scala is used by any parsing. We get a NullPointerException in this line
if (!(lastNoSuccess != null && next.pos < lastNoSuccess.next.pos))
The default way to implement the parser by making an object that extends one of the Parsers, but I want to construct a parser on demand so each has its own internal state, so I'm using a class instead of an object. However, I can't get it to compile since I need to pattern match on the result:
import scala.util.parsing.combinator.RegexParsers
class SqlParserImpl
extends RegexParsers
{
val term: Parser[String] = """(?i)term\b""".r
}
object Test
{
def main(args: Array[String]): Unit =
{
val parser = new SqlParserImpl
parser.parseAll(parser.term, "term") match {
// How do I match?
case SqlParserImpl#Success(result, _) => true
case SqlParserImpl#NoSuccess => false
}
}
}
Fails with
t.scala:16: error: '=>' expected but '#' found.
case SqlParserImpl#Success(result, _) => true
^
t.scala:17: error: '=>' expected but '#' found.
case SqlParserImpl#NoSuccess => false
^
two errors found
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用:
#
符号用于指定类型成员。在您的情况下,它使用构造函数或提取器模式,需要引用对象或看起来像构造函数的东西。唔。我手头没有2.7的。试试这个:
Use this:
The
#
sign is used to designate a type member. In your case it's using a constructor or an extractor pattern which needs to reference to an object or something that looks like a constructor.Hmm. I don't have a 2.7 handy. Try this:
我能够编译以下内容:
I was able to compile the following:
NoSuccess
对象(带有提取器)是在 2009 年添加的,当时没有任何代码被向后移植到 2.7,但是它的实现非常简单:因此您可以替换
parser .NoSuccess(_, _)
与一个parser.Failure(_, _)
匹配和一个parser.Error(_, _)
匹配。但是,如果您对返回的内容不感兴趣,那么与类型匹配会更简单:例如 由 Eugene 建议一个>。
The
NoSuccess
object (with extractor) was added back in 2009, at a time when no code was being backported to 2.7 anymore It's implementation, however, is pretty simple:So you can replace the
parser.NoSuccess(_, _)
match with oneparser.Failure(_, _)
and oneparser.Error(_, _)
match. But if you are not interested in what is being returned, then it's simpler to match against the type:Like suggested by Eugene.