Created
September 7, 2012 22:52
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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