Skip to content

Instantly share code, notes, and snippets.

@kmizu
Created October 15, 2010 10:59
Show Gist options
  • Save kmizu/628013 to your computer and use it in GitHub Desktop.
Save kmizu/628013 to your computer and use it in GitHub Desktop.
import java.io.StringReader
import scala.util.parsing.combinator._
import scala.util.parsing.input._
import scala.util.parsing.combinator.syntactical._
import java.util.Properties
object JSONLikeProperties {
object Parser extends StandardTokenParsers {
lexical.delimiters ++= List("{", "}", "=")
//lexical.reserved ++= List("{", "}", "=")
def parse(input: String): Either[String, Properties] = {
file(new lexical.Scanner(input)) match {
case Success(result, _) => Right(result)
case Failure(msg, pos) => Left(pos.pos + ":" + msg)
case Error(msg, pos) => Left(pos.pos + ":" + msg)
}
}
private lazy val file: Parser[Properties] = {
properties <~ lexical.EOF ^^ { case m =>
val prop = new Properties()
for((k, v) <- m) prop.put(k, v)
prop
}
}
private lazy val properties: Parser[Map[String, String]] = for(
id <- ident; _ <- keyword("{"); r <- contents(id); _ <- keyword("}")
) yield r
private def contents(prefix: String): Parser[Map[String, String]] = (
((kvPair | properties) ^^ {
case m => m.map{ case (k, v) => (prefix + "." + k, v) }
}).* ^^ { case ms => ms.foldLeft(Map.empty[String, String])(_ ++ _) }
)
private lazy val kvPair: Parser[Map[String, String]] = {
ident ~ "=" ~ stringLit ^^ { case k ~ _ ~ v => Map(k -> v) }
}
}
def main(args: Array[String]) {
Parser.parse("""| A {
| B = "C"
| D {
| E = "F"
| G = "H"
| }
| I = "K"
| }""".stripMargin) match {
case Left(error) => println(error)
case Right(result) => println(result)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment