2

有没有更简洁的方法将字符串映射到解析器组合器中的枚举值?

object Mode extends Enumeration {
  type Mode = Value
  val View, Add, Modify, Delete  = Value
}

import Mode._

object ModeParser extends JavaTokenParsers {
  def mode: Parser[Mode] = ("^(" + Mode.values.mkString("|") + ")$").r ^^ { 
    Mode.withName(_) 
  }
}
4

2 回答 2

2

解析器是可组合的,所以只要你可以构建一个解析器来读取一个Mode.Value,你就可以组合所有这些变体|

object ModeParser extends JavaTokenParsers {
  val mode: Parser[Mode.Value] = Mode.values.toList map{m =>
    literal(m.toString) ^^^ m
  } reduceLeft {_ | _}
}

你会像这样使用它:

scala> ModeParser.parseAll(ModeParser.mode, "Viewx")
于 2013-07-02T08:57:40.150 回答
0

您可以使用^?方法将ident解析器转换为mode解析器:

object ModeParser extends JavaTokenParsers {
  val modes = Mode.values.map{v => v.toString -> v}.toMap
  def mode: Parser[Mode.Value] = ident ^? ( 
    { case s if modes.contains(s) => modes(s) },
    s => s"Mode expected, but '$s' found."
  )
}

用法:

scala> ModeParser.parseAll(ModeParser.mode, "Modify")
res0: ModeParser.ParseResult[Mode.Value] = [1.7] parsed: Modify

scala> ModeParser.parseAll(ModeParser.mode, "modify")
res1: ModeParser.ParseResult[Mode.Value] =
[1.7] failure: Mode expected, but 'modify' found.

modify
      ^
于 2013-07-02T07:53:44.467 回答