Skip to content

Instantly share code, notes, and snippets.

@jroesch
Created September 7, 2012 22:52
Show Gist options
  • Save jroesch/3670461 to your computer and use it in GitHub Desktop.
Save jroesch/3670461 to your computer and use it in GitHub Desktop.
An implementation of a simple config parser that tries to implement a Dynamic(ish) Object
import scala.collection.mutable.{ Map => MMap }
import scala.util.parsing.combinator._
class Config(s: Seq[(String, Any)] = Seq()) {
val config = MMap[String, Any](s: _*)
def apply(x: String) = config(x)
}
class ConfigError(message: String) extends Exception(message) {
override def toString = "Config Error: " + message
}
class ConfigParser extends JavaTokenParsers {
//def parse(s: String) = parseAll(s, rule)
def config: Parser[Config] = (
rep(rule) ^^ {
case seq => new Config(seq)
}
)
def rule: Parser[(String, Any)] = (
ident~"="~rhs ^^ {
case id~_~v => id -> v
}
)
def rhs: Parser[Any] = (
value
| ident
/* | qualifiedName */
| list
)
def list: Parser[List[Any]] = (
"["~>repsep(value | ident, ",")<~"]"
/* "["~>repsep(value | ident | qualifiedName, ",")<~"]" */
)
def value: Parser[Any] = (
boolean
| integer
| double
| stringLiteral
)
/* def qualifiedName: Parser[String] =
repsep(ident, ".") ^^ { _.foldLeft("")(_ + "." _) } */
def boolean: Parser[Boolean] = (
"true" ^^ (x => true)
| "false" ^^ (x => false)
)
def integer: Parser[Int] = (
wholeNumber ^^ { x => x.toInt }
)
def double: Parser[Double] = (
decimalNumber ^^ { x => x.toDouble }
)
}
class GrapheneConfig(s: Seq[(String, Any)]) extends Config(s) {
val configError = new ConfigError("Bad Config File.")
/* Pull a value out of our Map and cast it to a value */
def edgelistPath: String = {
val value = config("edgelistPath")
if (value.isInstanceOf[String]) value.asInstanceOf[String] else throw configError
}
def subsetRandom: Boolean = {
val value = config("subsetRandom")
if (value.isInstanceOf[Boolean]) value.asInstanceOf[Boolean] else throw configError
}
def serverList: List[Any] =
config("serverList") match {
case xs: List[Any] => xs
case _ => throw configError
}
}
class GrapheneConfigParser extends ConfigParser {
override def config: Parser[Config] = (
rep(rule) ^^ {
case seq => new GrapheneConfig(seq)
}
)
def tryConfig: Config = {
import scala.io.Source._
val path = "/Users/jroesch/Downloads/graphene.cfg"
val lines = fromFile(path).getLines()
val contents = lines.foldLeft("") { _ + "\n" + _ }
val result = parseAll(config, contents)
result match {
case Success(res, next) => res
case Failure(msg, next) => throw new ConfigError(msg + "\n" + "Rest: " + next)
}
}
}
def runTest: GrapheneConfig = {
val gc = (new GrapheneConfigParser()).tryConfig.asInstanceOf[GrapheneConfig]
return gc
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment