Skip to content

Instantly share code, notes, and snippets.

@akr4
Forked from seratch/gist:1295847
Created October 19, 2011 10:12
Show Gist options
  • Save akr4/1297895 to your computer and use it in GitHub Desktop.
Save akr4/1297895 to your computer and use it in GitHub Desktop.
#daimonscala 19-1 "JSON parser"
// obj ::= "{" [members] "}".
// arr ::= "[" [values] "]".
// value ::= obj | arr | stringLiteral | floatingPointNumber | "null" | "true" | "false".
// values ::= value { "," value }.
// members ::= member { "," member }.
// member ::= stringLiteral ":" value.
object Main {
import util.parsing.combinator._
object JSONParser extends JavaTokenParsers {
def obj: Parser[Map[String,Any]] = "{" ~ members ~ "}" ^^ {
case "{" ~ members ~ "}" => members.toMap
}
def arr: Parser[List[Any]] = "[" ~ values ~ "]" ^^ { case "[" ~ values ~ "]" => values.toList }
def value: Parser[Any] = obj | arr | stringLiteral | floatingPointNumber | "null" | "true" | "false"
def values: Parser[List[Any]] = repsep(value, ",")
def member: Parser[Pair[String,Any]] = stringLiteral ~ ":" ~ value ^^ {
case key ~ ":" ~ value => (key -> value)
}
def members: Parser[Seq[Pair[String,Any]]] = repsep(member, ",")
def parse(json: String): ParseResult[Map[String,Any]] = parseAll(obj, json)
}
def main(args: Array[String]) {
val json = """
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
"""
val result = JSONParser.parse(json)
println(result.get)
// Map("menu" -> Map("id" -> "file", "value" -> "File", "popup" -> Map("menuitem" -> List(Map("value" -> "New", "onclick" -> "CreateNewDoc()"), Map("value" -> "Open", "onclick" -> "OpenDoc()"), Map("value" -> "Close", "onclick" -> "CloseDoc()"))))) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment