解析时,Scala警告匹配可能并不详尽

时间:2017-01-22 12:08:25

标签: scala parsing

  class ExprParser extends RegexParsers {
    val number = "[0-9]+".r
    def expr: Parser[Int] = term ~ rep(
      ("+" | "-") ~ term ^^ {
        case "+" ~ t => t
        case "-" ~ t => -t
      }) ^^ { case t ~ r => t + r.sum }
    def term: Parser[Int] = factor ~ (("*" ~ factor)*) ^^ {
      case f ~ r => f * r.map(_._2).product
    }
    def factor: Parser[Int] = number ^^ { _.toInt } | "(" ~> expr <~ ")"
  }

编译时我收到以下警告

warning: match may not be exhaustive.
It would fail on the following input: ~((x: String forSome x not in ("+", "-")), _)
      ("+" | "-") ~ term ^^ {
                            ^
one warning found            

我听说@unchecked注释可以提供帮助。但在这种情况下我应该把它放在哪里?

2 个答案:

答案 0 :(得分:4)

这里的问题是使用("+" | "-")创建一个只接受两个可能字符串的解析器。但是,当您在生成的解析器上映射以提取值时,您要提取的结果将只是String

在你的模式匹配中你只有字符串“+”和“ - ”的情况,但编译器无法知道那些是唯一可能出现的字符串,所以它在这里告诉你你的匹配可能并不详尽,因为它无法更好地了解。

您可以使用未经检查的注释来抑制警告,但有更好,更惯用的方法来消除此问题。解决此问题的一种方法是尽快用某种结构化类型替换这些字符串。例如,创建一个ADT

sealed trait Operation
case object Plus extends Operation
case object Minus extends Operation

//then in your parser
("+" ^^^ Plus | "-" ^^^ Minus) ~ term ^^ {
  case PLus ~ t => t
  case Minus ~ t  => -t
}

现在它应该能够意识到唯一可能的情况是PlusMinus

答案 1 :(得分:1)

添加案例以删除警告

class ExprParser extends RegexParsers {
val number = "[0-9]+".r
def expr: Parser[Int] = term ~ rep(
("+" | "-") ~ term ^^ {
  case "+" ~ t => t
  case "-" ~ t => -t
  case _ ~ t => t
}) ^^ { case t ~ r => t + r.sum }
def term: Parser[Int] = factor ~ (("*" ~ factor)*) ^^ {
 case f ~ r => f * r.map(_._2).product
}
 def factor: Parser[Int] = number ^^ { _.toInt } | "(" ~> expr <~ ")"
}