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 2012/10/10 10:22:45 UTC

svn commit: r1396509 - in /jena/trunk/jena-arq/Grammar: Final/ Final/README.txt Final/jj2html_11 Final/master_11.jj Final/sparql_10-final.jj Final/sparql_11-final.jj Final/tokens_11.txt master-lc2.jj sparql_10.jj sparql_11-final.jj sparql_11-lc2.jj

Author: andy
Date: Wed Oct 10 08:22:45 2012
New Revision: 1396509

URL: http://svn.apache.org/viewvc?rev=1396509&view=rev
Log:
Final copies of the grammar and HTML tools

Added:
    jena/trunk/jena-arq/Grammar/Final/
    jena/trunk/jena-arq/Grammar/Final/README.txt
    jena/trunk/jena-arq/Grammar/Final/jj2html_11
      - copied unchanged from r1392224, jena/trunk/jena-arq/Grammar/jj2html
    jena/trunk/jena-arq/Grammar/Final/master_11.jj
    jena/trunk/jena-arq/Grammar/Final/sparql_10-final.jj
      - copied unchanged from r1392224, jena/trunk/jena-arq/Grammar/sparql_10.jj
    jena/trunk/jena-arq/Grammar/Final/sparql_11-final.jj
      - copied, changed from r1392224, jena/trunk/jena-arq/Grammar/sparql_11-final.jj
    jena/trunk/jena-arq/Grammar/Final/tokens_11.txt
      - copied unchanged from r1392224, jena/trunk/jena-arq/Grammar/tokens.txt
Removed:
    jena/trunk/jena-arq/Grammar/master-lc2.jj
    jena/trunk/jena-arq/Grammar/sparql_10.jj
    jena/trunk/jena-arq/Grammar/sparql_11-final.jj
    jena/trunk/jena-arq/Grammar/sparql_11-lc2.jj

Added: jena/trunk/jena-arq/Grammar/Final/README.txt
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/Grammar/Final/README.txt?rev=1396509&view=auto
==============================================================================
--- jena/trunk/jena-arq/Grammar/Final/README.txt (added)
+++ jena/trunk/jena-arq/Grammar/Final/README.txt Wed Oct 10 08:22:45 2012
@@ -0,0 +1 @@
+Final-for-spec-publication versions of the grammar.

