You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2012/06/22 22:33:53 UTC
svn commit: r1353021 [1/2] - in /jena/trunk/jena-arq: ./ Grammar/
src/main/java/com/hp/hpl/jena/sparql/expr/
src/main/java/com/hp/hpl/jena/sparql/lang/arq/
src/test/java/com/hp/hpl/jena/sparql/expr/
Author: rvesse
Date: Fri Jun 22 20:33:52 2012
New Revision: 1353021
URL: http://svn.apache.org/viewvc?rev=1353021&view=rev
Log:
Experimental implementation of a CALL() built-in in the ARQ query language for dynamic function invocation with some rudimentary unit tests for this (JENA-270)
Modified:
jena/trunk/jena-arq/Grammar/arq.jj
jena/trunk/jena-arq/Grammar/master.jj
jena/trunk/jena-arq/ReleaseNotes.txt
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Call.java
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestExpressions2.java
Modified: jena/trunk/jena-arq/Grammar/arq.jj
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/Grammar/arq.jj?rev=1353021&r1=1353020&r2=1353021&view=diff
==============================================================================
--- jena/trunk/jena-arq/Grammar/arq.jj (original)
+++ jena/trunk/jena-arq/Grammar/arq.jj Fri Jun 22 20:33:52 2012
@@ -1,3 +1,5 @@
+
+
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -16,23 +18,26 @@
* limitations under the License.
*/
-// ARQ/SPARQL 1.1 Grammar - native syntax for the query engine
+// 1/SPARQL 1.1 Grammar - native syntax for the query engine
// UPDATE : SPARQL 1.1. Update
// ARQ_UPDATE : extensions to SPARQL 1.1 Update to cover SPARQL/Update (W3C Submission)
options
{
// \ u processed in the input stream
// SPARQL 1.0
- JAVA_UNICODE_ESCAPE = true ;
- UNICODE_INPUT = false ;
+ JAVA_UNICODE_ESCAPE = true ;
+ UNICODE_INPUT = false ;
+
// // \ u processed after parsing.
// // strings, prefix names, IRIs
// JAVA_UNICODE_ESCAPE = false ;
// UNICODE_INPUT = true ;
- STATIC = false ;
+
+ STATIC = false ;
// DEBUG_PARSER = true ;
// DEBUG_TOKEN_MANAGER = true ;
}
+
PARSER_BEGIN(ARQParser)
/**
* Licensed to the Apache Software Foundation (ASF) under one
@@ -51,7 +56,9 @@ PARSER_BEGIN(ARQParser)
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.hp.hpl.jena.sparql.lang.arq ;
+
import com.hp.hpl.jena.graph.* ;
import com.hp.hpl.jena.query.* ;
import com.hp.hpl.jena.sparql.core.Var ;
@@ -61,17 +68,20 @@ import com.hp.hpl.jena.sparql.path.* ;
import com.hp.hpl.jena.sparql.expr.aggregate.* ;
import com.hp.hpl.jena.update.* ;
import com.hp.hpl.jena.sparql.modify.request.* ;
+
public class ARQParser extends ARQParserBase
{
boolean allowAggregatesInExpressions = false ;
}
PARSER_END(ARQParser)
+
// // Common top for single entry point.
// void Top(): {}
// {
// ( Query() | Update() )
// <EOF>
// }
+
// Query only entry point
void QueryUnit(): { }
{
@@ -79,16 +89,19 @@ void QueryUnit(): { }
Query() <EOF>
{ finishQuery() ; }
}
+
void Query() : { }
-{
+{
Prologue()
- ( SelectQuery() | ConstructQuery() | DescribeQuery() | AskQuery()
-// #ifdef ARQ
+ ( SelectQuery() | ConstructQuery() | DescribeQuery() | AskQuery()
+// #ifdef 1
// | JsonTemplateQuery()
// #endif
)
ValuesClause()
}
+
+
void UpdateUnit() : {}
{
{ startUpdateRequest() ; }
@@ -96,67 +109,84 @@ void UpdateUnit() : {}
<EOF>
{ finishUpdateRequest() ; }
}
+
+
+
void Prologue() : {}
{
( BaseDecl() | PrefixDecl() )*
}
+
void BaseDecl() : { String iri ; }
{
<BASE> iri = IRIREF()
{ getPrologue().setBaseURI(iri) ; }
}
+
void PrefixDecl() : { Token t ; String iri ; }
{
<PREFIX> t = <PNAME_NS> iri = IRIREF()
{ String s = fixupPrefix(t.image, t.beginLine, t.beginColumn) ;
getPrologue().setPrefix(s, iri) ; }
}
+
// ---- Query type clauses
+
void SelectQuery() : { }
-{
+{
SelectClause()
( DatasetClause() )*
WhereClause()
SolutionModifier()
}
+
void SubSelect() :{ }
-{
+{
SelectClause()
WhereClause()
SolutionModifier()
ValuesClause()
-}
-void SelectClause() : { Var v ; Expr expr ; Node n ; }
+}
+
+void SelectClause() : { Var v ; Expr expr ; Node n ; }
{
<SELECT>
{ getQuery().setQuerySelectType() ; }
- ( <DISTINCT> { getQuery().setDistinct(true);}
- | <REDUCED> { getQuery().setReduced(true); }
- )?
+ ( <DISTINCT> { getQuery().setDistinct(true);}
+ | <REDUCED> { getQuery().setReduced(true); }
+ )?
+
{ allowAggregatesInExpressions = true ; }
(
(
- v = Var() { getQuery().addResultVar(v) ; }
- |
+ v = Var() { getQuery().addResultVar(v) ; }
+ |
+
// Expressions without ()
( LOOKAHEAD(2)
- expr = BuiltInCall() { getQuery().addResultVar((Var)null, expr) ; }
- | expr = FunctionCall() { getQuery().addResultVar((Var)null, expr) ; }
- | n = RDFLiteral() { getQuery().addResultVar((Var)null, NodeValue.makeNode(n)) ; }
- | n = NumericLiteral() { getQuery().addResultVar((Var)null, NodeValue.makeNode(n)) ; }
- | n = BooleanLiteral() { getQuery().addResultVar((Var)null, NodeValue.makeNode(n)) ; }
+ expr = BuiltInCall() { getQuery().addResultVar((Var)null, expr) ; }
+ | expr = FunctionCall() { getQuery().addResultVar((Var)null, expr) ; }
+ | n = RDFLiteral() { getQuery().addResultVar((Var)null, NodeValue.makeNode(n)) ; }
+ | n = NumericLiteral() { getQuery().addResultVar((Var)null, NodeValue.makeNode(n)) ; }
+ | n = BooleanLiteral() { getQuery().addResultVar((Var)null, NodeValue.makeNode(n)) ; }
)
// @@ PROBLEMS: expr = FunctionCall()
// <uri>(?x)
// looks like a function call and also a "<uri> ( ?v )"
//| expr = FunctionCall() { getQuery().addResultVar((Var)null, expr) ; }
|
+
// Expressions with ()
(
{ v = null ; }
<LPAREN>
- expr = Expression()
+ expr = Expression()
+
+
+
+
( <AS> v = Var() ) ?
+
<RPAREN>
{ getQuery().addResultVar(v, expr) ; }
)
@@ -167,10 +197,15 @@ void SelectClause() : { Var v ; Expr exp
)
{ allowAggregatesInExpressions = false ; }
}
-void ConstructQuery() : { Template t ;
+
+
+
+
+
+void ConstructQuery() : { Template t ;
TripleCollectorBGP acc = new TripleCollectorBGP() ; }
{
-// #ifndef ARQ
+// #ifndef 1
// <CONSTRUCT>
// { getQuery().setQueryConstructType() ; }
// t = ConstructTemplate()
@@ -179,11 +214,12 @@ void ConstructQuery() : { Template t ;
// WhereClause()
// SolutionModifier()
// #else
+
<CONSTRUCT>
{ getQuery().setQueryConstructType() ; }
(
// Full form.
- t = ConstructTemplate()
+ t = ConstructTemplate()
{ getQuery().setConstructTemplate(t) ; }
( DatasetClause() )*
WhereClause()
@@ -193,11 +229,11 @@ void ConstructQuery() : { Template t ;
( DatasetClause() )*
<WHERE>
// Should have been "ConstructTemplate()"
- <LBRACE>
+ <LBRACE>
(TriplesTemplate(acc))?
<RBRACE>
SolutionModifier()
- {
+ {
t = new Template(acc.getBGP()) ;
getQuery().setConstructTemplate(t) ;
// Create a query in the same shape as the query created by writing out in full.
@@ -209,6 +245,7 @@ void ConstructQuery() : { Template t ;
)
//#endif
}
+
void DescribeQuery() : { Node n ; }
{
<DESCRIBE>
@@ -224,6 +261,7 @@ void DescribeQuery() : { Node n ; }
( WhereClause() )?
SolutionModifier()
}
+
void AskQuery() : {}
{
<ASK> { getQuery().setQueryAskType() ; }
@@ -231,137 +269,160 @@ void AskQuery() : {}
WhereClause()
SolutionModifier()
}
+
// ----
+
void DatasetClause() : {}
{
<FROM>
( DefaultGraphClause() | NamedGraphClause() )
}
+
void DefaultGraphClause() : { String iri ; }
{
- iri = SourceSelector()
+ iri = SourceSelector()
{
// This checks for duplicates
getQuery().addGraphURI(iri) ;
}
}
+
void NamedGraphClause() : { String iri ; }
{
<NAMED>
iri = SourceSelector()
- {
+ {
// This checks for duplicates
getQuery().addNamedGraphURI(iri) ;
}
}
+
String SourceSelector() : { String iri ; }
{
iri = iri() { return iri ; }
}
+
+
void WhereClause() : { Element el ; }
{
(<WHERE>)? el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
}
+
void SolutionModifier() : { }
{
( GroupClause() )?
( HavingClause() )?
( OrderClause() )?
- ( LimitOffsetClauses() )?
+ ( LimitOffsetClauses() )?
}
+
void GroupClause() : { }
{
<GROUP> <BY> ( GroupCondition() )+
}
+
void GroupCondition() : { Var v = null ; Expr expr = null ; }
{
- ( expr = BuiltInCall() { getQuery().addGroupBy((Var)null, expr) ; }
- | expr = FunctionCall() { getQuery().addGroupBy((Var)null, expr) ; }
+ ( expr = BuiltInCall() { getQuery().addGroupBy((Var)null, expr) ; }
+ | expr = FunctionCall() { getQuery().addGroupBy((Var)null, expr) ; }
|
<LPAREN>
- expr = Expression()
- ( <AS> v = Var() )?
+ expr = Expression()
+ ( <AS> v = Var() )?
<RPAREN>
{ getQuery().addGroupBy(v ,expr) ; }
| v = Var()
{ getQuery().addGroupBy(v) ; }
)
}
+
void HavingClause() : { }
{
{ allowAggregatesInExpressions = true ; }
<HAVING> (HavingCondition())+
{ allowAggregatesInExpressions = false ; }
}
+
void HavingCondition() : { Expr c ; }
{
c = Constraint()
{ getQuery().addHavingCondition(c) ; }
}
+
void OrderClause() : { }
{
{ allowAggregatesInExpressions = true ; }
<ORDER> <BY> ( OrderCondition() )+
{ allowAggregatesInExpressions = false ; }
}
+
void OrderCondition() :
{ int direction = 0 ; Expr expr = null ; Node v = null ; }
{
{ direction = Query.ORDER_DEFAULT ; }
(
( // These are for clarity in the HTML
- ( <ASC> { direction = Query.ORDER_ASCENDING ; }
- | <DESC> { direction = Query.ORDER_DESCENDING ; } )
- expr = BrackettedExpression()
+ ( <ASC> { direction = Query.ORDER_ASCENDING ; }
+ | <DESC> { direction = Query.ORDER_DESCENDING ; } )
+ expr = BrackettedExpression()
)
|
( expr = Constraint()
| v = Var() //{ expr = asExpr(v) ; }
- )
+ )
)
{ if ( v == null )
getQuery().addOrderBy(expr, direction) ;
else
getQuery().addOrderBy(v, direction) ; }
}
+
void LimitOffsetClauses() : { }
{
// SPARQL does not care about the order here.
// SQL (where implemented) does (it's LIMIT then OFFSET generally)
// But that is counter intuitive as it's applied the other way round
(
- LimitClause() (OffsetClause())?
+ LimitClause() (OffsetClause())?
|
- OffsetClause() (LimitClause())?
+ OffsetClause() (LimitClause())?
)
}
+
void LimitClause() : { Token t ; }
{
<LIMIT> t = <INTEGER>
{ getQuery().setLimit(integerValue(t.image)) ; }
}
+
void OffsetClause() : { Token t ; }
{
<OFFSET> t = <INTEGER>
{ getQuery().setOffset(integerValue(t.image)) ; }
}
+
void ValuesClause() : { Token t ; }
{
(
- t = <VALUES>
+ t = <VALUES>
{ startValuesClause(t.beginLine, t.beginColumn) ; }
DataBlock()
{ finishValuesClause(t.beginLine, t.beginColumn) ; }
)?
}
+
+
// SPARQL Update + transitional extensions for SPARQL/Update (the W3C submission)
// Update only entry point
+
+
// Optional SEMICOLON
void Update() : { }
{
Prologue()
- ( Update1() (<SEMICOLON>)* Update() )?
+ ( Update1() (<SEMICOLON>)* Update() )?
}
+
void Update1() : { Update up ; }
{
{ startUpdateOperation() ; }
@@ -382,83 +443,96 @@ void Update1() : { Update up ; }
emitUpdate(up) ;
finishUpdateOperation() ;
}
+
}
+
Update Load() : { String url ; Node dest = null ; boolean silent = false ; }
{
// Should be +?
// <LOAD> ( iri() )+
- <LOAD> (<SILENT> { silent = true ; })? url = iri()
+ <LOAD> (<SILENT> { silent = true ; })? url = iri()
{ String iri ; }
(<INTO> (<GRAPH>)? iri = iri() { dest = createNode(iri) ; })?
{ return new UpdateLoad(url, dest, silent) ; }
}
+
Update Clear() : { boolean silent = false ; Target target ; }
{
<CLEAR> (<SILENT> { silent = true ; })? target = GraphRefAll()
{ return new UpdateClear(target, silent) ; }
}
+
Update Drop() : { boolean silent = false ; Target target ; }
{
<DROP> (<SILENT> { silent = true ; })? target = GraphRefAll()
{ return new UpdateDrop(target, silent) ; }
}
+
Update Create() : { Node iri ; boolean silent = false ; }
{
<CREATE> (<SILENT> { silent=true ; } )? iri = GraphRef()
- { return new UpdateCreate(iri, silent) ; }
+ { return new UpdateCreate(iri, silent) ; }
}
+
Update Add() : { Target src ; Target dest ; boolean silent = false ; }
{
- <ADD> (<SILENT> { silent=true ; } )? src = GraphOrDefault() <TO> dest = GraphOrDefault()
+ <ADD> (<SILENT> { silent=true ; } )? src = GraphOrDefault() <TO> dest = GraphOrDefault()
{ return new UpdateAdd(src, dest, silent) ; }
}
-Update Move() : { Target src ; Target dest ; boolean silent = false ; }
+
+Update Move() : { Target src ; Target dest ; boolean silent = false ; }
{
- <MOVE> (<SILENT> { silent=true ; } )? src = GraphOrDefault() <TO> dest = GraphOrDefault()
+ <MOVE> (<SILENT> { silent=true ; } )? src = GraphOrDefault() <TO> dest = GraphOrDefault()
{ return new UpdateMove(src, dest, silent) ; }
}
+
Update Copy() : { Target src ; Target dest ; boolean silent = false ; }
{
- <COPY> (<SILENT> { silent=true ; } )? src = GraphOrDefault() <TO> dest = GraphOrDefault()
+ <COPY> (<SILENT> { silent=true ; } )? src = GraphOrDefault() <TO> dest = GraphOrDefault()
{ return new UpdateCopy(src, dest, silent) ; }
}
-// #ifdef ARQ
+
+// #ifdef 1
// void Meta() : { QuadDataAcc qd = new QuadDataAcc() ; }
// {
// <META>
// QuadData(qd)
// }
// #endif
+
Update InsertData() : { QuadDataAcc qd = new QuadDataAcc() ; Token t ; }
{
- t = <INSERT_DATA>
+ t = <INSERT_DATA>
{ startDataInsert(qd, t.beginLine, t.beginColumn) ; }
OptionalIntoTarget(qd)
QuadPattern(qd)
{
finishDataInsert(qd, t.beginLine, t.beginColumn) ;
- return new UpdateDataInsert(qd) ;
+ return new UpdateDataInsert(qd) ;
}
}
+
Update DeleteData() : { QuadDataAcc qd = new QuadDataAcc() ; Token t ; }
{
t = <DELETE_DATA>
{ startDataDelete(qd, t.beginLine, t.beginColumn) ; }
OptionalFromTarget(qd)
QuadData(qd)
- {
+ {
finishDataDelete(qd, t.beginLine, t.beginColumn) ;
return new UpdateDataDelete(qd) ;
}
}
-Update DeleteWhere() : { QuadAcc qp = new QuadAcc() ; Token t ; }
+
+Update DeleteWhere() : { QuadAcc qp = new QuadAcc() ; Token t ; }
{
- t = <DELETE_WHERE>
+ t = <DELETE_WHERE>
{ startDeleteTemplate(qp, t.beginLine, t.beginColumn) ; }
QuadPattern(qp)
{ finishDeleteTemplate(qp, t.beginLine, t.beginColumn) ; }
{ return new UpdateDeleteWhere(qp) ; }
}
+
Update Modify() : { Element el ; String iri = null ;
UpdateModify up = new UpdateModify() ; }
{
@@ -468,9 +542,10 @@ Update Modify() : { Element el ; String
)
(UsingClause(up))*
<WHERE>
- el = GroupGraphPattern() { up.setElement(el) ; }
+ el = GroupGraphPattern() { up.setElement(el) ; }
{ return up ; }
}
+
Update ModifyOld() :
{ UpdateModify up = new UpdateModify() ; String iri ; Template template ; Element el ; }
{
@@ -479,10 +554,11 @@ Update ModifyOld() :
(DeleteClause(up))?
(InsertClause(up))?
<WHERE>
- el = GroupGraphPattern() { up.setElement(el) ; }
+ el = GroupGraphPattern() { up.setElement(el) ; }
{ return up ; }
}
-void DeleteClause(UpdateModify up) : { QuadAcc qp = up.getDeleteAcc() ; Token t ;}
+
+void DeleteClause(UpdateModify up) : { QuadAcc qp = up.getDeleteAcc() ; Token t ;}
{
t = <DELETE>
{ startDeleteTemplate(qp, t.beginLine, t.beginColumn) ; }
@@ -491,6 +567,7 @@ void DeleteClause(UpdateModify up) : { Q
{ finishDeleteTemplate(qp, t.beginLine, t.beginColumn) ; }
{ up.setHasDeleteClause(true) ; }
}
+
void InsertClause(UpdateModify up) : { QuadAcc qp = up.getInsertAcc() ; Token t ; }
{
t = <INSERT>
@@ -500,59 +577,67 @@ void InsertClause(UpdateModify up) : { Q
{ finishInsertTemplate(qp, t.beginLine, t.beginColumn) ; }
{ up.setHasInsertClause(true) ; }
}
+
void OptionalIntoTarget(QuadAcc qp) : { String iri ; }
{
- ( (<INTO>)?
+ ( (<INTO>)?
iri = iri()
{ Node gn = createNode(iri) ; setAccGraph(qp, gn) ; }
)?
}
+
void OptionalFromTarget(QuadAcc qp) : { String iri ; }
{
- ( (<FROM>)?
+ ( (<FROM>)?
iri = iri()
{ Node gn = createNode(iri) ; setAccGraph(qp, gn) ; }
)?
}
+
void UsingClause(UpdateWithUsing update) : { String iri ; Node n ; }
{
- <USING>
- ( iri = iri()
+ <USING>
+ ( iri = iri()
{ n = createNode(iri) ; update.addUsing(n) ; }
| <NAMED> iri = iri()
{ n = createNode(iri) ; update.addUsingNamed(n) ; }
)
}
+
Target GraphOrDefault() : { String iri ; }
{
( <DFT> { return Target.DEFAULT ; }
- | (<GRAPH>)?
+ | (<GRAPH>)?
iri = iri()
- { return Target.create(createNode(iri)) ; }
+ { return Target.create(createNode(iri)) ; }
)
}
+
Node GraphRef() : { String iri ; }
{
<GRAPH> iri = iri()
{ return createNode(iri) ; }
}
+
Target GraphRefAll() : { Node iri ; }
{
- ( iri = GraphRef()
+ ( iri = GraphRef()
{ return Target.create(iri) ; }
- | <DFT> { return Target.DEFAULT ; }
- | <NAMED> { return Target.NAMED ; }
- | <ALL> { return Target.ALL ; }
+ | <DFT> { return Target.DEFAULT ; }
+ | <NAMED> { return Target.NAMED ; }
+ | <ALL> { return Target.ALL ; }
)
?
{ return Target.DEFAULT ; }
}
+
void QuadPattern(QuadAcc acc) : { }
{
<LBRACE>
Quads(acc)
<RBRACE>
}
+
//Ground data : As QuadPattern but don't allow variables.
void QuadData(QuadDataAcc acc) : { }
{
@@ -560,6 +645,7 @@ void QuadData(QuadDataAcc acc) : { }
Quads(acc)
<RBRACE>
}
+
void Quads(QuadAcc acc) : { }
{
(TriplesTemplate(acc))?
@@ -569,30 +655,36 @@ void Quads(QuadAcc acc) : { }
(TriplesTemplate(acc))?
)*
}
+
void QuadsNotTriples(QuadAcc acc) : {Node gn ; Node prev = acc.getGraph() ; }
{
<GRAPH> gn = VarOrIri()
{ setAccGraph(acc, gn) ; }
- <LBRACE>
+ <LBRACE>
(TriplesTemplate(acc))?
<RBRACE>
{ setAccGraph(acc, prev) ; }
+
}
+
void TriplesTemplate(TripleCollector acc) : { }
-{ // same as ConstructTriples
+{ // same as ConstructTriples
// Rewrite for no recursion - grammar is not LL(1)
TriplesSameSubject(acc)
(LOOKAHEAD(2) (<DOT>) TriplesSameSubject(acc))*
(<DOT>)?
}
+
+
// ---- General Graph Pattern
+
Element GroupGraphPattern() : { Element el = null ; Token t ; }
{
t = <LBRACE>
- (
+ (
{ startSubSelect(t.beginLine, t.beginColumn) ; }
SubSelect()
- {
+ {
Query q = endSubSelect(t.beginLine, t.beginColumn) ;
el = new ElementSubQuery(q) ;
}
@@ -601,6 +693,7 @@ Element GroupGraphPattern() : { Element
<RBRACE>
{ return el ; }
}
+
Element GroupGraphPatternSub() : { Element el = null ; }
{
{ ElementGroup elg = new ElementGroup() ; }
@@ -612,22 +705,25 @@ Element GroupGraphPatternSub() : { Eleme
{ startTriplesBlock() ; }
el = TriplesBlock(null)
{ endTriplesBlock() ;
- elg.addElement(el) ; }
+ elg.addElement(el) ; }
)?
(
- el = GraphPatternNotTriples()
+ el = GraphPatternNotTriples()
{ elg.addElement(el) ; }
+
(<DOT>)?
+
(
{ startTriplesBlock() ; }
el = TriplesBlock(null)
{ endTriplesBlock() ;
- elg.addElement(el) ; }
+ elg.addElement(el) ; }
)?
)*
{ endGroup(elg) ; }
{ return elg ; }
}
+
Element TriplesBlock(ElementPathBlock acc) : { }
{
{ if ( acc == null )
@@ -637,7 +733,9 @@ Element TriplesBlock(ElementPathBlock ac
( <DOT> (TriplesBlock(acc))? )?
{ return acc ; }
}
+
// -----
+
Element GraphPatternNotTriples() : { Element el = null ; }
{
(
@@ -669,19 +767,24 @@ Element GraphPatternNotTriples() : { Ele
)
{ return el ; }
}
+
// ---- Definitions of each pattern element
+
Element OptionalGraphPattern() : { Element el ; }
{ <OPTIONAL> el = GroupGraphPattern()
{ return new ElementOptional(el) ; }
}
+
Element GraphGraphPattern() : { Element el ; Node n ;}
{
<GRAPH> n = VarOrIri() el = GroupGraphPattern()
{ return new ElementNamedGraph(n, el) ; }
}
+
+
Element ServiceGraphPattern() : { Element el ; Node n ; boolean silent = false ; }
{
- <SERVICE>
+ <SERVICE>
(<SILENT>
{ silent=true; }
)?
@@ -689,7 +792,8 @@ Element ServiceGraphPattern() : { Elemen
el = GroupGraphPattern()
{ return new ElementService(n, el, silent) ; }
}
-Element Bind() : { Var v ; Expr expr ; }
+
+Element Bind() : { Var v ; Expr expr ; }
{
<BIND>
<LPAREN>
@@ -699,6 +803,7 @@ Element Bind() : { Var v ; Expr expr ; }
<RPAREN>
{ return new ElementBind(v, expr) ; }
}
+
Element InlineData() : { ElementData el ; Token t ; }
{
t = <VALUES>
@@ -708,24 +813,27 @@ Element InlineData() : { ElementData el
{ finishInlineData(t.beginLine, t.beginColumn) ;
return el ; }
}
+
void DataBlock() : { }
{
- ( InlineDataOneVar() | InlineDataFull() )
+ ( InlineDataOneVar() | InlineDataFull() )
}
+
void InlineDataOneVar() : { Var v ; Node n ; Token t ; }
{
v = Var()
{ emitDataBlockVariable(v) ; }
t = <LBRACE>
- (
- n = DataBlockValue()
+ (
+ n = DataBlockValue()
{ startDataBlockValueRow(-1, -1) ;
emitDataBlockValue(n, -1, -1) ;
finishDataBlockValueRow(-1, -1) ;
}
)*
t = <RBRACE>
-}
+}
+
void InlineDataFull() : { Var v ; Node n ; Token t ; }
{
(
@@ -737,12 +845,12 @@ void InlineDataFull() : { Var v ; Node n
)
t = <LBRACE>
(
- t = <LPAREN>
+ t = <LPAREN>
{ startDataBlockValueRow(t.beginLine, t.beginColumn) ; }
- (n = DataBlockValue()
+ (n = DataBlockValue()
{ emitDataBlockValue(n, t.beginLine, t.beginColumn) ; }
) *
- t = <RPAREN>
+ t = <RPAREN>
{ finishDataBlockValueRow(t.beginLine, t.beginColumn) ; }
|
t = <NIL>
@@ -750,51 +858,63 @@ void InlineDataFull() : { Var v ; Node n
{ finishDataBlockValueRow(t.beginLine, t.beginColumn) ; }
)*
t = <RBRACE>
-}
+}
+
Node DataBlockValue() : { Node n ; String iri ; }
{
- iri = iri() { return createNode(iri) ; }
-| n = RDFLiteral() { return n ; }
-| n = NumericLiteral() { return n ; }
-| n = BooleanLiteral() { return n ; }
-| <UNDEF> { return null ; }
+ iri = iri() { return createNode(iri) ; }
+| n = RDFLiteral() { return n ; }
+| n = NumericLiteral() { return n ; }
+| n = BooleanLiteral() { return n ; }
+| <UNDEF> { return null ; }
}
+
+
Element Assignment() : { Var v ; Expr expr ; }
{
- <LET>
+ <LET>
<LPAREN>
v = Var()
- <ASSIGN>
+ <ASSIGN>
expr = Expression()
<RPAREN>
{ return new ElementAssign(v, expr) ; }
}
+
+
Element ExistsElt() : { Element el ; }
{
<EXISTS>
el = GroupGraphPattern()
{ return new ElementExists(el) ; }
}
+
Element NotExistsElt() : { Element el ; }
{
<NOT> <EXISTS>
el = GroupGraphPattern()
{ return new ElementNotExists(el) ; }
}
+
Element MinusGraphPattern() : { Element el ; }
{
<MINUS_P>
el = GroupGraphPattern()
{ return new ElementMinus(el) ; }
}
+
// Element UnionGraphPattern() : { Element el ; }
// {
// <UNION>
// el = GroupGraphPattern()
// { return new ElementUnion(el) ; }
// }
+
+
// SPARQL 1.0: {pattern} UNION {pattern} UNION {pattern} ... ::
// SPARQL 1.1 may introduce: { pattern UNION pattern UNION ... }
+
+
// G (union G)* can be a single group pattern
// or a group pattern as part of an union.
Element GroupOrUnionGraphPattern() :
@@ -809,32 +929,37 @@ Element GroupOrUnionGraphPattern() :
}
}
el = GroupGraphPattern()
- { el2.addElement(el) ; }
+ { el2.addElement(el) ; }
)*
{ return (el2==null)? el : el2 ; }
}
+
+
Element Filter() : { Expr c ; }
{
<FILTER> c = Constraint()
{ return new ElementFilter(c) ; }
}
+
Expr Constraint() : { Expr c ; }
{
- ( c = BrackettedExpression()
+ ( c = BrackettedExpression()
| c = BuiltInCall()
| c = FunctionCall()
)
{ return c ; }
}
+
Expr FunctionCall() : { String fname ; ExprList a ; }
{
fname = iri()
a = ArgList()
{ return new E_Function(fname, a) ; }
}
+
ExprList ArgList() : { Expr expr ; boolean distinct = false ;
ExprList args = new ExprList() ; Token t ; }
-{
+{
(
<NIL>
|
@@ -846,69 +971,80 @@ ExprList ArgList() : { Expr expr ; boole
t.beginLine, t.beginColumn) ;
}
)?
- expr = Expression() { args.add(expr) ; }
+ expr = Expression() { args.add(expr) ; }
(<COMMA> expr = Expression() { args.add(expr) ; } )*
<RPAREN>
)
{ return args ; }
}
+
ExprList ExpressionList() : { Expr expr = null ; ExprList args = new ExprList() ;}
{
(
<NIL>
|
<LPAREN>
- expr = Expression() { args.add(expr) ; }
- (<COMMA> expr = Expression() { args.add(expr) ; } )*
+ expr = Expression() { args.add(expr) ; }
+ (<COMMA> expr = Expression() { args.add(expr) ; } )*
<RPAREN>
)
{ return args ; }
}
+
+
+
// -------- Construct patterns
-Template ConstructTemplate() : { TripleCollectorBGP acc = new TripleCollectorBGP();
+
+Template ConstructTemplate() : { TripleCollectorBGP acc = new TripleCollectorBGP();
Template t = new Template(acc.getBGP()) ; }
{
{ setInConstructTemplate(true) ; }
- <LBRACE>
+ <LBRACE>
(ConstructTriples(acc))?
<RBRACE>
{ setInConstructTemplate(false) ;
return t ; }
}
+
void ConstructTriples(TripleCollector acc) : { }
-{ // Same as TriplesTemplate, but retain for 1.0 legacy
+{ // Same as TriplesTemplate, but retain for 1.0 legacy
// Rewrite for no recursion - grammar is not LL(1)
TriplesSameSubject(acc)
(LOOKAHEAD(2) (<DOT>) TriplesSameSubject(acc))*
(<DOT>)?
}
+
// -------- Triple lists with property and object lists
// -------- Without paths: entry: TriplesSameSubject
-void TriplesSameSubject(TripleCollector acc) : { Node s ; }
+
+void TriplesSameSubject(TripleCollector acc) : { Node s ; }
{
s = VarOrTerm()
- PropertyListNotEmpty(s, acc)
+ PropertyListNotEmpty(s, acc)
|
// Any of the triple generating syntax elements
s = TriplesNode(acc)
PropertyList(s, acc)
}
+
void PropertyList(Node s, TripleCollector acc) : { }
{
( PropertyListNotEmpty(s, acc) ) ?
}
-void PropertyListNotEmpty(Node s, TripleCollector acc) :
+
+void PropertyListNotEmpty(Node s, TripleCollector acc) :
{ Node p = null ; }
{
p = Verb()
ObjectList(s, p, null, acc)
- ( <SEMICOLON>
+ ( <SEMICOLON>
(
p = Verb()
ObjectList(s, p, null, acc)
- )?
+ )?
)*
}
+
Node Verb() : { Node p ;}
{
// Blank nodes as predicates
@@ -916,53 +1052,63 @@ Node Verb() : { Node p ;}
( p = VarOrIri() | <KW_A> { p = nRDFtype ; } )
{ return p ; }
}
-void ObjectList(Node s, Node p, Path path, TripleCollector acc): { Node o ; }
+
+void ObjectList(Node s, Node p, Path path, TripleCollector acc): { Node o ; }
{
Object(s, p, path, acc)
( <COMMA> Object(s, p, path, acc) )*
}
+
void Object(Node s, Node p, Path path, TripleCollector acc): { Node o ; }
{
{ int mark = acc.mark() ; }
- o = GraphNode(acc)
+ o = GraphNode(acc)
{ insert(acc, mark, s, p, path, o) ; }
}
+
// -------- BGPs with paths.
// -------- Entry point: TriplesSameSubjectPath
-void TriplesSameSubjectPath(TripleCollector acc) : { Node s ; }
+
+void TriplesSameSubjectPath(TripleCollector acc) : { Node s ; }
{
s = VarOrTerm()
- PropertyListPathNotEmpty(s, acc)
+ PropertyListPathNotEmpty(s, acc)
|
// Any of the triple generating syntax elements
s = TriplesNodePath(acc)
PropertyListPath(s, acc)
}
+
+
void PropertyListPath(Node s, TripleCollector acc) : { }
{
( PropertyListPathNotEmpty(s, acc) ) ?
}
-void PropertyListPathNotEmpty(Node s, TripleCollector acc) :
+
+void PropertyListPathNotEmpty(Node s, TripleCollector acc) :
{ Path path = null ; Node p = null ; }
{
( path = VerbPath()
| p = VerbSimple()
)
+
ObjectListPath(s, p, path, acc)
- ( <SEMICOLON>
+ ( <SEMICOLON>
{ path = null ; p = null ; }
(
( path = VerbPath()
| p = VerbSimple()
)
ObjectList(s, p, path, acc)
- )?
+ )?
)*
}
+
Path VerbPath() : {Node p ; Path path ; }
{
path = Path() { return path ; }
}
+
Node VerbSimple() : { Node p ; }
{
// "a" now allowed in paths.
@@ -970,30 +1116,38 @@ Node VerbSimple() : { Node p ; }
p = Var()
{ return p ; }
}
-void ObjectListPath(Node s, Node p, Path path, TripleCollector acc): { Node o ; }
+
+void ObjectListPath(Node s, Node p, Path path, TripleCollector acc): { Node o ; }
{
ObjectPath(s, p, path, acc)
( <COMMA> ObjectPath(s, p, path, acc) )*
}
+
void ObjectPath(Node s, Node p, Path path, TripleCollector acc): { Node o ; }
{
{ int mark = acc.mark() ; }
- o = GraphNodePath(acc)
+ o = GraphNodePath(acc)
{ insert(acc, mark, s, p, path, o) ; }
}
+
+
// End paths stuff.
+
// -------- Paths
+
Path PathUnit() : { Path p ; }
{
p = Path()
<EOF>
{ return p ; }
}
+
// Weakest outermost
Path Path() : { Path p ; }
{
p = PathAlternative() { return p ; }
}
+
Path PathAlternative() : { Path p1 , p2 ; }
{
p1 = PathSequence()
@@ -1003,6 +1157,7 @@ Path PathAlternative() : { Path p1 , p2
)*
{ return p1 ; }
}
+
Path PathSequence() : { Path p1 , p2 ; }
{
p1 = PathEltOrInverse()
@@ -1014,153 +1169,170 @@ Path PathSequence() : { Path p1 , p2 ; }
)*
{ return p1; }
}
+
// Path unit element, no inverse
Path PathElt() : { String str ; Node n ; Path p ; }
-{
- p = PathPrimary()
+{
+ p = PathPrimary()
( p = PathMod(p) )?
{ return p ; }
}
+
// Path unit element, including inverse.
Path PathEltOrInverse() : { String str ; Node n ; Path p ; }
-{
- ( p = PathElt()
+{
+ ( p = PathElt()
| <CARAT>
p = PathElt()
{ p = PathFactory.pathInverse(p) ; }
)
{ return p ; }
}
+
Path PathMod(Path p) : { long i1 ; long i2 ; }
{
- ( <QMARK> { return PathFactory.pathZeroOrOne(p) ; }
- | <STAR> { return PathFactory.pathZeroOrMore1(p) ; }
- | <PLUS> { return PathFactory.pathOneOrMore1(p) ; }
+ ( <QMARK> { return PathFactory.pathZeroOrOne(p) ; }
+ | <STAR> { return PathFactory.pathZeroOrMore1(p) ; }
+ | <PLUS> { return PathFactory.pathOneOrMore1(p) ; }
| <LBRACE>
//{*}
( <STAR> <RBRACE> { return PathFactory.pathZeroOrMoreN(p) ; }
// {+}
- | <PLUS> <RBRACE> { return PathFactory.pathOneOrMoreN(p) ; }
- | // {N} {N,M} {N,}
+ | <PLUS> <RBRACE> { return PathFactory.pathOneOrMoreN(p) ; }
+ | // {N} {N,M} {N,}
i1 = Integer()
( <COMMA>
( // case {N,}
- <RBRACE>
- { return PathFactory.pathMod(p, i1, PathFactory.UNSET) ; }
+ <RBRACE>
+ { return PathFactory.pathMod(p, i1, PathFactory.UNSET) ; }
| // case {N,M}
i2 = Integer() <RBRACE> // case {N,M}
- { return PathFactory.pathMod(p, i1, i2) ; }
+ { return PathFactory.pathMod(p, i1, i2) ; }
)
|
- <RBRACE> // {N}
+ <RBRACE> // {N}
{ return PathFactory.pathFixedLength(p, i1) ; }
)
- | // {,N}
+ | // {,N}
<COMMA>
i2 = Integer()
<RBRACE>
- { return PathFactory.pathMod(p, PathFactory.UNSET, i2) ; }
+ { return PathFactory.pathMod(p, PathFactory.UNSET, i2) ; }
)
)
}
+
Path PathPrimary() : { String str ; Path p ; Node n ; }
{
- (
+ (
str = iri()
{ n = createNode(str) ; p = PathFactory.pathLink(n) ; }
- | <KW_A>
+ | <KW_A>
{ p = PathFactory.pathLink(nRDFtype) ; }
| <BANG> p = PathNegatedPropertySet()
| <LPAREN> p = Path() <RPAREN>
|
- <DISTINCT><LPAREN>
+ <DISTINCT><LPAREN>
p = Path()
{ p = PathFactory.pathDistinct(p) ; }
<RPAREN>
|
- <SHORTEST> <LPAREN>
+ <SHORTEST> <LPAREN>
p = Path()
{ p = PathFactory.pathShortest(p) ; }
<RPAREN>
|
- <MULTI><LPAREN>
+ <MULTI><LPAREN>
p = Path()
{ p = PathFactory.pathMulti(p) ; }
<RPAREN>
)
{ return p ; }
}
+
Path PathNegatedPropertySet() : { P_Path0 p ; P_NegPropSet pNegSet ; }
{
{ pNegSet = new P_NegPropSet() ; }
+
( p = PathOneInPropertySet()
{ pNegSet.add(p) ; }
- | <LPAREN>
+ | <LPAREN>
( p = PathOneInPropertySet() { pNegSet.add(p) ; }
(<VBAR> p = PathOneInPropertySet() { pNegSet.add(p) ; }) *
- )?
+ )?
<RPAREN>
- )
+ )
{ return pNegSet ; }
}
+
P_Path0 PathOneInPropertySet() : { String str ; Node n ; }
{
- ( str = iri() { n = createNode(str) ; return new P_Link(n) ; }
- | <KW_A> { return new P_Link(nRDFtype) ; }
+ ( str = iri() { n = createNode(str) ; return new P_Link(n) ; }
+ | <KW_A> { return new P_Link(nRDFtype) ; }
// This is the !(^:property) form.
- | <CARAT>
- ( str = iri() { n = createNode(str) ; return new P_ReverseLink(n) ; }
- | <KW_A> { return new P_ReverseLink(nRDFtype) ; }
+ | <CARAT>
+ ( str = iri() { n = createNode(str) ; return new P_ReverseLink(n) ; }
+ | <KW_A> { return new P_ReverseLink(nRDFtype) ; }
)
)
}
+
long Integer() : {Token t ;}
{
- t = <INTEGER>
+ t = <INTEGER>
{ return integerValue(t.image) ; }
}
+
// -------- Triple expansions
+
// Anything that can stand in a node slot and which is
// a number of triples
+
Node TriplesNode(TripleCollector acc) : { Node n ; }
{
n = Collection(acc) { return n ; }
|
n = BlankNodePropertyList(acc) { return n ; }
}
+
Node BlankNodePropertyList(TripleCollector acc) : { Token t ; }
{
- t = <LBRACKET>
+ t = <LBRACKET>
{ Node n = createBNode( t.beginLine, t.beginColumn) ; }
PropertyListNotEmpty(n, acc)
<RBRACKET>
{ return n ; }
}
+
Node TriplesNodePath(TripleCollector acc) : { Node n ; }
{
n = CollectionPath(acc) { return n ; }
|
n = BlankNodePropertyListPath(acc) { return n ; }
}
+
Node BlankNodePropertyListPath(TripleCollector acc) : { Token t ; }
{
- t = <LBRACKET>
+ t = <LBRACKET>
{ Node n = createBNode( t.beginLine, t.beginColumn) ; }
PropertyListPathNotEmpty(n, acc)
<RBRACKET>
{ return n ; }
}
+
+
// ------- RDF collections
-Node Collection(TripleCollector acc) :
+
+Node Collection(TripleCollector acc) :
{ Node listHead = nRDFnil ; Node lastCell = null ; int mark ; Node n ; Token t ; }
{
- t = <LPAREN>
+ t = <LPAREN>
(
{ Node cell = createListNode( t.beginLine, t.beginColumn) ;
if ( listHead == nRDFnil )
listHead = cell ;
if ( lastCell != null )
- insert(acc, lastCell, nRDFrest, cell) ;
+ insert(acc, lastCell, nRDFrest, cell) ;
mark = acc.mark() ;
}
n = GraphNode(acc)
@@ -1172,19 +1344,20 @@ Node Collection(TripleCollector acc) :
// Not * here - "()" is handled separately.
<RPAREN>
{ if ( lastCell != null )
- insert(acc, lastCell, nRDFrest, nRDFnil) ;
+ insert(acc, lastCell, nRDFrest, nRDFnil) ;
return listHead ; }
}
-Node CollectionPath(TripleCollector acc) :
+
+Node CollectionPath(TripleCollector acc) :
{ Node listHead = nRDFnil ; Node lastCell = null ; int mark ; Node n ; Token t ; }
{
- t = <LPAREN>
+ t = <LPAREN>
(
{ Node cell = createListNode( t.beginLine, t.beginColumn) ;
if ( listHead == nRDFnil )
listHead = cell ;
if ( lastCell != null )
- insert(acc, lastCell, nRDFrest, cell) ;
+ insert(acc, lastCell, nRDFrest, cell) ;
mark = acc.mark() ;
}
n = GraphNodePath(acc)
@@ -1196,62 +1369,74 @@ Node CollectionPath(TripleCollector acc)
// Not * here - "()" is handled separately.
<RPAREN>
{ if ( lastCell != null )
- insert(acc, lastCell, nRDFrest, nRDFnil) ;
+ insert(acc, lastCell, nRDFrest, nRDFnil) ;
return listHead ; }
}
+
// -------- Nodes in a graph pattern or template
+
Node GraphNode(TripleCollector acc) : { Node n ; }
{
n = VarOrTerm() { return n ; }
|
n = TriplesNode(acc) { return n ; }
}
+
Node GraphNodePath(TripleCollector acc) : { Node n ; }
{
n = VarOrTerm() { return n ; }
|
n = TriplesNodePath(acc) { return n ; }
}
+
Node VarOrTerm() : {Node n = null ; }
{
( n = Var() | n = GraphTerm() )
{ return n ; }
}
+
// Property (if no bNodes) + DESCRIBE
Node VarOrIri() : {Node n = null ; String iri ; }
{
( n = Var() | iri = iri() { n = createNode(iri) ; } )
{ return n ; }
}
+
Var Var() : { Token t ;}
{
( t = <VAR1> | t = <VAR2> )
{ return createVariable(t.image, t.beginLine, t.beginColumn) ; }
}
+
Node GraphTerm() : { Node n ; String iri ; }
{
- iri = iri() { return createNode(iri) ; }
-| n = RDFLiteral() { return n ; }
-| n = NumericLiteral() { return n ; }
-| n = BooleanLiteral() { return n ; }
-| n = BlankNode() { return n ; }
+ iri = iri() { return createNode(iri) ; }
+| n = RDFLiteral() { return n ; }
+| n = NumericLiteral() { return n ; }
+| n = BooleanLiteral() { return n ; }
+| n = BlankNode() { return n ; }
// <LPAREN> <RPAREN> { return nRDFnil ; }
-| <NIL> { return nRDFnil ; }
+| <NIL> { return nRDFnil ; }
}
+
// -------- Constraint syntax
+
Expr Expression() : { Expr expr ; }
{
expr = ConditionalOrExpression()
{ return expr ; }
}
+
Expr ConditionalOrExpression() : { Expr expr1, expr2 ; }
{
- expr1 = ConditionalAndExpression()
+ expr1 = ConditionalAndExpression()
( <SC_OR> expr2 = ConditionalAndExpression()
- { expr1 = new E_LogicalOr(expr1, expr2) ; }
+ { expr1 = new E_LogicalOr(expr1, expr2) ; }
)*
{ return expr1 ; }
+
}
+
Expr ConditionalAndExpression() : { Expr expr1, expr2 ;}
{
expr1 = ValueLogical()
@@ -1260,11 +1445,13 @@ Expr ConditionalAndExpression() : { Expr
)*
{ return expr1 ; }
}
+
Expr ValueLogical() : { Expr expr ; }
{
expr = RelationalExpression()
{ return expr ; }
}
+
Expr RelationalExpression() : { Expr expr1, expr2 ; ExprList a ; }
{
expr1 = NumericExpression()
@@ -1288,11 +1475,13 @@ Expr RelationalExpression() : { Expr exp
)?
{ return expr1 ; }
}
-Expr NumericExpression () : { Expr expr ; }
+
+Expr NumericExpression () : { Expr expr ; }
{
expr = AdditiveExpression()
{ return expr ; }
}
+
Expr AdditiveExpression() : { Expr expr1, expr2, expr3 ; boolean addition ; Node n ; }
{
expr1 = MultiplicativeExpression()
@@ -1310,17 +1499,19 @@ Expr AdditiveExpression() : { Expr expr1
}
|
n = NumericLiteralNegative()
- {
+ {
n = stripSign(n) ;
expr2 = asExpr(n) ;
addition = false ;
}
)
+
(
- ( <STAR> expr3 = UnaryExpression() { expr2 = new E_Multiply(expr2, expr3) ; } )
+ ( <STAR> expr3 = UnaryExpression() { expr2 = new E_Multiply(expr2, expr3) ; } )
|
- ( <SLASH> expr3 = UnaryExpression() { expr2 = new E_Divide(expr2, expr3) ; } )
+ ( <SLASH> expr3 = UnaryExpression() { expr2 = new E_Divide(expr2, expr3) ; } )
)*
+
{ if ( addition )
expr1 = new E_Add(expr1, expr2) ;
else
@@ -1329,10 +1520,11 @@ Expr AdditiveExpression() : { Expr expr1
)*
{ return expr1 ; }
}
+
Expr MultiplicativeExpression() : { Expr expr1, expr2 ; }
{
expr1 = UnaryExpression()
- ( <STAR> expr2 = UnaryExpression()
+ ( <STAR> expr2 = UnaryExpression()
{ expr1 = new E_Multiply(expr1, expr2) ; }
| <SLASH> expr2 = UnaryExpression()
{ expr1 = new E_Divide(expr1, expr2) ; }
@@ -1341,31 +1533,36 @@ Expr MultiplicativeExpression() : { Expr
)*
{ return expr1 ; }
}
+
Expr UnaryExpression() : { Expr expr ; }
{
<BANG> expr = PrimaryExpression()
{ return new E_LogicalNot(expr) ; }
- | <PLUS> expr = PrimaryExpression() { return new E_UnaryPlus(expr) ; }
+ | <PLUS> expr = PrimaryExpression() { return new E_UnaryPlus(expr) ; }
| <MINUS> expr = PrimaryExpression() { return new E_UnaryMinus(expr) ; }
| expr = PrimaryExpression() { return expr ; }
}
+
Expr PrimaryExpression() : { Expr expr ; Node gn ; }
{
( expr = BrackettedExpression() { return expr ; }
- | expr = BuiltInCall() { return expr ; }
- | expr = iriOrFunction() { return expr ; }
+ | expr = BuiltInCall() { return expr ; }
+ | expr = iriOrFunction() { return expr ; }
+
// NOT | gn = VarOrTerm() { return asExpr(gn) ; }
// Because of iriOrFunction
- | gn = RDFLiteral() { return asExpr(gn) ; }
- | gn = NumericLiteral() { return asExpr(gn) ; }
- | gn = BooleanLiteral() { return asExpr(gn) ; }
- | gn = Var() { return asExpr(gn) ; }
+ | gn = RDFLiteral() { return asExpr(gn) ; }
+ | gn = NumericLiteral() { return asExpr(gn) ; }
+ | gn = BooleanLiteral() { return asExpr(gn) ; }
+ | gn = Var() { return asExpr(gn) ; }
)
}
+
Expr BrackettedExpression() : { Expr expr ; }
{
- <LPAREN> expr = Expression() <RPAREN> { return expr ; }
+ <LPAREN> expr = Expression() <RPAREN> { return expr ; }
}
+
Expr BuiltInCall() : { Expr expr ; Expr expr1 = null ; Expr expr2 = null ;
Node gn ; Token t ; ExprList a ; }
{
@@ -1375,170 +1572,236 @@ Expr BuiltInCall() : { Expr expr ; Expr
{ return new E_Str(expr) ; }
| <LANG> <LPAREN> expr = Expression() <RPAREN>
{ return new E_Lang(expr) ; }
- | <LANGMATCHES>
+
+ | <LANGMATCHES>
<LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_LangMatches(expr1, expr2) ; }
+
| <DTYPE> <LPAREN> expr = Expression() <RPAREN>
{ return new E_Datatype(expr) ; }
+
| <BOUND> <LPAREN> gn = Var() <RPAREN>
{ return new E_Bound(new ExprVar(gn)) ; }
+
| <IRI> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IRI(expr) ; }
+
| <URI> <LPAREN> expr = Expression() <RPAREN>
{ return new E_URI(expr) ; }
- | <BNODE>
+
+ | <BNODE>
( <LPAREN> expr1 = Expression() <RPAREN>
{ return new E_BNode(expr1) ; }
|
<NIL> { return new E_BNode() ; }
)
+
| <RAND> <NIL> { return new E_Random() ; }
- | <ABS> <LPAREN> expr1 = Expression() <RPAREN> { return new E_NumAbs(expr1) ; }
+
+ | <ABS> <LPAREN> expr1 = Expression() <RPAREN> { return new E_NumAbs(expr1) ; }
+
| <CEIL> <LPAREN> expr1 = Expression() <RPAREN> { return new E_NumCeiling(expr1) ; }
+
| <FLOOR> <LPAREN> expr1 = Expression() <RPAREN> { return new E_NumFloor(expr1) ; }
+
| <ROUND> <LPAREN> expr1 = Expression() <RPAREN> { return new E_NumRound(expr1) ; }
+
| <CONCAT> a = ExpressionList() { return new E_StrConcat(a) ; }
+
| expr = SubstringExpression() { return expr ; }
+
| <STRLEN> <LPAREN> expr1 = Expression() <RPAREN> { return new E_StrLength(expr1) ; }
+
| expr = StrReplaceExpression() { return expr ; }
+
| <UCASE> <LPAREN> expr1 = Expression() <RPAREN> { return new E_StrUpperCase(expr1) ; }
+
| <LCASE> <LPAREN> expr1 = Expression() <RPAREN> { return new E_StrLowerCase(expr1) ; }
+
| <ENCODE_FOR_URI> <LPAREN> expr1 = Expression() <RPAREN> { return new E_StrEncodeForURI(expr1) ; }
+
| <CONTAINS> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrContains(expr1, expr2) ; }
+
| <STRSTARTS> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrStartsWith(expr1, expr2) ; }
+
| <STRENDS> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrEndsWith(expr1, expr2) ; }
- | <STRBEFORE> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
+
+ | <STRBEFORE> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrBefore(expr1, expr2) ; }
- | <STRAFTER> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
+
+ | <STRAFTER> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrAfter(expr1, expr2) ; }
+
| <YEAR> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeYear(expr1) ; }
+
| <MONTH> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeMonth(expr1) ; }
+
| <DAY> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeDay(expr1) ; }
+
| <HOURS> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeHours(expr1) ; }
+
| <MINUTES> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeMinutes(expr1) ; }
+
| <SECONDS> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeSeconds(expr1) ; }
+
| <TIMEZONE> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeTimezone(expr1) ; }
| <TZ> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeTZ(expr1) ; }
- | <NOW> <NIL> { return new E_Now() ; }
- | <UUID> <NIL> { return new E_UUID() ; }
- | <STRUUID> <NIL> { return new E_StrUUID() ; }
- | <MD5> <LPAREN> expr1 = Expression() <RPAREN> { return new E_MD5(expr1) ; }
- | <SHA1> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA1(expr1) ; }
- | <SHA256> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA256(expr1) ; }
- | <SHA384> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA384(expr1) ; }
- | <SHA512> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA512(expr1) ; }
- | <VERSION> <NIL> { return new E_Version(); }
+
+ | <NOW> <NIL> { return new E_Now() ; }
+
+ | <UUID> <NIL> { return new E_UUID() ; }
+ | <STRUUID> <NIL> { return new E_StrUUID() ; }
+
+ | <MD5> <LPAREN> expr1 = Expression() <RPAREN> { return new E_MD5(expr1) ; }
+ | <SHA1> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA1(expr1) ; }
+ | <SHA256> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA256(expr1) ; }
+
+ | <SHA384> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA384(expr1) ; }
+
+ | <SHA512> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA512(expr1) ; }
+
+ | <VERSION> <NIL> { return new E_Version(); }
+
| <COALESCE> a = ExpressionList()
{ return new E_Coalesce(a) ; }
- | <IF> <LPAREN> expr = Expression() <COMMA>
- expr1 = Expression() <COMMA>
+
+ | <CALL> a = ExpressionList()
+ { return new E_Call(a) ; }
+
+ | <IF> <LPAREN> expr = Expression() <COMMA>
+ expr1 = Expression() <COMMA>
expr2 = Expression() <RPAREN>
{ return new E_Conditional(expr, expr1, expr2) ; }
+
| <STRLANG> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrLang(expr1, expr2) ; }
+
| <STRDT> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrDatatype(expr1, expr2) ; }
+
+
| <SAME_TERM> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_SameTerm(expr1, expr2) ; }
+
| t = <IS_IRI> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IsIRI(expr) ; }
+
| t = <IS_URI> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IsURI(expr) ; }
+
| <IS_BLANK> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IsBlank(expr) ; }
+
| <IS_LITERAL> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IsLiteral(expr) ; }
+
| <IS_NUMERIC> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IsNumeric(expr) ; }
+
| // Regular expression matcher
expr = RegexExpression() { return expr ; }
- | expr = ExistsFunc() { return expr ; }
- | expr = NotExistsFunc() { return expr ; }
+
+ | expr = ExistsFunc() { return expr ; }
+
+ | expr = NotExistsFunc() { return expr ; }
}
+
Expr RegexExpression() :
{ Expr expr ; Expr patExpr = null ; Expr flagsExpr = null ; }
{
- <REGEX>
- <LPAREN>
- expr = Expression()
+ <REGEX>
+ <LPAREN>
+ expr = Expression()
<COMMA>
patExpr = Expression()
( <COMMA> flagsExpr = Expression() ) ?
<RPAREN>
{ return new E_Regex(expr, patExpr, flagsExpr) ; }
}
+
Expr SubstringExpression() :
{ Expr expr1 ; Expr expr2 = null ; Expr expr3 = null ; }
{
<SUBSTR>
- <LPAREN>
- expr1 = Expression()
+ <LPAREN>
+ expr1 = Expression()
<COMMA>
expr2 = Expression()
( <COMMA> expr3 = Expression() ) ?
<RPAREN>
{ return new E_StrSubstring(expr1, expr2, expr3) ; }
}
+
Expr StrReplaceExpression() :
{ Expr expr1 ; Expr expr2 = null ; Expr expr3 = null ; Expr expr4 = null ;}
{
<REPLACE>
- <LPAREN>
- expr1 = Expression()
+ <LPAREN>
+ expr1 = Expression()
<COMMA> expr2 = Expression()
<COMMA> expr3 = Expression()
( <COMMA> expr4 = Expression() ) ?
- <RPAREN>
+ <RPAREN>
{ return new E_StrReplace(expr1,expr2,expr3,expr4) ; }
}
+
Expr ExistsFunc() : { Element el ; }
{
<EXISTS>
el = GroupGraphPattern()
{ return createExprExists(el) ; }
}
+
Expr NotExistsFunc() : { Element el ; }
{
<NOT> <EXISTS>
el = GroupGraphPattern()
{ return createExprNotExists(el) ; }
}
+
Expr Aggregate() : { Aggregator agg = null ; String sep = null ;
boolean distinct = false ;
- Expr expr = null ; Expr expr2 = null ;
+ Expr expr = null ; Expr expr2 = null ;
ExprList a = new ExprList() ;
ExprList ordered = new ExprList() ;
Token t ; }
{
// Count is special because of COUNT(*)
// GROUP_CONCAT is special because of separator=
- ( t = <COUNT> <LPAREN>
+
+ ( t = <COUNT> <LPAREN>
( <DISTINCT> { distinct = true ; } )?
( <STAR> | expr = Expression() )
<RPAREN>
{ if ( expr == null ) { agg = AggregatorFactory.createCount(distinct) ; }
if ( expr != null ) { agg = AggregatorFactory.createCountExpr(distinct, expr) ; }
}
- | t = <SUM> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
+
+ | t = <SUM> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
{ agg = AggregatorFactory.createSum(distinct, expr) ; }
+
| t = <MIN> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
{ agg = AggregatorFactory.createMin(distinct, expr) ; }
+
| t = <MAX> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
{ agg = AggregatorFactory.createMax(distinct, expr) ; }
+
| t = <AVG> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
{ agg = AggregatorFactory.createAvg(distinct, expr) ; }
+
| t = <SAMPLE> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
{ agg = AggregatorFactory.createSample(distinct, expr) ; }
+
| t = <GROUP_CONCAT>
<LPAREN>
(t = <DISTINCT> { distinct = true ; })?
- expr = Expression() { a.add(expr) ; }
+ expr = Expression() { a.add(expr) ; }
// JavcaCC 5.0 - rewriting as LL(1) didn't work - code generated was wrong
(LOOKAHEAD(2)
- ( <SEMICOLON> <SEPARATOR> <EQ> sep=String()
+ ( <SEMICOLON> <SEPARATOR> <EQ> sep=String()
(<SEMICOLON> <ORDER><BY> expr2 = Expression() { ordered.add(expr2) ; })?
)
|
@@ -1547,6 +1810,7 @@ Expr Aggregate() : { Aggregator agg = nu
<RPAREN>
{ agg = AggregatorFactory.createGroupConcat(distinct, expr, sep, ordered) ; }
)
+
{
if ( ! allowAggregatesInExpressions )
throwParseException("Aggregate expression not legal at this point",
@@ -1555,32 +1819,39 @@ Expr Aggregate() : { Aggregator agg = nu
{ Expr exprAgg = getQuery().allocAggregate(agg) ;
return exprAgg ; }
}
+
// See also FunctionCall.
// The case of "q:name()" or "q:agg()" or just "q:name"
// by expanding out FunctionCall()
-Expr iriOrFunction() : { String iri ; ExprList a = null ;
- ExprList params = null ;
+
+Expr iriOrFunction() : { String iri ; ExprList a = null ;
+ ExprList params = null ;
boolean distinct = false ; }
{
iri = iri()
(a = ArgList())?
- { if ( a == null )
+ { if ( a == null )
return asExpr(createNode(iri)) ;
return new E_Function(iri, a) ;
}
}
+
+
+
Node RDFLiteral() : { Token t ; String lex = null ; }
{
lex = String()
// Optional lang tag and datatype.
{ String lang = null ; String uri = null ; }
(
- ( t = <LANGTAG> { lang = stripChars(t.image, 1) ; } )
+ ( t = <LANGTAG> { lang = stripChars(t.image, 1) ; } )
|
( <DATATYPE> uri = iri() )
)?
{ return createLiteral(lex, lang, uri) ; }
-}
+}
+
+
Node NumericLiteral() : { Node n ; }
{
(
@@ -1589,31 +1860,38 @@ Node NumericLiteral() : { Node n ; }
| n = NumericLiteralNegative()
)
{ return n ; }
+
}
+
Node NumericLiteralUnsigned() : { Token t ; }
{
t = <INTEGER> { return createLiteralInteger(t.image) ; }
| t = <DECIMAL> { return createLiteralDecimal(t.image) ; }
-| t = <DOUBLE> { return createLiteralDouble(t.image) ; }
+| t = <DOUBLE> { return createLiteralDouble(t.image) ; }
}
+
Node NumericLiteralPositive() : { Token t ; }
{
t = <INTEGER_POSITIVE> { return createLiteralInteger(t.image) ; }
| t = <DECIMAL_POSITIVE> { return createLiteralDecimal(t.image) ; }
-| t = <DOUBLE_POSITIVE> { return createLiteralDouble(t.image) ; }
+| t = <DOUBLE_POSITIVE> { return createLiteralDouble(t.image) ; }
}
+
Node NumericLiteralNegative() : { Token t ; }
{
t = <INTEGER_NEGATIVE> { return createLiteralInteger(t.image) ; }
| t = <DECIMAL_NEGATIVE> { return createLiteralDecimal(t.image) ; }
-| t = <DOUBLE_NEGATIVE> { return createLiteralDouble(t.image) ; }
+| t = <DOUBLE_NEGATIVE> { return createLiteralDouble(t.image) ; }
}
+
+
Node BooleanLiteral() : {}
{
<TRUE> { return XSD_TRUE ; }
|
<FALSE> { return XSD_FALSE ; }
}
+
String String() : { Token t ; String lex ; }
{
( t = <STRING_LITERAL1> { lex = stripQuotes(t.image) ; }
@@ -1622,16 +1900,18 @@ String String() : { Token t ; String lex
| t = <STRING_LITERAL_LONG2> { lex = stripQuotes3(t.image) ; }
)
{
- lex = unescapeStr(lex, t.beginLine, t.beginColumn) ;
+ lex = unescapeStr(lex, t.beginLine, t.beginColumn) ;
return lex ;
}
}
+
String iri() : { String iri ; }
{
iri = IRIREF() { return iri ; }
|
iri = PrefixedName() { return iri ; }
}
+
String PrefixedName() : { Token t ; }
{
( t = <PNAME_LN>
@@ -1641,292 +1921,345 @@ String PrefixedName() : { Token t ; }
{ return resolvePName(t.image, t.beginLine, t.beginColumn) ; }
)
}
-Node BlankNode() : { Token t = null ; }
+
+Node BlankNode() : { Token t = null ; }
{
t = <BLANK_NODE_LABEL>
- { return createBNode(t.image, t.beginLine, t.beginColumn) ; }
+ { return createBNode(t.image, t.beginLine, t.beginColumn) ; }
|
// <LBRACKET> <RBRACKET> { return createBNode(t.beginLine, t.beginColumn) ; }
t = <ANON> { return createBNode(t.beginLine, t.beginColumn) ; }
+
}
+
String IRIREF() : { Token t ; }
{
t = <IRIref>
{ return resolveQuotedIRI(t.image, t.beginLine, t.beginColumn) ; }
}
+
// ------------------------------------------
// Tokens
+
// Comments and whitespace
+
SKIP : { " " | "\t" | "\n" | "\r" | "\f" }
+
SPECIAL_TOKEN :
{ <SINGLE_LINE_COMMENT: "#" (~["\n","\r"])* ("\n"|"\r"|"\r\n")? > }
-TOKEN: {
+
+
+
+TOKEN: {
<#WS: " " | "\t" | "\n" | "\r" | "\f">
|
// Whitespace or comment.
<#WSC: <WS> | <SINGLE_LINE_COMMENT> >
}
+
// Main tokens */
+
TOKEN:
{
// Includes # for relative URIs
- <IRIref: "<" (~[ ">","<", "\"", "{", "}", "^", "\\", "|", "`",
+ <IRIref: "<" (~[ ">","<", "\"", "{", "}", "^", "\\", "|", "`",
"\u0000"-"\u0020"])* ">" >
-| <PNAME_NS: (<PN_PREFIX>)? ":" >
-| <PNAME_LN: <PNAME_NS> <PN_LOCAL> >
-| <BLANK_NODE_LABEL: "_:" (<PN_CHARS_U> | ["0"-"9"]) ((<PN_CHARS>|".")* <PN_CHARS>)? >
-| <VAR1: "?" <VARNAME> >
-| <VAR2: "$" <VARNAME> >
-| <LANGTAG: <AT> (<A2Z>)+("-" (<A2ZN>)+)* >
-| <#A2Z: ["a"-"z","A"-"Z"]>
-| <#A2ZN: ["a"-"z","A"-"Z","0"-"9"]>
+| <PNAME_NS: (<PN_PREFIX>)? ":" >
+| <PNAME_LN: <PNAME_NS> <PN_LOCAL> >
+| <BLANK_NODE_LABEL: "_:" (<PN_CHARS_U> | ["0"-"9"]) ((<PN_CHARS>|".")* <PN_CHARS>)? >
+| <VAR1: "?" <VARNAME> >
+| <VAR2: "$" <VARNAME> >
+| <LANGTAG: <AT> (<A2Z>)+("-" (<A2ZN>)+)* >
+| <#A2Z: ["a"-"z","A"-"Z"]>
+| <#A2ZN: ["a"-"z","A"-"Z","0"-"9"]>
}
+
// -------------------------------------------------
// Keyworks : includes operators that are words and should be
// before general things like IDENTIFIER which swallow almost
// anything
-TOKEN : { <KW_A: "a" > }
+
+TOKEN : { <KW_A: "a" > }
+
TOKEN [IGNORE_CASE] :
{
// Prologue
- < BASE: "base" >
-| < PREFIX: "prefix" >
+ < BASE: "base" >
+| < PREFIX: "prefix" >
+
// Result forms
-| < SELECT: "select" >
-| < DISTINCT: "distinct" >
-| < REDUCED: "reduced" >
-| < DESCRIBE: "describe" >
-| < CONSTRUCT: "construct" >
-| < ASK: "ask" >
-| < LIMIT: "limit" >
-| < OFFSET: "offset" >
-| < ORDER: "order" >
-| < BY: "by" >
-| < VALUES: "values" >
-| < UNDEF: "undef" >
-| < ASC: "asc" >
-| < DESC: "desc" >
+| < SELECT: "select" >
+| < DISTINCT: "distinct" >
+| < REDUCED: "reduced" >
+| < DESCRIBE: "describe" >
+| < CONSTRUCT: "construct" >
+| < ASK: "ask" >
+
+| < LIMIT: "limit" >
+| < OFFSET: "offset" >
+| < ORDER: "order" >
+| < BY: "by" >
+| < VALUES: "values" >
+| < UNDEF: "undef" >
+
+| < ASC: "asc" >
+| < DESC: "desc" >
+
// Dataset
-| < NAMED: "named" >
-| < FROM: "from" >
+| < NAMED: "named" >
+| < FROM: "from" >
+
// Graph pattern operators
-| < WHERE: "where" >
-| < AND: "and" >
-| < GRAPH: "graph" >
-| < OPTIONAL: "optional" >
-| < UNION: "union" >
-| < MINUS_P: "minus" >
-| < BIND: "bind" >
-| < SERVICE: "service" >
-| < LET: "let" >
-| < FETCH: "fetch" >
-| < EXISTS: "exists" >
-| < NOT: "not" >
+| < WHERE: "where" >
+| < AND: "and" >
+| < GRAPH: "graph" >
+| < OPTIONAL: "optional" >
+| < UNION: "union" >
+| < MINUS_P: "minus" >
+| < BIND: "bind" >
+| < SERVICE: "service" >
+
+| < LET: "let" >
+| < FETCH: "fetch" >
+| < EXISTS: "exists" >
+| < NOT: "not" >
//| < UNSAID: "unsaid" >
-| < AS: "as" >
-| < GROUP: "group" >
-| < HAVING: "having" >
-| < SEPARATOR: "separator" >
-| < AGG: "agg" >
-| < COUNT: "count" >
-| < MIN: "min" >
-| < MAX: "max" >
-| < SUM: "sum" >
-| < AVG: "avg" >
-| < STDDEV: "stdev" >
-| < SAMPLE: "sample" >
-| < GROUP_CONCAT: "group_concat" >
-| < FILTER: "filter" >
+| < AS: "as" >
+| < GROUP: "group" >
+| < HAVING: "having" >
+| < SEPARATOR: "separator" >
+| < AGG: "agg" >
+| < COUNT: "count" >
+| < MIN: "min" >
+| < MAX: "max" >
+| < SUM: "sum" >
+| < AVG: "avg" >
+| < STDDEV: "stdev" >
+| < SAMPLE: "sample" >
+| < GROUP_CONCAT: "group_concat" >
+
+| < FILTER: "filter" >
+
// Expression operators
-| < BOUND: "bound" >
-| < COALESCE: "coalesce" >
-| < IN: "in" >
-| < IF: "if" >
-| < BNODE: "bnode" >
-| < IRI: "iri" >
-| < URI: "uri" >
-| < CAST: "cast" >
-| < CALL: "call" >
-| < MULTI: "multi" >
-| < SHORTEST: "shortest" >
-| < STR: "str" >
-| < STRLANG: "strlang" >
-| < STRDT: "strdt" >
-| < DTYPE: "datatype" >
-| < LANG: "lang" >
-| < LANGMATCHES: "langmatches" >
-| < IS_URI: "isURI" >
-| < IS_IRI: "isIRI" >
-| < IS_BLANK: "isBlank" >
-| < IS_LITERAL: "isLiteral" >
-| < IS_NUMERIC: "isNumeric" >
-| < REGEX: "regex" >
-| < SAME_TERM: "sameTerm" >
-| < RAND: "RAND" >
-| < ABS: "ABS" >
-| < CEIL: "CEIL" >
-| < FLOOR: "FLOOR" >
-| < ROUND: "ROUND" >
-| < CONCAT: "CONCAT" >
-| < SUBSTR: "SUBSTR" >
-| < STRLEN: "STRLEN" >
-| < REPLACE: "REPLACE" >
-| < UCASE: "UCASE" >
-| < LCASE: "LCASE" >
-| < ENCODE_FOR_URI: "ENCODE_FOR_URI" >
-| < CONTAINS: "CONTAINS" >
-| < STRSTARTS: "STRSTARTS" >
-| < STRENDS: "STRENDS" >
-| < STRBEFORE: "STRBEFORE" >
-| < STRAFTER : "STRAFTER" >
-| < YEAR: "YEAR" >
-| < MONTH: "MONTH" >
-| < DAY: "DAY" >
-| < HOURS: "HOURS" >
-| < MINUTES: "MINUTES" >
-| < SECONDS: "SECONDS" >
-| < TIMEZONE: "TIMEZONE" >
-| < TZ: "TZ" >
-| < NOW: "NOW" >
-| < UUID: "UUID" >
-| < STRUUID: "STRUUID" >
-| < VERSION: "VERSION" >
-| < MD5: "MD5" >
-| < SHA1: "SHA1" >
-| < SHA224: "SHA224" >
-| < SHA256: "SHA256" >
-| < SHA384: "SHA384" >
-| < SHA512: "SHA512" >
-| < TRUE: "true" >
-| < FALSE: "false" >
+| < BOUND: "bound" >
+| < COALESCE: "coalesce" >
+| < IN: "in" >
+| < IF: "if" >
+| < BNODE: "bnode" >
+| < IRI: "iri" >
+| < URI: "uri" >
+
+| < CAST: "cast" >
+| < CALL: "call" >
+| < MULTI: "multi" >
+| < SHORTEST: "shortest" >
+
+| < STR: "str" >
+| < STRLANG: "strlang" >
+| < STRDT: "strdt" >
+| < DTYPE: "datatype" >
+| < LANG: "lang" >
+| < LANGMATCHES: "langmatches" >
+| < IS_URI: "isURI" >
+| < IS_IRI: "isIRI" >
+| < IS_BLANK: "isBlank" >
+| < IS_LITERAL: "isLiteral" >
+| < IS_NUMERIC: "isNumeric" >
+| < REGEX: "regex" >
+| < SAME_TERM: "sameTerm" >
+
+| < RAND: "RAND" >
+| < ABS: "ABS" >
+| < CEIL: "CEIL" >
+| < FLOOR: "FLOOR" >
+| < ROUND: "ROUND" >
+| < CONCAT: "CONCAT" >
+| < SUBSTR: "SUBSTR" >
+| < STRLEN: "STRLEN" >
+| < REPLACE: "REPLACE" >
+| < UCASE: "UCASE" >
+| < LCASE: "LCASE" >
+| < ENCODE_FOR_URI: "ENCODE_FOR_URI" >
+| < CONTAINS: "CONTAINS" >
+| < STRSTARTS: "STRSTARTS" >
+| < STRENDS: "STRENDS" >
+| < STRBEFORE: "STRBEFORE" >
+| < STRAFTER : "STRAFTER" >
+| < YEAR: "YEAR" >
+| < MONTH: "MONTH" >
+| < DAY: "DAY" >
+| < HOURS: "HOURS" >
+| < MINUTES: "MINUTES" >
+| < SECONDS: "SECONDS" >
+| < TIMEZONE: "TIMEZONE" >
+| < TZ: "TZ" >
+| < NOW: "NOW" >
+| < UUID: "UUID" >
+| < STRUUID: "STRUUID" >
+| < VERSION: "VERSION" >
+
+| < MD5: "MD5" >
+| < SHA1: "SHA1" >
+| < SHA224: "SHA224" >
+| < SHA256: "SHA256" >
+| < SHA384: "SHA384" >
+| < SHA512: "SHA512" >
+
+| < TRUE: "true" >
+| < FALSE: "false" >
}
+
// SPARQL/Update parts.
+
TOKEN [IGNORE_CASE] :
{
- < DATA: "data" >
-| < INSERT: "insert">
-| < DELETE: "delete" >
-| < INSERT_DATA: <INSERT> (<WSC>)* <DATA> >
-| < DELETE_DATA: <DELETE> (<WSC>)* <DATA> >
+ < DATA: "data" >
+| < INSERT: "insert">
+| < DELETE: "delete" >
+
+| < INSERT_DATA: <INSERT> (<WSC>)* <DATA> >
+| < DELETE_DATA: <DELETE> (<WSC>)* <DATA> >
| < DELETE_WHERE: <DELETE> (<WSC>)* <WHERE> >
-| < MODIFY: "modify">
-| < LOAD: "load" >
-| < CLEAR: "clear" >
-| < CREATE: "create" >
-| < ADD: "add" >
-| < MOVE: "move" >
-| < COPY: "copy" >
-| < META: "meta" >
-| < SILENT: "silent" >
-| < DROP: "drop" >
-| < INTO: "into" >
-| < TO: "to" >
-| < DFT: "default" >
+
+| < MODIFY: "modify">
+| < LOAD: "load" >
+| < CLEAR: "clear" >
+| < CREATE: "create" >
+| < ADD: "add" >
+| < MOVE: "move" >
+| < COPY: "copy" >
+| < META: "meta" >
+| < SILENT: "silent" >
+| < DROP: "drop" >
+| < INTO: "into" >
+| < TO: "to" >
+| < DFT: "default" >
//| < NAMED: "named" >
-| < ALL: "all" >
-| < WITH: "with" >
-| < USING: "using" >
+| < ALL: "all" >
+| < WITH: "with" >
+| < USING: "using" >
+
//| < BEGIN: "begin" >
//| < COMMIT: "commit" >
//| < ABORT: "abort" >
}
+
// -------------------------------------------------
+
TOKEN :
{
< #DIGITS: (["0"-"9"])+>
| < INTEGER: <DIGITS> >
//| < DECIMAL: ( <DIGITS> "." (<DIGITS>)* | "." <DIGITS> ) >
| < DECIMAL: (<DIGITS>)? "." <DIGITS> >
-| < DOUBLE: // Required exponent.
+| < DOUBLE: // Required exponent.
(
(["0"-"9"])+ "." (["0"-"9"])* <EXPONENT>
| "." (["0"-"9"])+ (<EXPONENT>)
| (["0"-"9"])+ <EXPONENT>
)
>
+
| < INTEGER_POSITIVE: <PLUS> <INTEGER> >
| < DECIMAL_POSITIVE: <PLUS> <DECIMAL> >
-| < DOUBLE_POSITIVE: <PLUS> <DOUBLE> >
+| < DOUBLE_POSITIVE: <PLUS> <DOUBLE> >
+
| < INTEGER_NEGATIVE: <MINUS> <INTEGER> >
| < DECIMAL_NEGATIVE: <MINUS> <DECIMAL> >
-| < DOUBLE_NEGATIVE: <MINUS> <DOUBLE> >
+| < DOUBLE_NEGATIVE: <MINUS> <DOUBLE> >
+
| < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
| < #QUOTE_3D: "\"\"\"">
| < #QUOTE_3S: "'''">
| <ECHAR: "\\" ( "t"|"b"|"n"|"r"|"f"|"\\"|"\""|"'") >
-| < STRING_LITERAL1:
+| < STRING_LITERAL1:
// Single quoted string
- "'" ( (~["'","\\","\n","\r"]) | <ECHAR> )* "'" >
+ "'" ( (~["'","\\","\n","\r"]) | <ECHAR> )* "'" >
| < STRING_LITERAL2:
// Double quoted string
"\"" ( (~["\"","\\","\n","\r"]) | <ECHAR> )* "\"" >
| < STRING_LITERAL_LONG1:
- <QUOTE_3S>
+ <QUOTE_3S>
( ("'" | "''")? (~["'","\\"] | <ECHAR> ))*
<QUOTE_3S> >
-| < STRING_LITERAL_LONG2:
- <QUOTE_3D>
+
+| < STRING_LITERAL_LONG2:
+ <QUOTE_3D>
( ("\"" | "\"\"")? (~["\"","\\"] | <ECHAR> ))*
<QUOTE_3D> >
}
+
TOKEN :
{
- < LPAREN: "(" >
-| < RPAREN: ")" >
+ < LPAREN: "(" >
+| < RPAREN: ")" >
+
// All the stuff for NUL is needed just to make a
// single list "() ." as a triple pattern illegal.
// It leads to a lot of extra work.
// Similarly [].
+
| <NIL: <LPAREN> (<WSC>)* <RPAREN> >
-| < LBRACE: "{" >
-| < RBRACE: "}" >
-| < LBRACKET: "[" >
-| < RBRACKET: "]" >
-| < ANON: <LBRACKET> (<WSC>)* <RBRACKET> >
+
+| < LBRACE: "{" >
+| < RBRACE: "}" >
+
+| < LBRACKET: "[" >
+| < RBRACKET: "]" >
+| < ANON: <LBRACKET> (<WSC>)* <RBRACKET> >
+
| < SEMICOLON: ";" >
-| < COMMA: "," >
-| < DOT: "." >
-| < EQ: "=" >
-| < NE: "!=" >
-| < GT: ">" >
-| < LT: "<" >
-| < LE: "<=" > // Maybe: | "=>" >
-| < GE: ">=" > // Maybe: | "=<" >
-| < BANG: "!" >
-| < TILDE: "~" >
-| < COLON: ":" >
-| < SC_OR: "||" >
-| < SC_AND: "&&" >
-| < PLUS: "+" >
-| < MINUS: "-" >
-| < STAR: "*" >
-| < SLASH: "/" >
+| < COMMA: "," >
+| < DOT: "." >
+| < EQ: "=" >
+| < NE: "!=" >
+| < GT: ">" >
+| < LT: "<" >
+| < LE: "<=" > // Maybe: | "=>" >
+| < GE: ">=" > // Maybe: | "=<" >
+
+| < BANG: "!" >
+| < TILDE: "~" >
+| < COLON: ":" >
+
+| < SC_OR: "||" >
+| < SC_AND: "&&" >
+
+| < PLUS: "+" >
+| < MINUS: "-" >
+| < STAR: "*" >
+| < SLASH: "/" >
+
//| < AMP: "&" >
//| < REM: "%" >
+
| < DATATYPE: "^^">
| < AT: "@">
-| < ASSIGN: ":=">
+| < ASSIGN: ":=">
+
// Path related
-| < VBAR: "|" >
-| < CARAT: "^" >
-| < FPATH: "->" >
-| < RPATH: "<-" >
-| < QMARK: "?" >
+| < VBAR: "|" >
+| < CARAT: "^" >
+| < FPATH: "->" >
+| < RPATH: "<-" >
+| < QMARK: "?" >
}
+
// See XML chars.txt for notes
+
TOKEN:
{
- // ARQ extensions to the PN_LOCAL token.
+ // 1 extensions to the PN_LOCAL token.
< #HEX: ["0"-"9"] | ["A"-"F"] | ["a"-"f"] >
|
< #PERCENT: "%" <HEX> <HEX> >
|
// Prefixed Name, Local Part, charcater escape sequences
// Align with QueryParseBase unescapePName.
- < #PN_LOCAL_ESC: "\\"
- ( "_" |
- "~" | "." | "-" | "!" | "$" | "&" | "'" |
- "(" | ")" | "*" | "+" | "," | ";" | "=" |
+ < #PN_LOCAL_ESC: "\\"
+ ( "_" |
+ "~" | "." | "-" | "!" | "$" | "&" | "'" |
+ "(" | ")" | "*" | "+" | "," | ";" | "=" |
"/" | "?" | "#" | "@" | "%" ) >
|
// XML 1.1 NCNameStartChar without "_"
@@ -1935,7 +2268,7 @@ TOKEN:
["\u00C0"-"\u00D6"] | ["\u00D8"-"\u00F6"] | ["\u00F8"-"\u02FF"] |
["\u0370"-"\u037D"] | ["\u037F"-"\u1FFF"] |
["\u200C"-"\u200D"] | ["\u2070"-"\u218F"] | ["\u2C00"-"\u2FEF"] |
- ["\u3001"-"\uD7FF"] | ["\uF900"-"\uFFFD"]
+ ["\u3001"-"\uD7FF"] | ["\uF900"-"\uFFFD"]
>
// [#x10000-#xEFFFF]
|
@@ -1946,20 +2279,21 @@ TOKEN:
["\u0300"-"\u036F"] | ["\u203F"-"\u2040"] ) >
|
// No leading "_", no trailing ".", can have dot inside prefix name.
- <#PN_PREFIX: <PN_CHARS_BASE> ((<PN_CHARS>|".")* <PN_CHARS>)? >
+ <#PN_PREFIX: <PN_CHARS_BASE> ((<PN_CHARS>|".")* <PN_CHARS>)? >
|
- <#PLX: <PERCENT> | <PN_LOCAL_ESC> >
+ <#PLX: <PERCENT> | <PN_LOCAL_ESC> >
|
// If goes ahead, consolidate
- <#PN_LOCAL: (<PN_CHARS_U> | ["0"-"9"] | <PLX> )
- ( (<PN_CHARS>|"."| <PLX> )*
- (<PN_CHARS>|<PLX>) ) ? >
+ <#PN_LOCAL: (<PN_CHARS_U> | ["0"-"9"] | <PLX> )
+ ( (<PN_CHARS>|"."| <PLX> )*
+ (<PN_CHARS>|<PLX>) )? >
|
// NCNAME without "-" and ".", allowing leading digits.
<#VARNAME: ( <PN_CHARS_U> | ["0"-"9"] )
( <PN_CHARS_U> | ["0"-"9"] | "\u00B7" |
["\u0300"-"\u036F"] | ["\u203F"-"\u2040"] )* >
}
+
// Catch-all tokens. Must be last.
// Any non-whitespace. Causes a parser exception, rather than a
// token manager error (with hidden line numbers).
@@ -1968,6 +2302,7 @@ TOKEN:
{
<#UNKNOWN: (~[" ","\t","\n","\r","\f" ])+ >
}
+
/*
# Local Variables:
# tab-width: 4
Modified: jena/trunk/jena-arq/Grammar/master.jj
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/Grammar/master.jj?rev=1353021&r1=1353020&r2=1353021&view=diff
==============================================================================
--- jena/trunk/jena-arq/Grammar/master.jj (original)
+++ jena/trunk/jena-arq/Grammar/master.jj Fri Jun 22 20:33:52 2012
@@ -1812,6 +1812,11 @@ Expr BuiltInCall() : { Expr expr ; Expr
| <COALESCE> a = ExpressionList()
{ return new E_Coalesce(a) ; }
+
+#if ARQ
+ | <CALL> a = ExpressionList()
+ { return new E_Call(a) ; }
+#endif
| <IF> <LPAREN> expr = Expression() <COMMA>
expr1 = Expression() <COMMA>
Modified: jena/trunk/jena-arq/ReleaseNotes.txt
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/ReleaseNotes.txt?rev=1353021&r1=1353020&r2=1353021&view=diff
==============================================================================
--- jena/trunk/jena-arq/ReleaseNotes.txt (original)
+++ jena/trunk/jena-arq/ReleaseNotes.txt Fri Jun 22 20:33:52 2012
@@ -5,6 +5,9 @@ ChangeLog for ARQ
==== ARQ 2.9.2
+ Significant speed-up of MINUS queries (JENA-266) - contribution from Paul Gearon (@quoll).
++ Log warning messages generated by failures in SERVICE clauses now include the URI of the
+ service that failed (JENA-269) - suggestion by Claude Warren
++ Support for dynamic function invocation built-in CALL() when using ARQ language
==== ARQ 2.9.1
Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Call.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Call.java?rev=1353021&r1=1353020&r2=1353021&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Call.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/E_Call.java Fri Jun 22 20:33:52 2012
@@ -18,15 +18,25 @@
package com.hp.hpl.jena.sparql.expr;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List ;
+import java.util.Map;
-import com.hp.hpl.jena.sparql.ARQNotImplemented ;
+import com.hp.hpl.jena.sparql.ARQInternalErrorException;
import com.hp.hpl.jena.sparql.engine.binding.Binding ;
import com.hp.hpl.jena.sparql.function.FunctionEnv ;
+import com.hp.hpl.jena.sparql.util.Context;
+/**
+ * ARQ extension to SPARQL which provides for dynamic function invocation
+ */
public class E_Call extends ExprFunctionN
{
private static final String symbol = "call" ;
+ private Map<String,Expr> functionCache = new HashMap<String, Expr>();
+ private Expr identExpr;
+ private List<Expr> argExprs;
public E_Call(ExprList args)
{
@@ -36,22 +46,71 @@ public class E_Call extends ExprFunction
protected E_Call(String sym, ExprList args)
{
super(sym, args) ;
+ if (args.size() == 0) {
+ identExpr = null;
+ } else {
+ identExpr = args.get(0);
+ argExprs = new ArrayList<Expr>();
+ for (int i = 1; i < args.size(); i++) {
+ argExprs.add(args.get(i));
+ }
+ }
}
@Override
public NodeValue evalSpecial(Binding binding, FunctionEnv env)
{
- throw new ARQNotImplemented() ;
- }
-
- @Override
- protected NodeValue eval(List<NodeValue> args)
- {
- throw new ARQNotImplemented() ;
+ //No argument returns unbound
+ if (identExpr == null) return null;
+
+ //One/More arguments means invoke a function dynamically
+ NodeValue func = identExpr.eval(binding, env);
+ if (func == null) throw new ExprEvalException("CALL: Function identifier unbound");
+ if (func.isIRI()) {
+ Expr e = buildFunction(func.getNode().getURI(), argExprs, env.getContext());
+ if (e == null) throw new ExprEvalException("CALL: Function identifier <" + func.getNode().getURI() + "> does not identify a known function");
+ //Calling this may throw an error which we will just let bubble up
+ return e.eval(binding, env);
+ } else {
+ throw new ExprEvalException("CALL: Function identifier not an IRI");
+ }
}
@Override
protected Expr copy(ExprList newArgs) { return new E_Call(newArgs) ; }
+ @Override
+ protected NodeValue eval(List<NodeValue> args) {
+ if (args.size() == 0) return null; //Can evaluate in this form only if empty arg list, otherwise error
+ throw new ARQInternalErrorException();
+ }
+
+ /**
+ * Returns the expr representing the dynamic function to be invoked
+ * <p>
+ * Uses caching wherever possible to avoid
+ * </p>
+ */
+ private Expr buildFunction(String functionIRI, List<Expr> args, Context cxt)
+ {
+ //Use our cached version of the expression wherever possible
+ if (functionCache.containsKey(functionIRI)) {
+ return functionCache.get(functionIRI);
+ }
+
+ //Otherwise generate a new function and cache it
+ try
+ {
+ E_Function e = new E_Function(functionIRI, new ExprList(args));
+ e.buildFunction(cxt);
+ functionCache.put(functionIRI, e);
+ return e;
+ } catch (Throwable e) {
+ //Anything goes wrong in creating the function cache a null so we don't retry every time we see this IRI
+ functionCache.put(functionIRI, null);
+ return null;
+ }
+
+ }
}