Skip to content

Commit

Permalink
JENA-1881: SPARQL* syntax and print
Browse files Browse the repository at this point in the history
  • Loading branch information
afs committed Apr 13, 2020
1 parent 36ead9f commit 8e2036e
Show file tree
Hide file tree
Showing 66 changed files with 5,789 additions and 4,671 deletions.
15 changes: 13 additions & 2 deletions jena-arq/Grammar/arq.jj
Original file line number Diff line number Diff line change
Expand Up @@ -1158,9 +1158,18 @@ Node GraphNodePath(TripleCollectorMark acc) : { Node n ; }
|
n = TriplesNodePath(acc) { return n ; }
}
Node VarOrTerm() : {Node n = null ; }
Node VarOrTerm() : { Node n = null ; Token t = null; Node s , p , o ; }
{
( n = Var() | n = GraphTerm() )
(
t = <LT2>
s = VarOrTerm()
p = Verb()
o = VarOrTerm()
{ n = createTripleTerm(s,p,o); }
<GT2>
| n = Var()
| n = GraphTerm()
)
{ return n ; }
}
Node VarOrIri() : {Node n = null ; String iri ; }
Expand Down Expand Up @@ -1840,6 +1849,8 @@ TOKEN :
| < LT: "<" >
| < LE: "<=" >
| < GE: ">=" >
| < GT2: ">>" >
| < LT2: "<<" >
| < BANG: "!" >
| < TILDE: "~" >
| < COLON: ":" >
Expand Down
3 changes: 2 additions & 1 deletion jena-arq/Grammar/grammar
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ function grammar

F="$DIR/${CLASS}TokenManager.java"

sed -e 's/import .*//' -e 's/MatchLoop: do/do/' \
sed -e 's/@SuppressWarnings."unused".//' \
-e 's/import .*//' -e 's/MatchLoop: do/do/' \
-e 's/int hiByte = (int)(curChar/int hiByte = (curChar/' \
< $F > F
mv F $F
Expand Down
31 changes: 28 additions & 3 deletions jena-arq/Grammar/master.jj
Original file line number Diff line number Diff line change
Expand Up @@ -1519,13 +1519,13 @@ Node BlankNodePropertyListPath(TripleCollector acc) : { Token t ; }
{ return n ; }
}

// << >> as reification. Allows any subject/predicate/object nodes.
#if 0
Node Reification(Node id, TripleCollectorMark acc) :
{ Node s , p , o ; int mark ; Token t ; }
{
// For generality, should be AndNode for s/p/o
// Insert reification triple before the resulting subtriples (if any)
t = "<<"
t = <LT2>
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
{ if ( id == null )
id = createBNode(beginLine, beginColumn() ;
Expand All @@ -1540,7 +1540,7 @@ Node Reification(Node id, TripleCollectorMark acc) :
}
o = GraphNode(acc)
{ insert(acc, mark, id, nRDFobject, o) ; }
">>"
<GT2>
{ return id ; }
}
#endif
Expand Down Expand Up @@ -1615,11 +1615,32 @@ Node GraphNodePath(TripleCollectorMark acc) : { Node n ; }
n = TriplesNodePath(acc) { return n ; }
}

#ifdef SPARQL_11
Node VarOrTerm() : {Node n = null ; }
{
( n = Var() | n = GraphTerm() )
{ return n ; }
}
#endif
#ifdef ARQ
// RDF* Triple as term.
Node VarOrTerm() : { Node n = null ; Token t = null; Node s , p , o ; }
{
(
t = <LT2>
s = VarOrTerm()
p = Verb()
o = VarOrTerm()
{ n = createTripleTerm(s,p,o); }
<GT2>
| n = Var()
| n = GraphTerm()
)
{ return n ; }
}

#endif


// e.g. Property (if no bNodes) + DESCRIBE
Node VarOrIri() : {Node n = null ; String iri ; }
Expand Down Expand Up @@ -2564,6 +2585,10 @@ TOKEN :
| < LE: "<=" > // Maybe: | "=>" >
| < GE: ">=" > // Maybe: | "=<" >

#ifdef ARQ
| < GT2: ">>" >
| < LT2: "<<" >
#endif
| < BANG: "!" >
| < TILDE: "~" >
| < COLON: ":" >
Expand Down
3 changes: 2 additions & 1 deletion jena-arq/Grammar/sse/grammar-sse
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ function grammar
# Fix unnecessary imports
echo "---- Fixing Java warnings in ${CLASS}TokenManager ..."
F="$DIR/${CLASS}TokenManager.java"
sed -e 's/import .*//' -e 's/MatchLoop: do/do/' \
sed -e 's/@SuppressWarnings."unused".//' \
-e 's/import .*//' -e 's/MatchLoop: do/do/' \
-e 's/int hiByte = (int)(curChar/int hiByte = (curChar/' \
< $F > F
mv F $F
Expand Down
26 changes: 23 additions & 3 deletions jena-arq/Grammar/sse/sse.jj
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,13 @@ void BareList() : { }
)*
}

