Skip to content

Instantly share code, notes, and snippets.

@martintrojer
Last active December 18, 2015 14:48
Show Gist options
  • Save martintrojer/5799518 to your computer and use it in GitHub Desktop.
Save martintrojer/5799518 to your computer and use it in GitHub Desktop.
EDN Parser
// EDN-ish parser
// https://github.com/edn-format/edn
import scala.util.parsing.combinator._
import java.util.UUID
import java.text.DateFormat
class EDN extends JavaTokenParsers {
val set: Parser[Set[Any]] = "#{" ~> rep(elem) <~ "}" ^^ (Set() ++ _)
val map: Parser[Map[Any, Any]] = "{" ~> rep(pair) <~ "}" ^^ (Map() ++ _)
val vector: Parser[Vector[Any]] = "[" ~> rep(elem) <~ "]" ^^ (Vector() ++ _)
val list: Parser[List[Any]] = "(" ~> rep(elem) <~ ")"
val keyword: Parser[String] = """:[^,#\{\}\[\]\s]+""".r
lazy val pair: Parser[(Any, Any)] = elem ~ elem ^^ {
case key ~ value => (key, value)
}
lazy val tagElem: Parser[Any] = """#[^,#\{\}\[\]\s]+""".r ~ elem ^^ {
case "#uuid" ~ (value: String) => UUID.fromString(value.tail.init)
case "#inst" ~ (value: String) => DateFormat.getDateInstance(DateFormat.SHORT)
.parse(value.tail.init)
case name ~ value => (name, value)
}
val ednElem: Parser[Any] = set | map | vector | list | keyword | tagElem |
floatingPointNumber ^^ (_.toDouble) |
"nil" ^^ (_ => null) |
"true" ^^ (_ => true) |
"false" ^^ (_ => false) |
stringLiteral
val elem: Parser[Any] = ednElem | "," ~> elem
}
object ParseEDN extends EDN with App {
println(parseAll(elem, """(1 [2] #{3 "4" [] []} {:a12 false} #uuid "f81d4fae-7dec-11d0-a765-00a0c91e6bf6" #inst "6/17/13" #foo/bar {:data []})"""))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment