You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2014/12/28 21:35:24 UTC

jena git commit: JENA-803 : Inline SPARQL 11 syntax for custom aggragates.

Repository: jena
Updated Branches:
  refs/heads/master 66efb4f65 -> 85a337370


JENA-803 : Inline SPARQL 11 syntax for custom aggragates.

Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/85a33737
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/85a33737
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/85a33737

Branch: refs/heads/master
Commit: 85a3373703ce6ce1398a878037dbf2f813aa1906
Parents: 66efb4f
Author: Andy Seaborne <an...@apache.org>
Authored: Sun Dec 28 20:35:10 2014 +0000
Committer: Andy Seaborne <an...@apache.org>
Committed: Sun Dec 28 20:35:10 2014 +0000

----------------------------------------------------------------------
 jena-arq/Grammar/arq.jj                         |  18 +-
 jena-arq/Grammar/master.jj                      |  21 +-
 jena-arq/Grammar/sparql_11.jj                   |  18 +-
 .../jena/sparql/expr/aggregate/AggCustom.java   |  22 +-
 .../expr/aggregate/AggregatorFactory.java       |   2 +-
 .../hp/hpl/jena/sparql/lang/arq/ARQParser.java  | 596 ++++++++++---------
 .../sparql/lang/sparql_11/SPARQLParser11.java   |  16 +-
 .../java/com/hp/hpl/jena/sparql/sse/Tags.java   |   3 +-
 .../jena/sparql/sse/builders/BuilderExpr.java   |  25 +-
 9 files changed, 411 insertions(+), 310 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/85a33737/jena-arq/Grammar/arq.jj
----------------------------------------------------------------------
diff --git a/jena-arq/Grammar/arq.jj b/jena-arq/Grammar/arq.jj
index 66e030c..3bfc30b 100644
--- a/jena-arq/Grammar/arq.jj
+++ b/jena-arq/Grammar/arq.jj
@@ -735,7 +735,16 @@ Expr FunctionCall() : { String fname ; ExprList a ; }
 {
   fname = iri()
   a = ArgList()
-  { return new E_Function(fname, a) ; }
+  {
+     if ( AggregateRegistry.isRegistered(fname) ) {
+         if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point : "+fname, -1, -1) ;
+         Aggregator agg = AggregatorFactory.create(fname, a) ;
+         Expr exprAgg = getQuery().allocAggregate(agg) ;
+         return exprAgg ;
+     }
+     return new E_Function(fname, a) ;
+  }
 }
 ExprList ArgList() : { Expr expr ; boolean distinct = false ;
                       ExprList args = new ExprList() ; Token t ; }