void Term() : { Token t ; }
void Term() : { }
{
Symbol() | RDFTerm()
}

void RDFTerm() : { }
{
Symbol()
|
IRIref()
|
PrefixedName()
Expand All @@ -128,6 +131,8 @@ void Term() : { Token t ; }
Literal()
|
BlankNode()
|
TripleTerm()
}


Expand Down Expand Up @@ -188,6 +193,21 @@ void BlankNode() : { Token t ; }
// t = <ANON> { return emitBNode(t.beginLine, t.beginColumn) ; }
}

void TripleTerm() : { Token t1 = null ; Token t2 = null ; }
{
t1 = <LBRACE> // "{"
(<WS>)*
{ tripleTermStart(t1.beginLine, t1.beginColumn); }
RDFTerm()
(<WS>)*
RDFTerm()
(<WS>)*
RDFTerm()
(<WS>)*
t2 = <RBRACE>
{ tripleTermFinish(t2.beginLine, t2.beginColumn); }
}

void RDFLiteral() : { Token t = null ; int currLine ; int currColumn ;
String lex ; String lang = null ;
String dt_iri = null ; String dt_pn = null ; }
Expand Down
9 changes: 4 additions & 5 deletions jena-arq/Grammar/sse/tokens.inc
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ TOKEN :
< LPAREN: "(" >
| < RPAREN: ")" >


| < LBRACE: "{" >
| < RBRACE: "}" >

Expand Down Expand Up @@ -147,12 +146,12 @@ TOKEN:
TOKEN:
{
// Anything left that isn't structural
// LPAREN and RPAREN / LBRACKET/RBRACKET
// LPAREN and RPAREN / LBRACKET/RBRACKET / LBRACE/BRCAE
// Quotes
<#SYM: (~["(", ")", "[", "]", "'", "\"", " ", "\t","\n","\r","\f" ])>
<#SYM: (~["(", ")", "[", "]", "{", "}", "'", "\"", " ", "\t","\n","\r","\f" ])>
|
<#SYM1: (~["^", "@",
"(", ")", "[", "]", "'", "\"", " ", "\t","\n","\r","\f" ])>
<#SYM1: (~["^", "@",
"(", ")", "[", "]", "{", "}", "'", "\"", " ", "\t","\n","\r","\f" ])>
| <#SYM_ESC: "\\" ( " " | "'" | "\"" ) >
|
<SYMBOL: <SYM1> (<SYM>)*>
Expand Down
2 changes: 2 additions & 0 deletions jena-arq/Grammar/tokens.txt
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@
[<DOT>] ::= '.'
[<GT>] ::= '>'
[<LT>] ::= '<'
[<GT2>] ::= '>>'
[<LT2>] ::= '<<'
[<BANG>] ::= '!'
[<HOOK>] ::= '?'
[<COLON>] ::= ':'
Expand Down
2 changes: 1 addition & 1 deletion jena-arq/src/main/java/org/apache/jena/query/ARQ.java
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ public static void enableOptimizer(Context context, boolean state)
public static final Symbol optMergeBGPs = SystemARQ.allocSymbol("optMergeBGPs");

