Scala吧~  - 讨论区

标题:一个简单的自定义配置格式的Scala实现

2011年06月22日 星期三 17:21

http://www.zeuux.org/blog/content/3888/?action=52

本来想执行我Object As Configuration的理念, 不过google group上有人推荐我看看configgy, 看过之后, 觉得还是自己写一个简单些, So 马上动手...

 

配置格式先简单定义为:

ident = value

groupId = {

ident1 = value1

ident2 = value2

...

}

即可以配置为key-value的形式(以=或者:分割),或者group的形式(group暂时不考虑嵌套group的形式)。

 

定义一个Scala的Parser combinator如下:

 

class BlockOrItemConfigurationParser extends JavaTokenParsers {

 

  def entry = ((item | block) +) ^^ {

    _.foldLeft(Map[String, Any]()) {

      (accum, i) =>

        i._2 match {

          case lst: List[(String, Any)] => accum ++ lst.foldLeft(Map[String, Any]()) {

            (ac, it) =>

              ac + ((i._1 + "." + it._1) -> it._2)

          }

          case x => accum + (i._1 -> x)

        }

    }

  }

 

  def block = ident ~ "=" ~ "{" ~ rep(item) ~ "}" ^^ {

    case k ~ "=" ~ "{" ~ v ~ "}" => (k -> v)

  }

 

  def item = ident ~ ("=" | ":") ~ value <~ opt(";") ^^ {

    case k ~ _ ~ v => (k -> v)

  }

 

  def value = stringLit | decimalNumber | floatingPointNumber | booleanLiteral | nullLiteral

 

  def stringLit = "\"" ~> string <~ "\"" ^^ {

    case s => s

  }

 

  def string = ("""([^"\p{Cntrl}\\]|\\[\\/bfnrt]|\\u[a-fA-F0-9]{4})*""").r

 

  def booleanLiteral = "true" ^^^ true | "false" ^^^ false

 

  def nullLiteral = "null" ^^^ null

}

代码写的有点儿矬, 将就看吧,呵呵, 本来用的JavaTokenParsers.stringLiteral, 但后来发现他没有去掉引号", 所以,只能自己重新定义一个, 当然,代码直接拷贝它的。

有了parser之后, 就可以定义一个Configurator,比如:

class SimpleConfigurator(configFile:File) {

   val p = new BlockOrItemConfigurationParser

   p.parseAll(p.entry, new CharSeqReader(FileUtils.readFileToString(configFile))) match{

case p.Success(r, in)=> // use r to get parsed result and feed your program, hehe 

case x=> throw new Exception("parse error:"+x)

}

 

}

 

OK, That's it!Have Fun!


 

 

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2024

    京ICP备05028076号