How to match a pattern based on the result of a Scala parser combinator

We have a multi-threaded RPC server that parses input strings. We encountered a problem when the Scala library is not multithreaded security: var lastNoSuccess in Parsers.scala is used for any parsing, We get a NullPointerException on this line

if (!(lastNoSuccess != null && next.pos < lastNoSuccess.next.pos))

By default, to implement the parser, an object is created that extends one of the Parsers, but I want to build a parser on demand, so each of them has its own internal state, so I use a class instead of an object. However, I can not compile it, since I need to match the correspondence according to 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
    }
  }
}

Crash 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
+5
3

:

val parser = new SqlParserImpl
parser.parseAll(parser.term, "term") match {
  case parser.Success(result, _) => true
  case parser.NoSuccess(_, _) => false
}

# . , -, .

. 2.7 . :

parser.parseAll(parser.term, "term") match {
  case parser.Success(result, _) => true
  case parser.Failure(_, _) => false
  case parser.Error(_, _) => false
}
+10

:

object Test {  
  def main(args: Array[String]): Unit = {
    val parser = new SqlParserImpl

    println(parser.parseAll(parser.term, "term") match {
      case x: parser.Success[_] => true
      case x: parser.NoSuccess => false
    })
  }
}
+4

NoSuccess ( ) 2009 , , 2.7 . :

object NoSuccess {
  def unapply[T](x: ParseResult[T]) = x match {
    case Failure(msg, next)   => Some(msg, next)
    case Error(msg, next)     => Some(msg, next)
    case _                    => None
  }
}

, parser.NoSuccess(_, _) parser.Failure(_, _) parser.Error(_, _). , , :

case _: parser.Success[_] => true
case _: parser.NoSuccess  => false

Eugene.

+4

All Articles