Skip to content
This repository has been archived by the owner on Mar 6, 2019. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Dalton committed May 19, 2009
0 parents commit e647c0d
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 0 deletions.
74 changes: 74 additions & 0 deletions src/main/scala/tfd/scala/yaml/YAMLParser.scala
@@ -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)
}
}

}
113 changes: 113 additions & 0 deletions src/test/scala/tfd/scala/yaml/YAMLParserTest.scala
@@ -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 added test/lib/junit-4.5.jar
Binary file not shown.

0 comments on commit e647c0d

Please sign in to comment.