Permalink
Browse files

Initial commit

  • Loading branch information...
Tim Dalton
Tim Dalton committed May 19, 2009
0 parents commit e647c0d87ba569dcb84de98f18440e286d39916e
@@ -0,0 +1,74 @@
import scala.util.parsing.combinator._
import scala.util.matching.Regex
package tfd.scala.yaml {
object YAMLParser extends RegexParsers {
override def skipWhitespace = false
val mapSeparator = ": *\r?\n?"r
val seqIndicator = "- *\r?\n?"r
val scalarData = """[^,\r\n\}\{]+"""r
val mappingKey = """[^-:\r\n\}\{]+"""r
val newLine = " *\r*\n+"r
val inlineSeparator = " *, +"r
val openBrace = "\\{ *"r;
val closeBrace = " *\\}"r;
val openBracket = "\\[ *"r;
val closeBracket = " *\\]"r;
def leadingSpaces(numLeadingSpaces:Int):Parser[String] = ("^ {" + numLeadingSpaces + ",}"r)
def mappings(numLeadingSpaces:Int):Parser[Map[String, Any]] =
( indentedMap(numLeadingSpaces) | inlineMap) ^^ { Map() ++ _ }
def indentedMap(numLeadingSpaces:Int):Parser[List[(String, Any)]] = rep1sep(indentedMapping(numLeadingSpaces), newLine)
def inlineMap:Parser[List[(String, Any)]] = (openBrace ~> rep1sep(inlineMapping, inlineSeparator) <~ closeBrace)
def indentedMapping(numLeadingSpaces:Int):Parser[(String, Any)] =
leadingSpaces(numLeadingSpaces) ~> mappingKey ~ mapSeparator ~ (list(0) | mappings(numLeadingSpaces+1) | scalarElement) ^^ { case key~_~value => (key, value) }
def inlineMapping:Parser[(String, Any)] =
mappingKey ~ mapSeparator ~ (inlineList | inlineMap | scalarElement) ^^ { case key~_~value => (key, value) }
def list(numLeadingSpaces:Int):Parser[List[Any]] =
(inlineList | indentedList(numLeadingSpaces)) ^^ { List() ++ _ }
def indentedList(numLeadingSpaces:Int):Parser[List[Any]] =
rep1sep( leadingSpaces(numLeadingSpaces) ~ seqIndicator ~>nestedData(numLeadingSpaces), newLine)
def inlineList:Parser[List[Any]] =
(openBracket ~> rep1sep( nestedData(0), inlineSeparator) <~ closeBracket)
def nestedData(numLeadingSpaces:Int):Parser[Any] = (list(numLeadingSpaces+1) | mappings(0) | scalarElement)
def scalarElement:Parser[String] = scalarData ^^ { case value => value.trim }
def yaml:Parser[Any] = ( opt(newLine) ~> list(0) | opt(newLine) ~> mappings(0) )
def parse(text : String):ParseResult[Any] = {
parse(yaml, text)
}
}
object Main {
def main(args:Array[String]) {
val input = YAMLParser.parse(
"""
{ key1: value1, key2: value2 }
""")
System.out.println(input)
}
}
}
@@ -0,0 +1,113 @@
package tfd.scala.yaml
import junit.framework._
import org.junit.Assert._
class YAMLParserTest extends TestCase {
import YAMLParser._
def testSimpleMap {
assertEquals(Map("key"->"value"), parse("""key: value""").get)
assertEquals(Map("key1"->"value1", "key2"->"value2"), parse(
"""
key1: value1
key2: value2
""").get)
assertEquals(Map("key 1"->"value 1", "key 2"->"value 2"), parse(
"""
key 1: value 1
key 2: value 2
""").get)
}
def testSimpleList {
assertEquals(List("item1"), parse(
"""
- item1
""").get)
assertEquals(List("item1", "item2"), parse(
"""
- item1
- item2
""").get)
}
def testListOfList {
assertEquals(List(
List("item11", "item12"),
List("item21", "item22")),
parse(
"""
-
- item11
- item12
-
- item21
- item22
""").get)
}
def testMapOfMap {
assertEquals(Map("JFrame" -> Map("name" -> "myFrame", "title" -> "My App Frame")),
parse(
"""
JFrame:
name: myFrame
title: My App Frame
""").get)
}
def testListOfMap {
assertEquals(List(
Map("name"-> "John Smith", "age"->"33"),
Map("name"-> "Mary Smith", "age"->"27")),
parse(
"""
- name: John Smith
age: 33
- name: Mary Smith
age: 27
""").get)
}
def testMapOfList {
assertEquals(Map("men" -> List("John Smith", "Bill Jones"), "women" -> List("Mary Smith", "Susan Williams")),
parse(
"""
men:
- John Smith
- Bill Jones
women:
- Mary Smith
- Susan Williams
""").get)
}
def testInlineMap {
assertEquals(Map("key"->"value"), parse("""key: value""").get)
assertEquals(Map("key1"->"value1", "key2"->"value2"), parse(
"""{ key1: value1, key2: value2 }""").get)
}
def testMapOfMapOfMap {
assertEquals(Map("JFrame" -> Map("content" -> Map("button" -> "press"))),
parse(
"""
JFrame:
content:
button: press
""").get)
}
def testMapOfInlineList {
assertEquals(Map("men" -> List("John Smith", "Bill Jones"), "women" -> List("Mary Smith", "Susan Williams")),
parse(
"""
men: [ John Smith, Bill Jones ]
women: [ Mary Smith, Susan Williams ]
""").get)
}
}
Binary file not shown.

0 comments on commit e647c0d

Please sign in to comment.