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

パーサーは構成可能であるため、1 つを読み取るパーサーを構築できるとすぐに、そのよう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

メソッドを使用して、パーサーをパーサー^?に変換できます。identmode

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 に答える