MatchError в комбинаторе синтаксического анализатора Scala для анализа строки запроса - PullRequest
0 голосов
/ 10 июля 2019

Я создаю анализатор для разбора строки запроса, подобной этой

e = "500.3" AND dt = "20190710" AND s in ("ERROR", "WARN") OR cat = "Conditional"

Для предыдущей строки я получаю следующее: Exception in thread "main" scala.MatchError: (Identifier(e),(=,StringLiteral(500.3))) (of class scala.Tuple2)

Япри условии, что моя грамматика в порядке (возможно, нет).Может быть, кто-то может помочь выяснить, почему я получаю эту ошибку.Вот мой парсер.

class SearchQueryParser extends StandardTokenParsers {
  lexical.reserved += ("OR", "AND")
  lexical.delimiters += ( "<", "=", "<>", "!=", "<=", ">=", ">",  "(", ")")

  def expr: Parser[QueryExp] = orExp
  def orExp: Parser[QueryExp] = andExp *("OR" ^^^ {(a: QueryExp, b: QueryExp) => BoolExp("OR", (a, b))})
  def andExp: Parser[QueryExp] = compareExp *("AND" ^^^ {(a: QueryExp, b: QueryExp) => BoolExp("AND", (a, b))})

  def compareExp: Parser[QueryExp] = {
    identifier ~ rep(("=" | "<>" | "!=" | "<" | "<=" | ">" | ">=") ~ literal ^^ {
      case op ~ rhs => (op, rhs)
    }) ^^ {
      case lhs ~ elems =>
        elems.foldLeft(lhs) {
          case (id, ("=", rhs: String)) => Binomial("=", id.str, rhs)
          case (id, ("<>", rhs: String)) => Binomial("!=", id.str, rhs)
          case (id, ("!=", rhs: String)) => Binomial("!=", id.str, rhs)
          case (id, ("<", rhs: String)) => Binomial("<", id.str, rhs)
          case (id, ("<=", rhs: String)) => Binomial("<=", id.str, rhs)
          case (id, (">", rhs: String)) => Binomial(">", id.str, rhs)
          case (id, (">=", rhs: String)) => Binomial(">=", id.str, rhs)
        }
      }
  }

  def literal: Parser[QueryExp] = stringLit ^^ (s => StringLiteral(s))
  def identifier: Parser[QueryExp] = ident ^^ (s => Identifier(s))

  def parse(queryStr: String): Option[QueryExp] = {
    phrase(expr)(new lexical.Scanner(queryStr)) match {
      case Success(r, _) => Option(r)
      case x => println(x); None
    }
  } 
}

1 Ответ

0 голосов
/ 11 июля 2019

Мне удалось найти проблему.Похоже, ошибка была вызвана тем, что частичная функция в операторе foldLeft(lhs) не соответствовала кортежу (=,StringLiteral(500.3))

. Как вы можете видеть, в каждом случае оператора частичной функции я пытаюсьсоответствует правому значению типа String

...
 case (id, ("=", rhs: String)) => Binomial("=", id.str, rhs)
 case (id, ("<>", rhs: String)) => Binomial("!=", id.str, rhs)
 case (id, ("!=", rhs: String)) => Binomial("!=", id.str, rhs)
...

Однако, как видно из ошибки Exception in thread "main" scala.MatchError: (Identifier(e),(=,StringLiteral(500.3))) (of class scala.Tuple2), вход был проанализирован как кортеж "=" и StringLiteral.

Решение былочтобы изменить тип параметра rhs:

...
 case (id, ("=", rhs: StringLiteral)) => Binomial("=", id.str, rhs.toString)
 case (id, ("<>", rhs: StringLiteral)) => Binomial("!=", id.str, rhs.toString)
 case (id, ("!=", rhs: StringLiteral)) => Binomial("!=", id.str, rhs.toString)
...
...