--- a/src/main/scala/RDB2RDFMain.scala Sun Dec 27 16:44:52 2009 -0800
+++ b/src/main/scala/RDB2RDFMain.scala Mon Dec 28 11:45:54 2009 -0500
@@ -198,7 +198,7 @@
def findVars(gp:GraphPattern):Set[Var] = {
gp match {
- case BasicGraphPattern(triplepatterns, filter:SparqlExpression) => {
+ case TriplesBlock(triplepatterns, filter:SparqlExpression) => {
/* Examine each triple, updating the compilation state. */
triplepatterns.foldLeft(Set[Var]())((x, y) => x ++ findVars(y))
}
@@ -254,7 +254,7 @@
def mapGraphPattern(db:DatabaseDesc, stateP:R2RState, gp:GraphPattern, pk:PrimaryKey, enforeForeignKeys:Boolean):R2RState = {
var state = stateP
gp match {
- case BasicGraphPattern(triplepatterns, filter:SparqlExpression) => {
+ case TriplesBlock(triplepatterns, filter:SparqlExpression) => {
/* Examine each triple, updating the compilation state. */
triplepatterns.foreach(s => state = bindOnPredicate(db, state, s, pk, true))
--- a/src/main/scala/SPARQL.scala Sun Dec 27 16:44:52 2009 -0800
+++ b/src/main/scala/SPARQL.scala Mon Dec 28 11:45:54 2009 -0500
@@ -15,8 +15,13 @@
case class SparqlAttributeList(attributelist:List[Var])
sealed abstract class GraphPattern
-case class BasicGraphPattern(triplepatterns:List[TriplePattern], filter:SparqlExpression) extends GraphPattern
-case class GroupGraphPattern(gps:List[GraphPattern]) extends GraphPattern
+case class TriplesBlock(triplepatterns:List[TriplePattern], filter:SparqlExpression) extends GraphPattern
+case class TableConjunction(gps:List[GraphPattern]) extends GraphPattern
+case class TableDisjunction(gps:List[GraphPattern]) extends GraphPattern
+case class ParserTableFilter(expr:SparqlExpression) extends GraphPattern
+case class TableFilter(gp:GraphPattern, expr:SparqlExpression) extends GraphPattern
+case class OptionalGraphPattern(gp:GraphPattern) extends GraphPattern
+case class GraphGraphPattern(gp:GraphPattern) extends GraphPattern
case class TriplePattern(s:S, p:P, o:O)
case class ObjUri(stem:Stem, rel:Rel, attr:Attr, v:CellValue)
@@ -58,7 +63,7 @@
case class Sparql() extends JavaTokenParsers {
def select:Parser[SparqlSelect] =
- "SELECT" ~ attributelist ~ "{" ~ graphpattern ~ "}" ^^ { case "SELECT"~a~"{"~t~"}" => SparqlSelect(a, t) }
+ "SELECT" ~ attributelist ~ groupgraphpattern ^^ { case "SELECT"~a~gp => SparqlSelect(a, gp) }
def filter:Parser[SparqlExpression] =
"FILTER" ~ "(" ~ expression ~ ")" ^^ { case "FILTER"~"("~expression~")" => expression }
@@ -83,24 +88,45 @@
def attributelist:Parser[SparqlAttributeList] =
rep(varr) ^^ { SparqlAttributeList(_) }
- def graphpattern:Parser[GraphPattern] = (
- // "{"~graphpattern~"}" ^^ { case "{"~x~"}" => GroupGraphPattern(List(x)) }
- groupgraphpattern ^^ { ggp => ggp }
- | basicgraphpattern ^^ { bgp => bgp }
+ def groupgraphpattern:Parser[GraphPattern] = (
+ "{" ~ opt(triplesblock) ~ rep(graphpatternnottriplesORfilter ~ opt(triplesblock)) ~ "}" ^^
+ //"{" ~ opt(triplesblock) ~ rep(graphpatternnottriplesORfilter_OPTtriplesblock) ~ "}" ^^
+ {
+ case "{"~tbOPT~gpntORf_tbOPT~"}" => {
+ val l:Option[GraphPattern] = tbOPT
+ val r:List[~[GraphPattern,Option[TriplesBlock]]] = gpntORf_tbOPT
+ (tbOPT, gpntORf_tbOPT) match {
+ case (Some(x), list) => {
+ if (list.size == 0)
+ x
+ else {
+ println("ignoring " + list)
+ TableConjunction(List[GraphPattern](x))
+ }
+ }
+ }
+ }
+ }
)
- def groupgraphpattern:Parser[GraphPattern] = (
- "{"~graphpattern~"}" ^^ { case "{"~x~"}" => GroupGraphPattern(List(x)) }
+ def graphpatternnottriplesORfilter_OPTtriplesblock:Parser[(GraphPattern, Option[TriplesBlock])] =
+ graphpatternnottriplesORfilter ~ opt(triplesblock) ^^ { case a~b => (a, b) }
+
+ def graphpatternnottriplesORfilter:Parser[GraphPattern] = (
+ "OPTIONAL"~groupgraphpattern ^^ { case "OPTIONAL"~ggp => OptionalGraphPattern(ggp) }
+ | rep1sep(groupgraphpattern, "UNION") ^^ { x => if (x.size > 1) TableDisjunction(x) else x(0) }
+ | "GRAPH"~uri~groupgraphpattern ^^ { case "GRAPH"~u~ggp => GraphGraphPattern(ggp) }
+ | filter ^^ { x => ParserTableFilter(x) }
)
- def basicgraphpattern:Parser[BasicGraphPattern] =
+ def triplesblock:Parser[TriplesBlock] =
repsep(triplepattern, ".") ~ opt(filter) ^^ {
case pats~filter =>
val sparqlExpression:SparqlExpression = filter match {
case None => SparqlExpression(List())
case Some(f) => f
}
- BasicGraphPattern(pats, sparqlExpression)
+ TriplesBlock(pats, sparqlExpression)
}
def triplepattern:Parser[TriplePattern] =
--- a/src/test/scala/SparqlTest.scala Sun Dec 27 16:44:52 2009 -0800
+++ b/src/test/scala/SparqlTest.scala Mon Dec 28 11:45:54 2009 -0500
@@ -10,8 +10,8 @@
val e = """
?emp <http://hr.example/DB/Employee#lastName> "bob"^^<http://www.w3.org/2001/XMLSchema#string>
"""
- val expected = BasicGraphPattern(List(TriplePattern(SVar(Var("emp")),PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),OLit(SparqlLiteral(RDFLiteral("bob",Datatype(new URI("http://www.w3.org/2001/XMLSchema#string"))))))), SparqlExpression(List()))
- assert(expected === (a.parseAll(a.basicgraphpattern, e).get))
+ val expected = TriplesBlock(List(TriplePattern(SVar(Var("emp")),PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),OLit(SparqlLiteral(RDFLiteral("bob",Datatype(new URI("http://www.w3.org/2001/XMLSchema#string"))))))), SparqlExpression(List()))
+ assert(expected === (a.parseAll(a.triplesblock, e).get))
}
test("parse a litint") {
@@ -19,11 +19,11 @@
val e = """
?emp <http://hr.example/DB/Employee#age> "21"^^<http://www.w3.org/2001/XMLSchema#integer>
"""
- val expected = BasicGraphPattern(List(TriplePattern(SVar(Var("emp")),PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("age")),OLit(SparqlLiteral(RDFLiteral("21",Datatype(new URI("http://www.w3.org/2001/XMLSchema#integer"))))))), SparqlExpression(List()))
- assert(expected === (a.parseAll(a.basicgraphpattern, e).get))
+ val expected = TriplesBlock(List(TriplePattern(SVar(Var("emp")),PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("age")),OLit(SparqlLiteral(RDFLiteral("21",Datatype(new URI("http://www.w3.org/2001/XMLSchema#integer"))))))), SparqlExpression(List()))
+ assert(expected === (a.parseAll(a.triplesblock, e).get))
}
- test("parse a basicgraphpattern") {
+ test("parse a triplesblock") {
val a = Sparql()
val e = """
?emp <http://hr.example/DB/Employee#lastName> ?empName .
@@ -31,7 +31,7 @@
?manager <http://hr.example/DB/Employee#lastName> ?managName
"""
val tps =
- BasicGraphPattern(
+ TriplesBlock(
List(
TriplePattern(
SVar(Var("emp")),
@@ -45,7 +45,7 @@
SVar(Var("manager")),
PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
OVar(Var("managName")))), SparqlExpression(List()))
- assert(tps === a.parseAll(a.basicgraphpattern, e).get)
+ assert(tps === a.parseAll(a.triplesblock, e).get)
}
// ?manBday < ?empBday && ?grandManBday < ?manBday
@@ -89,6 +89,25 @@
assert(expected === (a.parseAll(a.filter, e).get))
}
+ test("SELECT") {
+ val a = Sparql()
+ val e = """
+SELECT ?empName ?manageName {
+?emp <http://hr.example/DB/Employee#lastName> ?empName
+}
+"""
+ val tps =
+ SparqlSelect(
+ SparqlAttributeList(List(Var("empName"), Var("manageName"))),
+ TriplesBlock(
+ List(
+ TriplePattern(
+ SVar(Var("emp")),
+ PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+ OVar(Var("empName")))), SparqlExpression(List())))
+ assert(tps === a.parseAll(a.select, e).get)
+ }
+
test("SELECT with FILTER") {
val a = Sparql()
val e = """
@@ -100,7 +119,7 @@
val tps =
SparqlSelect(
SparqlAttributeList(List(Var("empName"), Var("manageName"))),
- BasicGraphPattern(
+ TriplesBlock(
List(
TriplePattern(
SVar(Var("emp")),
@@ -126,7 +145,7 @@
val tps =
SparqlSelect(
SparqlAttributeList(List(Var("empName"), Var("manageName"))),
- BasicGraphPattern(
+ TriplesBlock(
List(
TriplePattern(
SVar(Var("emp")),