/**
* Context key controlling whether the standard optimizater applies the optimization
* Context key controlling whether the standard optimizer applies the optimization
* to combine stacks of (extend) into one compound operation. Ditto (assign).
* <p>By default, this transformation is applied.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,13 +251,13 @@ protected final void triplesSameSubject() {
private Node parseTripleNode() {
Token token = nextToken();
// subjectX()
Node s = nodeX("subject");
Node s = subjectX();

Node p = predicate(); // predicate() == node();nextToken();
nextToken();

// objectX()
Node o = nodeX("object");
Node o = objectX();

if ( ! lookingAt(GT2) )
exception(peekToken(), "Expected >>, found %s", peekToken().text()) ;
Expand All @@ -269,15 +269,24 @@ private Node parseTripleNode() {
return profile.createTripleNode(s, p, o, token.getLine(), token.getColumn());
}

private Node subjectX() {
Node node = nodeX("subject");
if ( node.isLiteral() )
exception(peekToken(), "Literal as subject in RDF* triple") ;
return node ;
}

private Node objectX() {
Node node = nodeX("object");
return node ;
}

// Does consume the token.
private Node nodeX(String posnLabel) {

if ( lookingAt(LT2) )
return parseTripleNode();
if ( ! lookingAt(NODE) )
// XXX Move to nodeX?
exception(peekToken(), "Bad %s in RDF* triple", posnLabel, peekToken().text()) ;

Node node = node();
nextToken();
return node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,24 @@ public class JSONResultsKW
public static String kBindings = "bindings" ;
public static String kType = "type" ;
public static String kUri = "uri" ;
public static String kObject = "object" ;

public static String kValue = "value" ;
public static String kLiteral = "literal" ;
public static String kUnbound = "undef" ;
// Legacy.

// Legacy: kTypedLiteral
public static String kTypedLiteral = "typed-literal" ;
public static String kXmlLang = "xml:lang" ;
public static String kDatatype = "datatype" ;
public static String kBnode = "bnode" ;
public static String kBoolean = "boolean" ;

// RDF* Triple terms
public static String kTriple = "triple" ;
public static String kSubject = "subject" ;
public static String kPredicate = "predicate" ;
public static String kProperty = "property" ;

}

Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@ private static Node parseOneTerm(JsonObject term, LabelToNode labelMap) {
checkContains(term, false, false, kType, kValue, kXmlLang, kDatatype);

String type = stringOrNull(term, kType);

if ( kTriple.equals(type) ) {
JsonObject x = term.get(kValue).getAsObject();
return parseTripleTerm(x, labelMap);
}

String v = stringOrNull(term, kValue);

if ( kUri.equals(type) ) {
Expand Down Expand Up @@ -226,10 +232,28 @@ private static Node parseOneTerm(JsonObject term, LabelToNode labelMap) {

if ( kBnode.equals(type) )
return labelMap.get(null, v);

throw new ResultSetException("Object key not recognized as valid for an RDF term: " + term);
}

private static Node parseTripleTerm(JsonObject term, LabelToNode labelMap) {
if ( term.entrySet().size() != 3 )
throw new ResultSetException("Wrong number of object keys for triple term: should be 3, got " + term.entrySet().size());
checkContains(term, true, true, kSubject, kObject);
checkContainsOneOf(term, kPredicate, kProperty);
JsonObject sTerm = term.get(kSubject).getAsObject();
JsonObject pTerm = term.get(kPredicate).getAsObject();
if ( pTerm == null )
pTerm = term.get(kProperty).getAsObject();
JsonObject oTerm = term.get(kObject).getAsObject();
if ( sTerm == null || pTerm == null || oTerm == null )
throw new ResultSetException("Bad triple term: "+term);
Node s = parseOneTerm(sTerm, labelMap);
Node p = parseOneTerm(pTerm, labelMap);
Node o = parseOneTerm(oTerm, labelMap);
return NodeFactory.createTripleNode(s, p, o);
}

private static String stringOrNull(JsonObject obj, String key) {
JsonValue v = obj.get(key);
if ( v == null )
Expand All @@ -252,5 +276,20 @@ private static void checkContains(JsonObject term, boolean allowUndefinedKeys, b
if ( requireAllExpectedKeys && declared.size() < expectedKeys.size() )
throw new ResultSetException("One or more of the required keys " + expectedKeys + " was not found");
}

private static void checkContainsOneOf(JsonObject term, String... keys) {
List<String> expectedKeys = Arrays.asList(keys);
String found = null;
for ( String k : term.keys() ) {
if ( found == null ) {
if ( expectedKeys.contains(k) )
found = k;
} else {
if ( expectedKeys.contains(k) )
throw new ResultSetException("More than one key out of "+expectedKeys);
}
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ private void write(DatasetGraph dsg) {

/** Return true if anything written */
private boolean writeGraphTriG(DatasetGraph dsg, Node name, Set<Node> graphNames) {
boolean dftGraph = ( name == null || name == Quad.defaultGraphNodeGenerated ) ;
boolean dftGraph = ( name == null || name == Quad.defaultGraphNodeGenerated ) ;

if ( dftGraph && dsg.getDefaultGraph().isEmpty() )
return false ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ protected void writePrefixes(PrefixMap prefixMap) {
RiotLib.writePrefixes(out, prefixMap, prefixStyle==DirectiveStyle.SPARQL) ;
}

// XXX
/** Write graph in Turtle syntax (or part of TriG) */
protected void writeGraphTTL(Graph graph) {
ShellGraph x = new ShellGraph(graph, null, null, null) ;
Expand All @@ -115,7 +114,7 @@ private final class ShellGraph {
private final Graph graph ;

// Blank nodes that have one incoming triple
private /*final*/ Set<Node> nestedObjects ;
private final Set<Node> nestedObjects ;
private final Set<Node> nestedObjectsWritten ;

// Blank node subjects that are not referenced as objects or graph names
Expand Down Expand Up @@ -189,11 +188,6 @@ private void printDetails(String label, Collection<Node> nodes) {
System.err.print(" = ") ;
System.err.println(nodes) ;
}
// Debug

private ShellGraph(Graph graph) {
this(graph, null, null, null) ;
}

// ---- Data access
/** Get all the triples for the graph.find */
Expand Down Expand Up @@ -476,7 +470,7 @@ private void writeGraph() {
// 2 - Free standing lists
somethingWritten = writeRemainingFreeLists(somethingWritten) ;

// 3 - Blank nodes that are unwrittern single objects.
// 3 - Blank nodes that are unwritten single objects.
// System.err.println("## ## ##") ;
// printDetails("nestedObjects", nestedObjects) ;
// printDetails("nestedObjectsWritten", nestedObjectsWritten) ;
Expand Down
Loading

0 comments on commit 8e2036e

Please sign in to comment.