用于枚举值的解析器组合器

时间:2013-07-02 03:13:16

标签: scala parser-combinators

是否有更简洁的方法将字符串映射到解析器组合器中的Enumeration值?

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(_) 
  }
}

2 个答案:

答案 0 :(得分: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")

答案 1 :(得分: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
      ^