@@ -1449,6 +1458,13 @@ Expr iriOrFunction() : { String iri ; ExprList a = null ;
   (a = ArgList())?
   { if ( a == null )
        return asExpr(createNode(iri)) ;
+    if ( AggregateRegistry.isRegistered(iri) ) {
+         if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point : "+iri, -1, -1) ;
+         Aggregator agg = AggregatorFactory.create(iri, a) ;
+         Expr exprAgg = getQuery().allocAggregate(agg) ;
+         return exprAgg ;
+      }
     return new E_Function(iri, a) ;
   }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/85a33737/jena-arq/Grammar/master.jj
----------------------------------------------------------------------
diff --git a/jena-arq/Grammar/master.jj b/jena-arq/Grammar/master.jj
index 7da14b4..9b99be9 100644
--- a/jena-arq/Grammar/master.jj
+++ b/jena-arq/Grammar/master.jj
@@ -1000,7 +1000,18 @@ Expr FunctionCall() : { String fname ; ExprList a ; }
 {
   fname = iri()
   a = ArgList()
-  { return new E_Function(fname, a) ; }
+
+  {
+     if ( AggregateRegistry.isRegistered(fname) ) {
+         // aggregates
+         if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point : "+fname, -1, -1) ;
+         Aggregator agg = AggregatorFactory.create(fname, a) ;
+         Expr exprAgg = getQuery().allocAggregate(agg) ;
+         return exprAgg ;
+     }
+     return new E_Function(fname, a) ; 
+  }
 }
 
 ExprList ArgList() : { Expr expr ; boolean distinct = false ;
@@ -1974,6 +1985,14 @@ Expr iriOrFunction() : { String iri ; ExprList a = null ;
   (a = ArgList())?
   { if ( a == null ) 
        return asExpr(createNode(iri)) ;
+    if ( AggregateRegistry.isRegistered(iri) ) {
+         // aggregates
+         if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point : "+iri, -1, -1) ;
+         Aggregator agg = AggregatorFactory.create(iri, a) ;
+         Expr exprAgg = getQuery().allocAggregate(agg) ;
+         return exprAgg ;
+      }
     return new E_Function(iri, a) ;
   }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/85a33737/jena-arq/Grammar/sparql_11.jj
----------------------------------------------------------------------
diff --git a/jena-arq/Grammar/sparql_11.jj b/jena-arq/Grammar/sparql_11.jj
index 512ac55..f269018 100644
--- a/jena-arq/Grammar/sparql_11.jj
+++ b/jena-arq/Grammar/sparql_11.jj
@@ -684,7 +684,16 @@ Expr FunctionCall() : { String fname ; ExprList a ; }
 {
   fname = iri()
   a = ArgList()
-  { return new E_Function(fname, a) ; }
+  {
+     if ( AggregateRegistry.isRegistered(fname) ) {
+         if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point : "+fname, -1, -1) ;
+         Aggregator agg = AggregatorFactory.create(fname, a) ;
+         Expr exprAgg = getQuery().allocAggregate(agg) ;
+         return exprAgg ;
+     }
+     return new E_Function(fname, a) ;
+  }
 }
 ExprList ArgList() : { Expr expr ; boolean distinct = false ;
                       ExprList args = new ExprList() ; Token t ; }
@@ -1332,6 +1341,13 @@ Expr iriOrFunction() : { String iri ; ExprList a = null ;
   (a = ArgList())?
   { if ( a == null )
        return asExpr(createNode(iri)) ;
+    if ( AggregateRegistry.isRegistered(iri) ) {
+         if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point : "+iri, -1, -1) ;
+         Aggregator agg = AggregatorFactory.create(iri, a) ;
+         Expr exprAgg = getQuery().allocAggregate(agg) ;
+         return exprAgg ;
+      }
     return new E_Function(iri, a) ;
   }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/85a33737/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/aggregate/AggCustom.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/aggregate/AggCustom.java b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/aggregate/AggCustom.java
index cb7add4..9dcf04a 100644
--- a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/aggregate/AggCustom.java
+++ b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/aggregate/AggCustom.java
@@ -52,14 +52,18 @@ public class AggCustom extends AggregatorBase
     @Override
     public String asSparqlExpr(SerializationContext sCxt) {
         IndentedLineBuffer x = new IndentedLineBuffer() ;
-        x.append("(") ;
-        x.incIndent(); 
-        x.append(getName().toLowerCase(Locale.ROOT)) ;
-        x.append(" <") ;
+        if ( false ) {
+            // AGG <iri>(...) syntax.
+            x.append(getName()) ;
+            x.append(" ") ;
+        }
+        x.append("<") ;
         x.append(iri);
         x.append(">") ;
         if ( isDistinct )
-            x.append("DISTINCT ") ;
+            x.append(" DISTINCT ") ;
+        x.incIndent(); 
+        x.append("(") ;
         ExprUtils.fmtSPARQL(x, getExprList(), sCxt) ;
         x.append(")") ;
         return x.asString() ;
@@ -69,13 +73,12 @@ public class AggCustom extends AggregatorBase
     public String toPrefixString() { 
         IndentedLineBuffer x = new IndentedLineBuffer() ;
         x.append("(") ;
-        x.append(getName()) ;
+        x.append(getName().toLowerCase(Locale.ROOT)) ;
         x.append(" <") ;
         x.append(iri);
-        x.append(">") ;
+        x.append("> ") ;
         x.incIndent(); 
-
-        x.append(getName().toLowerCase(Locale.ROOT)) ;
+        
         if ( isDistinct )
             x.append("distinct ") ;
         boolean first = true ;
@@ -85,7 +88,6 @@ public class AggCustom extends AggregatorBase
             first = false ;
             WriterExpr.output(x, e, null) ;
             first = false ;
-
         }
         x.decIndent();
         x.append(")") ;

http://git-wip-us.apache.org/repos/asf/jena/blob/85a33737/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/aggregate/AggregatorFactory.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/aggregate/AggregatorFactory.java b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/aggregate/AggregatorFactory.java
index a0a565e..9214539 100644
--- a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/aggregate/AggregatorFactory.java
+++ b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/aggregate/AggregatorFactory.java
@@ -64,7 +64,7 @@ public class AggregatorFactory {
         return new AggNull() ;
     }
 
-    public static Aggregator create(String iri, ExprList a) {
+    public static Aggregator createCustom(String iri, ExprList a) {
         if ( ! AggregateRegistry.isRegistered(iri) )
             Log.fatal(AggregatorFactory.class, "Not registered: custom aggregate <"+iri+">") ;
         return new AggCustom(iri, a) ;

http://git-wip-us.apache.org/repos/asf/jena/blob/85a33737/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java
index 3d46f1d..9250334 100644
--- a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java
+++ b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/arq/ARQParser.java
@@ -2603,7 +2603,14 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
                         String fname ; ExprList a ;
     fname = iri();
     a = ArgList();
-    {if (true) return new E_Function(fname, a) ;}
+     if ( AggregateRegistry.isRegistered(fname) ) {
+         if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point : "+fname, -1, -1) ;
+         Aggregator agg = AggregatorFactory.createCustom(fname, a) ;
+         Expr exprAgg = getQuery().allocAggregate(agg) ;
+         {if (true) return exprAgg ;}
+     }
+     {if (true) return new E_Function(fname, a) ;}
     throw new Error("Missing return statement in function");
   }
 
@@ -5099,7 +5106,7 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
             String iri ;
       iri = iri();
       a = ExpressionList();
-        agg = AggregatorFactory.create(iri, a) ;
+        agg = AggregatorFactory.createCustom(iri, a) ;
       break;
     default:
       jj_la1[158] = jj_gen;
@@ -5130,6 +5137,13 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     }
     if ( a == null )
        {if (true) return asExpr(createNode(iri)) ;}
+    if ( AggregateRegistry.isRegistered(iri) ) {
+         if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point : "+iri, -1, -1) ;
+         Aggregator agg = AggregatorFactory.createCustom(iri, a) ;
+         Expr exprAgg = getQuery().allocAggregate(agg) ;
+         {if (true) return exprAgg ;}
+      }
     {if (true) return new E_Function(iri, a) ;}
     throw new Error("Missing return statement in function");
   }
@@ -5407,72 +5421,44 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     finally { jj_save(4, xla); }
   }
 
-  private boolean jj_3R_152() {
-    if (jj_scan_token(PNAME_NS)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_92() {
-    if (jj_scan_token(IS_IRI)) return true;
-    if (jj_scan_token(LPAREN)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_91() {
-    if (jj_scan_token(SAME_TERM)) return true;
-    if (jj_scan_token(LPAREN)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_151() {
-    if (jj_scan_token(PNAME_LN)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_90() {
-    if (jj_scan_token(STRDT)) return true;
+  private boolean jj_3R_88() {
+    if (jj_scan_token(IF)) return true;
     if (jj_scan_token(LPAREN)) return true;
     return false;
   }
 
-  private boolean jj_3R_146() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_151()) {
-    jj_scanpos = xsp;
-    if (jj_3R_152()) return true;
-    }
-    return false;
-  }
-
-  private boolean jj_3R_89() {
-    if (jj_scan_token(STRLANG)) return true;
-    if (jj_scan_token(LPAREN)) return true;
+  private boolean jj_3R_164() {
+    if (jj_scan_token(STRING_LITERAL_LONG2)) return true;
     return false;
   }
 
-  private boolean jj_3R_139() {
-    if (jj_3R_146()) return true;
+  private boolean jj_3R_163() {
+    if (jj_scan_token(STRING_LITERAL_LONG1)) return true;
     return false;
   }
 
-  private boolean jj_3R_88() {
-    if (jj_scan_token(IF)) return true;
-    if (jj_scan_token(LPAREN)) return true;
+  private boolean jj_3R_162() {
+    if (jj_scan_token(STRING_LITERAL2)) return true;
     return false;
   }
 
-  private boolean jj_3R_138() {
-    if (jj_3R_133()) return true;
+  private boolean jj_3R_161() {
+    if (jj_scan_token(STRING_LITERAL1)) return true;
     return false;
   }
 
-  private boolean jj_3R_132() {
+  private boolean jj_3R_153() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_138()) {
+    if (jj_3R_161()) {
     jj_scanpos = xsp;
-    if (jj_3R_139()) return true;
+    if (jj_3R_162()) {
+    jj_scanpos = xsp;
+    if (jj_3R_163()) {
+    jj_scanpos = xsp;
+    if (jj_3R_164()) return true;
+    }
+    }
     }
     return false;
   }
@@ -5483,24 +5469,14 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_164() {
-    if (jj_scan_token(STRING_LITERAL_LONG2)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_163() {
-    if (jj_scan_token(STRING_LITERAL_LONG1)) return true;
-    return false;
-  }
-
   private boolean jj_3R_86() {
     if (jj_scan_token(COALESCE)) return true;
     if (jj_3R_106()) return true;
     return false;
   }
 
-  private boolean jj_3R_162() {
-    if (jj_scan_token(STRING_LITERAL2)) return true;
+  private boolean jj_3R_158() {
+    if (jj_scan_token(FALSE)) return true;
     return false;
   }
 
@@ -5515,11 +5491,6 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_161() {
-    if (jj_scan_token(STRING_LITERAL1)) return true;
-    return false;
-  }
-
   private boolean jj_3R_144() {
     if (jj_3R_150()) return true;
     return false;
@@ -5531,6 +5502,21 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3R_157() {
+    if (jj_scan_token(TRUE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_149() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_157()) {
+    jj_scanpos = xsp;
+    if (jj_3R_158()) return true;
+    }
+    return false;
+  }
+
   private boolean jj_3R_143() {
     if (jj_3R_149()) return true;
     return false;
@@ -5542,22 +5528,6 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_153() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_161()) {
-    jj_scanpos = xsp;
-    if (jj_3R_162()) {
-    jj_scanpos = xsp;
-    if (jj_3R_163()) {
-    jj_scanpos = xsp;
-    if (jj_3R_164()) return true;
-    }
-    }
-    }
-    return false;
-  }
-
   private boolean jj_3R_142() {
     if (jj_3R_148()) return true;
     return false;
@@ -5613,6 +5583,11 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3R_176() {
+    if (jj_scan_token(DOUBLE_NEGATIVE)) return true;
+    return false;
+  }
+
   private boolean jj_3R_129() {
     if (jj_3R_135()) return true;
     return false;
@@ -5624,8 +5599,8 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_158() {
-    if (jj_scan_token(FALSE)) return true;
+  private boolean jj_3R_175() {
+    if (jj_scan_token(DECIMAL_NEGATIVE)) return true;
     return false;
   }
 
@@ -5635,6 +5610,24 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3R_174() {
+    if (jj_scan_token(INTEGER_NEGATIVE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_167() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_174()) {
+    jj_scanpos = xsp;
+    if (jj_3R_175()) {
+    jj_scanpos = xsp;
+    if (jj_3R_176()) return true;
+    }
+    }
+    return false;
+  }
+
   private boolean jj_3R_134() {
     Token xsp;
     xsp = jj_scanpos;
@@ -5651,21 +5644,6 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_157() {
-    if (jj_scan_token(TRUE)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_149() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_157()) {
-    jj_scanpos = xsp;
-    if (jj_3R_158()) return true;
-    }
-    return false;
-  }
-
   private boolean jj_3R_76() {
     if (jj_scan_token(TZ)) return true;
     if (jj_scan_token(LPAREN)) return true;
@@ -5684,14 +5662,19 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3R_173() {
+    if (jj_scan_token(DOUBLE_POSITIVE)) return true;
+    return false;
+  }
+
   private boolean jj_3R_73() {
     if (jj_scan_token(MINUTES)) return true;
     if (jj_scan_token(LPAREN)) return true;
     return false;
   }
 
-  private boolean jj_3R_176() {
-    if (jj_scan_token(DOUBLE_NEGATIVE)) return true;
+  private boolean jj_3R_172() {
+    if (jj_scan_token(DECIMAL_POSITIVE)) return true;
     return false;
   }
 
@@ -5701,35 +5684,30 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_175() {
-    if (jj_scan_token(DECIMAL_NEGATIVE)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_71() {
-    if (jj_scan_token(DAY)) return true;
-    if (jj_scan_token(LPAREN)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_174() {
-    if (jj_scan_token(INTEGER_NEGATIVE)) return true;
+  private boolean jj_3R_171() {
+    if (jj_scan_token(INTEGER_POSITIVE)) return true;
     return false;
   }
 
-  private boolean jj_3R_167() {
+  private boolean jj_3R_166() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_174()) {
+    if (jj_3R_171()) {
     jj_scanpos = xsp;
-    if (jj_3R_175()) {
+    if (jj_3R_172()) {
     jj_scanpos = xsp;
-    if (jj_3R_176()) return true;
+    if (jj_3R_173()) return true;
     }
     }
     return false;
   }
 
+  private boolean jj_3R_71() {
+    if (jj_scan_token(DAY)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
   private boolean jj_3R_70() {
     if (jj_scan_token(MONTH)) return true;
     if (jj_scan_token(LPAREN)) return true;
@@ -5742,6 +5720,11 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3R_170() {
+    if (jj_scan_token(DOUBLE)) return true;
+    return false;
+  }
+
   private boolean jj_3R_128() {
     if (jj_3R_134()) return true;
     return false;
@@ -5753,13 +5736,26 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_173() {
-    if (jj_scan_token(DOUBLE_POSITIVE)) return true;
+  private boolean jj_3R_169() {
+    if (jj_scan_token(DECIMAL)) return true;
     return false;
   }
 
-  private boolean jj_3R_172() {
-    if (jj_scan_token(DECIMAL_POSITIVE)) return true;
+  private boolean jj_3R_168() {
+    if (jj_scan_token(INTEGER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_165() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_168()) {
+    jj_scanpos = xsp;
+    if (jj_3R_169()) {
+    jj_scanpos = xsp;
+    if (jj_3R_170()) return true;
+    }
+    }
     return false;
   }
 
@@ -5779,43 +5775,30 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_171() {
-    if (jj_scan_token(INTEGER_POSITIVE)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_166() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_171()) {
-    jj_scanpos = xsp;
-    if (jj_3R_172()) {
-    jj_scanpos = xsp;
-    if (jj_3R_173()) return true;
-    }
-    }
-    return false;
-  }
-
   private boolean jj_3R_66() {
     if (jj_scan_token(STRENDS)) return true;
     if (jj_scan_token(LPAREN)) return true;
     return false;
   }
 
+  private boolean jj_3R_156() {
+    if (jj_3R_167()) return true;
+    return false;
+  }
+
   private boolean jj_3R_65() {
     if (jj_scan_token(STRSTARTS)) return true;
     if (jj_scan_token(LPAREN)) return true;
     return false;
   }
 
-  private boolean jj_3R_170() {
-    if (jj_scan_token(DOUBLE)) return true;
+  private boolean jj_3R_155() {
+    if (jj_3R_166()) return true;
     return false;
   }
 
-  private boolean jj_3R_169() {
-    if (jj_scan_token(DECIMAL)) return true;
+  private boolean jj_3R_154() {
+    if (jj_3R_165()) return true;
     return false;
   }
 
@@ -5825,24 +5808,6 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_168() {
-    if (jj_scan_token(INTEGER)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_165() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_168()) {
-    jj_scanpos = xsp;
-    if (jj_3R_169()) {
-    jj_scanpos = xsp;
-    if (jj_3R_170()) return true;
-    }
-    }
-    return false;
-  }
-
   private boolean jj_3R_63() {
     if (jj_scan_token(ENCODE_FOR_URI)) return true;
     if (jj_scan_token(LPAREN)) return true;
@@ -5855,6 +5820,19 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3R_148() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_154()) {
+    jj_scanpos = xsp;
+    if (jj_3R_155()) {
+    jj_scanpos = xsp;
+    if (jj_3R_156()) return true;
+    }
+    }
+    return false;
+  }
+
   private boolean jj_3R_61() {
     if (jj_scan_token(UCASE)) return true;
     if (jj_scan_token(LPAREN)) return true;
@@ -5866,32 +5844,17 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_156() {
-    if (jj_3R_167()) return true;
-    return false;
-  }
-
   private boolean jj_3R_59() {
     if (jj_scan_token(STRLEN)) return true;
     if (jj_scan_token(LPAREN)) return true;
     return false;
   }
 
-  private boolean jj_3R_155() {
-    if (jj_3R_166()) return true;
-    return false;
-  }
-
   private boolean jj_3R_58() {
     if (jj_3R_107()) return true;
     return false;
   }
 
-  private boolean jj_3R_154() {
-    if (jj_3R_165()) return true;
-    return false;
-  }
-
   private boolean jj_3R_57() {
     if (jj_scan_token(CONCAT)) return true;
     if (jj_3R_106()) return true;
@@ -5910,15 +5873,46 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_148() {
+  private boolean jj_3R_54() {
+    if (jj_scan_token(CEIL)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_53() {
+    if (jj_scan_token(ABS)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_52() {
+    if (jj_scan_token(RAND)) return true;
+    if (jj_scan_token(NIL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_105() {
+    if (jj_scan_token(NIL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_147() {
+    if (jj_3R_153()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_104() {
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_51() {
+    if (jj_scan_token(BNODE)) return true;
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_154()) {
-    jj_scanpos = xsp;
-    if (jj_3R_155()) {
+    if (jj_3R_104()) {
     jj_scanpos = xsp;
-    if (jj_3R_156()) return true;
-    }
+    if (jj_3R_105()) return true;
     }
     return false;
   }
@@ -5971,70 +5965,26 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_54() {
-    if (jj_scan_token(CEIL)) return true;
-    if (jj_scan_token(LPAREN)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_53() {
-    if (jj_scan_token(ABS)) return true;
+  private boolean jj_3R_50() {
+    if (jj_scan_token(URI)) return true;
     if (jj_scan_token(LPAREN)) return true;
     return false;
   }
 
-  private boolean jj_3R_52() {
-    if (jj_scan_token(RAND)) return true;
-    if (jj_scan_token(NIL)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_105() {
-    if (jj_scan_token(NIL)) return true;
-    return false;
-  }
-
   private boolean jj_3R_125() {
     if (jj_scan_token(LBRACE)) return true;
     return false;
   }
 
-  private boolean jj_3_3() {
-    if (jj_scan_token(DOT)) return true;
-    if (jj_3R_42()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_104() {
-    if (jj_scan_token(LPAREN)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_51() {
-    if (jj_scan_token(BNODE)) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_104()) {
-    jj_scanpos = xsp;
-    if (jj_3R_105()) return true;
-    }
-    return false;
-  }
-
-  private boolean jj_3R_50() {
-    if (jj_scan_token(URI)) return true;
+  private boolean jj_3R_49() {
+    if (jj_scan_token(IRI)) return true;
     if (jj_scan_token(LPAREN)) return true;
     return false;
   }
 
-  private boolean jj_3R_147() {
-    if (jj_3R_153()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_49() {
-    if (jj_scan_token(IRI)) return true;
-    if (jj_scan_token(LPAREN)) return true;
+  private boolean jj_3_3() {
+    if (jj_scan_token(DOT)) return true;
+    if (jj_3R_42()) return true;
     return false;
   }
 
@@ -6050,11 +6000,6 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3_1() {
-    if (jj_3R_40()) return true;
-    return false;
-  }
-
   private boolean jj_3R_46() {
     if (jj_scan_token(LANGMATCHES)) return true;
     if (jj_scan_token(LPAREN)) return true;
@@ -6253,6 +6198,11 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3_1() {
+    if (jj_3R_40()) return true;
+    return false;
+  }
+
   private boolean jj_3R_123() {
     if (jj_scan_token(AGG)) return true;
     if (jj_3R_132()) return true;
@@ -6270,11 +6220,6 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_113() {
-    if (jj_3R_127()) return true;
-    return false;
-  }
-
   private boolean jj_3R_122() {
     if (jj_scan_token(GROUP_CONCAT)) return true;
     if (jj_scan_token(LPAREN)) return true;
@@ -6287,13 +6232,6 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_127() {
-    if (jj_scan_token(PREFIX)) return true;
-    if (jj_scan_token(PNAME_NS)) return true;
-    if (jj_3R_133()) return true;
-    return false;
-  }
-
   private boolean jj_3R_120() {
     if (jj_scan_token(AVG)) return true;
     if (jj_scan_token(LPAREN)) return true;
@@ -6312,9 +6250,8 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_126() {
-    if (jj_scan_token(BASE)) return true;
-    if (jj_3R_133()) return true;
+  private boolean jj_3R_113() {
+    if (jj_3R_127()) return true;
     return false;
   }
 
@@ -6324,27 +6261,10 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_112() {
-    if (jj_3R_126()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_100() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_112()) {
-    jj_scanpos = xsp;
-    if (jj_3R_113()) return true;
-    }
-    return false;
-  }
-
-  private boolean jj_3R_41() {
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_100()) { jj_scanpos = xsp; break; }
-    }
+  private boolean jj_3R_127() {
+    if (jj_scan_token(PREFIX)) return true;
+    if (jj_scan_token(PNAME_NS)) return true;
+    if (jj_3R_133()) return true;
     return false;
   }
 
@@ -6359,6 +6279,12 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3R_126() {
+    if (jj_scan_token(BASE)) return true;
+    if (jj_3R_133()) return true;
+    return false;
+  }
+
   private boolean jj_3R_103() {
     Token xsp;
     xsp = jj_scanpos;
@@ -6387,11 +6313,35 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3R_112() {
+    if (jj_3R_126()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_100() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_112()) {
+    jj_scanpos = xsp;
+    if (jj_3R_113()) return true;
+    }
+    return false;
+  }
+
   private boolean jj_3R_131() {
     if (jj_3R_137()) return true;
     return false;
   }
 
+  private boolean jj_3R_41() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_100()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
   private boolean jj_3R_130() {
     if (jj_3R_136()) return true;
     return false;
@@ -6457,12 +6407,22 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3R_133() {
+    if (jj_scan_token(IRIref)) return true;
+    return false;
+  }
+
   private boolean jj_3R_109() {
     if (jj_scan_token(REGEX)) return true;
     if (jj_scan_token(LPAREN)) return true;
     return false;
   }
 
+  private boolean jj_3R_160() {
+    if (jj_scan_token(ANON)) return true;
+    return false;
+  }
+
   private boolean jj_3R_99() {
     if (jj_3R_111()) return true;
     return false;
@@ -6473,8 +6433,18 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_133() {
-    if (jj_scan_token(IRIref)) return true;
+  private boolean jj_3R_159() {
+    if (jj_scan_token(BLANK_NODE_LABEL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_150() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_159()) {
+    jj_scanpos = xsp;
+    if (jj_3R_160()) return true;
+    }
     return false;
   }
 
@@ -6494,8 +6464,8 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_160() {
-    if (jj_scan_token(ANON)) return true;
+  private boolean jj_3R_152() {
+    if (jj_scan_token(PNAME_NS)) return true;
     return false;
   }
 
@@ -6505,18 +6475,8 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
-  private boolean jj_3R_159() {
-    if (jj_scan_token(BLANK_NODE_LABEL)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_150() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_159()) {
-    jj_scanpos = xsp;
-    if (jj_3R_160()) return true;
-    }
+  private boolean jj_3R_151() {
+    if (jj_scan_token(PNAME_LN)) return true;
     return false;
   }
 
@@ -6536,12 +6496,66 @@ public class ARQParser extends ARQParserBase implements ARQParserConstants {
     return false;
   }
 
+  private boolean jj_3R_146() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_151()) {
+    jj_scanpos = xsp;
+    if (jj_3R_152()) return true;
+    }
+    return false;
+  }
+
   private boolean jj_3R_93() {
     if (jj_scan_token(IS_URI)) return true;
     if (jj_scan_token(LPAREN)) return true;
     return false;
   }
 
+  private boolean jj_3R_92() {
+    if (jj_scan_token(IS_IRI)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_139() {
+    if (jj_3R_146()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_91() {
+    if (jj_scan_token(SAME_TERM)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_138() {
+    if (jj_3R_133()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_132() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_138()) {
+    jj_scanpos = xsp;
+    if (jj_3R_139()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_90() {
+    if (jj_scan_token(STRDT)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_89() {
+    if (jj_scan_token(STRLANG)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
   /** Generated Token Manager. */
   public ARQParserTokenManager token_source;
   JavaCharStream jj_input_stream;

http://git-wip-us.apache.org/repos/asf/jena/blob/85a33737/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/SPARQLParser11.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/SPARQLParser11.java b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/SPARQLParser11.java
index 711a2c6..531c438 100644
--- a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/SPARQLParser11.java
+++ b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/lang/sparql_11/SPARQLParser11.java
@@ -2257,7 +2257,14 @@ public class SPARQLParser11 extends SPARQLParser11Base implements SPARQLParser11
                         String fname ; ExprList a ;
     fname = iri();
     a = ArgList();
-    {if (true) return new E_Function(fname, a) ;}
+     if ( AggregateRegistry.isRegistered(fname) ) {
+         if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point : "+fname, -1, -1) ;
+         Aggregator agg = AggregatorFactory.createCustom(fname, a) ;
+         Expr exprAgg = getQuery().allocAggregate(agg) ;
+         {if (true) return exprAgg ;}
+     }
+     {if (true) return new E_Function(fname, a) ;}
     throw new Error("Missing return statement in function");
   }
 
@@ -4617,6 +4624,13 @@ public class SPARQLParser11 extends SPARQLParser11Base implements SPARQLParser11
     }
     if ( a == null )
        {if (true) return asExpr(createNode(iri)) ;}
+    if ( AggregateRegistry.isRegistered(iri) ) {
+         if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point : "+iri, -1, -1) ;
+         Aggregator agg = AggregatorFactory.createCustom(iri, a) ;
+         Expr exprAgg = getQuery().allocAggregate(agg) ;
+         {if (true) return exprAgg ;}
+      }
     {if (true) return new E_Function(iri, a) ;}
     throw new Error("Missing return statement in function");
   }

http://git-wip-us.apache.org/repos/asf/jena/blob/85a33737/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/Tags.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/Tags.java b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/Tags.java
index ed32195..62f7db1 100644
--- a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/Tags.java
+++ b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/Tags.java
@@ -60,7 +60,7 @@ public class Tags
     public static final String tagQuadPattern     = "quadpattern" ;
     public static final String tagQuadBlock       = "quadblock" ;
     public static final String tagFilter          = "filter" ;
-    // public static final String tagGraph = "graph" ;
+    // public static final String traph = "graph" ;
     public static final String tagLabel           = "label" ;
     public static final String tagService         = "service" ;
     public static final String tagProc            = "proc" ;
@@ -231,4 +231,5 @@ public class Tags
     public static final String tagSample          = "sample" ;
     public static final String tagGroupConcat     = "group_concat" ;
     public static final String tagSeparator       = "separator" ;
+    public static final String tagAgg             = "agg" ;             // Custom aggregate
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/85a33737/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderExpr.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderExpr.java b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderExpr.java
index cb31942..8eb48f7 100644
--- a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderExpr.java
+++ b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderExpr.java
@@ -323,6 +323,7 @@ public class BuilderExpr
         dispatch.put(Tags.tagAvg, buildAvg) ;
         dispatch.put(Tags.tagSample, buildSample) ;
         dispatch.put(Tags.tagGroupConcat, buildGroupConcat) ;
+        dispatch.put(Tags.tagAgg,  buildCustomAggregate) ;
     }
 
     // See exprbuilder.rb
@@ -1385,6 +1386,27 @@ public class BuilderExpr
         }
     };
     
+    final protected Build buildCustomAggregate = new Build() {
+        @Override
+        public Expr make(final ItemList list)
+        {
+            ItemList x = list.cdr();    // drop "agg"
+            if ( x.size() == 0 )
+                BuilderLib.broken(list, "Missing IRI for aggregate") ;
+            
+            Item z = x.car() ;
+            if ( ! z.isNodeURI() )
+                BuilderLib.broken(list, "Not an IRI for aggregate: "+z) ;
+            boolean distinct = startsWithDistinct(x) ;
+            if ( distinct )
+                x = x.cdr();
+            x = list.cdr();
+            ExprList e = buildExprListUntagged(x, 0) ;
+            Aggregator agg = AggregatorFactory.createCustom(z.getNode().getURI(), e) ;
+            return new ExprAggregator(null, agg) ; 
+        }
+    } ;
+    
     final protected Build buildAggNull = new Build()
     {
         @Override
@@ -1394,7 +1416,4 @@ public class BuilderExpr
             return new ExprAggregator(null, AggregatorFactory.createAggNull()) ;
         }
     };
-    
-
-
 }