+ turtle
authorAlexandre Bertails <alexandre@bertails.org>
Fri, 26 Nov 2010 13:13:55 -0500
changeset 275 e114cf8d916e
parent 274 ea4aabb5ebec
child 278 8626490ef8d1
+ turtle
turtle/.ensime
turtle/src/main/scala/turtle.scala
turtle/src/test/scala/turtleTest.scala
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/turtle/.ensime	Fri Nov 26 13:13:55 2010 -0500
@@ -0,0 +1,9 @@
+;; This config was generated using ensime-config-gen. Feel free to customize its contents manually.
+
+(
+
+:project-package "org.w3"
+
+:use-sbt t
+
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/turtle/src/main/scala/turtle.scala	Fri Nov 26 13:13:55 2010 -0500
@@ -0,0 +1,80 @@
+package org.w3.sw.turtle
+
+import org.w3.sw.rdf._
+import scala.util.parsing.combinator._
+import java.net.URI
+
+object MyParsers extends RegexParsers {
+
+  val uri = """[a-zA-Z0-9:/#_\.\-]+""".r
+  val integer = """[0-9]+""".r
+  val name = """[a-zA-Z][a-zA-Z0-9_-]*|[a-zA-Z_][a-zA-Z0-9_]+""".r
+  var prefixes:Map[String, String] = Map()
+  var bnodes:Map[String, BNode] = Map()
+  var nextBNode = 1
+}
+
+import MyParsers._
+
+case class Turtle() extends JavaTokenParsers {
+
+  def turtle:Parser[Graph] =
+    opt(triplesblock) ^^ { case tbOPT => tbOPT.getOrElse(Set[Triple]()) }
+
+  def prefixdecls:Parser[Unit] =
+    "PREFIX" ~ name ~ ":" ~ qnameORuri ^^ { case "PREFIX"~pre~":"~u => prefixes += (pre -> u.iri) }
+
+  def triplesblock:Parser[Graph] =
+    rep1sep(triplepattern, ".") ~ opt(".") ^^ { case pats~x => pats.toSet }
+
+  def triplepattern:Parser[Triple] =
+    subject ~ predicate ~ objectt ^^ { case s~p~o => Triple(s, p, o) }
+
+  def subject:Parser[Subject] = (
+      qnameORuri ^^ { case x => SubjectNode(NodeIRI(x)) }
+    | bnode ^^ { case x => SubjectNode(NodeBNode(x)) }
+  )
+
+  def predicate:Parser[Predicate] = (
+      qnameORuri ^^ { case x => PredicateIRI(x) }
+    | "a" ^^ { x => IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type") }
+  )
+
+  def objectt:Parser[Object] = (
+      qnameORuri ^^ { case x => ObjectNode(x) }
+    | bnode ^^ { case x => ObjectNode(x) }
+    | literal ^^ { case x => ObjectLiteral(x) }
+  )
+
+  def qnameORuri:Parser[IRI] = (
+      "<"~uri~">" ^^ { case "<"~x~">" => IRI(x) }
+    | name~":"~name ^^ {
+      case prefix~":"~localName => try {
+	IRI(prefixes(prefix) + localName)
+      } catch {
+	case e:java.util.NoSuchElementException =>
+	  throw new Exception("unknown prefix " + prefix)
+      }
+    }
+  )
+
+  def bnode:Parser[BNode] =
+    "_:"~name ^^ { case "_:"~name => BNode(name) }
+
+  def literal:Parser[Literal] = (
+      stringLiteral~"^^"~qnameORuri ^^
+      {
+	case lit~"^^"~dt => TypedLiteral(lit.substring(1,lit.size - 1), dt.iri match {
+ 	  case "http://www.w3.org/2001/XMLSchema#string" => StringDatatype
+ 	  case "http://www.w3.org/2001/XMLSchema#integer" => IntegerDatatype
+ 	  case "http://www.w3.org/2001/XMLSchema#date" => DateDatatype
+ 	  // case "http://www.w3.org/2001/XMLSchema#dateTime" => DateTimeDatatype
+ 	  case x => error("only programed to deal with string and integer, not " + x)
+ 	})
+      }
+    | integer ^^ { l => TypedLiteral(l, IntegerDatatype) }
+  )
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/turtle/src/test/scala/turtleTest.scala	Fri Nov 26 13:13:55 2010 -0500
@@ -0,0 +1,41 @@
+package org.w3.sw.turtle
+
+import org.w3.sw.rdf._
+
+import org.scalatest.FunSuite
+
+class TurtleTest extends FunSuite {
+
+  test("parse 1") {
+
+    val directgraph_emp_adder:Graph =
+      Set(
+	Triple(IRI("People/ID.7#_"),IRI("People#ID"),TypedLiteral("7",IRI("http://www.w3.org/2001/XMLSchema#int"))),
+	Triple(IRI("People/ID.7#_"),IRI("People#fname"),TypedLiteral("Bob",IRI("http://www.w3.org/2001/XMLSchema#string"))),
+	Triple(IRI("People/ID.7#_"),IRI("People#addr"),IRI("Addresses/ID.18#_")),
+	Triple(IRI("People/ID.8#_"),IRI("People#ID"),TypedLiteral("8",IRI("http://www.w3.org/2001/XMLSchema#int"))),
+	Triple(IRI("People/ID.8#_"),IRI("People#fname"),TypedLiteral("Sue",IRI("http://www.w3.org/2001/XMLSchema#string"))), 
+	
+	Triple(IRI("Addresses/ID.18#_"),IRI("Addresses#ID"),TypedLiteral("18",IRI("http://www.w3.org/2001/XMLSchema#int"))),
+	Triple(IRI("Addresses/ID.18#_"),IRI("Addresses#city"),TypedLiteral("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
+	Triple(IRI("Addresses/ID.18#_"),IRI("Addresses#state"),TypedLiteral("MA",IRI("http://www.w3.org/2001/XMLSchema#string")))
+      )
+
+    val turtle_emp_adder:String = """
+<People/ID.7#_> <People#ID> 7 .
+<People/ID.7#_> <People#fname> "Bob"^^<http://www.w3.org/2001/XMLSchema#string> .
+<People/ID.7#_> <People#addr> <Addresses/ID.18#_> .
+<People/ID.8#_> <People#ID> 8 .
+<People/ID.8#_> <People#fname> "Sue"^^<http://www.w3.org/2001/XMLSchema#string> .
+<Addresses/ID.18#_> <Addresses#ID> 18 .
+<Addresses/ID.18#_> <Addresses#city> "Cambridge"^^<http://www.w3.org/2001/XMLSchema#string> .
+<Addresses/ID.18#_> <Addresses#state> "MA"^^<http://www.w3.org/2001/XMLSchema#string> .
+"""
+
+    val turtleParser = Turtle()
+
+    assert(directgraph_emp_adder === turtleParser.parseAll(turtleParser.turtle, turtle_emp_adder).get)
+
+  }
+
+}