Added: jena/trunk/jena-arq/Grammar/Final/master_11.jj
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/Grammar/Final/master_11.jj?rev=1396509&view=auto
==============================================================================
--- jena/trunk/jena-arq/Grammar/Final/master_11.jj (added)
+++ jena/trunk/jena-arq/Grammar/Final/master_11.jj Wed Oct 10 08:22:45 2012
@@ -0,0 +1,2518 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ARQ/SPARQL 1.1 Grammar - native syntax for the query engine
+#if 0
+// (Run through cpp -P -C first)
+#endif
+
+
+#if !defined(ARQ) && !defined(SPARQL_11)
+#error Please define one of ARQ and SPARQL_11
+#endif
+
+#if defined(ARQ) && defined(SPARQL_11)
+#error Please define only one of ARQ and SPARQL_11
+#endif
+
+// UPDATE : SPARQL 1.1. Update
+// ARQ_UPDATE : extensions to SPARQL 1.1 Update to cover SPARQL/Update (W3C Submission)
+
+#ifdef SPARQL_11
+#define PACKAGE     lang.sparql_11
+#define CLASS       SPARQLParser11
+#define PARSERBASE  SPARQLParser11Base
+#define UPDATE
+#endif
+
+#ifdef ARQ
+#define PACKAGE     lang.arq
+#define CLASS       ARQParser
+#define PARSERBASE  ARQParserBase
+#define UPDATE
+#define ARQ_UPDATE
+#endif
+
+options
+{
+      // \ u processed in the input stream
+      // SPARQL 1.0
+    JAVA_UNICODE_ESCAPE   = true ;
+    UNICODE_INPUT         = false ;
+
+//       // \ u processed after parsing.
+//       // strings, prefix names, IRIs
+//       JAVA_UNICODE_ESCAPE   = false ;
+//       UNICODE_INPUT         = true ;
+
+  STATIC                = false ;
+//  DEBUG_PARSER          = true ;
+//  DEBUG_TOKEN_MANAGER   = true ;
+}
+
+PARSER_BEGIN(CLASS)
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hp.hpl.jena.sparql.PACKAGE ;
+
+import com.hp.hpl.jena.graph.* ;
+import com.hp.hpl.jena.query.* ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.syntax.* ;
+import com.hp.hpl.jena.sparql.expr.* ;
+import com.hp.hpl.jena.sparql.path.* ;
+import com.hp.hpl.jena.sparql.expr.aggregate.* ;
+#ifdef  UPDATE
+import com.hp.hpl.jena.update.* ;
+import com.hp.hpl.jena.sparql.modify.request.* ;
+#endif
+
+public class CLASS extends PARSERBASE
+{
+    boolean allowAggregatesInExpressions = false ;
+}
+PARSER_END(CLASS)
+
+// // Common top for single entry point.
+// void Top(): {}
+// {
+//     ( Query() | Update() )
+//     <EOF>
+// }
+
+// Query only entry point
+void QueryUnit(): { }
+{
+  { startQuery() ; }
+  Query() <EOF>
+  { finishQuery() ; }
+}
+
+void Query() : { }
+{    
+  Prologue()
+  ( SelectQuery() | ConstructQuery() | DescribeQuery() | AskQuery() 
+// #ifdef ARQ
+//   | JsonTemplateQuery()
+// #endif
+  )
+  ValuesClause()
+}
+
+#ifdef UPDATE
+void UpdateUnit() : {}
+{
+  { startUpdateRequest() ; }
+  Update()
+  <EOF>
+  { finishUpdateRequest() ; }
+}
+#endif
+
+
+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 ; }
+{
+  <SELECT>
+    { getQuery().setQuerySelectType() ; }
+  ( <DISTINCT> { getQuery().setDistinct(true);} 
+  | <REDUCED>  { getQuery().setReduced(true); }
+  )? 
+
+  { allowAggregatesInExpressions = true ; }
+  (
+    (
+      v = Var()                     { getQuery().addResultVar(v) ; }
+    | 
+#if ARQ
+      // 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)) ; }
+      )
+      // @@ PROBLEMS: expr = FunctionCall()
+      // <uri>(?x)
+      // looks like a function call and also a "<uri> ( ?v )"
+      //| expr = FunctionCall()  { getQuery().addResultVar((Var)null, expr) ; }
+    |
+#endif      
+        // Expressions with ()
+      (
+        { v = null ; }
+        <LPAREN>
+        expr = Expression() 
+#ifdef SPARQL_11
+        <AS> v = Var()
+#endif
+#ifdef ARQ
+        ( <AS> v = Var() ) ?
+#endif
+        <RPAREN>
+        { getQuery().addResultVar(v, expr) ; }
+      )
+      { getQuery().setQueryResultStar(false) ; }
+    )+
+  |
+    <STAR> { getQuery().setQueryResultStar(true) ; }
+  )
+  { allowAggregatesInExpressions = false ; }
+}
+
+#if 0
+#include  "json-extra.jj"
+#endif
+
+void ConstructQuery() : { Template t ; 
+                          TripleCollectorBGP acc = new TripleCollectorBGP() ; }
+{
+// #ifndef ARQ
+//   <CONSTRUCT>
+//      { getQuery().setQueryConstructType() ; }
+//   t = ConstructTemplate() 
+//     { getQuery().setConstructTemplate(t) ; }
+//   ( DatasetClause() )*
+//   WhereClause()
+//   SolutionModifier()
+// #else
+
+ <CONSTRUCT>
+   { getQuery().setQueryConstructType() ; }
+ (
+    // Full form.
+    t = ConstructTemplate() 
+      { getQuery().setConstructTemplate(t) ; }
+    ( DatasetClause() )*
+    WhereClause()
+    SolutionModifier()
+ |
+    // Abbreviated CONSTRUCT WHERE {}
+    ( DatasetClause() )*
+    <WHERE>
+    // Should have been "ConstructTemplate()"
+    <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.
+      ElementPathBlock epb = new ElementPathBlock(acc.getBGP()) ;
+      ElementGroup elg = new ElementGroup() ;
+      elg.addElement(epb) ;
+      getQuery().setQueryPattern(elg) ;
+    }
+ )
+//#endif
+}
+
+void DescribeQuery() : { Node n ; }
+{
+  <DESCRIBE>
+    { getQuery().setQueryDescribeType() ; }
+  (
+    ( n = VarOrIri() { getQuery().addDescribeNode(n) ; } )+
+    { getQuery().setQueryResultStar(false) ; }
+  |
+    <STAR>
+    { getQuery().setQueryResultStar(true) ; }
+  )
+  ( DatasetClause() )*
+  ( WhereClause() )?
+  SolutionModifier()
+}
+
+void AskQuery() : {}
+{
+  <ASK> { getQuery().setQueryAskType() ; }
+  ( DatasetClause() )*
+  WhereClause()
+  SolutionModifier()
+}
+
+// ----
+
+void DatasetClause() : {}
+{
+  <FROM>
+  ( DefaultGraphClause() | NamedGraphClause() )
+}
+
+void DefaultGraphClause() : { String iri ; }
+{
+  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>)? 
+   { startWherePattern() ; }
+   el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
+   { finishWherePattern() ; }
+}
+
+void SolutionModifier() : { }
+{
+  ( GroupClause() )?
+  ( HavingClause() )?
+  ( OrderClause() )?
+  ( 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) ; }
+  |
+    <LPAREN>
+      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() 
+    )
+  |
+    ( 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())? 
+  |
+    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>  
+    { startValuesClause(t.beginLine, t.beginColumn) ; }
+    DataBlock()
+    { finishValuesClause(t.beginLine, t.beginColumn) ; }
+  )?
+}
+
+#ifdef UPDATE
+// SPARQL Update + transitional extensions for SPARQL/Update (the W3C submission)
+// Update only entry point
+
+#ifdef ARQ_UPDATE
+// Optional SEMICOLON
+void Update() : { }
+{
+   Prologue()
+   ( Update1() (<SEMICOLON>)*  Update() )?
+}
+#else
+// Strict SPARQL 1.1 : mandatory separator, optional terminator.
+void Update() : { }
+{  
+   Prologue()
+   (Update1() ( <SEMICOLON> Update() )? )?
+}
+#endif
+
+void Update1() : { Update up ; }
+{
+  { startUpdateOperation() ; }
+  ( up = Load()
+  | up = Clear()
+  | up = Drop()
+  | up = Add()
+  | up = Move()
+  | up = Copy()
+  | up = Create()
+  | up = InsertData()
+  | up = DeleteData()
+  | up = DeleteWhere()
+  | up = Modify()
+#ifdef ARQ_UPDATE
+  | up = ModifyOld()
+#endif
+  )
+  {
+    emitUpdate(up) ;
+    finishUpdateOperation() ;
+  }
+}
+
+Update Load() : { String url ; Node dest = null ; boolean silent = false ; }
+{
+    //    <LOAD> ( iri() )+
+    <LOAD>  (<SILENT> { silent = true ; })? url = iri()
+#ifndef ARQ_UPDATE
+    (<INTO> dest = GraphRef() )?
+#else
+    { String iri ; }
+    (<INTO> (<GRAPH>)? iri = iri() { dest = createNode(iri) ; })?
+#endif
+    { 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) ; } 
+}
+
+Update Add() : { Target src ; Target dest ; boolean silent = false ; }
+{
+  <ADD>  (<SILENT> { silent=true ; } )? src = GraphOrDefault() <TO> dest = GraphOrDefault()
+  { return new UpdateAdd(src, dest, silent) ; }
+}
+
+Update Move() : { Target src ; Target dest ; boolean silent = false ; } 
+{
+  <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()
+  { return new UpdateCopy(src, dest, silent) ; }
+}
+
+// #ifdef ARQ
+// void Meta() : { QuadDataAcc qd = new QuadDataAcc() ; }
+// {
+//    <META> 
+//    QuadData(qd)
+// }
+// #endif
+
+Update InsertData() : { QuadDataAcc qd = new QuadDataAcc() ; Token t ; }
+{
+  t =  <INSERT_DATA>
+  { startDataInsert(qd, t.beginLine, t.beginColumn) ; }
+#ifndef ARQ_UPDATE
+   QuadData(qd)
+#else
+   OptionalIntoTarget(qd)
+   QuadData(qd)
+#endif
+  {
+    finishDataInsert(qd, t.beginLine, t.beginColumn) ;
+    return new UpdateDataInsert(qd) ; 
+  }
+}
+
+Update DeleteData() : { QuadDataAcc qd = new QuadDataAcc() ; Token t ; }
+{
+  t = <DELETE_DATA>
+  { startDataDelete(qd, t.beginLine, t.beginColumn) ; }
+#ifndef ARQ_UPDATE
+  QuadData(qd)
+#else
+  OptionalFromTarget(qd)
+  QuadData(qd)
+#endif
+  { 
+    finishDataDelete(qd, t.beginLine, t.beginColumn) ;
+    return new UpdateDataDelete(qd) ;
+  }
+}
+
+Update DeleteWhere() : { QuadAcc qp = new QuadAcc() ;  Token t ; }
+{
+  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() ; }
+{
+  { startModifyUpdate() ; }
+  ( <WITH> iri = iri() { Node n = createNode(iri) ; up.setWithIRI(n) ; } )?
+  ( DeleteClause(up) ( InsertClause(up) )?
+  | InsertClause(up)
+  )
+  (UsingClause(up))*
+  // WHERE is mandatory here.
+  <WHERE>
+  { startWherePattern() ; }
+  el = GroupGraphPattern() { up.setElement(el) ; }    
+  { finishWherePattern() ; }
+  { finishModifyUpdate() ; }
+  { return up ; }
+}
+
+#ifdef ARQ_UPDATE
+Update ModifyOld() :
+       { UpdateModify up = new UpdateModify() ; String iri ; Template template ; Element el ; }
+{
+    <MODIFY>
+    ( iri = iri() { Node n = createNode(iri) ; up.setWithIRI(n) ; } )?
+    (DeleteClause(up))?
+    (InsertClause(up))?
+    <WHERE>
+    el = GroupGraphPattern() { up.setElement(el) ; }    
+    { return up ; }
+}
+#endif
+
+void DeleteClause(UpdateModify up) : { QuadAcc qp = up.getDeleteAcc() ;  Token t ;}
+{
+   t = <DELETE>
+   { startDeleteTemplate(qp, t.beginLine, t.beginColumn) ; }
+#ifndef ARQ_UPDATE
+   QuadPattern(qp)
+#else
+   OptionalFromTarget(qp)
+   QuadPattern(qp)
+#endif
+   { finishDeleteTemplate(qp, t.beginLine, t.beginColumn) ; }
+   { up.setHasDeleteClause(true) ; }
+}
+
+void InsertClause(UpdateModify up) : { QuadAcc qp = up.getInsertAcc() ; Token t ; }
+{
+   t = <INSERT>
+   { startInsertTemplate(qp, t.beginLine, t.beginColumn) ; }
+#ifndef ARQ_UPDATE
+   QuadPattern(qp)
+#else
+   OptionalIntoTarget(qp)
+   QuadPattern(qp)
+#endif
+   { finishInsertTemplate(qp, t.beginLine, t.beginColumn) ; }
+   { up.setHasInsertClause(true) ; }
+}
+
+#ifdef ARQ_UPDATE
+void OptionalIntoTarget(QuadAcc qp) : { String iri ; }
+{
+  ( (<INTO>)? 
+     iri = iri()
+     { Node gn = createNode(iri) ; setAccGraph(qp, gn) ; }
+   )?
+}
+
+void OptionalFromTarget(QuadAcc qp) : { String iri ; }
+{
+  ( (<FROM>)? 
+     iri = iri()
+     { Node gn = createNode(iri) ; setAccGraph(qp, gn) ; }
+   )?
+}
+#endif
+
+void UsingClause(UpdateWithUsing update) : { String iri ; Node n ; }
+{
+  <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>)? 
+     iri = iri()
+     {  return Target.create(createNode(iri)) ; }
+  )
+}
+
+Node GraphRef() : { String iri ; }
+{
+    <GRAPH> iri = iri()
+    { return createNode(iri) ; }
+}
+
+Target GraphRefAll() : { Node iri ; }
+{
+   ( iri = GraphRef() 
+     { return Target.create(iri) ; }
+   | <DFT>    { return Target.DEFAULT ; }
+   | <NAMED>  { return Target.NAMED ; } 
+   | <ALL>    { return Target.ALL ; } 
+   )
+#ifdef ARQ_UPDATE
+   ?
+   { return Target.DEFAULT ; }
+#endif
+}
+
+void QuadPattern(QuadAcc acc) : { }
+{
+    <LBRACE>
+    Quads(acc)
+    <RBRACE>
+}
+
+//Ground data : As QuadPattern but don't allow variables.
+void QuadData(QuadDataAcc acc) : { }
+{
+    <LBRACE>
+    Quads(acc)
+    <RBRACE>
+}
+
+void Quads(QuadAcc acc) : { }
+{
+   (TriplesTemplate(acc))?
+   (
+     QuadsNotTriples(acc)
+     (<DOT>)?
+     (TriplesTemplate(acc))?
+   )*
+}
+
+void QuadsNotTriples(QuadAcc acc) : {Node gn ; Node prev = acc.getGraph() ; }
+{
+    <GRAPH> gn = VarOrIri()
+    { setAccGraph(acc, gn) ; }
+    <LBRACE> 
+    (TriplesTemplate(acc))?
+    <RBRACE>
+    { setAccGraph(acc, prev) ; }
+    
+}
+
+void TriplesTemplate(TripleCollector acc) : { }
+{    // same as ConstructTriples
+#if SPARQL_11
+    // Version for the spec.
+    TriplesSameSubject(acc)
+    (<DOT> (TriplesTemplate(acc))?)?
+#endif
+#ifdef ARQ
+    // Rewrite for no recursion - grammar is not LL(1)
+    TriplesSameSubject(acc)
+    (LOOKAHEAD(2) (<DOT>) TriplesSameSubject(acc))*
+    (<DOT>)?
+#endif
+}
+
+#endif // UPDATE
+
+// ---- 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) ;
+    }
+  | el = GroupGraphPatternSub()
+  )
+  <RBRACE>
+    { return el ; }
+}
+
+Element GroupGraphPatternSub() : { Element el = null ; }
+{
+      { ElementGroup elg = new ElementGroup() ; }
+      { startGroup(elg) ; }
+  // Ensure two BGP's can't be next to each other
+  // Done by seeing if there is a non-BGP and recursing
+  // if there is an intermediate
+  (
+    { startTriplesBlock() ; }
+    el = TriplesBlock(null)
+    { endTriplesBlock() ;
+      elg.addElement(el) ; } 
+  )?
+  (
+    el = GraphPatternNotTriples() 
+    { elg.addElement(el) ; }
+
+    (<DOT>)?
+
+    (
+      { startTriplesBlock() ; }
+      el = TriplesBlock(null)
+      { endTriplesBlock() ;
+        elg.addElement(el) ; } 
+    )?
+  )*
+      { endGroup(elg) ; }
+      { return elg ; }
+}
+
+Element TriplesBlock(ElementPathBlock acc) : { }
+{
+  { if ( acc == null )
+        acc = new ElementPathBlock() ;
+  }
+  TriplesSameSubjectPath(acc)
+  ( <DOT> (TriplesBlock(acc))? )?
+    { return acc ; }
+}
+
+// -----
+
+Element GraphPatternNotTriples() : { Element el = null ; }
+{
+ (
+//    el = GroupGraphPattern()
+//  |
+//    el = UnionGraphPattern()
+//  |
+   el = GroupOrUnionGraphPattern()
+ |
+   el = OptionalGraphPattern()
+ |
+   el = MinusGraphPattern()
+ |
+   el = GraphGraphPattern()
+ |
+   el = ServiceGraphPattern()
+ |
+   el = Filter()
+ |
+   el = Bind()
+ |
+   el = InlineData()
+#ifdef ARQ
+ |
+   el = Assignment()
+#ifdef ARQ_FETCH
+ | 
+   el = FetchGraph()
+#endif
+ |
+   el = ExistsElt()
+ |
+   el = NotExistsElt()
+#endif
+ )
+ { 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> 
+  (<SILENT>
+   { silent=true; }
+  )?
+  n = VarOrIri()
+  el = GroupGraphPattern()
+    { return new ElementService(n, el, silent) ; }
+}
+
+Element Bind() : {  Var v ; Expr expr ; }
+{
+  <BIND>
+  <LPAREN>
+  expr = Expression()
+  <AS>
+  v = Var()
+  <RPAREN>
+  { return new ElementBind(v, expr) ; }
+}
+
+Element InlineData() : { ElementData el ; Token t ; }
+{
+  t = <VALUES>
+  { el = new ElementData() ;
+    startInlineData(el.getVars(), el.getRows(), t.beginLine, t.beginColumn) ; }
+  DataBlock()
+  { finishInlineData(t.beginLine, t.beginColumn) ;
+    return el ; }
+}
+
+void DataBlock() : { }
+{
+  ( InlineDataOneVar() |  InlineDataFull() )
+}
+
+void InlineDataOneVar() : { Var v ; Node n ; Token t ; }
+{
+  v = Var()
+  { emitDataBlockVariable(v) ; }
+  t = <LBRACE>
+  ( 
+    n = DataBlockValue() 
+    { startDataBlockValueRow(-1, -1) ;
+      emitDataBlockValue(n, -1, -1) ;
+      finishDataBlockValueRow(-1, -1) ;
+    }
+  )*
+  t = <RBRACE>
+}  
+  
+void InlineDataFull() : { Var v ; Node n ; Token t ; }
+{
+  (
+     <NIL>
+  |
+    t = <LPAREN>
+    (v = Var() { emitDataBlockVariable(v) ; })*
+    t = <RPAREN>
+  )
+  t = <LBRACE>
+  (
+    t = <LPAREN> 
+    { startDataBlockValueRow(t.beginLine, t.beginColumn) ; }
+    (n = DataBlockValue() 
+        { emitDataBlockValue(n, t.beginLine, t.beginColumn) ; }
+    ) *
+    t = <RPAREN> 
+      { finishDataBlockValueRow(t.beginLine, t.beginColumn) ; }
+  |
+    t = <NIL>
+      { startDataBlockValueRow(t.beginLine, t.beginColumn) ; }
+      { 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 ; }
+}
+
+#ifdef ARQ
+
+Element Assignment() : { Var v ; Expr expr ; }
+{
+  <LET>  
+  <LPAREN>
+  v = Var()
+  <ASSIGN> 
+  expr = Expression()
+  <RPAREN>
+    { return new ElementAssign(v, expr) ; }
+}
+
+#ifdef ARQ_FETCH
+Element FetchGraph() : { Node n ; }
+{
+  <FETCH>
+  n = VarOrIri() 
+  { return new ElementFetch(n) ; }
+}
+#endif
+
+Element ExistsElt() : { Element el ; }
+{
+    <EXISTS>
+    el = GroupGraphPattern()
+    { return new ElementExists(el) ; }
+}
+
+Element NotExistsElt() : { Element el ; }
+{
+    <NOT> <EXISTS>
+    el = GroupGraphPattern()
+    { return new ElementNotExists(el) ; }
+}
+#endif
+
+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() :
+    { Element el = null ; ElementUnion el2 = null ; }
+{
+  el = GroupGraphPattern()
+  ( <UNION>
+    { if ( el2 == null )
+      {
+        el2 = new ElementUnion() ;
+        el2.addElement(el) ;
+      }
+    }
+  el = GroupGraphPattern()
+    { 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 = 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>
+  |
+    <LPAREN>
+      (t = <DISTINCT> { distinct = true ; }
+        {
+          if ( ! allowAggregatesInExpressions )
+              throwParseException("Aggregate expression not legal at this point",
+                                 t.beginLine, t.beginColumn) ;
+        }
+      )?
+      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) ; } )* 
+    <RPAREN>
+  )
+  { return args ; }
+}
+
+
+
+// -------- Construct patterns
+
+Template ConstructTemplate() : { TripleCollectorBGP acc = new TripleCollectorBGP(); 
+                                 Template t = new Template(acc.getBGP()) ; }
+{
+    { setInConstructTemplate(true) ; }
+  <LBRACE> 
+    (ConstructTriples(acc))?
+  <RBRACE>
+    { setInConstructTemplate(false) ;
+      return t ; }
+}
+
+void ConstructTriples(TripleCollector acc) : { }
+{    // Same as TriplesTemplate, but retain for 1.0 legacy
+#ifdef SPARQL_11
+// SPARQL - recursion - does not scale for SPARQL/Update
+    TriplesSameSubject(acc)
+    (<DOT> (ConstructTriples(acc))? )?
+#endif
+#ifdef ARQ
+    // Rewrite for no recursion - grammar is not LL(1)
+    TriplesSameSubject(acc)
+    (LOOKAHEAD(2) (<DOT>) TriplesSameSubject(acc))*
+    (<DOT>)?
+#endif
+}
+
+// -------- Triple lists with property and object lists
+// -------- Without paths: entry: TriplesSameSubject
+
+void TriplesSameSubject(TripleCollector acc) : { Node s ; } 
+{
+  s = VarOrTerm()
+  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) : 
+    { Node p = null ; }
+{
+    p = Verb()
+    ObjectList(s, p, null, acc)
+  ( <SEMICOLON> 
+    (
+       p = Verb()
+      ObjectList(s, p, null, acc)
+    )? 
+  )*
+}
+
+Node Verb() : { Node p ;}
+{
+// Blank nodes as predicates
+//   ( p = VarOrBlankNodeOriri() | <KW_A> { p = nRDFtype ; } )
+  ( p = VarOrIri() | <KW_A> { p = nRDFtype ; } )
+  { return p ; }
+}
+
+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) 
+  { insert(acc, mark, s, p, path, o) ; }
+}
+
+// -------- BGPs with paths.
+// -------- Entry point: TriplesSameSubjectPath
+
+void TriplesSameSubjectPath(TripleCollector acc) : { Node s ; } 
+{
+  s = VarOrTerm()
+  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) : 
+    { Path path = null ; Node p = null ; }
+{
+  ( path = VerbPath()
+  | p = VerbSimple()
+  )
+
+  ObjectListPath(s, p, path, acc)
+  ( <SEMICOLON> 
+    { path = null ; p = null ; }
+    (
+      ( path = VerbPath()
+      | p = VerbSimple()
+      )
+      ObjectList(s, p, path, acc)
+    )? 
+  )*
+#if 0
+  |
+  Reification(s, acc)
+#endif
+}
+
+Path VerbPath() : {Node p ; Path path ; }
+{
+  path = Path() { return path ; }
+}
+
+Node VerbSimple() : { Node p ; }
+{
+  // "a" now allowed in paths.
+  //( p = Var() | <KW_A> { p = nRDFtype ; } )
+  p = Var()
+  { return p ; }
+}
+
+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) 
+  { insert(acc, mark, s, p, path, o) ; }
+}
+
+
+// End paths stuff.
+
+// -------- Paths
+
+#ifdef ARQ
+Path PathUnit() : { Path p ; }
+{
+    p = Path()
+    <EOF>
+    { return p ; }
+}
+#endif
+
+// Weakest outermost
+Path Path() : { Path p ; }
+{
+  p = PathAlternative() { return p ; }
+}
+
+Path PathAlternative() : { Path p1 , p2 ; }
+{
+   p1 = PathSequence()
+   (
+      <VBAR> p2 = PathSequence()
+      { p1 = PathFactory.pathAlt(p1, p2) ; }
+   )*
+   { return p1 ; }
+}
+
+Path PathSequence() : { Path p1 , p2 ; }
+{
+    p1 = PathEltOrInverse()
+    ( <SLASH> p2 = PathEltOrInverse()
+      { p1 = PathFactory.pathSeq(p1, p2) ; }
+#ifdef ARQ
+    // :p^:q -- Not in SPARQL 1.1
+    | <CARAT> p2 = PathElt()
+      { p1 = PathFactory.pathSeq(p1, new P_Inverse(p2)) ; }
+#endif
+    )*
+   { return p1; }
+}
+
+// Path unit element, no inverse
+Path PathElt() : { String str ; Node n ; Path p ; }
+{ 
+   p = PathPrimary() 
+   ( p = PathMod(p) )?
+   { return p ; }
+}
+
+// Path unit element, including inverse.
+Path PathEltOrInverse() : { String str ; Node n ; Path p ; }
+{ 
+   ( 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) ; }
+#ifdef ARQ
+   | <LBRACE>
+         //{*}
+       ( <STAR> <RBRACE> { return PathFactory.pathZeroOrMoreN(p) ; }
+         // {+}
+       | <PLUS> <RBRACE> { return  PathFactory.pathOneOrMoreN(p) ; }
+       |  // {N} {N,M} {N,}
+          i1 = Integer()
+          ( <COMMA>
+            ( // case {N,}
+              <RBRACE> 
+              { return PathFactory.pathMod(p, i1, PathFactory.UNSET) ; } 
+            | // case {N,M}
+              i2 = Integer() <RBRACE> // case {N,M}
+              { return PathFactory.pathMod(p, i1, i2) ; } 
+            )
+          |
+            <RBRACE>   // {N}
+                     { return PathFactory.pathFixedLength(p, i1) ; }
+          )
+       |   // {,N}
+         <COMMA>
+         i2 = Integer()
+         <RBRACE>
+           { return PathFactory.pathMod(p, PathFactory.UNSET, i2) ; } 
+       )
+#endif
+   )
+}
+
+Path PathPrimary() : { String str ; Path p ; Node n ; }
+{
+  ( 
+    str = iri()
+     { n = createNode(str) ; p = PathFactory.pathLink(n) ; }
+  | <KW_A> 
+     { p = PathFactory.pathLink(nRDFtype) ; }
+  | <BANG> p = PathNegatedPropertySet()
+  | <LPAREN> p = Path() <RPAREN>
+#ifdef ARQ
+  |
+     <DISTINCT><LPAREN> 
+     p = Path()
+     { p = PathFactory.pathDistinct(p) ; }
+     <RPAREN>
+  |
+     <SHORTEST> <LPAREN> 
+     p = Path()
+     { p = PathFactory.pathShortest(p) ; }
+     <RPAREN>
+  |
+     <MULTI><LPAREN> 
+     p = Path()
+     { p = PathFactory.pathMulti(p) ; }
+     <RPAREN>
+#endif
+  )
+ { return p ; }
+}
+
+Path PathNegatedPropertySet() : { P_Path0 p ; P_NegPropSet pNegSet ; }
+{
+  { pNegSet = new P_NegPropSet() ; }
+
+  ( p = PathOneInPropertySet()
+    { pNegSet.add(p) ; }
+  | <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) ; }
+  // This is the !(^:property) form.
+  | <CARAT>  
+    ( str = iri() { n = createNode(str) ; return new P_ReverseLink(n) ; } 
+    | <KW_A> { return new P_ReverseLink(nRDFtype) ; } 
+    )
+  )
+}
+
+long Integer() : {Token t ;}
+{
+    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 ; }
+#if 0
+ |
+  n = Reification(null, acc) { return n ; }
+#endif
+}
+
+Node BlankNodePropertyList(TripleCollector acc) : { Token t ; }
+{
+  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 ; }
+#if 0
+ |
+  n = Reification(null, acc) { return n ; }
+#endif
+}
+
+Node BlankNodePropertyListPath(TripleCollector acc) : { Token t ; }
+{
+  t = <LBRACKET> 
+    { Node n = createBNode( t.beginLine, t.beginColumn) ; }
+  PropertyListPathNotEmpty(n, acc)
+  <RBRACKET>
+    { return n ; }
+}
+
+#if 0
+Node Reification(Node id, TripleCollector acc) : 
+    { Node s , p , o ; int mark ; Token t ; }
+{
+  // For generality, should be AndNode for s/p/o
+  // Insert reification triple before the resulting subtriples (if any)
+  t = "<<" 
+    { if ( id == null )
+        id = createBNode(t.beginLine, t.beginColumn() ;
+      mark = acc.mark() ; }
+  s = GraphNode(acc)
+    { insert(acc, mark, id, nRDFsubject, s) ;
+      mark = acc.mark() ; 
+    }
+  p = GraphNode(acc)
+    { insert(acc, mark, id, nRDFpredicate, p) ;
+      mark = acc.mark() ;
+    }
+  o = GraphNode(acc)
+    { insert(acc, mark, id, nRDFobject, o) ; }
+  ">>"
+    { return id ; }
+}
+#endif
+
+// ------- RDF collections
+
+Node Collection(TripleCollector acc) : 
+    { Node listHead = nRDFnil ; Node lastCell = null ; int mark ; Node n ; Token t ; }
+{
+  t = <LPAREN> 
+  (
+    { Node cell = createListNode( t.beginLine, t.beginColumn) ;
+      if ( listHead == nRDFnil )
+         listHead = cell ;
+      if ( lastCell != null )
+        insert(acc, lastCell, nRDFrest,  cell) ;
+      mark = acc.mark() ;
+    }
+    n = GraphNode(acc)
+    {
+      insert(acc, mark, cell, nRDFfirst, n) ;
+      lastCell = cell ;
+    }
+  ) +
+  // Not * here - "()" is handled separately.
+  <RPAREN>
+   { if ( lastCell != null )
+       insert(acc, lastCell, nRDFrest,  nRDFnil) ;
+     return listHead ; }
+}
+
+Node CollectionPath(TripleCollector acc) : 
+    { Node listHead = nRDFnil ; Node lastCell = null ; int mark ; Node n ; Token t ; }
+{
+  t = <LPAREN> 
+  (
+    { Node cell = createListNode( t.beginLine, t.beginColumn) ;
+      if ( listHead == nRDFnil )
+         listHead = cell ;
+      if ( lastCell != null )
+        insert(acc, lastCell, nRDFrest,  cell) ;
+      mark = acc.mark() ;
+    }
+    n = GraphNodePath(acc)
+    {
+      insert(acc, mark, cell, nRDFfirst, n) ;
+      lastCell = cell ;
+    }
+  ) +
+  // Not * here - "()" is handled separately.
+  <RPAREN>
+   { if ( lastCell != null )
+       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 ; }   
+  //  <LPAREN> <RPAREN>     { return nRDFnil ; }
+| <NIL>  { return nRDFnil ; }
+}
+
+// -------- Constraint syntax
+
+Expr Expression() : { Expr expr ; }
+{
+  expr = ConditionalOrExpression()
+  { return expr ; }
+}
+
+Expr ConditionalOrExpression() : { Expr expr1, expr2 ; }
+{
+  expr1 = ConditionalAndExpression() 
+  ( <SC_OR> expr2 = ConditionalAndExpression()
+    { expr1 = new E_LogicalOr(expr1, expr2) ; } 
+  )*
+    { return expr1 ; }
+    
+}
+
+Expr ConditionalAndExpression() : { Expr expr1, expr2 ;}
+{
+  expr1 = ValueLogical()
+  ( <SC_AND> expr2 = ValueLogical()
+    { expr1 = new E_LogicalAnd(expr1, expr2) ; }
+  )*
+    { return expr1 ; }
+}
+
+Expr ValueLogical() : { Expr expr ; }
+{
+  expr = RelationalExpression()
+    { return expr ; }
+}
+
+Expr RelationalExpression() : { Expr expr1, expr2 ; ExprList a ; }
+{
+  expr1 = NumericExpression()
+  (
+    <EQ> expr2 = NumericExpression()
+      { expr1 = new E_Equals(expr1, expr2) ; }
+  | <NE> expr2 = NumericExpression()
+      { expr1 = new E_NotEquals(expr1, expr2) ; }
+  | <LT> expr2 = NumericExpression()
+      { expr1 = new E_LessThan(expr1, expr2) ; }
+  | <GT> expr2 = NumericExpression()
+      { expr1 = new E_GreaterThan(expr1, expr2) ; }
+  | <LE> expr2 = NumericExpression()
+      { expr1 = new E_LessThanOrEqual(expr1, expr2) ; }
+  | <GE> expr2 = NumericExpression()
+      { expr1 = new E_GreaterThanOrEqual(expr1, expr2) ; }
+  | <IN> a = ExpressionList()
+      { expr1 = new E_OneOf(expr1, a) ; }
+  | <NOT> <IN> a = ExpressionList()
+      { expr1 = new E_NotOneOf(expr1, a) ; }
+  )?
+    { return expr1 ; }
+}
+
+Expr NumericExpression ()  : { Expr expr ; }
+{
+  expr = AdditiveExpression()
+    { return expr ; }
+}
+
+Expr AdditiveExpression() : { Expr expr1, expr2, expr3 ; boolean addition ; Node n ; }
+{
+  expr1 = MultiplicativeExpression()
+  ( <PLUS> expr2 = MultiplicativeExpression()
+    { expr1 = new E_Add(expr1, expr2) ; }
+  | <MINUS> expr2 = MultiplicativeExpression()
+    { expr1 = new E_Subtract(expr1, expr2) ; }
+  |
+    (
+      n = NumericLiteralPositive()
+      {
+         n = stripSign(n) ;
+         expr2 = asExpr(n) ;
+         addition = true ;
+      }
+    |
+      n = NumericLiteralNegative()
+     { 
+         n = stripSign(n) ;
+         expr2 = asExpr(n) ;
+         addition = false ;
+     }
+     )
+
+    (
+      ( <STAR>  expr3 = UnaryExpression() { expr2 = new E_Multiply(expr2, expr3) ; } )
+    |
+      ( <SLASH>  expr3 = UnaryExpression() { expr2 = new E_Divide(expr2, expr3) ; } )
+    )*
+
+    { if ( addition )
+         expr1 = new E_Add(expr1, expr2) ;
+      else
+         expr1 = new E_Subtract(expr1, expr2) ;
+    }
+  )*
+  { return expr1 ; }
+}
+
+Expr MultiplicativeExpression() : { Expr expr1, expr2 ; }
+{
+  expr1 = UnaryExpression()
+  ( <STAR>  expr2 = UnaryExpression()
+    { expr1 = new E_Multiply(expr1, expr2) ; }
+  | <SLASH> expr2 = UnaryExpression()
+    { expr1 = new E_Divide(expr1, expr2) ; }
+//   | <REM>   expr2 = UnaryExpression()
+//     { expr1 = new E_Modulus(expr1, expr2) ; }
+  )*
+    { return expr1 ; }
+}
+
+Expr UnaryExpression() : { Expr expr ; }
+{
+  <BANG> expr = PrimaryExpression()
+    { return new E_LogicalNot(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 ; }
+// 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) ; }
+#ifdef ARQ
+// and not SPARQL 11
+// needs checking.
+// Use this for ?var(args)
+//  |  expr = VarOrFunction()  { return expr ; }
+#endif
+  )
+}
+
+Expr BrackettedExpression() : { Expr expr ; }
+{
+    <LPAREN> expr = Expression() <RPAREN>  { return expr ; }
+}
+
+Expr BuiltInCall() : { Expr expr ; Expr expr1 = null ; Expr expr2 = null ;
+                       Node gn ; Token t ; ExprList a ; }
+{
+    expr = Aggregate() { return expr ; }
+  |
+    <STR> <LPAREN> expr = Expression() <RPAREN>
+    { return new E_Str(expr) ; }
+  | <LANG> <LPAREN> expr = Expression() <RPAREN>
+    { return new E_Lang(expr) ; }
+
+  | <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> 
+    ( <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) ; }
+    
+  | <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>
+    { return new E_StrBefore(expr1, expr2) ; }
+
+  | <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) ; }
+#if 0
+  | <SHA224>      <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA224(expr1) ; }
+#endif
+  | <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) ; }
+
+#if ARQ
+  | <VERSION> <NIL>     { return new E_Version(); }
+#endif    
+
+  | <COALESCE> a = ExpressionList()
+    { return new E_Coalesce(a) ; }
+    
+#if ARQ
+  // Maybe also allow ?func(?a1,?a2,...)
+//  | <CALL> a = ExpressionList()
+//    { return new E_Call(a) ; }
+
+  | <CALL> 
+    // at least one argument (the function to call).
+      {  a = new ExprList() ; }
+    <LPAREN> 
+      expr = Expression()  { a.add(expr) ; }
+      ( <COMMA> expr = Expression() { a.add(expr) ; } )* 
+    <RPAREN>
+    { return new E_Call(a) ; }
+#endif
+
+  | <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 RegexExpression() :
+{ Expr expr ; Expr patExpr = null ; Expr flagsExpr = null ; }
+{
+    <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() 
+      <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() 
+  <COMMA> expr2 = Expression()
+  <COMMA> expr3 = Expression()
+  ( <COMMA> expr4 = Expression() ) ?
+  <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 ;
+                     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> 
+    ( <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> 
+    { 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) ; } 
+#ifdef SPARQL_11
+    // Single arg version
+    (<SEMICOLON> <SEPARATOR> <EQ> sep=String())?
+#endif
+#ifdef ARQ
+       // JavcaCC 5.0 - rewriting as LL(1) didn't work - code generated was wrong
+    (LOOKAHEAD(2)
+       ( <SEMICOLON>  <SEPARATOR> <EQ> sep=String()
+           (<SEMICOLON> <ORDER><BY> expr2 = Expression() { ordered.add(expr2) ; })?
+       )
+       |
+       (<SEMICOLON> <ORDER><BY> expr2 = Expression() { ordered.add(expr2) ; } )
+    )?
+#endif
+    <RPAREN>
+    { agg = AggregatorFactory.createGroupConcat(distinct, expr, sep, ordered) ; }
+   )
+
+   {
+     if ( ! allowAggregatesInExpressions )
+            throwParseException("Aggregate expression not legal at this point",
+                                 t.beginLine, t.beginColumn) ;
+   }
+   { 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 ; 
+                         boolean distinct = false ; }
+{
+  iri = iri()
+  (a = ArgList())?
+  { if ( a == null ) 
+       return asExpr(createNode(iri)) ;
+    return new E_Function(iri, a) ;
+  }
+}
+
+#ifdef ARQ_CALL
+// Needs checking.
+// The case of "?var()" or just "?var"
+Expr VarOrFunction() : { Var v ; ExprList a = null ; }
+{
+  v = Var()
+  { Expr ev = new ExprVar(v) ; }
+  ( a = ExpressionList() )?
+  { if ( a == null ) return ev ;
+    return new E_FunctionDynamic(ev, a) ;
+  }
+}
+#endif
+
+
+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) ; } )
+  |
+    ( <DATATYPE> uri = iri() )
+  )?
+    { return createLiteral(lex, lang, uri) ; }
+} 
+
+
+Node NumericLiteral() : { Node n ; }
+{
+  (
+    n = NumericLiteralUnsigned()
+  | n = NumericLiteralPositive()
+  | 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) ; }
+}
+
+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) ; }
+}
+
+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) ; }
+}
+
+
+Node BooleanLiteral() : {}
+{
+  <TRUE> { return XSD_TRUE ; }
+ |
+  <FALSE> { return XSD_FALSE ; }
+}
+
+String String() : { Token t ; String lex ; }
+{
+  ( t = <STRING_LITERAL1> { lex = stripQuotes(t.image) ; }
+  | t = <STRING_LITERAL2> { lex = stripQuotes(t.image) ; }
+  | t = <STRING_LITERAL_LONG1> { lex = stripQuotes3(t.image) ; }
+  | t = <STRING_LITERAL_LONG2> { lex = stripQuotes3(t.image) ; }
+  )
+    {
+      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>
+    { return resolvePName(t.image, t.beginLine, t.beginColumn) ; }
+  |
+    t = <PNAME_NS>
+    { return resolvePName(t.image, t.beginLine, t.beginColumn) ; }
+  )
+}
+
+Node BlankNode() :  { Token t = null ; }
+{
+  t = <BLANK_NODE_LABEL>
+    { 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")? > }
+
+#if 0
+// DISABLED
+// C-style comments (they don't nest /* /*...*/ */ is a syntax error)
+// When a /* is seen in the DEFAULT state, skip it and switch to the IN_COMMENT state
+SKIP : { "/*": IN_COMMENT }
+      
+// When any other character is seen in the IN_COMMENT state, skip it.
+< IN_COMMENT > SKIP : { < ~[] > }
+      
+// When a */ is seen in the IN_COMMENT state, skip it and switch back to the DEFAULT state
+< IN_COMMENT > SKIP : { "*/": DEFAULT } 
+#endif
+
+
+TOKEN: { 
+  <#WS: " " | "\t" | "\n" | "\r" | "\f">
+|
+  // Whitespace or comment.
+  <#WSC: <WS> | <SINGLE_LINE_COMMENT> >
+}
+
+// Main tokens */
+
+TOKEN:
+{
+   // Includes # for relative URIs
+   <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"]>
+}
+
+// -------------------------------------------------
+// Keyworks : includes operators that are words and should be
+// before general things like IDENTIFIER which swallow almost
+// anything
+
+TOKEN : { <KW_A:  "a" > }
+
+TOKEN [IGNORE_CASE] :
+{
+// Prologue
+   < 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" >
+
+// Dataset
+|  < NAMED:       "named" >
+|  < FROM:        "from" >
+
+// Graph pattern operators 
+|  < WHERE:       "where" >
+|  < AND:         "and" >
+|  < GRAPH:       "graph" >
+|  < OPTIONAL:    "optional" >
+|  < UNION:       "union" >
+|  < MINUS_P:     "minus" >
+|  < BIND:        "bind" >
+|  < SERVICE:     "service" >
+
+#ifdef ARQ
+|  < LET:         "let" >
+|  < FETCH:       "fetch" >
+#endif
+|  < 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" >
+
+// Expression operators
+|  < BOUND:       "bound" >
+|  < COALESCE:    "coalesce" >
+|  < IN:          "in" >
+|  < IF:          "if" >
+|  < BNODE:       "bnode" >
+|  < IRI:         "iri" >
+|  < URI:         "uri" >
+
+#ifdef ARQ
+|  < CAST:        "cast" >
+|  < CALL:        "call" >
+|  < MULTI:       "multi" >
+|  < SHORTEST:    "shortest" >
+#endif
+
+|  < 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" >
+#ifdef ARQ
+|  < VERSION:     "VERSION" >
+#endif
+
+| < MD5:          "MD5" >
+| < SHA1:         "SHA1" >
+| < SHA224:       "SHA224" >
+| < SHA256:       "SHA256" >
+| < SHA384:       "SHA384" >
+| < SHA512:       "SHA512" >
+
+|  < TRUE:        "true" >
+|  < FALSE:       "false" >
+}
+
+#if defined(UPDATE)
+// SPARQL/Update parts.
+
+TOKEN [IGNORE_CASE] :
+{
+  < DATA:	      "data" >
+| < INSERT:       "insert">
+| < DELETE:       "delete" >
+
+| < INSERT_DATA:  <INSERT> (<WSC>)* <DATA> >
+| < DELETE_DATA:  <DELETE> (<WSC>)* <DATA> >
+| < DELETE_WHERE: <DELETE> (<WSC>)* <WHERE> >
+
+#ifdef ARQ_UPDATE
+| < MODIFY:      "modify">
+#endif
+| < 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" >
+
+//| < BEGIN:       "begin" >
+//| < COMMIT:      "commit" >
+//| < ABORT:       "abort" >
+}
+#endif
+
+// -------------------------------------------------
+
+TOKEN :
+{
+  < #DIGITS: (["0"-"9"])+>
+| < INTEGER: <DIGITS> >
+//| < DECIMAL: ( <DIGITS> "." (<DIGITS>)* | "." <DIGITS> ) >
+| < DECIMAL: (<DIGITS>)? "." <DIGITS> >
+| < 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> >
+
+| < INTEGER_NEGATIVE: <MINUS> <INTEGER> >
+| < DECIMAL_NEGATIVE: <MINUS> <DECIMAL> >
+| < DOUBLE_NEGATIVE:  <MINUS> <DOUBLE> >
+
+| < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+| < #QUOTE_3D: "\"\"\"">
+| < #QUOTE_3S: "'''">
+| <ECHAR: "\\" ( "t"|"b"|"n"|"r"|"f"|"\\"|"\""|"'") >
+| < STRING_LITERAL1: 
+      // Single quoted string
+      "'" ( (~["'","\\","\n","\r"]) | <ECHAR> )* "'" > 
+| < STRING_LITERAL2:
+    // Double quoted string
+      "\"" ( (~["\"","\\","\n","\r"]) | <ECHAR> )* "\"" >
+| < STRING_LITERAL_LONG1:
+     <QUOTE_3S> 
+      ( ("'" | "''")? (~["'","\\"] | <ECHAR> ))*
+     <QUOTE_3S> >
+
+| < STRING_LITERAL_LONG2: 
+     <QUOTE_3D> 
+      ( ("\"" | "\"\"")? (~["\"","\\"] | <ECHAR> ))*
+     <QUOTE_3D> >
+}
+
+TOKEN :
+{
+  < 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> >
+
+| < SEMICOLON: ";" >
+| < 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: "@">
+#ifdef ARQ
+| < ASSIGN:     ":=">
+#endif
+
+// Path related
+| < VBAR:     "|" >
+| < CARAT:    "^" >
+| < FPATH:    "->" >
+| < RPATH:    "<-" >
+| < QMARK:    "?" >
+}
+
+// See XML chars.txt for notes
+
+TOKEN:
+{
+  // XML 1.1 NCNameStartChar without "_"
+  <#PN_CHARS_BASE:
+          ["A"-"Z"] | ["a"-"z"] |
+          ["\u00C0"-"\u00D6"] | ["\u00D8"-"\u00F6"] | ["\u00F8"-"\u02FF"] |
+          ["\u0370"-"\u037D"] | ["\u037F"-"\u1FFF"] |
+          ["\u200C"-"\u200D"] | ["\u2070"-"\u218F"] | ["\u2C00"-"\u2FEF"] |
+          ["\u3001"-"\uD7FF"] | ["\uF900"-"\uFFFD"] 
+          >
+          // [#x10000-#xEFFFF]
+|
+  // With underscore
+  <#PN_CHARS_U: <PN_CHARS_BASE> | "_" >
+|
+  <#PN_CHARS: (<PN_CHARS_U> | "-" | ["0"-"9"] | "\u00B7" |
+              ["\u0300"-"\u036F"] | ["\u203F"-"\u2040"] ) >
+|
+  // No leading "_", no trailing ".", can have dot inside prefix name.
+  <#PN_PREFIX: <PN_CHARS_BASE> ((<PN_CHARS>|".")* <PN_CHARS>)?  >
+|
+  // Local part.
+  <#PN_LOCAL: (<PN_CHARS_U> | ":" | ["0"-"9"] | <PLX> ) 
+              ( (<PN_CHARS> | "." |":" | <PLX> )* 
+                (<PN_CHARS> | ":" | <PLX>) )?  >
+|
+  <#VARNAME: ( <PN_CHARS_U> | ["0"-"9"] )
+             ( <PN_CHARS_U> | ["0"-"9"] | "\u00B7" |
+               ["\u0300"-"\u036F"] | ["\u203F"-"\u2040"] )* >
+|
+  // Align with QueryParseBase unescapePName.
+  < #PN_LOCAL_ESC: "\\" 
+          ( "_" | 
+            "~" | "." | "-" | "!" | "$" | "&" | "'" | 
+           "(" | ")" | "*" | "+" | "," | ";" | "=" | 
+           "/" | "?" | "#" | "@" | "%" ) >
+|
+  <#PLX:  <PERCENT> | <PN_LOCAL_ESC> >
+|
+  < #HEX: ["0"-"9"] | ["A"-"F"] | ["a"-"f"] >
+|
+  < #PERCENT: "%" <HEX> <HEX> >
+}
+
+// Catch-all tokens.  Must be last.  
+// Any non-whitespace.  Causes a parser exception, rather than a
+// token manager error (which hides the line numbers).
+TOKEN:
+{
+  <#UNKNOWN: (~[" ","\t","\n","\r","\f" ])+ >
+}
+
+/*
+# Local Variables:
+# tab-width: 4
+# indent-tabs-mode: nil
+# comment-default-style: "//"
+# End:
+*/

Copied: jena/trunk/jena-arq/Grammar/Final/sparql_11-final.jj (from r1392224, jena/trunk/jena-arq/Grammar/sparql_11-final.jj)
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/Grammar/Final/sparql_11-final.jj?p2=jena/trunk/jena-arq/Grammar/Final/sparql_11-final.jj&p1=jena/trunk/jena-arq/Grammar/sparql_11-final.jj&r1=1392224&r2=1396509&rev=1396509&view=diff
==============================================================================
--- jena/trunk/jena-arq/Grammar/sparql_11-final.jj (original)
+++ jena/trunk/jena-arq/Grammar/Final/sparql_11-final.jj Wed Oct 10 08:22:45 2012
@@ -247,7 +247,10 @@ String SourceSelector() : { String iri ;
 }
 void WhereClause() : { Element el ; }
 {
-   (<WHERE>)? el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
+   (<WHERE>)?
+   { startWherePattern() ; }
+   el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
+   { finishWherePattern() ; }
 }
 void SolutionModifier() : { }
 {
@@ -444,13 +447,18 @@ Update DeleteWhere() : { QuadAcc qp = ne
 Update Modify() : { Element el ; String iri = null ;
                     UpdateModify up = new UpdateModify() ; }
 {
+  { startModifyUpdate() ; }
   ( <WITH> iri = iri() { Node n = createNode(iri) ; up.setWithIRI(n) ; } )?
   ( DeleteClause(up) ( InsertClause(up) )?
   | InsertClause(up)
   )
   (UsingClause(up))*
+  // WHERE is mandatory here.
   <WHERE>
+  { startWherePattern() ; }
   el = GroupGraphPattern() { up.setElement(el) ; }
+  { finishWherePattern() ; }
+  { finishModifyUpdate() ; }
   { return up ; }
 }
 void DeleteClause(UpdateModify up) : { QuadAcc qp = up.getDeleteAcc() ; Token t ;}