2013-07-02 149 views
2

是否有更简洁的方式将字符串映射到解析器组合器中的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

解析器是可组合的,所以只要你可以建立一个解析器读取一个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") 
+0

一个reduceLeft的解决方案是什么,我试图进行实验,但找不到。谢谢,我会试试看! – warpedjavaguy

+0

'literal(m.toString)'允许“Viewx”和“xView”成功解析。改变它使用'phrase(m.toString)'来修正它。 – warpedjavaguy

+0

我假设你会将它用作ModeParser.parseAll(ModeParser.mode,Viewx),就像@senia的回答暗示 –

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 
    ^