[Mulgara-svn] r1219 - in trunk/src/jar/querylang: . java/org/mulgara/sparql java/org/mulgara/sparql/parser java/org/mulgara/sparql/parser/cst javacc javacc/org javacc/org/mulgara javacc/org/mulgara/sparql javacc/org/mulgara/sparql/parser

pag at mulgara.org pag at mulgara.org
Mon Sep 1 04:54:05 UTC 2008


Author: pag
Date: 2008-08-31 21:54:04 -0700 (Sun, 31 Aug 2008)
New Revision: 1219

Added:
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryStructure.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryStructureImpl.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryType.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/VarNameAllocator.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractBinaryOperator.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractNaryOperator.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractUnaryOperator.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AndExpression.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AnnotatedNode.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/ArgList.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AssociativeNumericOpExpression.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BasicGraphPattern.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicBound.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicDatatype.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsBlank.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsIri.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsLiteral.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsUri.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicLang.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicLangMatches.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicRegEx.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicSameTerm.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicStr.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BlankNode.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BooleanLiteral.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BuiltInCall.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/DecimalLiteral.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Divide.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/DoubleLiteral.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/EmptyGraphPattern.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Equals.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Expression.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/FunctionCall.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphList.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternConjunction.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternDisjunction.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternOptional.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GreaterThan.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GreaterThanEqual.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GroupGraphPattern.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IntegerLiteral.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LessThan.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LessThanEqual.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LogicExpression.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Minus.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Multiply.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Nil.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Node.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Not.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NotEquals.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NumericExpression.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NumericLiteral.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/OrExpression.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Ordering.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Plus.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/PrimaryExpression.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/PropertyList.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/RDFLiteral.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/RelationalExpression.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Triple.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/TripleList.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/UnaryMinus.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/UnaryPlus.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Variable.java
   trunk/src/jar/querylang/javacc/
   trunk/src/jar/querylang/javacc/org/
   trunk/src/jar/querylang/javacc/org/mulgara/
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/ParseException.java
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SimpleCharStream.java
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.java
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.jj
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParserConstants.java
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParserTokenManager.java
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/Token.java
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/TokenMgrError.java
Modified:
   trunk/src/jar/querylang/build.xml
Log:
Imported the sparql parser library

Modified: trunk/src/jar/querylang/build.xml
===================================================================
--- trunk/src/jar/querylang/build.xml	2008-09-01 04:19:15 UTC (rev 1218)
+++ trunk/src/jar/querylang/build.xml	2008-09-01 04:54:04 UTC (rev 1219)
@@ -49,15 +49,18 @@
     <mkdir dir="${querylang.obj.dir}/java"/>
   </target>
 
-  <target name="gen-querylang-parser" depends="-querylang-prepare, querylang-parser-uptodate, sablecc" unless="querylang-parser-uptodate">
+  <target name="gen-tql-parser" depends="-querylang-prepare, querylang-parser-uptodate, sablecc" unless="tql-parser-uptodate">
     <sablecc src="${querylang.src.dir}/sablecc" outputdirectory="${querylang.obj.dir}/java">
       <include name="itql.grammar"/>
     </sablecc>
-    <!-- TODO: Add in JavaCC generation -->
   </target>
 
+  <target name="gen-sparql-parser" description="Build the JavaCC generated files">
+    <javacc target="${querylang.src.dir}/javacc/org/mulgara/sparql/parser/SparqlParser.jj" javacchome="${lib.dir}" />
+  </target>
+
   <target name="querylang-parser-uptodate" depends="-prepare-build">
-    <uptodate property="querylang-parser-uptodate"
+    <uptodate property="tql-parser-uptodate"
         targetfile="${obj.dir}/jar/querylang/java/org/mulgara/itql/analysis/DepthFirstAdapter.java">
       <srcfiles dir="${querylang.src.dir}/sablecc" includes="itql.grammar"/>
     </uptodate>
@@ -72,9 +75,10 @@
     </uptodate>
   </target>
 
-  <target name="querylang-compile" depends="-querylang-prepare, gen-querylang-parser, driver-jar" description="Compiles all query language related files included generated source code">
+  <target name="querylang-compile" depends="-querylang-prepare, gen-tql-parser, gen-sparql-parser, driver-jar" description="Compiles all query language related files included generated source code">
     <copy todir="${querylang.obj.dir}/java/" preservelastmodified="yes">
       <fileset dir="${querylang.src.dir}/java/" includes="**/*.java"/>
+      <fileset dir="${querylang.src.dir}/javacc/" includes="**/*.java"/>
     </copy>
     <antcall target="-querylang-token-build-label"/>
     <javac destdir="${querylang.obj.dir}/classes" debug="on" deprecation="on" source="1.5" classpathref="querylang-classpath">
@@ -144,7 +148,6 @@
       <zipfileset src="${lib.dir}/${emory-util.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/${jta.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/${axis.jar}" excludes="META-INF/**"/>
-      <zipfileset src="${lib.dir}/${mulgara-sparql.jar}" excludes="META-INF/**"/>
     </jar>
   </target>
 

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryStructure.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryStructure.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryStructure.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2008 Fedora Commons
+ * 
+ * Licensed 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 org.mulgara.sparql.parser;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.mulgara.sparql.parser.cst.GroupGraphPattern;
+import org.mulgara.sparql.parser.cst.IRIReference;
+import org.mulgara.sparql.parser.cst.Node;
+import org.mulgara.sparql.parser.cst.Ordering;
+import org.mulgara.sparql.parser.cst.TripleList;
+import org.mulgara.sparql.parser.cst.Variable;
+
+/**
+ * <p>CST data for SPARQL query parsing.</p>
+ * <p>This interface serves as the main external interface for this library, and provides
+ * access to all the structure of a parsed query. Some of the structural elements include
+ * substructures from the {@link org.mulgara.sparql.parser.cst} packace, which need to be
+ * interrogated as well.</p>
+ * <p>This interface is returned by calling the static {@link SparqlParser#parse(String)}
+ * method on {@link SparqlParser}.</p>
+ *
+ * @created February 28, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public interface QueryStructure {
+
+  /**
+   * <p>Retrieve the base namespace URI for the query.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#QSynIRI">SPARQL Query Language: 4.1.1 Syntax for IRIs</a>
+   * @return The base namespace URI.
+   */
+  public URI getBase();
+
+  /**
+   * <p>Gets the list of prefix mappings.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#QSynIRI">SPARQL Query Language: 4.1.1 Syntax for IRIs</a>
+   * @return a map of prefix labels to namespace URIs
+   */
+  public Map<String, URI> getPrefixes();
+
+  /**
+   * <p>Gets the type of the query.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#QueryForms">SPARQL Query Language: 10 Query Forms</a>
+   * @return The query type, encoded by the {@link QueryType} enumeration.
+   */
+  public QueryType getType();
+
+  /**
+   * <p>Tests if this query should return distinct results.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#modDistinct">SPARQL Query Language: 9.3.1 DISTINCT</a>
+   * @return <code>true</code> if the query should return distinct results.
+   */
+  public boolean isDistinct();
+
+  /**
+   * <p>Tests if this query should return reduced results.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#modReduced">SPARQL Query Language: 9.3.2 REDUCED</a>
+   * @return <code>true</code> if the query should return reduced results.
+   */
+  public boolean isReduced();
+
+  /**
+   * <p>Tests if this query returns all its variables, and not a projected subset.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#solutionModifiers">SPARQL Query Language: 9 Solution Sequences and Modifiers</a>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#modProjection">9.1 Projection</a>
+   * @return <code>true</code> if the query should return all variables.
+   */
+  public boolean isSelectAll();
+
+  /**
+   * <p>Gets the list of {@link org.mulgara.sparql.parser.cst.Variable}s to project
+   * the solution to. If {@link #isSelectAll()} returns <code>true</code> then this
+   * list will contain all the variables from the query.</p>
+   * <p>The returned list contains Node and not Variable to permit implementations
+   * to modify the parser to return non-Variables, such as
+   * {@link org.mulgara.sparql.parser.cst.IRIReference}s.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#modProjection">SPARQL Query Language: 9.1 Projection</a>
+   * @return A list of elements to return from the query.
+   */
+  public List<? extends Node> getSelection();
+
+  /**
+   * <p>Gets the template for constructing triples in a CONSTRUCT query.
+   * Each triple in the template list can contain IRIReferences, Literals, Blank Nodes
+   * and Variables, where all but the variables will be constructed directly, while the
+   * variables will be bound from the results coming from the rest of the query. Refer
+   * to the {@link org.mulgara.sparql.parser.cst.TripleList} and 
+   * {@link org.mulgara.sparql.parser.cst.Triple} classes for details on the structure
+   * of the template list.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#construct">SPARQL Query Language: 10.2 CONSTRUCT</a>
+   * @return A list of triples containing a template for new triples to be constructed.
+   */
+  public TripleList getConstructTemplate();
+
+  /**
+   * <p>Gets the list of default graphs, as specified by the FROM clauses. If there were no
+   * FROM clauses, then this list will be empty, indicating that the system should
+   * query the system default graph.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#specifyingDataset">SPARQL Query Language: 8.2 Specifying RDF Datasets</a>
+   * @return A list of graph IRIs. This list may be empty, indicating the use of the
+   * system default graph.
+   */
+  public List<IRIReference> getDefaultFroms();
+
+  /**
+   * <p>Gets the list of named graphs, as specified by the FROM NAMED clauses. The contents
+   * of this list specify which graphs may be referred to (either explicitly, or by
+   * variable) by any GRAPH modifiers to patterns in the WHERE clause.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#specifyingDataset">SPARQL Query Language: 8.2 Specifying RDF Datasets</a>
+   * <p>For details on how the GRAPH modifier refers to members from this named graph list:</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#queryDataset">8.3 Querying the Dataset</a>
+   * @return The list of IRIs in the named graph list.
+   */
+  public List<IRIReference> getNamedFroms();
+
+  /**
+   * <p>Gets the WHERE clause for the query. This is the structure that defines all the
+   * processing work required to get the results.</p>
+   * <p>The returned structure is a tree of {@link org.mulgara.sparql.parser.cst.GroupGraphPattern}
+   * elements, where all the leaves are {@link org.mulgara.sparql.parser.cst.Triple}s. Each
+   * node in this tree may optionally have a FILTER applied to it.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#GraphPattern">SPARQL Query Language: 5 Graph Patterns</a>
+   * @return The {@link org.mulgara.sparql.parser.cst.GroupGraphPattern} representing the
+   *         WHERE clause for this query.
+   */
+  public GroupGraphPattern getWhereClause();
+
+  /**
+   * <p>Gets the list of required orderings. Orderings appear in the list in decreasing
+   * ordering priority. An empty list means that the implementation is free to return
+   * results in any order. This order should be consistent to allow a paged result
+   * when issuing similar consecutive queries using differing OFFSET/LIMIT values, though
+   * the specification explicitly disavows the need for this.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#modOrderBy">SPARQL Query Language: 9.1 ORDER BY</a>
+   * @return A list of {@link org.mulgara.sparql.parser.cst.Ordering} values, in order of priority.
+   */
+  public List<Ordering> getOrderings();
+
+  /**
+   * <p>Gets the numeric offset of the first row to be returned by the query. The default
+   * is 0 offset, meaning to start at the beginning.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#modResultLimit">SPARQL Query Language: 9.4 OFFSET</a>
+   * @return The number of rows to skip in the result. A value of zero does nothing.
+   */
+  public int getOffset();
+
+  /**
+   * <p>Gets the maximum number of results to be returned by the query. A limit of -1 means
+   * no limit at all (return all results). A limit of 0 means that no results should
+   * be returned.</p>
+   * @see <a href="http://www.w3.org/TR/rdf-sparql-query/#modResultLimit">SPARQL Query Language: 9.5 LIMIT</a>
+   * @return The maximum number of rows to returned by the query.
+   */
+  public int getLimit();
+
+  /**
+   * Retrieve all the variables used anywhere in the query.
+   * @return A Collection of variables used in this query.
+   */
+  public Collection<Variable> getAllVariables();
+
+  /**
+   * Emits a string representation of the original query.
+   * @see java.lang.Object#toString()
+   * @return A string containing an equivalent query to the original. This is unlikely
+   *         to be exactly the same string as the original query.
+   */
+  public String toString();
+
+}
\ No newline at end of file

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryStructureImpl.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryStructureImpl.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryStructureImpl.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2008 Fedora Commons
+ * 
+ * Licensed 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 org.mulgara.sparql.parser;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.mulgara.sparql.parser.cst.BlankNode;
+import org.mulgara.sparql.parser.cst.Expression;
+import org.mulgara.sparql.parser.cst.GraphList;
+import org.mulgara.sparql.parser.cst.GroupGraphPattern;
+import org.mulgara.sparql.parser.cst.IRIReference;
+import org.mulgara.sparql.parser.cst.Node;
+import org.mulgara.sparql.parser.cst.Ordering;
+import org.mulgara.sparql.parser.cst.TripleList;
+import org.mulgara.sparql.parser.cst.Variable;
+
+/**
+ * <p>CST data for SPARQL query parsing.</p>
+ * <p>This class contains the entire structure for a query, and implements the main
+ * external interface for this library. All elements of a query are found in here after
+ * a query has been parsed.</p>
+ * <p>This class is not public, as only the {@link org.mulgara.sparql.parser.SparqlParser}
+ * class generated by JavaCC is expected to create instances it. Instances of this
+ * class are returned by calling the static {@link SparqlParser#parse(String)}
+ * method on {@link SparqlParser}.</p>
+ *
+ * @created January 15, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+class QueryStructureImpl implements QueryStructure {
+  
+  /** The base namespace */
+  private URI base = URI.create("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
+  
+  /** The prefixes to use in the query */
+  private Map<String,URI> prefixes = new HashMap<String,URI>();
+
+  /** The type of query */
+  private QueryType type;
+
+  /** Distinct results in the query */
+  private boolean distinct = false;
+
+  /** Reduced results from the query */
+  private boolean reduced = false;
+
+  /** The query selection */
+  private List<Node> selection = new ArrayList<Node>();
+
+  /** Indicates if all variables should be selected */
+  private boolean selectAll = false;
+
+  /** A template used for building triples in a CONSTRUCT query */
+  private TripleList constructTemplate = null;
+
+  /** The graphs to get data from by default */
+  private List<IRIReference> defaultFroms = new ArrayList<IRIReference>();
+
+  /** The names graphs to get data from by use of the GRAPH keyword */
+  private List<IRIReference> namedFroms = new ArrayList<IRIReference>();
+
+  /** The WHERE clause */
+  private GroupGraphPattern whereClause = null;
+
+  /** Order info on the results */
+  private List<Ordering> orderings = new ArrayList<Ordering>();
+
+  /** Result offset. 0 means no offset. */
+  private int offset = 0;
+
+  /** Result limit. -1 means no limit. */
+  private int limit = -1;
+
+  /** Remembers all used variables by name */
+  private Map<String,Variable> variables = new LinkedHashMap<String,Variable>();
+
+  /**
+   * Blank node allocator. Blank nodes are like variables,
+   * but with generated names and they cannot be selected.
+   */
+  private VarNameAllocator bNodeAllocator = new VarNameAllocator();
+
+  /** A RegEx pattern for separating out a namespace from a prefixed name. */
+  private static final Pattern pnamePattern = Pattern.compile("([^:]*):(.*)");
+
+  /**
+   * Creates a string representation of the prefix map. Used for debugging.
+   * @return A list of namespace/uri pairs.
+   */
+  private String prologToString() {
+    StringBuffer s = new StringBuffer();
+    if (base != null) s.append("BASE <").append(base).append(">\n");
+    for (Map.Entry<String,URI> p: prefixes.entrySet()) s.append("PREFIX ").append(p.getKey()).append(": <").append(p.getValue()).append(">\n");
+    return s.toString();
+  }
+
+  ///////////////////////////////////////////////////////////////
+  // Package scope methods.  Used to build the structure.
+  ///////////////////////////////////////////////////////////////
+
+  /**
+   * Sets the base namespace for the query.
+   * @param base The URI for the base namespace.
+   */
+  void setBase(URI base) { this.base = base; }
+
+  /**
+   * Add a prefix to the list of prefix mappings.
+   * WARNING: Don't use a prefix with a common URL protocol, as this will result in
+   * unexpected substitutions!
+   * @param prefix The prefix to map
+   * @param namespace The namespace the prefix refers to
+   */
+  void addPrefix(String prefix, URI namespace) { prefixes.put(prefix.substring(0, prefix.length() - 1), namespace); }
+
+  /**
+   * Set the type of query.
+   * @param type The type of this query:
+   */
+  void setType(QueryType type) { this.type = type; }
+
+  /**
+   * Sets this query to have Distinct results
+   */
+  void setDistinct() { distinct = true; }
+
+  /**
+   * Sets this query to have Reduced results
+   */
+  void setReduced() { reduced = true; }
+
+  /**
+   * Set this query to select all variables
+   */
+  void setSelectAll() {
+    // no variables should have been encountered yet
+    assert variables.isEmpty();
+    selectAll = true;
+  }
+
+  /**
+   * Adds a variable (or selectable expression) to be returned by the query.
+   * @param var The variable to add.
+   */
+  void addSelection(Node var) { selection.add(var); }
+
+  /**
+   * Set the template for triples to be created in a Construct query.
+   * @param template A template in the form of a list of triples.
+   */
+  void setConstructTemplate(TripleList template) {
+    assert type == QueryType.construct;
+    constructTemplate = template;
+  }
+
+  /**
+   * Adds a default graph to select from.
+   * @param g A graph to select from when not using a named graph.
+   */
+  void addDefaultFrom(IRIReference g) { defaultFroms.add(g); }
+
+  /**
+   * Adds a graph to the list of named graphs, making it available to be resolved
+   * against on patterns with a named graph.
+   * @param g The graph to add to the named graphs list.
+   */
+  void addNamedFrom(IRIReference g) { namedFroms.add(g); }
+
+  /**
+   * Sets the WHERE clause clause for this query.
+   * @param g The graph pattern to match against graphs to obtain results.
+   */
+  void setWhereClause(GroupGraphPattern g) { whereClause = g; }
+
+  /**
+   * Appends an ordering of results, based on an expression and a direction.
+   * NOTE: while the specification allows for arbitrary expressions here, we do not
+   *       expect to order by anything more complex than a variable.
+   * @param expr The expression (variable) to order by.
+   * @param ascending <code>true</code> if ordering is ascending, <code>false</code>
+   *        if ordering is descending.
+   */
+  void addOrdering(Expression expr, boolean ascending) { orderings.add(new Ordering(expr, ascending)); }
+
+  /**
+   * Sets the offset for the first returned result. Accepts a string, but this should be
+   * fine as the pattern matcher has already established that it is a valid number.
+   * @param o The numeric offset as a string. A value of "0" has no effect on the query.
+   */
+  void setOffset(String o) { offset = Integer.parseInt(o); }
+
+  /**
+   * Set the upper limit to the number of returned results. Accepts a string, but this
+   * should be fine as the pattern matcher has already established that it is a valid
+   * number.
+   * @param l The numeric limit as a string. A value of "0" will give an empty result from
+   *          the query, while a value of "-1" will allow all the results to be returned.
+   */
+  void setLimit(String l) { limit = Integer.parseInt(l); }
+
+  /**
+   * Factory method for {@link org.mulgara.sparql.parser.cst.Variable}s, returning only
+   * one variable for each unique name. After a variable is created for a name, any
+   * requests for a variable of that name will return the existing Variable instead of
+   * creating a new one.
+   * @param name The name of the variable, with either '?' or '$' prepended.
+   * @return A new variable with the requested name, or an existing variable if one
+   *         already existed with that name.
+   */
+  Variable newVariable(String name) {
+    // remove the variable identifier: ? or $
+    name = name.substring(1);
+    // look for an existing variable
+    if (variables.containsKey(name)) return variables.get(name);
+    // create and remember a new variable
+    Variable v = new Variable(name);
+    variables.put(name, v);
+    // selectAll should have been set by now if it is going to be
+    if (selectAll) selection.add(v);
+    return v;
+  }
+
+  /**
+   * Allocate a new anonymous blank node.
+   * @return A blank node with a random unique label.
+   */
+  BlankNode newBlankNode() {
+    return bNodeAllocator.allocate();
+  }
+  
+  /**
+   * Create a new {@link org.mulgara.sparql.parser.cst.IRIReference}.
+   * Tests to see if the IRI starts with a known namespace and performs a
+   * substitution if it does. Note that this implementation only accepts URIs,
+   * and not the more complete IRI.
+   * @param r The string containing the image of the IRI
+   * @return A new {@link org.mulgara.sparql.parser.cst.IRIReference} for the string image.
+   * @throws ParseException The r parameter was not a syntactically valid URI.
+   */
+  IRIReference newIRIRef(String r) throws ParseException {
+    return newPrefixedName(r);
+  }
+
+  /**
+   * Create a new IRI based on a prefixed name.Note that this implementation
+   * only accepts URIs, and not the more complete IRI.
+   * @param r The string containing the image of the IRI
+   * @returnA new {@link org.mulgara.sparql.parser.cst.IRIReference} for the string image.
+   * @throws ParseException The r parameter was not a syntactically valid URI.
+   */
+  IRIReference newPrefixedName(String r) throws ParseException {
+    // Create an IRI directly if the string does not start with a prefix
+    Matcher m = pnamePattern.matcher(r);
+    if (!m.matches()) {
+      // either a normal IRI, or one with a BASE
+      return isRelative(r) ? new IRIReference(base + r, "<" + r + ">") : new IRIReference(r);
+    }
+    // extract the prefix, and attempt to convert to a URI before creating the reference
+    URI ns = prefixes.get(m.group(1));
+    return ns == null ? new IRIReference(r) : new IRIReference(ns.toString() + m.group(2), r);
+  }
+
+  /**
+   * Gets a new RDF list for the current graph pattern.
+   * @return A new list object for generating triples for an RDF Collection.
+   */
+  GraphList newList() { return new GraphList(bNodeAllocator); }
+
+  /**
+   * Tests if the string for a URI is relative or absolute. The test is based on a scheme existing
+   * in the string, which in turn expects a : character to follow it. If there is no colon, then
+   * it is presumed to be relative. Otherwise, if there are special characters preceding the first
+   * colon these are presumed to not be in a scheme.
+   * @param u A string for a URI.
+   * @return <code>true</code> if the URI appears to be relative, <code>false</code> otherwise.
+   */
+  boolean isRelative(String u) {
+    int colon = u.indexOf(':');
+    if (colon < 0) return true;
+    for (int c = 0; c < colon; c++) {
+      // if there a non-alphanum characters then this is not a scheme, so the URI is relative
+      if (!Character.isLetterOrDigit(u.charAt(c))) return true;
+    }
+    // found a (probably) valid scheme, so the URI is absolute
+    return false;
+  }
+
+  ///////////////////////////////////////////////////////////////////////////////////
+  // Public interfaces for accessing this structure.
+  ///////////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getBase()
+   */
+  public URI getBase() { return base; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getPrefixes()
+   */
+  public Map<String,URI> getPrefixes() { return prefixes; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getType()
+   */
+  public QueryType getType() { return type; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#isDistinct()
+   */
+  public boolean isDistinct() { return distinct; }
+ 
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#isReduced()
+   */
+  public boolean isReduced() { return reduced; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#isSelectAll()
+   */
+  public boolean isSelectAll() { return selectAll; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getSelection()
+   */
+  public List<? extends Node> getSelection() { return selection; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getConstructTemplate()
+   */
+  public TripleList getConstructTemplate() { return constructTemplate; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getDefaultFroms()
+   */
+  public List<IRIReference> getDefaultFroms() { return defaultFroms; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getNamedFroms()
+   */
+  public List<IRIReference> getNamedFroms() { return namedFroms; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getWhereClause()
+   */
+  public GroupGraphPattern getWhereClause() { return whereClause; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getOrderings()
+   */
+  public List<Ordering> getOrderings() { return orderings; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getOffset()
+   */
+  public int getOffset() { return offset; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getLimit()
+   */
+  public int getLimit() { return limit; }
+
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#getAllVariables()
+   */
+  public Collection<Variable> getAllVariables() { return variables.values(); }
+  
+  /**
+   * @see org.mulgara.sparql.parser.QueryStructure#toString()
+   */
+  public String toString() {
+    return prologToString() + type.toString(this);
+  }
+  
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryType.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryType.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryType.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2008 Fedora Commons
+ * 
+ * Licensed 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 org.mulgara.sparql.parser;
+
+import org.mulgara.sparql.parser.cst.IRIReference;
+import org.mulgara.sparql.parser.cst.Node;
+import org.mulgara.sparql.parser.cst.Ordering;
+import org.mulgara.sparql.parser.cst.TripleList;
+
+/**
+ * The various query types present in SPARQL.
+ * Each type also includes the {@link #toString(QueryStructure)} method to convert
+ * a {@link QueryStructure} to an equivalent form of the query.
+ *
+ * @created January 25, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public enum QueryType {
+  
+  select {
+    public String toString(QueryStructure qs) {
+      StringBuffer s = new StringBuffer("SELECT ");
+      if (qs.isDistinct()) s.append("DISTINCT\n");
+      if (qs.isReduced()) s.append("REDUCED\n");
+      appendSelection(s, qs);
+      appendDataset(s, qs);
+      appendWhere(s, qs);
+      appendModifier(s, qs);
+      return s.toString();
+    }
+  },
+
+  construct {
+    public String toString(QueryStructure qs) {
+      StringBuffer s = new StringBuffer("CONSTRUCT\n");
+      TripleList template = qs.getConstructTemplate();
+      s.append("{ ");
+      if (template != null) s.append(template.getImage());
+      s.append("}\n");
+      appendDataset(s, qs);
+      appendWhere(s, qs);
+      appendModifier(s, qs);
+      return s.toString();
+    }
+  },
+
+  describe {
+    public String toString(QueryStructure qs) {
+      StringBuffer s = new StringBuffer("DESCRIBE\n");
+      appendSelection(s, qs);
+      appendDataset(s, qs);
+      appendWhere(s, qs);
+      appendModifier(s, qs);
+      return s.toString();
+    }
+  },
+
+  ask {
+    public String toString(QueryStructure qs) {
+      StringBuffer s = new StringBuffer("ASK\n");
+      appendDataset(s, qs);
+      appendWhere(s, qs);
+      return s.toString();
+    }
+  };
+
+  /**
+   * Converts a {@link QueryStructure} to a string that is equivalent to the original query
+   * @param qs The structure to convert
+   * @return A string containing a query equivalent to the one used to build qs.
+   */
+  public abstract String toString(QueryStructure qs);
+  
+  /**
+   * Internal method to add the dataset clause.
+   * @param s The {@link java.lang.StringBuffer} to append to.
+   * @param qs The {@link QueryStructure} to read the dataset clause from.
+   */
+  void appendDataset(StringBuffer s, QueryStructure qs) {
+    for (IRIReference f: qs.getDefaultFroms()) s.append("FROM ").append(f.getImage()).append("\n");
+    for (IRIReference f: qs.getNamedFroms()) s.append("FROM NAMED ").append(f.getImage()).append("\n");
+  }
+  
+  /**
+   * Internal method to add the where clause.
+   * @param s The {@link java.lang.StringBuffer} to append to.
+   * @param qs The {@link QueryStructure} to read the where clause from.
+   */
+  void appendWhere(StringBuffer s, QueryStructure qs) {
+    s.append("WHERE { ").append(qs.getWhereClause().getImage()).append(" }\n");
+  }
+
+  /**
+   * Internal method to add the solution modifier clause.
+   * @param s The {@link java.lang.StringBuffer} to append to.
+   * @param qs The {@link QueryStructure} to read the solution modifier clause from.
+   */
+  void appendModifier(StringBuffer s, QueryStructure qs) {
+    for (Ordering o: qs.getOrderings()) s.append("ORDER BY ").append(o.getImage()).append("\n");
+    if (qs.getOffset() > 0) s.append("OFFSET ").append(qs.getOffset()).append("\n");
+    if (qs.getLimit() >= 0) s.append("LIMIT ").append(qs.getLimit()).append("\n");
+  }
+  
+  /**
+   * Internal method to add the query selection.
+   * @param s The {@link java.lang.StringBuffer} to append to.
+   * @param qs The {@link QueryStructure} to read the query selection from.
+   */
+  void appendSelection(StringBuffer s, QueryStructure qs) {
+    if (qs.isSelectAll()) s.append("*");
+    else for (Node n: qs.getSelection()) s.append(n.getImage()).append(" ");
+    s.append("\n");
+  }
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/VarNameAllocator.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/VarNameAllocator.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/VarNameAllocator.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2008 Fedora Commons
+ * 
+ * Licensed 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 org.mulgara.sparql.parser;
+
+import org.mulgara.sparql.parser.cst.BlankNode;
+
+/**
+ * This class allocated names for anonymous variables used for indicating blank nodes in queries.
+ *
+ * @created Feb 19, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class VarNameAllocator {
+
+  /** A marker for variable names that is not valid in any query syntax */
+  private static final String ANON_MARKER = "*";
+
+  /** An incrementing value to make names unique */
+  private int counter = 0;
+
+  /**
+   * Create a unique BlankNode.
+   * @return The new blank node.
+   */
+  public BlankNode allocate() {
+    return new BlankNode(ANON_MARKER + counter++);
+  }
+
+  /**
+   * Get the name for a new blank node.
+   * @return A unique name for a blank node.
+   */
+  public String allocateName() {
+    return ANON_MARKER + counter++;
+  }
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractBinaryOperator.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractBinaryOperator.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractBinaryOperator.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Absract class to provide basic functionality of an N-ary, associative operation.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public abstract class AbstractBinaryOperator implements Expression {
+
+  /** The first operand */
+  protected Expression op1;
+
+  /** The second operand */
+  protected Expression op2;
+  
+  /**
+   * Creates the operation.
+   */
+  public AbstractBinaryOperator(Expression op1, Expression op2) {
+    this.op1 = op1;
+    this.op2 = op2;
+  }
+
+  /**
+   * @return the first operand for this operation
+   */
+  public Expression getFirstOperand() {
+    return op1;
+  }
+
+  /**
+   * @return the second operand for this operation
+   */
+  public Expression getSecondOperand() {
+    return op2;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   * Used for Prefix notation. Override for infix notation.
+   */
+  public String getImage() {
+    StringBuffer result = new StringBuffer(getOperatorString());
+    result.append(op1.getImage());
+    result.append(", ");
+    result.append(op2.getImage());
+    result.append(")");
+    return result.toString();
+  }
+
+  /**
+   * A string representation of the operator for this operator
+   * @return The operator as a string
+   */
+  protected abstract String getOperatorString();
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractNaryOperator.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractNaryOperator.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractNaryOperator.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.List;
+
+
+/**
+ * Absract class to provide basic functionality of an N-ary, associative operation.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public abstract class AbstractNaryOperator<T extends Expression> implements Expression {
+
+  /** The list of expression operands */
+  protected List<T> operands;
+
+  /**
+   * @return the list of operands for this operation
+   */
+  public List<T> getOperands() {
+    return operands;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    StringBuffer result = new StringBuffer();
+    boolean first = true;
+    for (Expression e: operands) {
+      if (!first) result.append(" ").append(getOperatorString()).append(" ");
+      else first = false;
+      
+      boolean bracket = e instanceof PrimaryExpression;
+      if (bracket) result.append("(");
+      result.append(e);
+      if (bracket) result.append(")");
+    }
+    return result.toString();
+  }
+
+  /**
+   * A string representation of the operator for this relation
+   * @return The operator as a string
+   */
+  protected abstract String getOperatorString();
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractUnaryOperator.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractUnaryOperator.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractUnaryOperator.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+/**
+ * Absract class to provide basic functionality of an N-ary, associative operation.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public abstract class AbstractUnaryOperator<T extends Expression> implements Expression {
+
+  /** The expression operand */
+  protected T operand;
+
+  /**
+   * @return the list of operands for this operation
+   */
+  public T getOperand() {
+    return operand;
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AndExpression.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AndExpression.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AndExpression.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+
+
+/**
+ * Represents an n-ary AND expression.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class AndExpression extends AbstractNaryOperator<LogicExpression> implements Node, LogicExpression {
+  
+  /**
+   *  Creates an AND expression from a pair of expressions
+   *  @param e1 An existing AND expression
+   *  @param e2 The expression to append to the AND
+   */
+  public AndExpression(Expression e1, Expression e2) {
+    this((LogicExpression)e1, (LogicExpression)e2);
+  }
+
+  /**
+   *  Creates an AND expression from a pair of expressions,
+   *  appending the RHS if the LHS is already an AND expression
+   *  @param e1 The LHS expression
+   *  @param e2 The RHS expression
+   */
+  public AndExpression(LogicExpression e1, LogicExpression e2) {
+    if (e1 instanceof AndExpression) {
+      operands = new ArrayList<LogicExpression>(((AndExpression)e1).operands);
+      assert operands.size() > 2;
+    } else {
+      operands = new ArrayList<LogicExpression>();
+      operands.add(e1);
+    }
+    operands.add(e2);
+  }
+
+  /**
+   * A string representation of the operator for this operator
+   * @return The operator as a string
+   */
+  protected String getOperatorString() {
+    return "AND";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AnnotatedNode.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AnnotatedNode.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AnnotatedNode.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * A query syntax node, which has a series of triples related to it.
+ * The related triples should be incorporated into a conjunction with anything
+ * that uses the initial node.
+ * An example is an RDF collection, where the first node represents the entire
+ * list, and the list is built from triples.
+ *
+ * @created Feb 26, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class AnnotatedNode implements Node {
+  
+  /** The node of interest */
+  private Node subject;
+  
+  /** A list of triples annotating the subject */
+  private TripleList annotation;
+
+  /**
+   * Create an annotated subject node.
+   * @param subject The subject of interest.
+   * @param triples A list of triples annotating that node.
+   */
+  public AnnotatedNode(Node subject, TripleList triples) {
+    this.subject = subject;
+    annotation = triples;
+    // could assert that subject appears somewhere in triples
+  }
+
+  /**
+   * Create an annotated subject node from a collection.
+   * @param list The RDF collection.
+   */
+  public AnnotatedNode(GraphList list) {
+    TripleList tList = list.asTripleList();
+    subject = tList.getSubject();
+    annotation = tList;
+  }
+
+  /**
+   * Create an annotated subject node from a collection.
+   * @param list The RDF collection.
+   */
+  public AnnotatedNode(Node subject, PropertyList properties) {
+    this.subject = subject;
+    annotation = new TripleList();
+    for (PropertyList.Property p: properties) {
+      annotation.add(new Triple(subject, p.getPredicate(), p.getObject()));
+    }
+  }
+
+  /**
+   * @return The subject of interest.
+   */
+  public Node getSubject() {
+    return subject;
+  }
+
+  /**
+   * @return The list of triples annotating the subject node.
+   */
+  public TripleList getAnnotation() {
+    return annotation;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return annotation.getImage();
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/ArgList.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/ArgList.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/ArgList.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+
+
+/**
+ * Represents a list of expressions, used for arguments to a function call.
+ *
+ * @created Feb 12, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class ArgList extends ArrayList<Expression> implements Node {
+
+  /** ID for serialization */
+  private static final long serialVersionUID = -5665518307457225791L;
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    StringBuffer result = new StringBuffer("(");
+    boolean first = true;
+    for (Expression e: this) {
+      if (!first) result.append(", ");
+      else first = false;
+      result.append(e.getImage());
+    }
+    result.append(")");
+    return result.toString();
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AssociativeNumericOpExpression.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AssociativeNumericOpExpression.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AssociativeNumericOpExpression.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Describes an operator expression that is associative.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public abstract class AssociativeNumericOpExpression extends AbstractNaryOperator<NumericExpression> implements NumericExpression {
+
+  /**
+   * Creates the binary relation
+   * @param lhs The left hand side of the operation
+   * @param rhs The right hand side of the operation
+   */
+  public AssociativeNumericOpExpression(NumericExpression lhs, NumericExpression rhs) {
+    assert !this.getClass().isInstance(lhs);
+    operands = new ArrayList<NumericExpression>();
+    operands.add(lhs);
+    operands.add(rhs);
+  }
+
+  /**
+   * Creates an operation to be expanded on
+   * @param operands The operand list to initialize with
+   */
+  public AssociativeNumericOpExpression(List<NumericExpression> operands) {
+    assert operands.size() >= 2;
+    this.operands = operands;
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BasicGraphPattern.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BasicGraphPattern.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BasicGraphPattern.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * This class contains some simple common functionality for data that appears
+ * in graph patterns.
+ *
+ * @created Feb 19, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public abstract class BasicGraphPattern implements GroupGraphPattern {
+  
+  /** The graph that this pattern is to match on */
+  Expression graph;
+
+  /** The filter to apply to this pattern */
+  Expression filter;
+
+  /**
+   * Creates the basic pattern, with no specific graph.
+   */
+  BasicGraphPattern() {
+    graph = null;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.GroupGraphPattern#getElements()
+   */
+  public abstract List<? extends GroupGraphPattern> getElements();
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.GroupGraphPattern#getAllTriples()
+   */
+  public List<GroupGraphPattern> getAllTriples() {
+    // accumulate all triples into a single list
+    List<GroupGraphPattern> result = new ArrayList<GroupGraphPattern>();
+    for (GroupGraphPattern p: getElements()) result.addAll(p.getAllTriples());
+    return result;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.GroupGraphPattern#setGraph(org.mulgara.sparql.parser.cst.Expression)
+   */
+  public void setGraph(Expression g) {
+    graph = g;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.GroupGraphPattern#getGraph()
+   */
+  public Expression getGraph() {
+    return graph;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.GroupGraphPattern#setFilter(org.mulgara.sparql.parser.cst.Expression)
+   */
+  public void setFilter(Expression f) {
+    filter = f;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.GroupGraphPattern#getFilter()
+   */
+  public Expression getFilter() {
+    return filter;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public abstract String getImage();
+  
+  /**
+   * Update the pattern with any GRAPH or FILTER patterns
+   * @param image The original image of this graph pattern
+   * @return An updated string for this pattern
+   */
+  String addPatterns(String image) {
+    if (graph != null) image = " GRAPH " + graph.getImage() + " {" + image + " }";
+    if (filter != null) image += " FILTER (" + filter.getImage() + ")";
+    return image;
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicBound.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicBound.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicBound.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the BOUND function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicBound extends AbstractUnaryOperator<Variable> implements BuiltInCall, LogicExpression {
+
+  /**
+   * Construct an invocation to the BOUND function
+   * @param operand The operand for the function
+   */
+  public BicBound(Variable operand) {
+    this.operand = operand;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "BOUND(" + operand.getImage() + ")";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicDatatype.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicDatatype.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicDatatype.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the DATATYPE function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicDatatype extends AbstractUnaryOperator<Expression> implements BuiltInCall, LogicExpression {
+
+  /**
+   * Construct an invocation to the DATATYPE function
+   * @param operand The operand for the function
+   */
+  public BicDatatype(Expression operand) {
+    this.operand = operand;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "DATATYPE(" + operand.getImage() + ")";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsBlank.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsBlank.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsBlank.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the IS_BLANK function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicIsBlank extends AbstractUnaryOperator<Expression> implements BuiltInCall, LogicExpression {
+
+  /**
+   * Construct an invocation to the IS_BLANK function
+   * @param operand The operand for the function
+   */
+  public BicIsBlank(Expression operand) {
+    this.operand = operand;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "IS_BLANK(" + operand.getImage() + ")";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsIri.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsIri.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsIri.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the IS_IRI function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicIsIri extends AbstractUnaryOperator<Expression> implements BuiltInCall, LogicExpression {
+
+  /**
+   * Construct an invocation to the IS_IRI function
+   * @param operand The operand for the function
+   */
+  public BicIsIri(Expression operand) {
+    this.operand = operand;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "IS_IRI(" + operand.getImage() + ")";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsLiteral.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsLiteral.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsLiteral.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the IS_LITERAL function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicIsLiteral extends AbstractUnaryOperator<Expression> implements BuiltInCall, LogicExpression {
+
+  /**
+   * Construct an invocation to the IS_LITERAL function
+   * @param operand The operand for the function
+   */
+  public BicIsLiteral(Expression operand) {
+    this.operand = operand;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "IS_LITERAL(" + operand.getImage() + ")";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsUri.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsUri.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicIsUri.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the IS_URI function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicIsUri extends AbstractUnaryOperator<Expression> implements BuiltInCall, LogicExpression {
+
+  /**
+   * Construct an invocation to the IS_URI function
+   * @param operand The operand for the function
+   */
+  public BicIsUri(Expression operand) {
+    this.operand = operand;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "IS_URI(" + operand.getImage() + ")";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicLang.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicLang.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicLang.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the LANG function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicLang extends AbstractUnaryOperator<Expression> implements BuiltInCall, LogicExpression {
+
+  /**
+   * Construct an invocation to the STR function
+   * @param operand The operand for the function
+   */
+  public BicLang(Expression operand) {
+    this.operand = operand;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "LANG(" + operand.getImage() + ")";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicLangMatches.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicLangMatches.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicLangMatches.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the LANGMATCHES function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicLangMatches extends AbstractBinaryOperator implements BuiltInCall, LogicExpression {
+
+  /**
+   * Construct an invocation to the STR function
+   * @param operand The operand for the function
+   */
+  public BicLangMatches(Expression op1, Expression op2) {
+    super(op1, op2);
+  }
+
+  @Override
+  protected String getOperatorString() {
+    return "LANGMATCHES";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicRegEx.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicRegEx.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicRegEx.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the REGEX function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicRegEx implements BuiltInCall, LogicExpression {
+  /** The expression being tested */
+  private Expression expr;
+
+  /** The pattern to test for */
+  private Expression pattern;
+
+  /** The flags to use for matching */
+  private Expression flags;
+
+  /** The parameter separator in the string represenation */
+  private static final String COMMA = ", ";
+
+  /**
+   * Construct an invocation to the REGEX function
+   * @param expr The expression to test
+   * @param pattern The pattern to test for
+   * @param flags The flags to use for matching
+   */
+  public BicRegEx(Expression expr, Expression pattern, Expression flags) {
+    this.expr = expr;
+    this.pattern = pattern;
+    this.flags = flags;
+  }
+
+  /**
+   * @return the expr
+   */
+  public Expression getExpr() {
+    return expr;
+  }
+
+  /**
+   * @return the pattern
+   */
+  public Expression getPattern() {
+    return pattern;
+  }
+
+  /**
+   * @return the flags
+   */
+  public Expression getFlags() {
+    return flags;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    StringBuffer result = new StringBuffer("REGEX(");
+    result.append(expr.getImage()).append(COMMA);
+    result.append(pattern.getImage()).append(COMMA);
+    result.append(flags.getImage()).append(")");
+    return result.toString();
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicSameTerm.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicSameTerm.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicSameTerm.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the SAME_TERM function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicSameTerm extends AbstractBinaryOperator implements BuiltInCall, LogicExpression {
+
+  /**
+   * Construct an invocation to the STR function
+   * @param operand The operand for the function
+   */
+  public BicSameTerm(Expression op1, Expression op2) {
+    super(op1, op2);
+  }
+
+  @Override
+  protected String getOperatorString() {
+    return "SAME_TERM";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicStr.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicStr.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BicStr.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An invocation to the STR function
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BicStr extends AbstractUnaryOperator<Expression> implements BuiltInCall, LogicExpression {
+
+  /**
+   * Construct an invocation to the STR function
+   * @param operand The operand for the function
+   */
+  public BicStr(Expression operand) {
+    this.operand = operand;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "STR(" + operand.getImage() + ")";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BlankNode.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BlankNode.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BlankNode.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Object for representing RDF blank nodes.
+ * This will be emitted as a variable for use in queries.
+ *
+ * @created February 11, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BlankNode implements Node {
+
+  private String label;
+
+  /**
+   * Creates a blank node with a given label
+   * @param s The string containing the label
+   */
+  public BlankNode(String s) {
+    label = s;
+  }
+
+  /**
+   * Get the label for this node.
+   * @return 
+   */
+  public String getLabel() {
+    return label;
+  }
+
+  /**
+   * Get a printable representation of this class.
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return label;
+  }
+
+  /**
+   * Check if this BlankNode is equivalent to another.
+   * @param o The other BlankNode
+   * @return <code>true</code> iff o is a BlankNode, and has the same label.
+   * @see java.lang.Object#equals(java.lang.Object)
+   */
+  public boolean equals(Object o) {
+    return (o instanceof BlankNode && ((BlankNode)o).label.equals(label));
+  }
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BooleanLiteral.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BooleanLiteral.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BooleanLiteral.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * 
+ *
+ * @created Feb 11, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class BooleanLiteral implements PrimaryExpression, LogicExpression {
+
+  /** Constant value for <code>true</code> */
+  public static final BooleanLiteral TRUE = new BooleanLiteral(true);
+
+  /** Constant value for <code>false</code> */
+  public static final BooleanLiteral FALSE = new BooleanLiteral(false);
+
+  /** The internal value. */
+  private boolean value;
+  
+  /**
+   * Private constructor.
+   * @param value
+   */
+  private BooleanLiteral(boolean value) {
+    this.value = value;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return Boolean.toString(value);
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BuiltInCall.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BuiltInCall.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/BuiltInCall.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * 
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public interface BuiltInCall extends Expression {
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/DecimalLiteral.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/DecimalLiteral.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/DecimalLiteral.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Represents a Decimal literal number.
+ *
+ * @created Feb 11, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class DecimalLiteral implements NumericLiteral {
+
+  /** The value of this literal. */
+  private float value;
+
+  /**
+   * Constructs the literal from a string image.
+   * @param value The string image of the value for this literal
+   */
+  public DecimalLiteral(String s) {
+    this.value = Float.parseFloat(s);
+  }
+
+  /**
+   * Constructs the literal.
+   * @param value The floating point value for this literal
+   */
+  public DecimalLiteral(float value) {
+    this.value = value;
+  }
+  
+  /**
+   * Retrieve the value as a generic Number.
+   * @return A Number object containing the value.
+   */
+  public Number getValue() {
+    return new Float(value);
+  }
+
+  /**
+   * Retrieve the value as a raw type.
+   * @return The internal value.
+   */
+  public float getFloat() {
+    return value;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return Float.toString(value);
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Divide.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Divide.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Divide.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+
+
+/**
+ * A division operator expression.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class Divide extends AssociativeNumericOpExpression {
+
+  /**
+   * Creates the division operation
+   * @param lhs The first expression
+   * @param rhs The expression to be added to the lhs
+   */
+  public Divide(Expression lhs, Expression rhs) {
+    this((NumericExpression)lhs, (NumericExpression)rhs);
+  }
+
+  /**
+   * Creates the division operation
+   * @param lhs The first expression
+   * @param rhs The expression to be added to the lhs
+   */
+  public Divide(NumericExpression lhs, NumericExpression rhs) {
+    super(new ArrayList<NumericExpression>());
+    if (lhs instanceof Divide) {
+      operands.addAll(((Divide)lhs).operands);
+    } else {
+      operands.add(lhs);
+    }
+    operands.add(rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.AbstractNaryOperator#getOperatorString()
+   */
+  @Override
+  protected String getOperatorString() {
+    return "/";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/DoubleLiteral.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/DoubleLiteral.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/DoubleLiteral.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Represents a Double precision literal number.
+ *
+ * @created Feb 11, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class DoubleLiteral implements NumericLiteral {
+
+  /** The value of this literal. */
+  private double value;
+
+  /**
+   * Constructs the literal from a string image.
+   * @param value The string image of the value for this literal
+   */
+  public DoubleLiteral(String s) {
+    this.value = Double.parseDouble(s);
+  }
+
+  /**
+   * Constructs the literal.
+   * @param value The double value for this literal
+   */
+  public DoubleLiteral(double value) {
+    this.value = value;
+  }
+  
+  /**
+   * Retrieve the value as a generic Number.
+   * @return A Number object containing the value.
+   */
+  public Number getValue() {
+    return new Double(value);
+  }
+
+  /**
+   * Retrieve the value as a raw type.
+   * @return The internal value.
+   */
+  public double getDouble() {
+    return value;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return Double.toString(value);
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/EmptyGraphPattern.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/EmptyGraphPattern.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/EmptyGraphPattern.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.List;
+import java.util.Collections;
+
+
+/**
+ * Represents an empty pattern.  Matches everything.
+ *
+ * @created Feb 20, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class EmptyGraphPattern extends BasicGraphPattern {
+
+  /**
+   * Package scope constructor
+   */
+  EmptyGraphPattern() {
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.BasicGraphPattern#getElements()
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public List<GroupGraphPattern> getElements() {
+    return (List<GroupGraphPattern>)Collections.EMPTY_LIST;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.BasicGraphPattern#getImage()
+   */
+  @Override
+  public String getImage() {
+    return addPatterns(" { }");
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Equals.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Equals.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Equals.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An equality relation
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class Equals extends RelationalExpression {
+
+  /**
+   * Create an equality relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public Equals(Expression lhs, Expression rhs) {
+    super((NumericExpression)lhs, (NumericExpression)rhs);
+  }
+
+  /**
+   * Create an equality relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public Equals(NumericExpression lhs, NumericExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.RelationalExpression#getOperator()
+   */
+  public String getOperator() {
+    return " = ";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Expression.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Expression.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Expression.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Used for expressions in functions.
+ *
+ * @created Feb 12, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public interface Expression extends Node {
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/FunctionCall.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/FunctionCall.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/FunctionCall.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * 
+ *
+ * @created Feb 12, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class FunctionCall implements PrimaryExpression {
+
+  /** The name of this function */
+  private IRIReference name;
+
+  /** The arguments used in this invokation */
+  private ArgList args;
+  
+  /**
+   * Constructs the function representation, with its name and arguments.
+   * @param name The function name
+   * @param args The function arguments
+   */
+  public FunctionCall(IRIReference name, ArgList args) {
+    this.name = name;
+    this.args = args;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return null;
+  }
+
+  
+  /**
+   * @return the name
+   */
+  public IRIReference getName() {
+    return name;
+  }
+
+  
+  /**
+   * @return the args
+   */
+  public ArgList getArgs() {
+    return args;
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphList.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphList.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphList.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.mulgara.sparql.parser.VarNameAllocator;
+
+import static org.mulgara.sparql.parser.cst.IRIReference.*;
+
+/**
+ * Represents an RDF "Collection" list.
+ *
+ * @created Feb 15, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class GraphList implements Node {
+
+  /** The list of nodes that is being represented */
+  List<Node> nodes = new LinkedList<Node>();
+  
+  /** The variable name allocator for generating blank nodes */
+  VarNameAllocator bNodeAllocator;
+
+  public GraphList(VarNameAllocator allocator) {
+    bNodeAllocator = allocator;    
+  }
+
+  /**
+   * Appends a new node to the end of this list.
+   * @param n The node to append
+   */
+  public void add(Node n) {
+    nodes.add(n);
+  }
+
+  /**
+   * Return a Collections list of triples
+   * @return a list of Triple
+   */
+  public TripleList asTripleList() {
+    List<Triple> result = new LinkedList<Triple>();
+    Node lastNode = null;
+    for (Node n: nodes) {
+      Node currentNode = bNodeAllocator.allocate();
+      if (lastNode != null) result.add(new Triple(lastNode, RDF_REST, currentNode));
+      result.add(new Triple(currentNode, RDF_FIRST, n));
+      lastNode = currentNode;
+    }
+    if (lastNode != null) result.add(new Triple(lastNode, RDF_REST, RDF_NIL));
+    return new TripleList(result);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    StringBuffer result = new StringBuffer("( ");
+    boolean first = true;
+    for (Node n: nodes) {
+      if (!first) result.append(", "); else first = false;
+      result.append(n.getImage());
+    }
+    result.append(" )");
+    return result.toString();
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternConjunction.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternConjunction.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternConjunction.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Represents a conjunction of patterns.
+ *
+ * @created Feb 19, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class GraphPatternConjunction extends BasicGraphPattern {
+
+  /** The patterns to join */
+  List<GroupGraphPattern> patterns = new ArrayList<GroupGraphPattern>();
+
+  /**
+   * Build a conjunction out of two GroupGraphPatterns.
+   * @param lhs The first GroupGraphPattern
+   * @param rhs The second GroupGraphPattern
+   */
+  public GraphPatternConjunction(GroupGraphPattern lhs, GroupGraphPattern rhs) {
+    if (lhs instanceof GraphPatternConjunction && lhs.getFilter() == null && lhs.getGraph() == null) {
+      patterns.addAll(((GraphPatternConjunction)lhs).patterns);
+    } else patterns.add(lhs);
+
+    if (rhs instanceof GraphPatternConjunction && rhs.getFilter() == null && rhs.getGraph() == null) {
+      patterns.addAll(((GraphPatternConjunction)rhs).patterns);
+    } else patterns.add(rhs);
+  }
+
+  /**
+   * Build a conjunction by expanding on an existing conjunction.
+   * @param lhs The existing conjunction
+   * @param rhs The pattern to be appended to the lhs
+   */
+  public GraphPatternConjunction(GraphPatternConjunction lhs, GroupGraphPattern rhs) {
+    patterns.addAll(lhs.patterns);
+    patterns.add(rhs);
+  }
+
+  /**
+   * Build a conjunction by prepending on an existing conjunction.
+   * @param lhs The existing conjunction
+   * @param rhs The pattern to be appended to the lhs
+   */
+  public GraphPatternConjunction(GroupGraphPattern lhs, GraphPatternConjunction rhs) {
+    patterns.add(lhs);
+    patterns.addAll(rhs.patterns);
+  }
+
+  /**
+   * Build a conjunction from two conjunctions.  Slightly better than
+   *   @see #GraphPatternConjunction(GroupGraphPattern, GroupGraphPattern)
+   * @param lhs The first conjunction
+   * @param rhs The pattern to be appended to the lhs
+   */
+  public GraphPatternConjunction(GraphPatternConjunction lhs, GraphPatternConjunction rhs) {
+    patterns.addAll(lhs.patterns);
+    patterns.addAll(rhs.patterns);
+  }
+
+  /**
+   * Build a conjunction from a triples list.
+   * @param triples The list to turn into a conjunction
+   */
+  public GraphPatternConjunction(TripleList triples) {
+    patterns.addAll(triples.getElements());
+  }
+
+  /**
+   * Build a conjunction by appending a list of triples to an existing conjunction
+   * @param lhs The first conjunction
+   * @param triples The list to be appended
+   */
+  public GraphPatternConjunction(GraphPatternConjunction lhs, TripleList triples) {
+    patterns.addAll(lhs.patterns);
+    patterns.addAll(triples.getElements());
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.BasicGraphPattern#getElements()
+   */
+  @Override
+  public List<GroupGraphPattern> getElements() {
+    return patterns;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.BasicGraphPattern#getImage()
+   */
+  @Override
+  public String getImage() {
+    StringBuffer result = new StringBuffer();
+    result.append(patterns.get(0).getImage());
+    for (int i = 1; i < patterns.size(); i++) result.append(" . ").append(patterns.get(i).getImage());
+    return addPatterns(result.toString());
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternDisjunction.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternDisjunction.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternDisjunction.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Represents a disjunction of patterns.
+ *
+ * @created Feb 19, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class GraphPatternDisjunction extends BasicGraphPattern {
+
+  /** The patterns to union */
+  List<GroupGraphPattern> patterns = new ArrayList<GroupGraphPattern>();
+
+  /**
+   * Build a disjunction out of two GroupGraphPatterns.
+   * @param lhs The first GroupGraphPattern
+   * @param rhs The second GroupGraphPattern
+   */
+  public GraphPatternDisjunction(GroupGraphPattern lhs, GroupGraphPattern rhs) {
+    patterns.add(lhs);
+    patterns.add(rhs);
+  }
+
+  /**
+   * Build a disjunction by expanding on an existing disjunction.
+   * @param lhs The existing disjunction
+   * @param rhs The pattern to be appended to the lhs
+   */
+  public GraphPatternDisjunction(GraphPatternDisjunction lhs, GroupGraphPattern rhs) {
+    patterns.addAll(lhs.patterns);
+    patterns.add(rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.BasicGraphPattern#getElements()
+   */
+  @Override
+  public List<GroupGraphPattern> getElements() {
+    return patterns;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.BasicGraphPattern#getImage()
+   */
+  @Override
+  public String getImage() {
+    StringBuffer result = new StringBuffer(" {");
+    result.append(patterns.get(0).getImage()).append(" }");
+    for (int i = 1; i < patterns.size(); i++) result.append(" UNION { ").append(patterns.get(i).getImage()).append(" }");
+    return addPatterns(result.toString());
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternOptional.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternOptional.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GraphPatternOptional.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ * Represents an optional join between patterns.
+ *
+ * @created Feb 20, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class GraphPatternOptional extends BasicGraphPattern {
+
+  /** The main pattern */
+  GroupGraphPattern main;
+
+  /** The optional pattern */
+  GroupGraphPattern optional;
+
+  /**
+   * Build an optional join out of two GroupGraphPatterns.
+   * @param main The main pattern to be matched
+   * @param optional The pattern to be optionally matched
+   */
+  public GraphPatternOptional(GroupGraphPattern main, GroupGraphPattern optional) {
+    this.main = main;
+    this.optional = optional;
+  }
+
+  /**
+   * @return the main pattern
+   */
+  public GroupGraphPattern getMain() {
+    return main;
+  }
+
+  /**
+   * @return the optional pattern
+   */
+  public GroupGraphPattern getOptional() {
+    return optional;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.BasicGraphPattern#getElements()
+   */
+  @Override
+  public List<GroupGraphPattern> getElements() {
+    List<GroupGraphPattern> result = new LinkedList<GroupGraphPattern>();
+    result.add(main);
+    result.add(optional);
+    return result;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.BasicGraphPattern#getImage()
+   */
+  @Override
+  public String getImage() {
+    return addPatterns(main.getImage() + " OPTIONAL { " + optional.getImage() + " }");
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GreaterThan.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GreaterThan.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GreaterThan.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * A greater than relation
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class GreaterThan extends RelationalExpression {
+
+  /**
+   * Create a greater than relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public GreaterThan(Expression lhs, Expression rhs) {
+    super((NumericExpression)lhs, (NumericExpression)rhs);
+  }
+
+  /**
+   * Create a greater than relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public GreaterThan(NumericExpression lhs, NumericExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.RelationalExpression#getOperator()
+   */
+  public String getOperator() {
+    return " > ";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GreaterThanEqual.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GreaterThanEqual.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GreaterThanEqual.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * A greater than or equal to relation
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class GreaterThanEqual extends RelationalExpression {
+
+  /**
+   * Create a greater than or equal to relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public GreaterThanEqual(Expression lhs, Expression rhs) {
+    super((NumericExpression)lhs, (NumericExpression)rhs);
+  }
+
+  /**
+   * Create a greater than or equal to relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public GreaterThanEqual(NumericExpression lhs, NumericExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.RelationalExpression#getOperator()
+   */
+  public String getOperator() {
+    return " >= ";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GroupGraphPattern.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GroupGraphPattern.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/GroupGraphPattern.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.List;
+
+
+/**
+ * A group of triple patterns, ANDed together.
+ *
+ * @created Feb 18, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public interface GroupGraphPattern extends Node {
+  
+  /** A singleton empty graph pattern */
+  public static final GroupGraphPattern EMPTY = new EmptyGraphPattern();
+
+  /**
+   * Returns all the elements at this operational level
+   */
+  public List<? extends GroupGraphPattern> getElements();
+
+  /**
+   * Returns all the patterns flattened from this level down.
+   */
+  public List<GroupGraphPattern> getAllTriples();
+
+  /**
+   * Sets the graph for an expression
+   * @param g The graph the triples match on.
+   */
+  public void setGraph(Expression g);
+  
+  /**
+   * @return the graph for the pattern. Either a variable or an IRI
+   */
+  public Expression getGraph();
+
+  /**
+   * Sets the filter for a pattern
+   * @param f The filter for the matched triples
+   */
+  public void setFilter(Expression f);
+  
+  /**
+   * @return the filter for the pattern.
+   */
+  public Expression getFilter();
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.mulgara.sparql.parser.ParseException;
+
+
+/**
+ * Represents IRI references in SPARQL. This is a superset of URI references.
+ * For the moment, just wrap a URI, even though this doesn't meet the strict
+ * definition of an IRI.
+ *
+ * @created Feb 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class IRIReference implements Node, PrimaryExpression {
+  
+  /** The RDF namespace */
+  private static final String RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+
+  /** Constant IRI for RDF_TYPE */
+  public static final IRIReference RDF_TYPE = new IRIReference(URI.create(RDF_NS + "type"));
+
+  /** Constant IRI for RDF_FIRST */
+  public static final IRIReference RDF_FIRST = new IRIReference(URI.create(RDF_NS + "first"));
+
+  /** Constant IRI for RDF_REST */
+  public static final IRIReference RDF_REST = new IRIReference(URI.create(RDF_NS + "rest"));
+
+  /** Constant IRI for RDF_NIL */
+  public static final IRIReference RDF_NIL = new IRIReference(URI.create(RDF_NS + "nil"));
+
+  /** The internal URI value */
+  private URI uri;
+
+  /** The original text of the URI */
+  private String text;
+
+  /**
+   * Create an IRI reference from a URI.
+   * @param uri The URI referred to.
+   */
+  public IRIReference(URI uri) {
+    this.uri = uri;
+    text = "<" + uri.toString() + ">";
+  }
+
+  /**
+   * Create an IRI reference from a URI.
+   * @param uri The URI referred to.
+   */
+  public IRIReference(String uri) throws ParseException {
+    try {
+      this.uri = new URI(uri);
+    } catch (URISyntaxException e) {
+      throw new ParseException("Unable to create a URI from: " + uri);
+    }
+    text = "<" + uri + ">";
+  }
+
+  /**
+   * Create an IRI reference from a URI with an abbreviated namespace.
+   * @param uri The URI referred to.
+   * @param text The abbreviated form.
+   */
+  public IRIReference(String uri, String text) throws ParseException {
+    this(uri);
+    this.text = text;
+  }
+
+  /**
+   * @return the IRI value
+   */
+  public URI getUri() {
+    return uri;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return text;
+  }
+  
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IntegerLiteral.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IntegerLiteral.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IntegerLiteral.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Represents an Integer literal number.
+ *
+ * @created Feb 11, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class IntegerLiteral implements NumericLiteral {
+
+  /** The value of this literal. */
+  private int value;
+
+  /**
+   * Constructs the literal from a string image.
+   * @param value The string image of the value for this literal
+   */
+  public IntegerLiteral(String s) {
+    this.value = Integer.parseInt(s);
+  }
+
+  /**
+   * Constructs the literal.
+   * @param value The double value for this literal
+   */
+  public IntegerLiteral(int value) {
+    this.value = value;
+  }
+  
+  /**
+   * Retrieve the value as a generic Number.
+   * @return A Number object containing the value.
+   */
+  public Number getValue() {
+    return new Integer(value);
+  }
+
+  /**
+   * Retrieve the value as a raw type.
+   * @return The internal value.
+   */
+  public int getInteger() {
+    return value;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return Integer.toString(value);
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LessThan.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LessThan.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LessThan.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * A less than relation
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class LessThan extends RelationalExpression {
+
+  /**
+   * Create a less than relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public LessThan(Expression lhs, Expression rhs) {
+    super((NumericExpression)lhs, (NumericExpression)rhs);
+  }
+
+  /**
+   * Create a less than relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public LessThan(NumericExpression lhs, NumericExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.RelationalExpression#getOperator()
+   */
+  public String getOperator() {
+    return " < ";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LessThanEqual.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LessThanEqual.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LessThanEqual.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * A less than or equal to relation
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class LessThanEqual extends RelationalExpression {
+
+  /**
+   * Create a less than or equal relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public LessThanEqual(Expression lhs, Expression rhs) {
+    super((NumericExpression)lhs, (NumericExpression)rhs);
+  }
+
+  /**
+   * Create a less than or equal to relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public LessThanEqual(NumericExpression lhs, NumericExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.RelationalExpression#getOperator()
+   */
+  public String getOperator() {
+    return " <= ";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LogicExpression.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LogicExpression.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/LogicExpression.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Describes an expression the calculates to true or false with an Effective Boolean Value (EBV).
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public interface LogicExpression extends Expression {
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Minus.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Minus.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Minus.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+
+
+/**
+ * A subtraction operator expression.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class Minus extends AssociativeNumericOpExpression {
+
+  /**
+   * Creates the subtraction operation
+   * @param lhs The first expression
+   * @param rhs The expression to be subtracted from the lhs
+   */
+  public Minus(Expression lhs, Expression rhs) {
+    this((NumericExpression)lhs, (NumericExpression)rhs);
+  }
+
+  /**
+   * Creates the subtraction operation
+   * @param lhs The first expression
+   * @param rhs The expression to be subtracted from the lhs
+   */
+  public Minus(NumericExpression lhs, NumericExpression rhs) {
+    super(new ArrayList<NumericExpression>());
+    if (lhs instanceof Minus) {
+      operands.addAll(((Minus)lhs).operands);
+    } else {
+      operands.add(lhs);
+    }
+    operands.add(rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.AbstractNaryOperator#getOperatorString()
+   */
+  @Override
+  protected String getOperatorString() {
+    return "-";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Multiply.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Multiply.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Multiply.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+
+
+/**
+ * A multiplication operator expression.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class Multiply extends AssociativeNumericOpExpression {
+
+  /**
+   * Creates the multiplication operation
+   * @param lhs The first expression
+   * @param rhs The expression to be multiplied by the lhs
+   */
+  public Multiply(Expression lhs, Expression rhs) {
+    this((NumericExpression)lhs, (NumericExpression)rhs);
+  }
+
+  /**
+   * Creates the multiplication operation
+   * @param lhs The first expression
+   * @param rhs The expression to be multiplied by the lhs
+   */
+  public Multiply(NumericExpression lhs, NumericExpression rhs) {
+    super(new ArrayList<NumericExpression>());
+    if (lhs instanceof Multiply) {
+      operands.addAll(((Multiply)lhs).operands);
+    } else {
+      operands.add(lhs);
+    }
+    operands.add(rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.AbstractNaryOperator#getOperatorString()
+   */
+  @Override
+  protected String getOperatorString() {
+    return "*";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Nil.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Nil.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Nil.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Represents no data in a given position of a query
+ *
+ * @created Feb 21, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class Nil implements Node {
+
+  public static final Nil NIL_NODE = new Nil();
+  
+  /**
+   * Private constructor to enforce the singleton
+   */
+  private Nil() {
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "()";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Node.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Node.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Node.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * A syntactic node in a query.  Used for RDF nodes, as well as other SPARQL elements,
+ * such as variables.
+ *
+ * @created Feb 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public interface Node {
+
+  /**
+   * Gets an equivalent text representation for this node.
+   * @return Equivalent parsed text to what was used to created this node.
+   */
+  public String getImage();
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Not.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Not.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Not.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * A logic inversion unary operator.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class Not extends AbstractUnaryOperator<LogicExpression> implements LogicExpression {
+
+  /**
+   * Create the inversion operation
+   * @param operand The expression to invert.
+   */
+  public Not(Expression operand) {
+    assert operand instanceof LogicExpression;
+    this.operand = (LogicExpression)operand;
+  }
+  
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "!" + operand.getImage();
+  }
+  
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NotEquals.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NotEquals.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NotEquals.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * An inequality relation
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class NotEquals extends RelationalExpression {
+
+  /**
+   * Create an inequality relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public NotEquals(Expression lhs, Expression rhs) {
+    super((NumericExpression)lhs, (NumericExpression)rhs);
+  }
+
+  /**
+   * Create an inequality relation
+   * @param lhs The LHS of the relation
+   * @param rhs The LHS of the relation
+   */
+  public NotEquals(NumericExpression lhs, NumericExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.RelationalExpression#getOperator()
+   */
+  public String getOperator() {
+    return " != ";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NumericExpression.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NumericExpression.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NumericExpression.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Describes an expression that represents a numeric value.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public interface NumericExpression extends Expression, LogicExpression {
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NumericLiteral.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NumericLiteral.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/NumericLiteral.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Literal elements in the query.
+ *
+ * @created Feb 11, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public interface NumericLiteral extends PrimaryExpression, LogicExpression {
+
+  /**
+   * Retrieve the value as a generic Number.
+   * @return A Number object containing the value.
+   */
+  public Number getValue();
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/OrExpression.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/OrExpression.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/OrExpression.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+
+
+/**
+ * Represents an n-ary OR expression.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class OrExpression extends AbstractNaryOperator<LogicExpression> implements Node, LogicExpression {
+  
+  /**
+   *  Creates an OR expression from a pair of expressions
+   *  @param e1 The LHS expression
+   *  @param e2 The RHS expression
+   */
+  public OrExpression(Expression e1, Expression e2) {
+    this((LogicExpression)e1, (LogicExpression)e2);
+  }
+
+  /**
+   *  Creates an OR expression from a pair of expressions
+   *  @param e1 The LHS expression
+   *  @param e2 The RHS expression
+   */
+  public OrExpression(LogicExpression e1, LogicExpression e2) {
+    if (e1 instanceof OrExpression) {
+      operands = new ArrayList<LogicExpression>(((OrExpression)e1).operands);
+    } else {
+      operands = new ArrayList<LogicExpression>();
+      operands.add(e1);
+    }
+    operands.add(e2);
+  }
+
+  /**
+   * A string representation of the operator for this operator
+   * @return The operator as a string
+   */
+  protected String getOperatorString() {
+    return "OR";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Ordering.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Ordering.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Ordering.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Wraps ordering information.
+ *
+ * @created Feb 18, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class Ordering implements Node {
+
+  /** The expression that describes the ordering */
+  private Expression expr;
+
+  /** The direction of the data with respect to the expression. <code>true</code> for ascending. */
+  private boolean ascending;
+
+  /**
+   * Create an ordering on a given expression, in a specific direction.
+   * @param expr The expression to order with respect to.
+   * @param ascending <code>true</code> if ascending, <code>false</code> if descending.
+   */
+  public Ordering(Expression expr, boolean ascending) {
+    this.expr = expr;
+    this.ascending = ascending;
+  }
+  
+  /**
+   * Create an ordering, ascending on a given expression.
+   * @param expr The expression to order with respect to.
+   */
+  public Ordering(Expression expr) {
+    this(expr, true);
+  }
+
+  /**
+   * @return the expr
+   */
+  public Expression getExpr() {
+    return expr;
+  }
+
+  /**
+   * @return <code>true</code> if ascending, <code>false</code> if descending
+   */
+  public boolean isAscending() {
+    return ascending;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return direction() + expr.getImage();
+  }
+  
+  /**
+   * Gets a string representing the direction wrt the expression.
+   * @return The label for the direction.
+   */
+  private String direction() {
+    return ascending ? "ASC " : "DESC ";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Plus.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Plus.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Plus.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.ArrayList;
+
+
+/**
+ * An addition operator expression.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class Plus extends AssociativeNumericOpExpression {
+
+  /**
+   * Creates the addition operation
+   * @param lhs The first expression
+   * @param rhs The expression to be added to the lhs
+   */
+  public Plus(Expression lhs, Expression rhs) {
+    this((NumericExpression)lhs, (NumericExpression)rhs);
+  }
+
+  /**
+   * Creates the addition operation
+   * @param lhs The first expression
+   * @param rhs The expression to be added to the lhs
+   */
+  public Plus(NumericExpression lhs, NumericExpression rhs) {
+    super(new ArrayList<NumericExpression>());
+    if (lhs instanceof Plus) {
+      operands.addAll(((Plus)lhs).operands);
+    } else {
+      operands.add(lhs);
+    }
+    operands.add(rhs);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.AbstractNaryOperator#getOperatorString()
+   */
+  @Override
+  protected String getOperatorString() {
+    return "+";
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/PrimaryExpression.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/PrimaryExpression.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/PrimaryExpression.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Designates the most basic atomic expressions.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public interface PrimaryExpression extends NumericExpression {
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/PropertyList.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/PropertyList.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/PropertyList.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.List;
+import java.util.LinkedList;
+
+/**
+ * Represents a list of properties for a subject.
+ *
+ * @created Feb 26, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class PropertyList extends LinkedList<PropertyList.Property> implements Node {
+
+  /** Serialization ID */
+  private static final long serialVersionUID = -83780094455353423L;
+  
+  /**
+   * Adds a new Property to the list.  This creates a new entry for each property/object pair.
+   * @param property The name of the property
+   * @param objects a list of objects for the property
+   */
+  public void add(Node property, List<Node> objects) {
+    for (Node o: objects) add(new Property(property, o));
+  }
+
+  /**
+   * Retrieves the internal list.
+   * @return The property list
+   */
+  public List<Property> getElements() {
+    return this;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    StringBuffer sb = new StringBuffer(" ");
+    for (Property p: this) sb.append(p.getPredicate()).append(" ").append(p.getObject()).append(" ; ");
+    return sb.toString();
+  }
+
+  public class Property {
+    /** The name of the property */
+    private Node predicate;
+    
+    /** The value of the property */
+    private Node object;
+    
+    /**
+     * Creates a new predicate/object pair
+     * @param predicate The name of the property
+     * @param object The value of the property
+     */
+    public Property(Node predicate, Node object) {
+      this.predicate = predicate;
+      this.object = object;
+    }
+    
+    /**
+     * @return The predicate of this pair
+     */
+    public Node getPredicate() {
+      return predicate;
+    }
+    
+    /**
+     * @return The value of this pair
+     */
+    public Node getObject() {
+      return object;
+    }
+  }
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/RDFLiteral.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/RDFLiteral.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/RDFLiteral.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Object for representing RDF literals.
+ *
+ * @created February 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class RDFLiteral implements Node, PrimaryExpression, LogicExpression {
+
+  /** The string data for this literal */
+  private String value;
+
+  /** The datatype */
+  private IRIReference datatype;
+
+  /** The language code */
+  private String language;
+  
+  /** Characters that get escaped for printing */
+  private static final HashMap<String,String> escapeMap = new HashMap<String,String>();
+  static {
+    // escape the following: tbnrf\"'
+    escapeMap.put("\\t", "\\\\t");
+    escapeMap.put("\b", "\\\\b");
+    escapeMap.put("\\n", "\\\\n");
+    escapeMap.put("\\r", "\\\\r");
+    escapeMap.put("\\f", "\\\\f");
+    escapeMap.put("\\\\", "\\\\\\\\");
+    escapeMap.put("\"", "\\\\\"");
+    escapeMap.put("'", "\\\\'");
+  }
+
+
+  /**
+   * Constructor for an untyped literal.
+   * @param value The literal data.
+   */
+  public RDFLiteral(String value) {
+    this.value = unescape(value);
+    this.datatype = null;
+    this.language = null;
+  }
+
+  /**
+   * Constructor for a typed literal.
+   * @param value The literal data.
+   * @param datatype The type of the literal.
+   */
+  public RDFLiteral(String value, IRIReference datatype) {
+    this.value = unescape(value);
+    this.datatype = datatype;
+    this.language = null;
+  }
+
+  /**
+   * Constructor for a typed literal.
+   * @param value The literal data.
+   * @param datatype The type of the literal.
+   */
+  public RDFLiteral(String value, String language) {
+    this.value = unescape(value);
+    this.datatype = null;
+    setLanguage(language);
+  }
+
+  /**
+   * Gets the string representation of the literal - regardless of datatype.
+   * @return the string representation of the value of this literal
+   */
+  public String getValue() {
+    return value;
+  }
+
+  /**
+   * Gets the datatype for the literal.
+   * @return the datatype
+   */
+  public IRIReference getDatatype() {
+    return datatype;
+  }
+
+  /**
+   * @param datatype the datatype to set
+   */
+  public void setDatatype(IRIReference datatype) {
+    this.datatype = datatype;
+  }
+
+  /**
+   * Gets the language code.
+   * @return the language
+   */
+  public String getLanguage() {
+    return language;
+  }
+
+  /**
+   * @param language the language to set
+   */
+  public void setLanguage(String language) {
+    if (language.charAt(0) == '@') language = language.substring(1);
+    this.language = language;
+  }
+
+  /**
+   * Indicates that the literal has a datatype.
+   * @return <code>true</code> if the literal is typed.
+   */
+  public boolean isTyped() {
+    return datatype != null;
+  }
+  
+  /**
+   * Indicates that the literal has a language code.
+   * @return <code>true</code> if the literal has a language code.
+   */
+  public boolean isLanguageCoded() {
+    return language != null;
+  }
+
+  /**
+   * Convert an escaped string into it's normal form
+   * @param s The string to convert
+   * @return The unescaped version of the string.
+   */
+  private static String unescape(String s) {
+    for (Map.Entry<String,String> escapeEntry: escapeMap.entrySet()) {
+      s = s.replaceAll(escapeEntry.getValue(), escapeEntry.getKey());
+    }
+    return s;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    if (isTyped()) return "'" + escapedValue() + "'^^" + datatype.toString();
+    if (isLanguageCoded()) return "'" + escapedValue() + "'@" + language;
+    else return "'" + escapedValue() + "'";
+  }
+
+  /**
+   * Escape the characters in the value of a literal for printing
+   * @return The literal value, with escaped characters.
+   */
+  private String escapedValue() {
+    String escaped = value;
+    for (Map.Entry<String,String> escapeEntry: escapeMap.entrySet()) {
+      escaped = escaped.replaceAll(escapeEntry.getKey(), escapeEntry.getValue());
+    }
+    return "'" + escaped + "'";
+  }
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/RelationalExpression.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/RelationalExpression.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/RelationalExpression.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Describes an expression that represents a binary relation.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public abstract class RelationalExpression implements LogicExpression {
+  /** The left hand side of this binary expression */
+  private Expression lhs;
+
+  /** The right hand side of this binary expression */
+  private Expression rhs;
+
+  /**
+   * Creates the binary relation
+   * @param lhs The left hand side of the relation
+   * @param rhs The right hand side of the relation
+   */
+  public RelationalExpression(NumericExpression lhs, NumericExpression rhs) {
+    this.lhs = lhs;
+    this.rhs = rhs;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return lhs.getImage() + getOperator() + rhs.getImage();
+  }
+
+  /**
+   * @return the lhs
+   */
+  public Expression getLhs() {
+    return lhs;
+  }
+
+  
+  /**
+   * @return the rhs
+   */
+  public Expression getRhs() {
+    return rhs;
+  }
+
+  /**
+   * A string representation of the operator for this relation
+   * @return The operator as a string, including spaces if desired
+   */
+  protected abstract String getOperator();
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Triple.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Triple.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Triple.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+ * Represents the standard subject/predicate/object of a triple.
+ *
+ * @created Feb 18, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class Triple extends BasicGraphPattern {
+
+  /** First element of a triple */
+  private Node subject;
+
+  /** Second element of a triple */
+  private Node predicate;
+
+  /** Third element of a triple */
+  private Node object;
+
+  public Triple(Node s, Node p, Node o) {
+    subject = s;
+    predicate = p;
+    object = o;
+  }
+
+  /**
+   * @return the subject
+   */
+  public Node getSubject() {
+    return subject;
+  }
+
+  /**
+   * @return the predicate
+   */
+  public Node getPredicate() {
+    return predicate;
+  }
+
+  /**
+   * @return the object
+   */
+  public Node getObject() {
+    return object;
+  }
+
+  /**
+   * Returns this object as a list.
+   * @see org.mulgara.sparql.parser.cst.GroupGraphPattern#getElements()
+   */
+  @Override
+  public List<GroupGraphPattern> getElements() {
+    return Collections.singletonList((GroupGraphPattern)this);
+  }
+
+  /**
+   * Returns this object as a list.
+   * @see org.mulgara.sparql.parser.cst.GroupGraphPattern#getAllTriples()
+   */
+  @Override
+  public List<GroupGraphPattern> getAllTriples() {
+    return Collections.singletonList((GroupGraphPattern)this);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    StringBuffer result = new StringBuffer(subject.getImage());
+    result.append(" ").append(predicate.getImage()).append(" ").append(object.getImage());
+    return addPatterns(result.toString());
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/TripleList.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/TripleList.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/TripleList.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ * Represents a list of triples to be eventually put together in a conjunction.
+ * The first subject in this list may be considered significant.
+ *
+ * @created Feb 26, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class TripleList extends BasicGraphPattern {
+
+  /** The list of triples */
+  private List<Triple> triples;
+
+  /**
+   * Default constructor, creating an empty list.
+   */
+  public TripleList() {
+    triples = new LinkedList<Triple>();
+  }
+
+  /**
+   * Build a list of triples about a common subject
+   * @param subject The subject of every triple in this list
+   * @param properties The properties of the subject
+   */
+  public TripleList(Node subject, PropertyList properties) {
+    this();
+    for (PropertyList.Property p: properties) triples.add(new Triple(subject, p.getPredicate(), p.getObject()));
+  }
+  
+  /**
+   * Build a list of triples about a common subject that is already in a list
+   * @param an An annotated node that is the suject of the given properties
+   * @param properties The properties of the an
+   */
+  public TripleList(AnnotatedNode an, PropertyList properties) {
+    // start with the existing triples
+    triples = new LinkedList<Triple>(an.getAnnotation().triples);
+    // add in the triples for the properties
+    for (PropertyList.Property p: properties) triples.add(new Triple(an.getSubject(), p.getPredicate(), p.getObject()));
+  }
+  
+  /**
+   * Package constructor, used by other classes that build a list of triples
+   * @param triples Preallocated list of triples
+   */
+  TripleList(List<Triple> triples) {
+    this.triples = triples;
+  }
+  
+  /**
+   * Retrieve the node that represents this list.
+   * @return A single list node.
+   */
+  public Node getSubject() {
+    return triples.isEmpty() ? Nil.NIL_NODE : triples.get(0).getSubject();
+  }
+
+  /**
+   * Appends a triple to the list.
+   * @param t The triple to add.
+   */
+  public void add(Triple t) {
+    triples.add(t);
+  }
+
+  /**
+   * Concatenates another list to this one
+   * @param l The TripleList to add.
+   */
+  public void concat(TripleList l) {
+    triples.addAll(l.triples);
+  }
+  
+  /**
+   * Convert this list into a GroupGraphPattern
+   * @return a conjunction of all triples in the list, or a single triple if there is only one
+   */
+  public GroupGraphPattern asGroupGraphPattern() {
+    if (triples.size() == 1) return triples.get(0);
+    return new GraphPatternConjunction(this);
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.BasicGraphPattern#getElements()
+   */
+  @Override
+  public List<? extends GroupGraphPattern> getElements() {
+    return triples;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.BasicGraphPattern#getImage()
+   */
+  @Override
+  public String getImage() {
+    StringBuffer result = new StringBuffer();
+    for (Triple t: triples) result.append(" ").append(t.getImage()).append(" .");
+    return addPatterns(result.toString());
+  }
+
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/UnaryMinus.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/UnaryMinus.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/UnaryMinus.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * A numeric unary minus operator.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class UnaryMinus extends AbstractUnaryOperator<NumericExpression> implements NumericExpression {
+
+  /**
+   * Create the inversion operation
+   * @param operand The expression to invert.
+   */
+  public UnaryMinus(Expression operand) {
+    assert operand instanceof NumericExpression;
+    this.operand = (NumericExpression)operand;
+  }
+  
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "+" + operand.getImage();
+  }
+  
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/UnaryPlus.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/UnaryPlus.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/UnaryPlus.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * A numeric unary plus operator.
+ *
+ * @created Feb 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class UnaryPlus extends AbstractUnaryOperator<NumericExpression> implements NumericExpression {
+
+  /**
+   * Create the inversion operation
+   * @param operand The expression to invert.
+   */
+  public UnaryPlus(Expression operand) {
+    assert operand instanceof NumericExpression;
+    this.operand = (NumericExpression)operand;
+  }
+  
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "+" + operand.getImage();
+  }
+  
+}

Added: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Variable.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Variable.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Variable.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008 Fedora Commons
+ *
+ * Licensed 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 org.mulgara.sparql.parser.cst;
+
+
+/**
+ * Represents a named variable.
+ *
+ * @created Feb 12, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ * @licence <a href="{@docRoot}/../LICENCE.txt">Apache License, Version 2.0</a>
+ */
+public class Variable implements Node, PrimaryExpression, NumericExpression, LogicExpression {
+
+  /** The name of this variable */
+  private String name;
+  
+  /** Constructs a named variable */
+  public Variable(String name) {
+    this.name = name;
+  }
+
+  /**
+   * @return the name
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * @see org.mulgara.sparql.parser.cst.Node#getImage()
+   */
+  public String getImage() {
+    return "?" + name;
+  }
+
+}

Added: trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/ParseException.java
===================================================================
--- trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/ParseException.java	                        (rev 0)
+++ trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/ParseException.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,192 @@
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
+package org.mulgara.sparql.parser;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+public class ParseException extends Exception {
+
+  /**
+   * This constructor is used by the method "generateParseException"
+   * in the generated parser.  Calling this constructor generates
+   * a new object of this type with the fields "currentToken",
+   * "expectedTokenSequences", and "tokenImage" set.  The boolean
+   * flag "specialConstructor" is also set to true to indicate that
+   * this constructor was used to create this object.
+   * This constructor calls its super class with the empty string
+   * to force the "toString" method of parent class "Throwable" to
+   * print the error message in the form:
+   *     ParseException: <result of getMessage>
+   */
+  public ParseException(Token currentTokenVal,
+                        int[][] expectedTokenSequencesVal,
+                        String[] tokenImageVal
+                       )
+  {
+    super("");
+    specialConstructor = true;
+    currentToken = currentTokenVal;
+    expectedTokenSequences = expectedTokenSequencesVal;
+    tokenImage = tokenImageVal;
+  }
+
+  /**
+   * The following constructors are for use by you for whatever
+   * purpose you can think of.  Constructing the exception in this
+   * manner makes the exception behave in the normal way - i.e., as
+   * documented in the class "Throwable".  The fields "errorToken",
+   * "expectedTokenSequences", and "tokenImage" do not contain
+   * relevant information.  The JavaCC generated code does not use
+   * these constructors.
+   */
+
+  public ParseException() {
+    super();
+    specialConstructor = false;
+  }
+
+  public ParseException(String message) {
+    super(message);
+    specialConstructor = false;
+  }
+
+  /**
+   * This variable determines which constructor was used to create
+   * this object and thereby affects the semantics of the
+   * "getMessage" method (see below).
+   */
+  protected boolean specialConstructor;
+
+  /**
+   * This is the last token that has been consumed successfully.  If
+   * this object has been created due to a parse error, the token
+   * followng this token will (therefore) be the first error token.
+   */
+  public Token currentToken;
+
+  /**
+   * Each entry in this array is an array of integers.  Each array
+   * of integers represents a sequence of tokens (by their ordinal
+   * values) that is expected at this point of the parse.
+   */
+  public int[][] expectedTokenSequences;
+
+  /**
+   * This is a reference to the "tokenImage" array of the generated
+   * parser within which the parse error occurred.  This array is
+   * defined in the generated ...Constants interface.
+   */
+  public String[] tokenImage;
+
+  /**
+   * This method has the standard behavior when this object has been
+   * created using the standard constructors.  Otherwise, it uses
+   * "currentToken" and "expectedTokenSequences" to generate a parse
+   * error message and returns it.  If this object has been created
+   * due to a parse error, and you do not catch it (it gets thrown
+   * from the parser), then this method is called during the printing
+   * of the final stack trace, and hence the correct error message
+   * gets displayed.
+   */
+  public String getMessage() {
+    if (!specialConstructor) {
+      return super.getMessage();
+    }
+    StringBuffer expected = new StringBuffer();
+    int maxSize = 0;
+    for (int i = 0; i < expectedTokenSequences.length; i++) {
+      if (maxSize < expectedTokenSequences[i].length) {
+        maxSize = expectedTokenSequences[i].length;
+      }
+      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+        expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
+      }
+      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+        expected.append("...");
+      }
+      expected.append(eol).append("    ");
+    }
+    String retval = "Encountered \"";
+    Token tok = currentToken.next;
+    for (int i = 0; i < maxSize; i++) {
+      if (i != 0) retval += " ";
+      if (tok.kind == 0) {
+        retval += tokenImage[0];
+        break;
+      }
+      retval += add_escapes(tok.image);
+      tok = tok.next; 
+    }
+    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
+    retval += "." + eol;
+    if (expectedTokenSequences.length == 1) {
+      retval += "Was expecting:" + eol + "    ";
+    } else {
+      retval += "Was expecting one of:" + eol + "    ";
+    }
+    retval += expected.toString();
+    return retval;
+  }
+
+  /**
+   * The end of line string for this machine.
+   */
+  protected String eol = System.getProperty("line.separator", "\n");
+ 
+  /**
+   * Used to convert raw characters to their escaped version
+   * when these raw version cannot be used as part of an ASCII
+   * string literal.
+   */
+  protected String add_escapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case 0 :
+              continue;
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+}

Added: trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SimpleCharStream.java
===================================================================
--- trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SimpleCharStream.java	                        (rev 0)
+++ trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SimpleCharStream.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,439 @@
+/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 4.0 */
+package org.mulgara.sparql.parser;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (without unicode processing).
+ */
+
+public class SimpleCharStream
+{
+  public static final boolean staticFlag = false;
+  int bufsize;
+  int available;
+  int tokenBegin;
+  public int bufpos = -1;
+  protected int bufline[];
+  protected int bufcolumn[];
+
+  protected int column = 0;
+  protected int line = 1;
+
+  protected boolean prevCharIsCR = false;
+  protected boolean prevCharIsLF = false;
+
+  protected java.io.Reader inputStream;
+
+  protected char[] buffer;
+  protected int maxNextCharInd = 0;
+  protected int inBuf = 0;
+  protected int tabSize = 8;
+
+  protected void setTabSize(int i) { tabSize = i; }
+  protected int getTabSize(int i) { return tabSize; }
+
+
+  protected void ExpandBuff(boolean wrapAround)
+  {
+     char[] newbuffer = new char[bufsize + 2048];
+     int newbufline[] = new int[bufsize + 2048];
+     int newbufcolumn[] = new int[bufsize + 2048];
+
+     try
+     {
+        if (wrapAround)
+        {
+           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+           System.arraycopy(buffer, 0, newbuffer,
+                                             bufsize - tokenBegin, bufpos);
+           buffer = newbuffer;
+
+           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+           System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+           bufline = newbufline;
+
+           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+           System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+           bufcolumn = newbufcolumn;
+
+           maxNextCharInd = (bufpos += (bufsize - tokenBegin));
+        }
+        else
+        {
+           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+           buffer = newbuffer;
+
+           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+           bufline = newbufline;
+
+           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+           bufcolumn = newbufcolumn;
+
+           maxNextCharInd = (bufpos -= tokenBegin);
+        }
+     }
+     catch (Throwable t)
+     {
+        throw new Error(t.getMessage());
+     }
+
+
+     bufsize += 2048;
+     available = bufsize;
+     tokenBegin = 0;
+  }
+
+  protected void FillBuff() throws java.io.IOException
+  {
+     if (maxNextCharInd == available)
+     {
+        if (available == bufsize)
+        {
+           if (tokenBegin > 2048)
+           {
+              bufpos = maxNextCharInd = 0;
+              available = tokenBegin;
+           }
+           else if (tokenBegin < 0)
+              bufpos = maxNextCharInd = 0;
+           else
+              ExpandBuff(false);
+        }
+        else if (available > tokenBegin)
+           available = bufsize;
+        else if ((tokenBegin - available) < 2048)
+           ExpandBuff(true);
+        else
+           available = tokenBegin;
+     }
+
+     int i;
+     try {
+        if ((i = inputStream.read(buffer, maxNextCharInd,
+                                    available - maxNextCharInd)) == -1)
+        {
+           inputStream.close();
+           throw new java.io.IOException();
+        }
+        else
+           maxNextCharInd += i;
+        return;
+     }
+     catch(java.io.IOException e) {
+        --bufpos;
+        backup(0);
+        if (tokenBegin == -1)
+           tokenBegin = bufpos;
+        throw e;
+     }
+  }
+
+  public char BeginToken() throws java.io.IOException
+  {
+     tokenBegin = -1;
+     char c = readChar();
+     tokenBegin = bufpos;
+
+     return c;
+  }
+
+  protected void UpdateLineColumn(char c)
+  {
+     column++;
+
+     if (prevCharIsLF)
+     {
+        prevCharIsLF = false;
+        line += (column = 1);
+     }
+     else if (prevCharIsCR)
+     {
+        prevCharIsCR = false;
+        if (c == '\n')
+        {
+           prevCharIsLF = true;
+        }
+        else
+           line += (column = 1);
+     }
+
+     switch (c)
+     {
+        case '\r' :
+           prevCharIsCR = true;
+           break;
+        case '\n' :
+           prevCharIsLF = true;
+           break;
+        case '\t' :
+           column--;
+           column += (tabSize - (column % tabSize));
+           break;
+        default :
+           break;
+     }
+
+     bufline[bufpos] = line;
+     bufcolumn[bufpos] = column;
+  }
+
+  public char readChar() throws java.io.IOException
+  {
+     if (inBuf > 0)
+     {
+        --inBuf;
+
+        if (++bufpos == bufsize)
+           bufpos = 0;
+
+        return buffer[bufpos];
+     }
+
+     if (++bufpos >= maxNextCharInd)
+        FillBuff();
+
+     char c = buffer[bufpos];
+
+     UpdateLineColumn(c);
+     return c;
+  }
+
+  /**
+   * @deprecated 
+   * @see #getEndColumn
+   */
+
+  public int getColumn() {
+     return bufcolumn[bufpos];
+  }
+
+  /**
+   * @deprecated 
+   * @see #getEndLine
+   */
+
+  public int getLine() {
+     return bufline[bufpos];
+  }
+
+  public int getEndColumn() {
+     return bufcolumn[bufpos];
+  }
+
+  public int getEndLine() {
+     return bufline[bufpos];
+  }
+
+  public int getBeginColumn() {
+     return bufcolumn[tokenBegin];
+  }
+
+  public int getBeginLine() {
+     return bufline[tokenBegin];
+  }
+
+  public void backup(int amount) {
+
+    inBuf += amount;
+    if ((bufpos -= amount) < 0)
+       bufpos += bufsize;
+  }
+
+  public SimpleCharStream(java.io.Reader dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    available = bufsize = buffersize;
+    buffer = new char[buffersize];
+    bufline = new int[buffersize];
+    bufcolumn = new int[buffersize];
+  }
+
+  public SimpleCharStream(java.io.Reader dstream, int startline,
+                          int startcolumn)
+  {
+     this(dstream, startline, startcolumn, 4096);
+  }
+
+  public SimpleCharStream(java.io.Reader dstream)
+  {
+     this(dstream, 1, 1, 4096);
+  }
+  public void ReInit(java.io.Reader dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    if (buffer == null || buffersize != buffer.length)
+    {
+      available = bufsize = buffersize;
+      buffer = new char[buffersize];
+      bufline = new int[buffersize];
+      bufcolumn = new int[buffersize];
+    }
+    prevCharIsLF = prevCharIsCR = false;
+    tokenBegin = inBuf = maxNextCharInd = 0;
+    bufpos = -1;
+  }
+
+  public void ReInit(java.io.Reader dstream, int startline,
+                     int startcolumn)
+  {
+     ReInit(dstream, startline, startcolumn, 4096);
+  }
+
+  public void ReInit(java.io.Reader dstream)
+  {
+     ReInit(dstream, 1, 1, 4096);
+  }
+  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+     this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+  public SimpleCharStream(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+     this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+
+  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
+                          int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+     this(dstream, encoding, startline, startcolumn, 4096);
+  }
+
+  public SimpleCharStream(java.io.InputStream dstream, int startline,
+                          int startcolumn)
+  {
+     this(dstream, startline, startcolumn, 4096);
+  }
+
+  public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+     this(dstream, encoding, 1, 1, 4096);
+  }
+
+  public SimpleCharStream(java.io.InputStream dstream)
+  {
+     this(dstream, 1, 1, 4096);
+  }
+
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+                          int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+  public void ReInit(java.io.InputStream dstream, int startline,
+                          int startcolumn, int buffersize)
+  {
+     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+
+  public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(dstream, encoding, 1, 1, 4096);
+  }
+
+  public void ReInit(java.io.InputStream dstream)
+  {
+     ReInit(dstream, 1, 1, 4096);
+  }
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+                     int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(dstream, encoding, startline, startcolumn, 4096);
+  }
+  public void ReInit(java.io.InputStream dstream, int startline,
+                     int startcolumn)
+  {
+     ReInit(dstream, startline, startcolumn, 4096);
+  }
+  public String GetImage()
+  {
+     if (bufpos >= tokenBegin)
+        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+     else
+        return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+                              new String(buffer, 0, bufpos + 1);
+  }
+
+  public char[] GetSuffix(int len)
+  {
+     char[] ret = new char[len];
+
+     if ((bufpos + 1) >= len)
+        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+     else
+     {
+        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+                                                          len - bufpos - 1);
+        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+     }
+
+     return ret;
+  }
+
+  public void Done()
+  {
+     buffer = null;
+     bufline = null;
+     bufcolumn = null;
+  }
+
+  /**
+   * Method to adjust line and column numbers for the start of a token.
+   */
+  public void adjustBeginLineColumn(int newLine, int newCol)
+  {
+     int start = tokenBegin;
+     int len;
+
+     if (bufpos >= tokenBegin)
+     {
+        len = bufpos - tokenBegin + inBuf + 1;
+     }
+     else
+     {
+        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+     }
+
+     int i = 0, j = 0, k = 0;
+     int nextColDiff = 0, columnDiff = 0;
+
+     while (i < len &&
+            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+     {
+        bufline[j] = newLine;
+        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+        bufcolumn[j] = newCol + columnDiff;
+        columnDiff = nextColDiff;
+        i++;
+     } 
+
+     if (i < len)
+     {
+        bufline[j] = newLine++;
+        bufcolumn[j] = newCol + columnDiff;
+
+        while (i++ < len)
+        {
+           if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+              bufline[j] = newLine++;
+           else
+              bufline[j] = newLine;
+        }
+     }
+
+     line = bufline[j];
+     column = bufcolumn[j];
+  }
+
+}

Added: trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.java
===================================================================
--- trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.java	                        (rev 0)
+++ trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,2250 @@
+/* Generated By:JavaCC: Do not edit this line. SparqlParser.java */
+package org.mulgara.sparql.parser;
+
+import java.io.StringReader;
+import static org.mulgara.sparql.parser.QueryType.*;
+import org.mulgara.sparql.parser.cst.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.LinkedList;
+import static org.mulgara.sparql.parser.cst.Nil.NIL_NODE;
+
+public class SparqlParser implements SparqlParserConstants {
+
+  private QueryStructureImpl queryStructure = new QueryStructureImpl();
+
+  public void setDefaultBase(URI base) {
+        queryStructure.setBase(base);
+  }
+
+  public static QueryStructure parse(String query) throws ParseException {
+    SparqlParser parser = new SparqlParser(new StringReader(query));
+    parser.Query();
+    return parser.queryStructure;
+  }
+
+  public static QueryStructure parse(String query, URI defaultBase) throws ParseException {
+    SparqlParser parser = new SparqlParser(new StringReader(query));
+    parser.Query();
+    parser.setDefaultBase(defaultBase);
+    return parser.queryStructure;
+  }
+
+  private static String unquote(String s) {
+    return s.substring(1, s.length() - 1);
+  }
+
+  private static String unTripleQuote(String s) {
+    return s.substring(3, s.length() - 3);
+  }
+
+  private static GroupGraphPattern conjoin(GroupGraphPattern g1, GroupGraphPattern g2) {
+        assert g2 != null;
+    if (g1 == GroupGraphPattern.EMPTY) return g2;
+    return new GraphPatternConjunction(g1, g2);
+  }
+
+  private static URI uri(String u) throws ParseException {
+        try {
+          return new URI(unquote(u));
+        } catch (URISyntaxException e) {
+          throw new ParseException("Bad URI syntax");
+        }
+  }
+
+/* [1]      Query      ::=      Prologue ( SelectQuery | ConstructQuery | DescribeQuery | AskQuery ) */
+  final public void Query() throws ParseException {
+    Prologue();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case SELECT:
+      SelectQuery();
+      break;
+    case CONSTRUCT:
+      ConstructQuery();
+      break;
+    case DESCRIBE:
+      DescribeQuery();
+      break;
+    case ASK:
+      AskQuery();
+      break;
+    default:
+      jj_la1[0] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(0);
+  }
+
+/* [2]      Prologue      ::=      BaseDecl? PrefixDecl* */
+  final public void Prologue() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BASE:
+      BaseDecl();
+      break;
+    default:
+      jj_la1[1] = jj_gen;
+      ;
+    }
+    label_1:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case PREFIX:
+        ;
+        break;
+      default:
+        jj_la1[2] = jj_gen;
+        break label_1;
+      }
+      PrefixDecl();
+    }
+  }
+
+/* [3]      BaseDecl      ::=      'BASE' IRI_REF */
+  final public void BaseDecl() throws ParseException {
+                    IRIReference ref;
+    jj_consume_token(BASE);
+    ref = IRIref();
+                          queryStructure.setBase(ref.getUri());
+  }
+
+/* [4]      PrefixDecl      ::=      'PREFIX' PNAME_NS IRI_REF */
+  final public void PrefixDecl() throws ParseException {
+                      Token ns, ref;
+    jj_consume_token(PREFIX);
+    ns = jj_consume_token(PNAME_NS);
+    ref = jj_consume_token(IRI_REF);
+      queryStructure.addPrefix(ns.image, uri(ref.image));
+  }
+
+/* [5]      SelectQuery   ::=   'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( Var+ | '*' ) DatasetClause* WhereClause SolutionModifier */
+  final public void SelectQuery() throws ParseException {
+                       Variable v;
+    jj_consume_token(SELECT);
+               queryStructure.setType(select);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case DISTINCT:
+    case REDUCED:
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case DISTINCT:
+        jj_consume_token(DISTINCT);
+                   queryStructure.setDistinct();
+        break;
+      case REDUCED:
+        jj_consume_token(REDUCED);
+                    queryStructure.setReduced();
+        break;
+      default:
+        jj_la1[3] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+    default:
+      jj_la1[4] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case VAR1:
+    case VAR2:
+      label_2:
+      while (true) {
+        v = Var();
+                  queryStructure.addSelection(v);
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case VAR1:
+        case VAR2:
+          ;
+          break;
+        default:
+          jj_la1[5] = jj_gen;
+          break label_2;
+        }
+      }
+      break;
+    case 40:
+      jj_consume_token(40);
+            queryStructure.setSelectAll();
+      break;
+    default:
+      jj_la1[6] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    label_3:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case FROM:
+        ;
+        break;
+      default:
+        jj_la1[7] = jj_gen;
+        break label_3;
+      }
+      DatasetClause();
+    }
+    WhereClause();
+    SolutionModifier();
+  }
+
+/* [6]      ConstructQuery    ::=   'CONSTRUCT' ConstructTemplate DatasetClause* WhereClause SolutionModifier */
+  final public void ConstructQuery() throws ParseException {
+    jj_consume_token(CONSTRUCT);
+                  queryStructure.setType(construct);
+    ConstructTemplate();
+    label_4:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case FROM:
+        ;
+        break;
+      default:
+        jj_la1[8] = jj_gen;
+        break label_4;
+      }
+      DatasetClause();
+    }
+    WhereClause();
+    SolutionModifier();
+  }
+
+/* [7]      DescribeQuery      ::=      'DESCRIBE' ( VarOrIRIref+ | '*' ) DatasetClause* WhereClause? SolutionModifier */
+  final public void DescribeQuery() throws ParseException {
+                         Node n;
+    jj_consume_token(DESCRIBE);
+                 queryStructure.setType(describe);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+    case VAR1:
+    case VAR2:
+      label_5:
+      while (true) {
+        n = VarOrIRIref();
+                          queryStructure.addSelection(n);
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case IRI_REF:
+        case PNAME_NS:
+        case PNAME_LN:
+        case VAR1:
+        case VAR2:
+          ;
+          break;
+        default:
+          jj_la1[9] = jj_gen;
+          break label_5;
+        }
+      }
+      break;
+    case 40:
+      jj_consume_token(40);
+            queryStructure.setSelectAll();
+      break;
+    default:
+      jj_la1[10] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    label_6:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case FROM:
+        ;
+        break;
+      default:
+        jj_la1[11] = jj_gen;
+        break label_6;
+      }
+      DatasetClause();
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case WHERE:
+    case 43:
+      WhereClause();
+      break;
+    default:
+      jj_la1[12] = jj_gen;
+      ;
+    }
+    SolutionModifier();
+  }
+
+/* [8]      AskQuery      ::=   'ASK' DatasetClause* WhereClause */
+  final public void AskQuery() throws ParseException {
+    jj_consume_token(ASK);
+            queryStructure.setType(ask);
+    label_7:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case FROM:
+        ;
+        break;
+      default:
+        jj_la1[13] = jj_gen;
+        break label_7;
+      }
+      DatasetClause();
+    }
+    WhereClause();
+  }
+
+/* [9]   DatasetClause   ::=   'FROM' ( DefaultGraphClause | NamedGraphClause ) */
+  final public void DatasetClause() throws ParseException {
+    jj_consume_token(FROM);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+      DefaultGraphClause();
+      break;
+    case NAMED:
+      NamedGraphClause();
+      break;
+    default:
+      jj_la1[14] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  }
+
+/* [10]    DefaultGraphClause    ::=    SourceSelector */
+  final public void DefaultGraphClause() throws ParseException {
+                              IRIReference ref;
+    ref = SourceSelector();
+                           queryStructure.addDefaultFrom(ref);
+  }
+
+/* [11]    NamedGraphClause    ::=    'NAMED' SourceSelector */
+  final public void NamedGraphClause() throws ParseException {
+                            IRIReference ref;
+    jj_consume_token(NAMED);
+    ref = SourceSelector();
+                                   queryStructure.addNamedFrom(ref);
+  }
+
+/* [12]    SourceSelector    ::=    IRIref */
+  final public IRIReference SourceSelector() throws ParseException {
+                                  IRIReference r;
+    r = IRIref();
+                 {if (true) return r;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [13]    WhereClause    ::=    'WHERE'? GroupGraphPattern */
+  final public void WhereClause() throws ParseException {
+                       GroupGraphPattern g;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case WHERE:
+      jj_consume_token(WHERE);
+      break;
+    default:
+      jj_la1[15] = jj_gen;
+      ;
+    }
+    g = GroupGraphPattern();
+                                       queryStructure.setWhereClause(g);
+  }
+
+/* [14]    SolutionModifier    ::=    OrderClause? LimitOffsetClauses? */
+  final public void SolutionModifier() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case ORDER:
+      OrderClause();
+      break;
+    default:
+      jj_la1[16] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LIMIT:
+    case OFFSET:
+      LimitOffsetClauses();
+      break;
+    default:
+      jj_la1[17] = jj_gen;
+      ;
+    }
+  }
+
+/* [15]    LimitOffsetClauses    ::=    ( LimitClause OffsetClause? | OffsetClause LimitClause? ) */
+  final public void LimitOffsetClauses() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LIMIT:
+      LimitClause();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case OFFSET:
+        OffsetClause();
+        break;
+      default:
+        jj_la1[18] = jj_gen;
+        ;
+      }
+      break;
+    case OFFSET:
+      OffsetClause();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LIMIT:
+        LimitClause();
+        break;
+      default:
+        jj_la1[19] = jj_gen;
+        ;
+      }
+      break;
+    default:
+      jj_la1[20] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  }
+
+/* [16]    OrderClause    ::=    'ORDER' 'BY' OrderCondition+ */
+  final public void OrderClause() throws ParseException {
+    jj_consume_token(ORDER);
+    jj_consume_token(BY);
+    label_8:
+    while (true) {
+      OrderCondition();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case STR:
+      case IS_URI:
+      case LANG:
+      case IS_IRI:
+      case LANGMATCHES:
+      case IS_BLANK:
+      case IS_LITERAL:
+      case DATATYPE:
+      case REGEX:
+      case BOUND:
+      case SAME_TERM:
+      case 41:
+      case 42:
+      case 46:
+      case IRI_REF:
+      case PNAME_NS:
+      case PNAME_LN:
+      case VAR1:
+      case VAR2:
+        ;
+        break;
+      default:
+        jj_la1[21] = jj_gen;
+        break label_8;
+      }
+    }
+  }
+
+/* [17]    OrderCondition    ::=     ( ( 'ASC' | 'DESC' ) BrackettedExpression ) | ( Constraint | Var ) */
+  final public void OrderCondition() throws ParseException {
+                          boolean asc = true; Expression e;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 41:
+    case 42:
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 41:
+        jj_consume_token(41);
+        break;
+      case 42:
+        jj_consume_token(42);
+                       asc = false;
+        break;
+      default:
+        jj_la1[22] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      e = BrackettedExpression();
+      break;
+    case STR:
+    case IS_URI:
+    case LANG:
+    case IS_IRI:
+    case LANGMATCHES:
+    case IS_BLANK:
+    case IS_LITERAL:
+    case DATATYPE:
+    case REGEX:
+    case BOUND:
+    case SAME_TERM:
+    case 46:
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+    case VAR1:
+    case VAR2:
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case STR:
+      case IS_URI:
+      case LANG:
+      case IS_IRI:
+      case LANGMATCHES:
+      case IS_BLANK:
+      case IS_LITERAL:
+      case DATATYPE:
+      case REGEX:
+      case BOUND:
+      case SAME_TERM:
+      case 46:
+      case IRI_REF:
+      case PNAME_NS:
+      case PNAME_LN:
+        e = Constraint();
+        break;
+      case VAR1:
+      case VAR2:
+        e = Var();
+        break;
+      default:
+        jj_la1[23] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    queryStructure.addOrdering(e, asc);
+      break;
+    default:
+      jj_la1[24] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  }
+
+/* [18]    LimitClause    ::=    'LIMIT' INTEGER */
+  final public void LimitClause() throws ParseException {
+                       Token t;
+    jj_consume_token(LIMIT);
+    t = jj_consume_token(INTEGER);
+                          queryStructure.setLimit(t.image);
+  }
+
+/* [19]    OffsetClause    ::=    'OFFSET' INTEGER */
+  final public void OffsetClause() throws ParseException {
+                        Token t;
+    jj_consume_token(OFFSET);
+    t = jj_consume_token(INTEGER);
+                           queryStructure.setOffset(t.image);
+  }
+
+/* [20]    GroupGraphPattern    ::=    '{' TriplesBlock? ( ( GraphPatternNotTriples | Filter ) '.'? TriplesBlock? )* '}' */
+  final public GroupGraphPattern GroupGraphPattern() throws ParseException {
+  GroupGraphPattern g = null, g2;
+  GraphPatternConjunction c = null;
+  Expression f;
+          g = GroupGraphPattern.EMPTY;
+    jj_consume_token(43);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case TRUE:
+    case FALSE:
+    case 46:
+    case 51:
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+    case BLANK_NODE_LABEL:
+    case VAR1:
+    case VAR2:
+    case INTEGER:
+    case DECIMAL:
+    case DOUBLE:
+    case INTEGER_POSITIVE:
+    case DECIMAL_POSITIVE:
+    case DOUBLE_POSITIVE:
+    case INTEGER_NEGATIVE:
+    case DECIMAL_NEGATIVE:
+    case DOUBLE_NEGATIVE:
+    case STRING_LITERAL1:
+    case STRING_LITERAL2:
+    case STRING_LITERAL_LONG1:
+    case STRING_LITERAL_LONG2:
+    case NIL:
+    case ANON:
+      g = TriplesBlock();
+      break;
+    default:
+      jj_la1[25] = jj_gen;
+      ;
+    }
+    label_9:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case GRAPH:
+      case OPTIONAL:
+      case FILTER:
+      case 43:
+        ;
+        break;
+      default:
+        jj_la1[26] = jj_gen;
+        break label_9;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case GRAPH:
+      case OPTIONAL:
+      case 43:
+        g = GraphPatternNotTriples(g);
+        break;
+      case FILTER:
+        f = Filter();
+            if (g == null) {if (true) throw new ParseException("Cannot filter an empty pattern");}
+            g.setFilter(f);
+        break;
+      default:
+        jj_la1[27] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 44:
+        jj_consume_token(44);
+        break;
+      default:
+        jj_la1[28] = jj_gen;
+        ;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case TRUE:
+      case FALSE:
+      case 46:
+      case 51:
+      case IRI_REF:
+      case PNAME_NS:
+      case PNAME_LN:
+      case BLANK_NODE_LABEL:
+      case VAR1:
+      case VAR2:
+      case INTEGER:
+      case DECIMAL:
+      case DOUBLE:
+      case INTEGER_POSITIVE:
+      case DECIMAL_POSITIVE:
+      case DOUBLE_POSITIVE:
+      case INTEGER_NEGATIVE:
+      case DECIMAL_NEGATIVE:
+      case DOUBLE_NEGATIVE:
+      case STRING_LITERAL1:
+      case STRING_LITERAL2:
+      case STRING_LITERAL_LONG1:
+      case STRING_LITERAL_LONG2:
+      case NIL:
+      case ANON:
+        g2 = TriplesBlock();
+            if (g == null) g = g2;
+            else {
+                    // preferentially choose c so we get the right constructor
+                    if (c == null) c = new GraphPatternConjunction(g, g2);
+                    else c = new GraphPatternConjunction(c, g2);
+                    g = c;
+            }
+        break;
+      default:
+        jj_la1[29] = jj_gen;
+        ;
+      }
+    }
+    jj_consume_token(45);
+      {if (true) return g;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [21]    TriplesBlock    ::=    TriplesSameSubject ( '.' TriplesBlock? )? */
+  final public GraphPatternConjunction TriplesBlock() throws ParseException {
+                                           TripleList l; GraphPatternConjunction g = null;
+    l = TriplesSameSubject();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 44:
+      jj_consume_token(44);
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case TRUE:
+      case FALSE:
+      case 46:
+      case 51:
+      case IRI_REF:
+      case PNAME_NS:
+      case PNAME_LN:
+      case BLANK_NODE_LABEL:
+      case VAR1:
+      case VAR2:
+      case INTEGER:
+      case DECIMAL:
+      case DOUBLE:
+      case INTEGER_POSITIVE:
+      case DECIMAL_POSITIVE:
+      case DOUBLE_POSITIVE:
+      case INTEGER_NEGATIVE:
+      case DECIMAL_NEGATIVE:
+      case DOUBLE_NEGATIVE:
+      case STRING_LITERAL1:
+      case STRING_LITERAL2:
+      case STRING_LITERAL_LONG1:
+      case STRING_LITERAL_LONG2:
+      case NIL:
+      case ANON:
+        g = TriplesBlock();
+                                                     g = new GraphPatternConjunction(g, l);
+        break;
+      default:
+        jj_la1[30] = jj_gen;
+        ;
+      }
+      break;
+    default:
+      jj_la1[31] = jj_gen;
+      ;
+    }
+      if (g == null) {if (true) return new GraphPatternConjunction(l);}
+      {if (true) return g;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [22]    GraphPatternNotTriples    ::=    OptionalGraphPattern | GroupOrUnionGraphPattern | GraphGraphPattern */
+  final public GroupGraphPattern GraphPatternNotTriples(GroupGraphPattern in) throws ParseException {
+                                                                   GroupGraphPattern g;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case OPTIONAL:
+      g = OptionalGraphPattern(in);
+      break;
+    case 43:
+      g = GroupOrUnionGraphPattern(in);
+      break;
+    case GRAPH:
+      g = GraphGraphPattern(in);
+      break;
+    default:
+      jj_la1[32] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return g;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [23]    OptionalGraphPattern    ::=    'OPTIONAL' GroupGraphPattern */
+  final public GroupGraphPattern OptionalGraphPattern(GroupGraphPattern in) throws ParseException {
+                                                                 GroupGraphPattern g;
+    jj_consume_token(OPTIONAL);
+    g = GroupGraphPattern();
+                                       {if (true) return new GraphPatternOptional(in, g);}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [24]    GraphGraphPattern    ::=    'GRAPH' VarOrIRIref GroupGraphPattern */
+  final public GroupGraphPattern GraphGraphPattern(GroupGraphPattern in) throws ParseException {
+                                                              Expression e; GroupGraphPattern g;
+    jj_consume_token(GRAPH);
+    e = VarOrIRIref();
+    g = GroupGraphPattern();
+      g.setGraph(e);
+      {if (true) return conjoin(in, g);}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [25]    GroupOrUnionGraphPattern    ::=    GroupGraphPattern ( 'UNION' GroupGraphPattern )* */
+  final public GroupGraphPattern GroupOrUnionGraphPattern(GroupGraphPattern in) throws ParseException {
+                                                                     GroupGraphPattern g1, g2; GraphPatternDisjunction d = null;
+    g1 = GroupGraphPattern();
+    label_10:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case UNION:
+        ;
+        break;
+      default:
+        jj_la1[33] = jj_gen;
+        break label_10;
+      }
+      jj_consume_token(UNION);
+      g2 = GroupGraphPattern();
+        // use an existing disjunction if available, to pick the correct constructor
+        if (d == null) d = new GraphPatternDisjunction(g1, g2);
+        else d = new GraphPatternDisjunction(d, g2);
+        g1 = d;
+    }
+      {if (true) return conjoin(in, g1);}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [26]    Filter    ::=    'FILTER' Constraint */
+  final public Expression Filter() throws ParseException {
+                        Expression e;
+    jj_consume_token(FILTER);
+    e = Constraint();
+                              {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [27]    Constraint    ::=    BrackettedExpression | BuiltInCall | FunctionCall */
+  final public Expression Constraint() throws ParseException {
+                            Expression e;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 46:
+      e = BrackettedExpression();
+      break;
+    case STR:
+    case IS_URI:
+    case LANG:
+    case IS_IRI:
+    case LANGMATCHES:
+    case IS_BLANK:
+    case IS_LITERAL:
+    case DATATYPE:
+    case REGEX:
+    case BOUND:
+    case SAME_TERM:
+      e = BuiltInCall();
+      break;
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+      e = FunctionCall();
+      break;
+    default:
+      jj_la1[34] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [28]    FunctionCall    ::=    IRIref ArgList */
+  final public FunctionCall FunctionCall() throws ParseException {
+                                IRIReference r; ArgList l;
+    r = IRIref();
+    l = ArgList();
+      {if (true) return new FunctionCall(r, l);}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [29]    ArgList    ::=    ( NIL | '(' Expression ( ',' Expression )* ')' ) */
+  final public ArgList ArgList() throws ParseException {
+                      ArgList list = new ArgList(); Expression e;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case NIL:
+      jj_consume_token(NIL);
+      break;
+    case 46:
+      jj_consume_token(46);
+      e = Expression();
+                             list.add(e);
+      label_11:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 47:
+          ;
+          break;
+        default:
+          jj_la1[35] = jj_gen;
+          break label_11;
+        }
+        jj_consume_token(47);
+        e = Expression();
+                                                                   list.add(e);
+      }
+      jj_consume_token(48);
+      break;
+    default:
+      jj_la1[36] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return list;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [30]    ConstructTemplate    ::=    '{' ConstructTriples? '}' */
+  final public void ConstructTemplate() throws ParseException {
+                             TripleList triples = null;
+    jj_consume_token(43);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case TRUE:
+    case FALSE:
+    case 46:
+    case 51:
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+    case BLANK_NODE_LABEL:
+    case VAR1:
+    case VAR2:
+    case INTEGER:
+    case DECIMAL:
+    case DOUBLE:
+    case INTEGER_POSITIVE:
+    case DECIMAL_POSITIVE:
+    case DOUBLE_POSITIVE:
+    case INTEGER_NEGATIVE:
+    case DECIMAL_NEGATIVE:
+    case DOUBLE_NEGATIVE:
+    case STRING_LITERAL1:
+    case STRING_LITERAL2:
+    case STRING_LITERAL_LONG1:
+    case STRING_LITERAL_LONG2:
+    case NIL:
+    case ANON:
+      triples = ConstructTriples();
+      break;
+    default:
+      jj_la1[37] = jj_gen;
+      ;
+    }
+    jj_consume_token(45);
+      queryStructure.setConstructTemplate(triples);
+  }
+
+/* [31]    ConstructTriples    ::=    TriplesSameSubject ( '.' ConstructTriples? )? */
+  final public TripleList ConstructTriples() throws ParseException {
+                                  TripleList triples, t;
+    triples = TriplesSameSubject();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 44:
+      jj_consume_token(44);
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case TRUE:
+      case FALSE:
+      case 46:
+      case 51:
+      case IRI_REF:
+      case PNAME_NS:
+      case PNAME_LN:
+      case BLANK_NODE_LABEL:
+      case VAR1:
+      case VAR2:
+      case INTEGER:
+      case DECIMAL:
+      case DOUBLE:
+      case INTEGER_POSITIVE:
+      case DECIMAL_POSITIVE:
+      case DOUBLE_POSITIVE:
+      case INTEGER_NEGATIVE:
+      case DECIMAL_NEGATIVE:
+      case DOUBLE_NEGATIVE:
+      case STRING_LITERAL1:
+      case STRING_LITERAL2:
+      case STRING_LITERAL_LONG1:
+      case STRING_LITERAL_LONG2:
+      case NIL:
+      case ANON:
+        t = ConstructTriples();
+                                                               triples.concat(t);
+        break;
+      default:
+        jj_la1[38] = jj_gen;
+        ;
+      }
+      break;
+    default:
+      jj_la1[39] = jj_gen;
+      ;
+    }
+      {if (true) return triples;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [32]    TriplesSameSubject    ::=    VarOrTerm PropertyListNotEmpty |  TriplesNode PropertyList */
+  final public TripleList TriplesSameSubject() throws ParseException {
+                                    Node s; AnnotatedNode an; PropertyList pl;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case TRUE:
+    case FALSE:
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+    case BLANK_NODE_LABEL:
+    case VAR1:
+    case VAR2:
+    case INTEGER:
+    case DECIMAL:
+    case DOUBLE:
+    case INTEGER_POSITIVE:
+    case DECIMAL_POSITIVE:
+    case DOUBLE_POSITIVE:
+    case INTEGER_NEGATIVE:
+    case DECIMAL_NEGATIVE:
+    case DOUBLE_NEGATIVE:
+    case STRING_LITERAL1:
+    case STRING_LITERAL2:
+    case STRING_LITERAL_LONG1:
+    case STRING_LITERAL_LONG2:
+    case NIL:
+    case ANON:
+      s = VarOrTerm();
+      pl = PropertyListNotEmpty();
+                                              {if (true) return new TripleList(s, pl);}
+      break;
+    case 46:
+    case 51:
+      an = TriplesNode();
+      pl = PropertyList();
+                                         {if (true) return new TripleList(an, pl);}
+      break;
+    default:
+      jj_la1[40] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/* [33]    PropertyListNotEmpty    ::=    Verb ObjectList ( ';' ( Verb ObjectList )? )* */
+  final public PropertyList PropertyListNotEmpty() throws ParseException {
+                                        Node v; List<Node> o; PropertyList pl = new PropertyList();
+    v = Verb();
+    o = ObjectList();
+                              pl.add(v, o);
+    label_12:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 49:
+        ;
+        break;
+      default:
+        jj_la1[41] = jj_gen;
+        break label_12;
+      }
+      jj_consume_token(49);
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 50:
+      case IRI_REF:
+      case PNAME_NS:
+      case PNAME_LN:
+      case VAR1:
+      case VAR2:
+        v = Verb();
+        o = ObjectList();
+                                      pl.add(v, o);
+        break;
+      default:
+        jj_la1[42] = jj_gen;
+        ;
+      }
+    }
+      {if (true) return pl;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [34]    PropertyList    ::=    PropertyListNotEmpty? */
+  final public PropertyList PropertyList() throws ParseException {
+                                PropertyList pl = null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 50:
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+    case VAR1:
+    case VAR2:
+      pl = PropertyListNotEmpty();
+      break;
+    default:
+      jj_la1[43] = jj_gen;
+      ;
+    }
+      {if (true) return pl == null ? new PropertyList() : pl;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [35]    ObjectList    ::=    Object ( ',' Object )* */
+  final public List<Node> ObjectList() throws ParseException {
+                            List<Node> l; Node n;
+          l = new LinkedList<Node>();
+    n = Object();
+                 l.add(n);
+    label_13:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 47:
+        ;
+        break;
+      default:
+        jj_la1[44] = jj_gen;
+        break label_13;
+      }
+      jj_consume_token(47);
+      Object();
+                     l.add(n);
+    }
+      {if (true) return l;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [36]    Object    ::=    GraphNode */
+  final public Node Object() throws ParseException {
+                  Node n;
+    n = GraphNode();
+                    {if (true) return n;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [37]    Verb    ::=    VarOrIRIref | 'a' */
+  final public Expression Verb() throws ParseException {
+                      Expression e;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+    case VAR1:
+    case VAR2:
+      e = VarOrIRIref();
+                      {if (true) return e;}
+      break;
+    case 50:
+      jj_consume_token(50);
+            {if (true) return IRIReference.RDF_TYPE;}
+      break;
+    default:
+      jj_la1[45] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+// Return a node AND a conjunction to the current context
+/* [38]    TriplesNode    ::=    Collection |  BlankNodePropertyList */
+  final public AnnotatedNode TriplesNode() throws ParseException {
+                                AnnotatedNode n;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 46:
+      n = Collection();
+      break;
+    case 51:
+      n = BlankNodePropertyList();
+      break;
+    default:
+      jj_la1[46] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return n;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [39]    BlankNodePropertyList    ::=    '[' PropertyListNotEmpty ']' */
+  final public AnnotatedNode BlankNodePropertyList() throws ParseException {
+                                          PropertyList pl;
+    jj_consume_token(51);
+    pl = PropertyListNotEmpty();
+    jj_consume_token(52);
+      {if (true) return new AnnotatedNode(queryStructure.newBlankNode(), pl);}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [40]    Collection    ::=    '(' GraphNode+ ')' */
+/* Returns a *NODE* that is a collection.  The rest of the collection will be conjoined after. */
+  final public AnnotatedNode Collection() throws ParseException {
+                               Node n; GraphList l = queryStructure.newList();
+    jj_consume_token(46);
+    label_14:
+    while (true) {
+      n = GraphNode();
+                       l.add(n);
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case TRUE:
+      case FALSE:
+      case 46:
+      case 51:
+      case IRI_REF:
+      case PNAME_NS:
+      case PNAME_LN:
+      case BLANK_NODE_LABEL:
+      case VAR1:
+      case VAR2:
+      case INTEGER:
+      case DECIMAL:
+      case DOUBLE:
+      case INTEGER_POSITIVE:
+      case DECIMAL_POSITIVE:
+      case DOUBLE_POSITIVE:
+      case INTEGER_NEGATIVE:
+      case DECIMAL_NEGATIVE:
+      case DOUBLE_NEGATIVE:
+      case STRING_LITERAL1:
+      case STRING_LITERAL2:
+      case STRING_LITERAL_LONG1:
+      case STRING_LITERAL_LONG2:
+      case NIL:
+      case ANON:
+        ;
+        break;
+      default:
+        jj_la1[47] = jj_gen;
+        break label_14;
+      }
+    }
+    jj_consume_token(48);
+      {if (true) return new AnnotatedNode(l);}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [41]    GraphNode    ::=    VarOrTerm |  TriplesNode */
+  final public Node GraphNode() throws ParseException {
+                     Node n;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case TRUE:
+    case FALSE:
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+    case BLANK_NODE_LABEL:
+    case VAR1:
+    case VAR2:
+    case INTEGER:
+    case DECIMAL:
+    case DOUBLE:
+    case INTEGER_POSITIVE:
+    case DECIMAL_POSITIVE:
+    case DOUBLE_POSITIVE:
+    case INTEGER_NEGATIVE:
+    case DECIMAL_NEGATIVE:
+    case DOUBLE_NEGATIVE:
+    case STRING_LITERAL1:
+    case STRING_LITERAL2:
+    case STRING_LITERAL_LONG1:
+    case STRING_LITERAL_LONG2:
+    case NIL:
+    case ANON:
+      n = VarOrTerm();
+      break;
+    case 46:
+    case 51:
+      n = TriplesNode();
+      break;
+    default:
+      jj_la1[48] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return n;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [42]    VarOrTerm    ::=    Var | GraphTerm */
+  final public Node VarOrTerm() throws ParseException {
+                     Node n;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case VAR1:
+    case VAR2:
+      n = Var();
+      break;
+    case TRUE:
+    case FALSE:
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+    case BLANK_NODE_LABEL:
+    case INTEGER:
+    case DECIMAL:
+    case DOUBLE:
+    case INTEGER_POSITIVE:
+    case DECIMAL_POSITIVE:
+    case DOUBLE_POSITIVE:
+    case INTEGER_NEGATIVE:
+    case DECIMAL_NEGATIVE:
+    case DOUBLE_NEGATIVE:
+    case STRING_LITERAL1:
+    case STRING_LITERAL2:
+    case STRING_LITERAL_LONG1:
+    case STRING_LITERAL_LONG2:
+    case NIL:
+    case ANON:
+      n = GraphTerm();
+      break;
+    default:
+      jj_la1[49] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return n;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [43]    VarOrIRIref    ::=    Var | IRIref */
+  final public Expression VarOrIRIref() throws ParseException {
+                             Expression e;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case VAR1:
+    case VAR2:
+      e = Var();
+      break;
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+      e = IRIref();
+      break;
+    default:
+      jj_la1[50] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [44]    Var    ::=    VAR1 | VAR2 */
+  final public Variable Var() throws ParseException {
+                   Token t;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case VAR1:
+      t = jj_consume_token(VAR1);
+      break;
+    case VAR2:
+      t = jj_consume_token(VAR2);
+      break;
+    default:
+      jj_la1[51] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+                            {if (true) return queryStructure.newVariable(t.image);}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [45]    GraphTerm    ::=    IRIref |  RDFLiteral |  NumericLiteral |  BooleanLiteral |  BlankNode |  NIL */
+  final public Node GraphTerm() throws ParseException {
+                     Node n;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+      n = IRIref();
+      break;
+    case STRING_LITERAL1:
+    case STRING_LITERAL2:
+    case STRING_LITERAL_LONG1:
+    case STRING_LITERAL_LONG2:
+      n = RDFLiteral();
+      break;
+    case INTEGER:
+    case DECIMAL:
+    case DOUBLE:
+    case INTEGER_POSITIVE:
+    case DECIMAL_POSITIVE:
+    case DOUBLE_POSITIVE:
+    case INTEGER_NEGATIVE:
+    case DECIMAL_NEGATIVE:
+    case DOUBLE_NEGATIVE:
+      n = NumericLiteral();
+      break;
+    case TRUE:
+    case FALSE:
+      n = BooleanLiteral();
+      break;
+    case BLANK_NODE_LABEL:
+    case ANON:
+      n = BlankNode();
+      break;
+    case NIL:
+      jj_consume_token(NIL);
+                                                                                                     n = NIL_NODE;
+      break;
+    default:
+      jj_la1[52] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return n;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [46]    Expression    ::=    ConditionalOrExpression */
+  final public Expression Expression() throws ParseException {
+                            Expression e;
+    e = ConditionalOrExpression();
+                                  {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [47]    ConditionalOrExpression    ::=    ConditionalAndExpression ( '||' ConditionalAndExpression )* */
+  final public Expression ConditionalOrExpression() throws ParseException {
+                                         Expression e, ae;
+    e = ConditionalAndExpression();
+    label_15:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 53:
+        ;
+        break;
+      default:
+        jj_la1[53] = jj_gen;
+        break label_15;
+      }
+      jj_consume_token(53);
+      ae = ConditionalAndExpression();
+                                                                        e = new OrExpression(e, ae);
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [48]    ConditionalAndExpression    ::=    ValueLogical ( '&&' ValueLogical )* */
+  final public Expression ConditionalAndExpression() throws ParseException {
+                                          Expression e, e2;
+    e = ValueLogical();
+    label_16:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 54:
+        ;
+        break;
+      default:
+        jj_la1[54] = jj_gen;
+        break label_16;
+      }
+      jj_consume_token(54);
+      e2 = ValueLogical();
+                                                e = new AndExpression(e, e2);
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [49]    ValueLogical    ::=    RelationalExpression */
+  final public Expression ValueLogical() throws ParseException {
+                              Expression e;
+    e = RelationalExpression();
+                               {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [50]    RelationalExpression    ::=    NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression )? */
+  final public Expression RelationalExpression() throws ParseException {
+                                      Expression e, e2;
+    e = NumericExpression();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 55:
+    case 56:
+    case 57:
+    case 58:
+    case 59:
+    case 60:
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 55:
+        jj_consume_token(55);
+        e2 = NumericExpression();
+                                   e = new Equals(e, e2);
+        break;
+      case 56:
+        jj_consume_token(56);
+        e2 = NumericExpression();
+                                      e = new NotEquals(e, e2);
+        break;
+      case 57:
+        jj_consume_token(57);
+        e2 = NumericExpression();
+                                     e = new LessThan(e, e2);
+        break;
+      case 58:
+        jj_consume_token(58);
+        e2 = NumericExpression();
+                                     e = new GreaterThan(e, e2);
+        break;
+      case 59:
+        jj_consume_token(59);
+        e2 = NumericExpression();
+                                      e = new LessThanEqual(e, e2);
+        break;
+      case 60:
+        jj_consume_token(60);
+        e2 = NumericExpression();
+                                      e = new GreaterThanEqual(e, e2);
+        break;
+      default:
+        jj_la1[55] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+    default:
+      jj_la1[56] = jj_gen;
+      ;
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [51]    NumericExpression    ::=    AdditiveExpression */
+  final public Expression NumericExpression() throws ParseException {
+                                   Expression e;
+    e = AdditiveExpression();
+                             {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [52]    AdditiveExpression    ::=    MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | NumericLiteralPositive | NumericLiteralNegative )* */
+  final public Expression AdditiveExpression() throws ParseException {
+                                    Expression e, e2;
+    e = MultiplicativeExpression();
+    label_17:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 61:
+      case 62:
+      case INTEGER_POSITIVE:
+      case DECIMAL_POSITIVE:
+      case DOUBLE_POSITIVE:
+      case INTEGER_NEGATIVE:
+      case DECIMAL_NEGATIVE:
+      case DOUBLE_NEGATIVE:
+        ;
+        break;
+      default:
+        jj_la1[57] = jj_gen;
+        break label_17;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 61:
+        jj_consume_token(61);
+        e2 = MultiplicativeExpression();
+                                          e = new Plus(e, e2);
+        break;
+      case 62:
+        jj_consume_token(62);
+        e2 = MultiplicativeExpression();
+                                            e = new Minus(e, e2);
+        break;
+      case INTEGER_POSITIVE:
+      case DECIMAL_POSITIVE:
+      case DOUBLE_POSITIVE:
+        e2 = NumericLiteralPositive();
+                                      e = new Plus(e, e2);
+        break;
+      case INTEGER_NEGATIVE:
+      case DECIMAL_NEGATIVE:
+      case DOUBLE_NEGATIVE:
+        e2 = NumericLiteralNegative();
+                                      e = new Minus(e, e2);
+        break;
+      default:
+        jj_la1[58] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [53]    MultiplicativeExpression    ::=    UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )* */
+  final public Expression MultiplicativeExpression() throws ParseException {
+                                          Expression e, e2;
+    e = UnaryExpression();
+    label_18:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 40:
+      case 63:
+        ;
+        break;
+      default:
+        jj_la1[59] = jj_gen;
+        break label_18;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 40:
+        jj_consume_token(40);
+        e2 = UnaryExpression();
+                                 e = new Multiply(e, e2);
+        break;
+      case 63:
+        jj_consume_token(63);
+        e2 = UnaryExpression();
+                                   e = new Divide(e, e2);
+        break;
+      default:
+        jj_la1[60] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [54]    UnaryExpression    ::=      '!' PrimaryExpression  |  '+' PrimaryExpression  | '-' PrimaryExpression  | PrimaryExpression */
+  final public Expression UnaryExpression() throws ParseException {
+                                 Expression e;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 64:
+      jj_consume_token(64);
+      e = PrimaryExpression();
+                                {if (true) return new Not(e);}
+      break;
+    case 61:
+      jj_consume_token(61);
+      e = PrimaryExpression();
+                                  {if (true) return new UnaryPlus(e);}
+      break;
+    case 62:
+      jj_consume_token(62);
+      e = PrimaryExpression();
+                                  {if (true) return new UnaryMinus(e);}
+      break;
+    case STR:
+    case IS_URI:
+    case LANG:
+    case IS_IRI:
+    case LANGMATCHES:
+    case IS_BLANK:
+    case IS_LITERAL:
+    case DATATYPE:
+    case REGEX:
+    case BOUND:
+    case TRUE:
+    case SAME_TERM:
+    case FALSE:
+    case 46:
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+    case VAR1:
+    case VAR2:
+    case INTEGER:
+    case DECIMAL:
+    case DOUBLE:
+    case INTEGER_POSITIVE:
+    case DECIMAL_POSITIVE:
+    case DOUBLE_POSITIVE:
+    case INTEGER_NEGATIVE:
+    case DECIMAL_NEGATIVE:
+    case DOUBLE_NEGATIVE:
+    case STRING_LITERAL1:
+    case STRING_LITERAL2:
+    case STRING_LITERAL_LONG1:
+    case STRING_LITERAL_LONG2:
+      e = PrimaryExpression();
+                              {if (true) return e;}
+      break;
+    default:
+      jj_la1[61] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/* [55]    PrimaryExpression    ::=    BrackettedExpression | BuiltInCall | IRIrefOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var */
+  final public Expression PrimaryExpression() throws ParseException {
+                                   Expression e;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 46:
+      e = BrackettedExpression();
+      break;
+    case STR:
+    case IS_URI:
+    case LANG:
+    case IS_IRI:
+    case LANGMATCHES:
+    case IS_BLANK:
+    case IS_LITERAL:
+    case DATATYPE:
+    case REGEX:
+    case BOUND:
+    case SAME_TERM:
+      e = BuiltInCall();
+      break;
+    case IRI_REF:
+    case PNAME_NS:
+    case PNAME_LN:
+      e = IRIrefOrFunction();
+      break;
+    case STRING_LITERAL1:
+    case STRING_LITERAL2:
+    case STRING_LITERAL_LONG1:
+    case STRING_LITERAL_LONG2:
+      e = RDFLiteral();
+      break;
+    case INTEGER:
+    case DECIMAL:
+    case DOUBLE:
+    case INTEGER_POSITIVE:
+    case DECIMAL_POSITIVE:
+    case DOUBLE_POSITIVE:
+    case INTEGER_NEGATIVE:
+    case DECIMAL_NEGATIVE:
+    case DOUBLE_NEGATIVE:
+      e = NumericLiteral();
+      break;
+    case TRUE:
+    case FALSE:
+      e = BooleanLiteral();
+      break;
+    case VAR1:
+    case VAR2:
+      e = Var();
+      break;
+    default:
+      jj_la1[62] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [56]    BrackettedExpression    ::=    '(' Expression ')' */
+  final public Expression BrackettedExpression() throws ParseException {
+                                      Expression e;
+    jj_consume_token(46);
+    e = Expression();
+    jj_consume_token(48);
+                             {if (true) return e;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [57]    BuiltInCall    ::=      'STR' '(' Expression ')' */
+/* |  'LANG' '(' Expression ')' */
+/* |  'LANGMATCHES' '(' Expression ',' Expression ')' */
+/* |  'DATATYPE' '(' Expression ')' */
+/* |  'BOUND' '(' Var ')' */
+/* |  'sameTerm' '(' Expression ',' Expression ')' */
+/* |  'isIRI' '(' Expression ')' */
+/* |  'isURI' '(' Expression ')' */
+/* |  'isBLANK' '(' Expression ')' */
+/* |  'isLITERAL' '(' Expression ')' */
+/* |  RegexExpression */
+  final public BuiltInCall BuiltInCall() throws ParseException {
+                              Expression e, e2; Variable v;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case STR:
+      jj_consume_token(STR);
+      jj_consume_token(46);
+      e = Expression();
+      jj_consume_token(48);
+                                   {if (true) return new BicStr(e);}
+      break;
+    case LANG:
+      jj_consume_token(LANG);
+      jj_consume_token(46);
+      e = Expression();
+      jj_consume_token(48);
+                                      {if (true) return new BicLang(e);}
+      break;
+    case LANGMATCHES:
+      jj_consume_token(LANGMATCHES);
+      jj_consume_token(46);
+      e = Expression();
+      jj_consume_token(47);
+      e2 = Expression();
+      jj_consume_token(48);
+                                                                 {if (true) return new BicLangMatches(e, e2);}
+      break;
+    case DATATYPE:
+      jj_consume_token(DATATYPE);
+      jj_consume_token(46);
+      e = Expression();
+      jj_consume_token(48);
+                                          {if (true) return new BicDatatype(e);}
+      break;
+    case BOUND:
+      jj_consume_token(BOUND);
+      jj_consume_token(46);
+      v = Var();
+      jj_consume_token(48);
+                                {if (true) return new BicBound(v);}
+      break;
+    case SAME_TERM:
+      jj_consume_token(SAME_TERM);
+      jj_consume_token(46);
+      e = Expression();
+      jj_consume_token(47);
+      e2 = Expression();
+      jj_consume_token(48);
+                                                               {if (true) return new BicSameTerm(e, e2);}
+      break;
+    case IS_IRI:
+      jj_consume_token(IS_IRI);
+      jj_consume_token(46);
+      e = Expression();
+      jj_consume_token(48);
+                                        {if (true) return new BicIsIri(e);}
+      break;
+    case IS_URI:
+      jj_consume_token(IS_URI);
+      jj_consume_token(46);
+      e = Expression();
+      jj_consume_token(48);
+                                        {if (true) return new BicIsUri(e);}
+      break;
+    case IS_BLANK:
+      jj_consume_token(IS_BLANK);
+      jj_consume_token(46);
+      e = Expression();
+      jj_consume_token(48);
+                                          {if (true) return new BicIsBlank(e);}
+      break;
+    case IS_LITERAL:
+      jj_consume_token(IS_LITERAL);
+      jj_consume_token(46);
+      e = Expression();
+      jj_consume_token(48);
+                                            {if (true) return new BicIsLiteral(e);}
+      break;
+    case REGEX:
+      e = RegexExpression();
+                            {if (true) return (BuiltInCall)e;}
+      break;
+    default:
+      jj_la1[63] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/* [58]    RegexExpression    ::=    'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')' */
+  final public BuiltInCall RegexExpression() throws ParseException {
+                                  Expression e1, e2, e3 = null;
+    jj_consume_token(REGEX);
+    jj_consume_token(46);
+    e1 = Expression();
+    jj_consume_token(47);
+    e2 = Expression();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 47:
+      jj_consume_token(47);
+      e3 = Expression();
+      break;
+    default:
+      jj_la1[64] = jj_gen;
+      ;
+    }
+    jj_consume_token(48);
+      {if (true) return new BicRegEx(e1, e2, e3);}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [59]    IRIrefOrFunction    ::=    IRIref ArgList? */
+  final public Expression IRIrefOrFunction() throws ParseException {
+                                  IRIReference ref; ArgList list;
+    ref = IRIref();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 46:
+    case NIL:
+      list = ArgList();
+                                   {if (true) return new FunctionCall(ref, list);}
+      break;
+    default:
+      jj_la1[65] = jj_gen;
+      ;
+    }
+      {if (true) return ref;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [60]    RDFLiteral    ::=    String ( LANGTAG | ( '^^' IRIref ) )? */
+  final public RDFLiteral RDFLiteral() throws ParseException {
+                            Token t; RDFLiteral l; String s; IRIReference ref;
+    s = String();
+                   l = new RDFLiteral(s);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 65:
+    case LANGTAG:
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LANGTAG:
+        t = jj_consume_token(LANGTAG);
+                    l.setLanguage(t.image);
+        break;
+      case 65:
+        jj_consume_token(65);
+        ref = IRIref();
+                            l.setDatatype(ref);
+        break;
+      default:
+        jj_la1[66] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+    default:
+      jj_la1[67] = jj_gen;
+      ;
+    }
+      {if (true) return l;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [61]    NumericLiteral    ::=    NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative */
+  final public NumericLiteral NumericLiteral() throws ParseException {
+                                    NumericLiteral l;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case INTEGER:
+    case DECIMAL:
+    case DOUBLE:
+      l = NumericLiteralUnsigned();
+      break;
+    case INTEGER_POSITIVE:
+    case DECIMAL_POSITIVE:
+    case DOUBLE_POSITIVE:
+      l = NumericLiteralPositive();
+      break;
+    case INTEGER_NEGATIVE:
+    case DECIMAL_NEGATIVE:
+    case DOUBLE_NEGATIVE:
+      l = NumericLiteralNegative();
+      break;
+    default:
+      jj_la1[68] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return l;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [62]    NumericLiteralUnsigned    ::=    INTEGER |  DECIMAL |  DOUBLE */
+  final public NumericLiteral NumericLiteralUnsigned() throws ParseException {
+                                            Token t;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case INTEGER:
+      t = jj_consume_token(INTEGER);
+                  {if (true) return new IntegerLiteral(t.image);}
+      break;
+    case DECIMAL:
+      t = jj_consume_token(DECIMAL);
+                    {if (true) return new DecimalLiteral(t.image);}
+      break;
+    case DOUBLE:
+      t = jj_consume_token(DOUBLE);
+                   {if (true) return new DoubleLiteral(t.image);}
+      break;
+    default:
+      jj_la1[69] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/* [63]    NumericLiteralPositive    ::=    INTEGER_POSITIVE |  DECIMAL_POSITIVE |  DOUBLE_POSITIVE */
+  final public NumericLiteral NumericLiteralPositive() throws ParseException {
+                                            Token t;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case INTEGER_POSITIVE:
+      t = jj_consume_token(INTEGER_POSITIVE);
+                           {if (true) return new IntegerLiteral(t.image);}
+      break;
+    case DECIMAL_POSITIVE:
+      t = jj_consume_token(DECIMAL_POSITIVE);
+                             {if (true) return new DecimalLiteral(t.image);}
+      break;
+    case DOUBLE_POSITIVE:
+      t = jj_consume_token(DOUBLE_POSITIVE);
+                            {if (true) return new DoubleLiteral(t.image);}
+      break;
+    default:
+      jj_la1[70] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/* [64]    NumericLiteralNegative    ::=    INTEGER_NEGATIVE |  DECIMAL_NEGATIVE |  DOUBLE_NEGATIVE */
+  final public NumericLiteral NumericLiteralNegative() throws ParseException {
+                                            Token t;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case INTEGER_NEGATIVE:
+      t = jj_consume_token(INTEGER_NEGATIVE);
+                           {if (true) return new IntegerLiteral(t.image);}
+      break;
+    case DECIMAL_NEGATIVE:
+      t = jj_consume_token(DECIMAL_NEGATIVE);
+                             {if (true) return new DecimalLiteral(t.image);}
+      break;
+    case DOUBLE_NEGATIVE:
+      t = jj_consume_token(DOUBLE_NEGATIVE);
+                            {if (true) return new DoubleLiteral(t.image);}
+      break;
+    default:
+      jj_la1[71] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/* [65]    BooleanLiteral    ::=    'true' |  'false' */
+  final public BooleanLiteral BooleanLiteral() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case TRUE:
+      jj_consume_token(TRUE);
+             {if (true) return BooleanLiteral.TRUE;}
+      break;
+    case FALSE:
+      jj_consume_token(FALSE);
+                {if (true) return BooleanLiteral.FALSE;}
+      break;
+    default:
+      jj_la1[72] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/* [66]    String    ::=    STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2 */
+  final public String String() throws ParseException {
+                    Token t;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case STRING_LITERAL1:
+      t = jj_consume_token(STRING_LITERAL1);
+                          {if (true) return unquote(t.image) ;}
+      break;
+    case STRING_LITERAL2:
+      t = jj_consume_token(STRING_LITERAL2);
+                            {if (true) return unquote(t.image) ;}
+      break;
+    case STRING_LITERAL_LONG1:
+      t = jj_consume_token(STRING_LITERAL_LONG1);
+                                 {if (true) return unTripleQuote(t.image) ;}
+      break;
+    case STRING_LITERAL_LONG2:
+      t = jj_consume_token(STRING_LITERAL_LONG2);
+                                 {if (true) return unTripleQuote(t.image) ;}
+      break;
+    default:
+      jj_la1[73] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/* [67]    IRIref    ::=    IRI_REF |  PrefixedName */
+  final public IRIReference IRIref() throws ParseException {
+                          IRIReference i; Token t;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IRI_REF:
+      t = jj_consume_token(IRI_REF);
+                  {if (true) return queryStructure.newIRIRef(unquote(t.image));}
+      break;
+    case PNAME_NS:
+    case PNAME_LN:
+      i = PrefixedName();
+                         {if (true) return i;}
+      break;
+    default:
+      jj_la1[74] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/* [68]    PrefixedName    ::=    PNAME_LN | PNAME_NS */
+  final public IRIReference PrefixedName() throws ParseException {
+                                Token t;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case PNAME_LN:
+      t = jj_consume_token(PNAME_LN);
+      break;
+    case PNAME_NS:
+      t = jj_consume_token(PNAME_NS);
+      break;
+    default:
+      jj_la1[75] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      {if (true) return queryStructure.newPrefixedName(t.image);}
+    throw new Error("Missing return statement in function");
+  }
+
+/* [69]    BlankNode    ::=    BLANK_NODE_LABEL |  ANON */
+  final public BlankNode BlankNode() throws ParseException {
+                          Token t;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BLANK_NODE_LABEL:
+      t = jj_consume_token(BLANK_NODE_LABEL);
+                           {if (true) return new BlankNode(t.image);}
+      break;
+    case ANON:
+      jj_consume_token(ANON);
+               {if (true) return queryStructure.newBlankNode();}
+      break;
+    default:
+      jj_la1[76] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  public SparqlParserTokenManager token_source;
+  SimpleCharStream jj_input_stream;
+  public Token token, jj_nt;
+  private int jj_ntk;
+  private int jj_gen;
+  final private int[] jj_la1 = new int[77];
+  static private int[] jj_la1_0;
+  static private int[] jj_la1_1;
+  static private int[] jj_la1_2;
+  static private int[] jj_la1_3;
+  static {
+      jj_la1_0();
+      jj_la1_1();
+      jj_la1_2();
+      jj_la1_3();
+   }
+   private static void jj_la1_0() {
+      jj_la1_0 = new int[] {0x40820100,0x200,0x10000,0x80000000,0x80000000,0x0,0x0,0x1000,0x1000,0x0,0x0,0x1000,0x2000000,0x1000,0x80000,0x2000000,0x400,0x1040000,0x1000000,0x40000,0x1040000,0x3860c000,0x0,0x3860c000,0x3860c000,0x0,0x102000,0x102000,0x0,0x0,0x0,0x0,0x102000,0x4000000,0x3860c000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3860c000,0x3860c000,0x3860c000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+   }
+   private static void jj_la1_1() {
+      jj_la1_1 = new int[] {0x0,0x0,0x0,0x8,0x8,0x0,0x100,0x0,0x0,0x0,0x100,0x0,0x800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4656,0x600,0x4056,0x4656,0x840a0,0x801,0x801,0x1000,0x840a0,0x840a0,0x1000,0x800,0x0,0x4056,0x8000,0x4000,0x840a0,0x840a0,0x1000,0x840a0,0x20000,0x40000,0x40000,0x8000,0x40000,0x84000,0x840a0,0x840a0,0xa0,0x0,0x0,0xa0,0x200000,0x400000,0x1f800000,0x1f800000,0x60000000,0x60000000,0x80000100,0x80000100,0x600040f6,0x40f6,0x56,0x8000,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0xa0,0x0,0x0,0x0,0x0,};
+   }
+   private static void jj_la1_2() {
+      jj_la1_2 = new int[] {0x0,0x0,0x0,0x0,0x0,0xc0,0xc0,0x0,0x0,0xdc,0xdc,0x0,0x0,0x0,0x1c,0x0,0x0,0x0,0x0,0x0,0x0,0xdc,0x0,0xdc,0xdc,0x2bdff0fc,0x0,0x0,0x0,0x2bdff0fc,0x2bdff0fc,0x0,0x0,0x0,0x1c,0x0,0x8000000,0x2bdff0fc,0x2bdff0fc,0x0,0x2bdff0fc,0x0,0xdc,0xdc,0x0,0xdc,0x0,0x2bdff0fc,0x2bdff0fc,0x2bdff0fc,0xdc,0xc0,0x2bdff03c,0x0,0x0,0x0,0x0,0x1f8000,0x1f8000,0x0,0x0,0x3dff0dd,0x3dff0dc,0x0,0x0,0x8000000,0x102,0x102,0x1ff000,0x7000,0x38000,0x1c0000,0x0,0x3c00000,0x1c,0x18,0x20000020,};
+   }
+   private static void jj_la1_3() {
+      jj_la1_3 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+   }
+
+  public SparqlParser(java.io.InputStream stream) {
+     this(stream, null);
+  }
+  public SparqlParser(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source = new SparqlParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 77; i++) jj_la1[i] = -1;
+  }
+
+  public void ReInit(java.io.InputStream stream) {
+     ReInit(stream, null);
+  }
+  public void ReInit(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 77; i++) jj_la1[i] = -1;
+  }
+
+  public SparqlParser(java.io.Reader stream) {
+    jj_input_stream = new SimpleCharStream(stream, 1, 1);
+    token_source = new SparqlParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 77; i++) jj_la1[i] = -1;
+  }
+
+  public void ReInit(java.io.Reader stream) {
+    jj_input_stream.ReInit(stream, 1, 1);
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 77; i++) jj_la1[i] = -1;
+  }
+
+  public SparqlParser(SparqlParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 77; i++) jj_la1[i] = -1;
+  }
+
+  public void ReInit(SparqlParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 77; i++) jj_la1[i] = -1;
+  }
+
+  final private Token jj_consume_token(int kind) throws ParseException {
+    Token oldToken;
+    if ((oldToken = token).next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    if (token.kind == kind) {
+      jj_gen++;
+      return token;
+    }
+    token = oldToken;
+    jj_kind = kind;
+    throw generateParseException();
+  }
+
+  final public Token getNextToken() {
+    if (token.next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    jj_gen++;
+    return token;
+  }
+
+  final public Token getToken(int index) {
+    Token t = token;
+    for (int i = 0; i < index; i++) {
+      if (t.next != null) t = t.next;
+      else t = t.next = token_source.getNextToken();
+    }
+    return t;
+  }
+
+  final private int jj_ntk() {
+    if ((jj_nt=token.next) == null)
+      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
+    else
+      return (jj_ntk = jj_nt.kind);
+  }
+
+  private java.util.Vector<int[]> jj_expentries = new java.util.Vector<int[]>();
+  private int[] jj_expentry;
+  private int jj_kind = -1;
+
+  public ParseException generateParseException() {
+    jj_expentries.removeAllElements();
+    boolean[] la1tokens = new boolean[100];
+    for (int i = 0; i < 100; i++) {
+      la1tokens[i] = false;
+    }
+    if (jj_kind >= 0) {
+      la1tokens[jj_kind] = true;
+      jj_kind = -1;
+    }
+    for (int i = 0; i < 77; i++) {
+      if (jj_la1[i] == jj_gen) {
+        for (int j = 0; j < 32; j++) {
+          if ((jj_la1_0[i] & (1<<j)) != 0) {
+            la1tokens[j] = true;
+          }
+          if ((jj_la1_1[i] & (1<<j)) != 0) {
+            la1tokens[32+j] = true;
+          }
+          if ((jj_la1_2[i] & (1<<j)) != 0) {
+            la1tokens[64+j] = true;
+          }
+          if ((jj_la1_3[i] & (1<<j)) != 0) {
+            la1tokens[96+j] = true;
+          }
+        }
+      }
+    }
+    for (int i = 0; i < 100; i++) {
+      if (la1tokens[i]) {
+        jj_expentry = new int[1];
+        jj_expentry[0] = i;
+        jj_expentries.addElement(jj_expentry);
+      }
+    }
+    int[][] exptokseq = new int[jj_expentries.size()][];
+    for (int i = 0; i < jj_expentries.size(); i++) {
+      exptokseq[i] = (int[])jj_expentries.elementAt(i);
+    }
+    return new ParseException(token, exptokseq, tokenImage);
+  }
+
+  final public void enable_tracing() {
+  }
+
+  final public void disable_tracing() {
+  }
+
+}

Added: trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.jj
===================================================================
--- trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.jj	                        (rev 0)
+++ trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.jj	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,842 @@
+/*
+ * Copyright 2008 Fedora Commons
+ * 
+ * Licensed 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.
+ *
+ * Credits: Peter Royal peter.royal at pobox.com
+ *            - for providing the grammar structure of this file.
+ *          Andy Seaborne andy.seaborne at hp.com
+ *            - for general direction on grammar processing,
+ *              as implemented in Jena ARQ
+ */
+
+options
+{
+   STATIC=false;
+   UNICODE_INPUT=true;
+   IGNORE_CASE=false;
+   JAVA_UNICODE_ESCAPE=false;
+   DEBUG_PARSER=false;
+   JDK_VERSION="1.5";
+}
+
+PARSER_BEGIN(SparqlParser)
+package org.mulgara.sparql.parser;
+
+import java.io.StringReader;
+import static org.mulgara.sparql.parser.QueryType.*;
+import org.mulgara.sparql.parser.cst.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.LinkedList;
+import static org.mulgara.sparql.parser.cst.Nil.NIL_NODE;
+
+public class SparqlParser {
+
+  private QueryStructureImpl queryStructure = new QueryStructureImpl();
+
+  public void setDefaultBase(URI base) {
+  	queryStructure.setBase(base);
+  }
+
+  public static QueryStructure parse(String query) throws ParseException {
+    SparqlParser parser = new SparqlParser(new StringReader(query));
+    parser.Query();
+    return parser.queryStructure;
+  }
+
+  public static QueryStructure parse(String query, URI defaultBase) throws ParseException {
+    SparqlParser parser = new SparqlParser(new StringReader(query));
+    parser.Query();
+    parser.setDefaultBase(defaultBase);
+    return parser.queryStructure;
+  }
+
+  private static String unquote(String s) {
+    return s.substring(1, s.length() - 1);
+  }
+  
+  private static String unTripleQuote(String s) {
+    return s.substring(3, s.length() - 3);
+  }
+  
+  private static GroupGraphPattern conjoin(GroupGraphPattern g1, GroupGraphPattern g2) {
+  	assert g2 != null;
+    if (g1 == GroupGraphPattern.EMPTY) return g2;
+    return new GraphPatternConjunction(g1, g2);
+  }
+  
+  private static URI uri(String u) throws ParseException {
+  	try {
+  	  return new URI(unquote(u));
+  	} catch (URISyntaxException e) {
+  	  throw new ParseException("Bad URI syntax");
+  	}
+  }
+
+}
+PARSER_END(SparqlParser)
+
+SKIP :
+{
+    "\t" | "\n" | "\r" | "\f" | " "
+}
+
+MORE :
+{
+    "#" : IN_COMMENT
+}
+
+<IN_COMMENT>
+SPECIAL_TOKEN :
+{
+  <COMMENT: ( ~[ "\r","\n" ] )* > : DEFAULT
+}
+
+TOKEN [IGNORE_CASE] :
+{
+    < SELECT : "SELECT" >
+|   < BASE : "BASE" >
+|   < ORDER : "ORDER" >
+|   < BY : "BY" >
+|   < FROM : "FROM" >
+|   < GRAPH : "GRAPH" >
+|   < STR : "STR" >
+|   < IS_URI : "isURI" >
+|   < PREFIX : "PREFIX" >
+|   < CONSTRUCT : "construct" >
+|   < LIMIT : "limit" >
+|   < NAMED : "named" >
+|   < OPTIONAL : "optional" >
+|   < LANG : "lang" >
+|   < IS_IRI : "isIRI" >
+|   < DESCRIBE : "describe" >
+|   < OFFSET : "offset" >
+|   < WHERE : "where" >
+|   < UNION : "union" >
+|   < LANGMATCHES : "LANGMATCHES" >
+|   < IS_BLANK : "isBLANK" >
+|   < IS_LITERAL : "isLITERAL" >
+|   < ASK : "ask" >
+|   < DISTINCT : "distinct" >
+|   < FILTER : "filter" >
+|   < DATATYPE : "datatype" >
+|   < REGEX : "regex" >
+|   < REDUCED : "reduced" >
+|   < BOUND : "bound" >
+|   < TRUE : "true" >
+|   < SAME_TERM : "sameTERM" >
+|   < FALSE : "false" >
+}
+
+
+/* [1]      Query      ::=      Prologue ( SelectQuery | ConstructQuery | DescribeQuery | AskQuery ) */
+void Query() : {}
+{
+    Prologue() ( SelectQuery() | ConstructQuery() | DescribeQuery() | AskQuery() ) <EOF>
+}
+
+/* [2]      Prologue      ::=      BaseDecl? PrefixDecl* */
+void Prologue() : {}
+{
+    ( BaseDecl() )? ( PrefixDecl() )*
+}
+
+/* [3]      BaseDecl      ::=      'BASE' IRI_REF */
+void BaseDecl() : { IRIReference ref; }
+{
+    <BASE> ref=IRIref() { queryStructure.setBase(ref.getUri()); }
+}
+
+/* [4]      PrefixDecl      ::=      'PREFIX' PNAME_NS IRI_REF */
+void PrefixDecl() : { Token ns, ref; }
+{
+    <PREFIX> ns=<PNAME_NS> ref=<IRI_REF>
+    { queryStructure.addPrefix(ns.image, uri(ref.image)); }
+}
+
+/* [5]      SelectQuery   ::=   'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( Var+ | '*' ) DatasetClause* WhereClause SolutionModifier */
+void SelectQuery() : { Variable v; }
+{
+    <SELECT> { queryStructure.setType(select); }
+    (
+      <DISTINCT> { queryStructure.setDistinct(); }
+      | <REDUCED> { queryStructure.setReduced(); }
+    )?
+    (
+      ( v=Var() { queryStructure.addSelection(v); } )+
+      |
+      "*" { queryStructure.setSelectAll(); }
+    )
+    ( DatasetClause() )*
+    WhereClause()
+    SolutionModifier()
+}
+
+/* [6]      ConstructQuery    ::=   'CONSTRUCT' ConstructTemplate DatasetClause* WhereClause SolutionModifier */
+void ConstructQuery() : {}
+{
+    <CONSTRUCT> { queryStructure.setType(construct); }
+    ConstructTemplate()
+    ( DatasetClause() )*
+    WhereClause()
+    SolutionModifier()
+}
+
+/* [7]      DescribeQuery      ::=      'DESCRIBE' ( VarOrIRIref+ | '*' ) DatasetClause* WhereClause? SolutionModifier */
+void DescribeQuery() : { Node n; }
+{
+    <DESCRIBE> { queryStructure.setType(describe); }
+    (
+      ( n=VarOrIRIref() { queryStructure.addSelection(n); } )+
+      |
+      "*" { queryStructure.setSelectAll(); }
+    )
+    ( DatasetClause() )*
+    ( WhereClause() )?
+    SolutionModifier()
+}
+
+/* [8]      AskQuery      ::=   'ASK' DatasetClause* WhereClause */
+void AskQuery() : {}
+{
+    <ASK> { queryStructure.setType(ask); }
+    ( DatasetClause() )*
+    WhereClause()
+}
+
+/* [9]   DatasetClause   ::=   'FROM' ( DefaultGraphClause | NamedGraphClause ) */
+void DatasetClause() : {}
+{
+    <FROM> (DefaultGraphClause() | NamedGraphClause())
+}
+
+/* [10]    DefaultGraphClause    ::=    SourceSelector */
+void DefaultGraphClause() : { IRIReference ref; }
+{
+    ref=SourceSelector() { queryStructure.addDefaultFrom(ref); }
+}
+
+/* [11]    NamedGraphClause    ::=    'NAMED' SourceSelector */
+void NamedGraphClause() : { IRIReference ref; }
+{
+    <NAMED> ref=SourceSelector() { queryStructure.addNamedFrom(ref); }
+}
+
+/* [12]    SourceSelector    ::=    IRIref */
+IRIReference SourceSelector() : { IRIReference r; }
+{
+    r=IRIref() { return r; }
+}
+
+/* [13]    WhereClause    ::=    'WHERE'? GroupGraphPattern */
+void WhereClause() : { GroupGraphPattern g; }
+{
+    (<WHERE>)? g=GroupGraphPattern() { queryStructure.setWhereClause(g); }
+}
+
+/* [14]    SolutionModifier    ::=    OrderClause? LimitOffsetClauses? */
+void SolutionModifier() : {}
+{
+    ( OrderClause() )?
+    ( LimitOffsetClauses() )?
+}
+
+/* [15]    LimitOffsetClauses    ::=    ( LimitClause OffsetClause? | OffsetClause LimitClause? ) */
+void LimitOffsetClauses() : {}
+{
+  ( LimitClause() (OffsetClause())? )
+  |
+  ( OffsetClause() (LimitClause())? )
+}
+
+/* [16]    OrderClause    ::=    'ORDER' 'BY' OrderCondition+ */
+void OrderClause() : {}
+{
+    <ORDER> <BY> ( OrderCondition() )+
+}
+
+/* [17]    OrderCondition    ::=     ( ( 'ASC' | 'DESC' ) BrackettedExpression ) | ( Constraint | Var ) */
+void OrderCondition() : { boolean asc = true; Expression e; }
+{
+  ( ( "ASC" | "DESC" { asc = false; } ) e=BrackettedExpression() )
+  |
+  ( e=Constraint() | e=Var() )
+  { queryStructure.addOrdering(e, asc); }
+}
+
+/* [18]    LimitClause    ::=    'LIMIT' INTEGER */
+void LimitClause() : { Token t; }
+{
+    <LIMIT> t=<INTEGER> { queryStructure.setLimit(t.image); }
+}
+
+/* [19]    OffsetClause    ::=    'OFFSET' INTEGER */
+void OffsetClause() : { Token t; }
+{
+    <OFFSET> t=<INTEGER> { queryStructure.setOffset(t.image); }
+}
+
+/* [20]    GroupGraphPattern    ::=    '{' TriplesBlock? ( ( GraphPatternNotTriples | Filter ) '.'? TriplesBlock? )* '}' */
+GroupGraphPattern GroupGraphPattern() : {
+  GroupGraphPattern g = null, g2;
+  GraphPatternConjunction c = null;
+  Expression f;
+} {
+	{ g = GroupGraphPattern.EMPTY; }
+    "{"
+    ( g=TriplesBlock() )?
+    (
+      (
+        g=GraphPatternNotTriples(g)
+        | f=Filter() {
+            if (g == null) throw new ParseException("Cannot filter an empty pattern");
+            g.setFilter(f);
+        }
+      )
+      (".")?
+      (
+        g2=TriplesBlock() {
+            if (g == null) g = g2;
+            else {
+	            // preferentially choose c so we get the right constructor
+	            if (c == null) c = new GraphPatternConjunction(g, g2);
+	            else c = new GraphPatternConjunction(c, g2);
+	            g = c;
+            }
+        }
+      )?
+    )*
+    "}"
+    { return g; }
+}
+
+/* [21]    TriplesBlock    ::=    TriplesSameSubject ( '.' TriplesBlock? )? */
+GraphPatternConjunction TriplesBlock() : { TripleList l; GraphPatternConjunction g = null; }
+{
+    l=TriplesSameSubject() ( "." (g=TriplesBlock() { g = new GraphPatternConjunction(g, l); } )? )?
+    {
+      if (g == null) return new GraphPatternConjunction(l);
+      return g;
+    }
+}
+
+/* [22]    GraphPatternNotTriples    ::=    OptionalGraphPattern | GroupOrUnionGraphPattern | GraphGraphPattern */
+GroupGraphPattern GraphPatternNotTriples(GroupGraphPattern in) : { GroupGraphPattern g; }
+{
+    ( g=OptionalGraphPattern(in) | g=GroupOrUnionGraphPattern(in) | g=GraphGraphPattern(in) )
+    { return g; }
+}
+
+/* [23]    OptionalGraphPattern    ::=    'OPTIONAL' GroupGraphPattern */
+GroupGraphPattern OptionalGraphPattern(GroupGraphPattern in) : { GroupGraphPattern g; }
+{
+    <OPTIONAL> g=GroupGraphPattern() { return new GraphPatternOptional(in, g); }
+}
+
+/* [24]    GraphGraphPattern    ::=    'GRAPH' VarOrIRIref GroupGraphPattern */
+GroupGraphPattern GraphGraphPattern(GroupGraphPattern in) : { Expression e; GroupGraphPattern g; }
+{
+    <GRAPH> e=VarOrIRIref() g=GroupGraphPattern() {
+      g.setGraph(e);
+      return conjoin(in, g);
+    }
+}
+
+/* [25]    GroupOrUnionGraphPattern    ::=    GroupGraphPattern ( 'UNION' GroupGraphPattern )* */
+GroupGraphPattern GroupOrUnionGraphPattern(GroupGraphPattern in) : { GroupGraphPattern g1, g2; GraphPatternDisjunction d = null; }
+{
+    g1=GroupGraphPattern() (
+      <UNION> g2=GroupGraphPattern() {
+      	// use an existing disjunction if available, to pick the correct constructor
+      	if (d == null) d = new GraphPatternDisjunction(g1, g2);
+      	else d = new GraphPatternDisjunction(d, g2);
+      	g1 = d;
+      } 
+    )*
+    { return conjoin(in, g1); }
+}
+
+/* [26]    Filter    ::=    'FILTER' Constraint */
+Expression Filter() : { Expression e; }
+{
+    <FILTER> e=Constraint() { return e; }
+}
+
+/* [27]    Constraint    ::=    BrackettedExpression | BuiltInCall | FunctionCall */
+Expression Constraint() : { Expression e; }
+{
+    ( e=BrackettedExpression() | e=BuiltInCall() | e=FunctionCall() )
+    { return e; }
+}
+
+/* [28]    FunctionCall    ::=    IRIref ArgList */
+FunctionCall FunctionCall() : { IRIReference r; ArgList l;}
+{
+    r=IRIref() l=ArgList()
+    { return new FunctionCall(r, l); }
+}
+
+/* [29]    ArgList    ::=    ( NIL | '(' Expression ( ',' Expression )* ')' ) */
+ArgList ArgList() : { ArgList list = new ArgList(); Expression e; }
+{
+  (
+    <NIL>
+    | ( "(" e=Expression() { list.add(e); } ( "," e=Expression() { list.add(e); } )*
+        ")"
+    )
+  ) { return list; }
+}
+
+/* [30]    ConstructTemplate    ::=    '{' ConstructTriples? '}' */
+void ConstructTemplate() : { TripleList triples = null; }
+{
+    "{" ( triples=ConstructTriples() )? "}"
+    { queryStructure.setConstructTemplate(triples); }
+}
+
+/* [31]    ConstructTriples    ::=    TriplesSameSubject ( '.' ConstructTriples? )? */
+TripleList ConstructTriples() : { TripleList triples, t; }
+{
+    triples=TriplesSameSubject() ( "." (t=ConstructTriples() { triples.concat(t); } )? )?
+    { return triples; }
+}
+
+/* [32]    TriplesSameSubject    ::=    VarOrTerm PropertyListNotEmpty |  TriplesNode PropertyList */
+TripleList TriplesSameSubject() : { Node s; AnnotatedNode an; PropertyList pl; }
+{
+  ( s=VarOrTerm() pl=PropertyListNotEmpty() { return new TripleList(s, pl); } )
+  |
+  ( an=TriplesNode() pl=PropertyList() { return new TripleList(an, pl); } )
+}
+
+/* [33]    PropertyListNotEmpty    ::=    Verb ObjectList ( ';' ( Verb ObjectList )? )* */
+PropertyList PropertyListNotEmpty() : { Node v; List<Node> o; PropertyList pl = new PropertyList(); }
+{
+    v=Verb() o=ObjectList() { pl.add(v, o); }
+    ( ";" ( v=Verb() o=ObjectList() { pl.add(v, o); } )? )*
+    { return pl; }
+}
+
+/* [34]    PropertyList    ::=    PropertyListNotEmpty? */
+PropertyList PropertyList() : { PropertyList pl = null; }
+{
+    ( pl=PropertyListNotEmpty() )?
+    { return pl == null ? new PropertyList() : pl; }
+}
+
+/* [35]    ObjectList    ::=    Object ( ',' Object )* */
+List<Node> ObjectList() : { List<Node> l; Node n; }
+{
+	{ l = new LinkedList<Node>(); }
+    n=Object() { l.add(n); }
+    ( "," Object() { l.add(n); } )*
+    { return l; }
+}
+
+/* [36]    Object    ::=    GraphNode */
+Node Object() : { Node n; }
+{
+    n=GraphNode() { return n; }
+}
+
+/* [37]    Verb    ::=    VarOrIRIref | 'a' */
+Expression Verb() : { Expression e; }
+{
+    e=VarOrIRIref() { return e; }
+    | "a" { return IRIReference.RDF_TYPE; }
+}
+
+// Return a node AND a conjunction to the current context
+/* [38]    TriplesNode    ::=    Collection |  BlankNodePropertyList */
+AnnotatedNode TriplesNode() : { AnnotatedNode n; }
+{
+    ( n=Collection() | n=BlankNodePropertyList() )
+    { return n; }
+}
+
+/* [39]    BlankNodePropertyList    ::=    '[' PropertyListNotEmpty ']' */
+AnnotatedNode BlankNodePropertyList() : { PropertyList pl; }
+{
+    "[" pl=PropertyListNotEmpty() "]"
+    { return new AnnotatedNode(queryStructure.newBlankNode(), pl); }
+}
+
+/* [40]    Collection    ::=    '(' GraphNode+ ')' */
+/* Returns a *NODE* that is a collection.  The rest of the collection will be conjoined after. */
+AnnotatedNode Collection() : { Node n; GraphList l = queryStructure.newList(); }
+{
+    "(" (
+      n=GraphNode()  { l.add(n); }
+    )+ ")"
+    { return new AnnotatedNode(l); }
+}
+
+/* [41]    GraphNode    ::=    VarOrTerm |  TriplesNode */
+Node GraphNode() : { Node n; }
+{
+    ( n=VarOrTerm() | n=TriplesNode() )
+    { return n; }
+}
+
+/* [42]    VarOrTerm    ::=    Var | GraphTerm */
+Node VarOrTerm() : { Node n; }
+{
+    ( n=Var() | n=GraphTerm() )
+    { return n; }
+}
+
+/* [43]    VarOrIRIref    ::=    Var | IRIref */
+Expression VarOrIRIref() : { Expression e; }
+{
+    (e=Var() | e=IRIref())
+    { return e; }
+}
+
+/* [44]    Var    ::=    VAR1 | VAR2 */
+Variable Var() : { Token t;}
+{
+    (t=<VAR1> | t=<VAR2>) { return queryStructure.newVariable(t.image); }
+}
+
+/* [45]    GraphTerm    ::=    IRIref |  RDFLiteral |  NumericLiteral |  BooleanLiteral |  BlankNode |  NIL */
+Node GraphTerm() : { Node n; }
+{
+    (n=IRIref() | n=RDFLiteral() | n=NumericLiteral() | n=BooleanLiteral() | n=BlankNode() | <NIL> { n = NIL_NODE; })
+    { return n; }
+}
+
+/* [46]    Expression    ::=    ConditionalOrExpression */
+Expression Expression() : { Expression e; }
+{
+    e=ConditionalOrExpression() { return e; }
+}
+
+/* [47]    ConditionalOrExpression    ::=    ConditionalAndExpression ( '||' ConditionalAndExpression )* */
+Expression ConditionalOrExpression() : { Expression e, ae; }
+{
+    e=ConditionalAndExpression() ( "||" ae=ConditionalAndExpression() { e = new OrExpression(e, ae); } )*
+    { return e; }
+}
+
+/* [48]    ConditionalAndExpression    ::=    ValueLogical ( '&&' ValueLogical )* */
+Expression ConditionalAndExpression() : { Expression e, e2; }
+{
+    e=ValueLogical() ( "&&" e2=ValueLogical() { e = new AndExpression(e, e2); } )*
+    { return e; }
+}
+
+/* [49]    ValueLogical    ::=    RelationalExpression */
+Expression ValueLogical() : { Expression e; }
+{
+    e=RelationalExpression() { return e; }
+}
+
+/* [50]    RelationalExpression    ::=    NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression )? */
+Expression RelationalExpression() : { Expression e, e2; }
+{
+    e=NumericExpression()
+    (
+      "=" e2=NumericExpression() { e = new Equals(e, e2); }
+      | "!=" e2=NumericExpression() { e = new NotEquals(e, e2); }
+      | "<" e2=NumericExpression() { e = new LessThan(e, e2); }
+      | ">" e2=NumericExpression() { e = new GreaterThan(e, e2); }
+      | "<=" e2=NumericExpression() { e = new LessThanEqual(e, e2); }
+      | ">=" e2=NumericExpression() { e = new GreaterThanEqual(e, e2); }
+    )?
+    { return e; }
+}
+
+/* [51]    NumericExpression    ::=    AdditiveExpression */
+Expression NumericExpression() : { Expression e; }
+{
+    e=AdditiveExpression() { return e; }
+}
+
+/* [52]    AdditiveExpression    ::=    MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | NumericLiteralPositive | NumericLiteralNegative )* */
+Expression AdditiveExpression() : { Expression e, e2; }
+{
+    e=MultiplicativeExpression()
+    (
+      "+" e2=MultiplicativeExpression() { e = new Plus(e, e2); }
+      | "-" e2=MultiplicativeExpression() { e = new Minus(e, e2); }
+      | e2=NumericLiteralPositive() { e = new Plus(e, e2); }
+      | e2=NumericLiteralNegative() { e = new Minus(e, e2); }
+    )*
+    { return e; }
+}
+
+/* [53]    MultiplicativeExpression    ::=    UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )* */
+Expression MultiplicativeExpression() : { Expression e, e2; }
+{
+    e=UnaryExpression()
+    (
+      "*" e2=UnaryExpression() { e = new Multiply(e, e2); }
+      | "/" e2=UnaryExpression() { e = new Divide(e, e2); }
+    )*
+    { return e; }
+}
+
+/* [54]    UnaryExpression    ::=      '!' PrimaryExpression  |  '+' PrimaryExpression  | '-' PrimaryExpression  | PrimaryExpression */
+Expression UnaryExpression() : { Expression e; }
+{
+    "!" e=PrimaryExpression() { return new Not(e); } 
+    | "+" e=PrimaryExpression() { return new UnaryPlus(e); }
+    | "-" e=PrimaryExpression() { return new UnaryMinus(e); }
+    | e=PrimaryExpression() { return e; }
+}
+
+/* [55]    PrimaryExpression    ::=    BrackettedExpression | BuiltInCall | IRIrefOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var */
+Expression PrimaryExpression() : { Expression e; }
+{
+    ( e=BrackettedExpression() | e=BuiltInCall() | e=IRIrefOrFunction() | e=RDFLiteral() | e=NumericLiteral() | e=BooleanLiteral() | e=Var() )
+    { return e; }
+}
+
+/* [56]    BrackettedExpression    ::=    '(' Expression ')' */
+Expression BrackettedExpression() : { Expression e; }
+{
+    "(" e=Expression() ")" { return e; }
+}
+
+/* [57]    BuiltInCall    ::=      'STR' '(' Expression ')' */
+/* |  'LANG' '(' Expression ')' */
+/* |  'LANGMATCHES' '(' Expression ',' Expression ')' */
+/* |  'DATATYPE' '(' Expression ')' */
+/* |  'BOUND' '(' Var ')' */
+/* |  'sameTerm' '(' Expression ',' Expression ')' */
+/* |  'isIRI' '(' Expression ')' */
+/* |  'isURI' '(' Expression ')' */
+/* |  'isBLANK' '(' Expression ')' */
+/* |  'isLITERAL' '(' Expression ')' */
+/* |  RegexExpression */
+BuiltInCall BuiltInCall() : { Expression e, e2; Variable v; }
+{
+    <STR> "(" e=Expression() ")" { return new BicStr(e); }
+    | <LANG> "(" e=Expression() ")" { return new BicLang(e); }
+    | <LANGMATCHES> "(" e=Expression() "," e2=Expression() ")" { return new BicLangMatches(e, e2); }
+    | <DATATYPE> "(" e=Expression() ")" { return new BicDatatype(e); }
+    | <BOUND> "(" v=Var() ")" { return new BicBound(v); }
+    | <SAME_TERM> "(" e=Expression() "," e2=Expression() ")" { return new BicSameTerm(e, e2); }
+    | <IS_IRI> "(" e=Expression() ")" { return new BicIsIri(e); }
+    | <IS_URI> "(" e=Expression() ")" { return new BicIsUri(e); }
+    | <IS_BLANK> "(" e=Expression() ")" { return new BicIsBlank(e); }
+    | <IS_LITERAL> "(" e=Expression() ")" { return new BicIsLiteral(e); }
+    | e=RegexExpression() { return (BuiltInCall)e; }
+}
+
+/* [58]    RegexExpression    ::=    'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')' */
+BuiltInCall RegexExpression() : { Expression e1, e2, e3 = null; }
+{
+    <REGEX> "(" e1=Expression() "," e2=Expression() ( "," e3=Expression() )? ")"
+    { return new BicRegEx(e1, e2, e3); }
+}
+
+/* [59]    IRIrefOrFunction    ::=    IRIref ArgList? */
+Expression IRIrefOrFunction() : { IRIReference ref; ArgList list; }
+{
+    ref=IRIref() (list=ArgList() { return new FunctionCall(ref, list); } )?
+    { return ref; }
+}
+
+/* [60]    RDFLiteral    ::=    String ( LANGTAG | ( '^^' IRIref ) )? */
+RDFLiteral RDFLiteral() : { Token t; RDFLiteral l; String s; IRIReference ref; }
+{
+    s = String() { l = new RDFLiteral(s); }
+    (
+      t=<LANGTAG> { l.setLanguage(t.image); }
+      |
+      ( "^^" ref=IRIref() { l.setDatatype(ref); })
+    )?
+    { return l; }
+}
+
+/* [61]    NumericLiteral    ::=    NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative */
+NumericLiteral NumericLiteral() : { NumericLiteral l; }
+{
+    ( l=NumericLiteralUnsigned() | l=NumericLiteralPositive() | l=NumericLiteralNegative() )
+    { return l; }
+}
+
+/* [62]    NumericLiteralUnsigned    ::=    INTEGER |  DECIMAL |  DOUBLE */
+NumericLiteral NumericLiteralUnsigned() : { Token t; }
+{
+    t=<INTEGER> { return new IntegerLiteral(t.image); }
+    | t=<DECIMAL> { return new DecimalLiteral(t.image); }
+    | t=<DOUBLE> { return new DoubleLiteral(t.image); }
+}
+
+/* [63]    NumericLiteralPositive    ::=    INTEGER_POSITIVE |  DECIMAL_POSITIVE |  DOUBLE_POSITIVE */
+NumericLiteral NumericLiteralPositive() : { Token t; }
+{
+    t=<INTEGER_POSITIVE> { return new IntegerLiteral(t.image); }
+    | t=<DECIMAL_POSITIVE> { return new DecimalLiteral(t.image); }
+    | t=<DOUBLE_POSITIVE> { return new DoubleLiteral(t.image); }
+}
+
+/* [64]    NumericLiteralNegative    ::=    INTEGER_NEGATIVE |  DECIMAL_NEGATIVE |  DOUBLE_NEGATIVE */
+NumericLiteral NumericLiteralNegative() : { Token t; }
+{
+    t=<INTEGER_NEGATIVE> { return new IntegerLiteral(t.image); }
+    | t=<DECIMAL_NEGATIVE> { return new DecimalLiteral(t.image); }
+    | t=<DOUBLE_NEGATIVE> { return new DoubleLiteral(t.image); }
+}
+
+/* [65]    BooleanLiteral    ::=    'true' |  'false' */
+BooleanLiteral BooleanLiteral() : {}
+{
+    <TRUE> { return BooleanLiteral.TRUE; } 
+    | <FALSE> { return BooleanLiteral.FALSE; }
+}
+
+/* [66]    String    ::=    STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2 */
+String String() : { Token t; }
+{
+    t=<STRING_LITERAL1> { return unquote(t.image) ; }
+    | t=<STRING_LITERAL2> { return unquote(t.image) ; }
+    | t=<STRING_LITERAL_LONG1> { return unTripleQuote(t.image) ; }
+    | t=<STRING_LITERAL_LONG2> { return unTripleQuote(t.image) ; }
+}
+
+/* [67]    IRIref    ::=    IRI_REF |  PrefixedName */
+IRIReference IRIref() : { IRIReference i; Token t; }
+{
+    t=<IRI_REF> { return queryStructure.newIRIRef(unquote(t.image)); }
+    | i=PrefixedName() { return i; }
+}
+
+/* [68]    PrefixedName    ::=    PNAME_LN | PNAME_NS */
+IRIReference PrefixedName() : { Token t; }
+{
+    ( t=<PNAME_LN> | t=<PNAME_NS> )
+    { return queryStructure.newPrefixedName(t.image); }
+}
+
+/* [69]    BlankNode    ::=    BLANK_NODE_LABEL |  ANON */
+BlankNode BlankNode() : { Token t; }
+{
+    t=<BLANK_NODE_LABEL> { return new BlankNode(t.image); }
+    | <ANON> { return queryStructure.newBlankNode(); }
+}
+
+
+TOKEN : {
+  /* [70]    IRI_REF    ::=    '<' ([^<>"{}|^`\]-[#x00-#x20])* '>' */
+  < IRI_REF : "<" ( ~["<", ">", "\"", "{", "}", "|", "^", "`", "\\", "\u0000"-"\u0020"] )* ">" >
+  |
+  /* [71]    PNAME_NS    ::=    PN_PREFIX? ':' */
+  < PNAME_NS : (<PN_PREFIX>)? ":" >
+  |
+  /* [72]    PNAME_LN    ::=    PNAME_NS PN_LOCAL */
+  < PNAME_LN : <PNAME_NS> <PN_LOCAL> >
+  |
+  /* [73]    BLANK_NODE_LABEL    ::=    '_:' PN_LOCAL */
+  < BLANK_NODE_LABEL : "_:" <PN_LOCAL> >
+  |
+  /* [74]    VAR1    ::=    '?' VARNAME */
+  < VAR1 : "?" <VARNAME> >
+  |
+  /* [75]    VAR2    ::=    '$' VARNAME */
+  < VAR2 : "$" <VARNAME> >
+  |
+  /* [76]    LANGTAG    ::=    '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* */
+  < LANGTAG : "@" (["a"-"z", "A"-"Z"])+ ( "-" (["a"-"z", "A"-"Z", "0"-"9"])+ )* >
+}
+
+TOKEN : {
+  < #Z_9 : ["0"-"9"] >
+  |
+  < #Z_9r : (<Z_9>)+ >
+  |
+   < #Z_9o : (<Z_9>)* >
+  |
+  /* [77]    INTEGER    ::=    [0-9]+ */
+  < INTEGER : <Z_9r> >
+  |
+  /* [78]    DECIMAL    ::=    [0-9]+ '.' [0-9]* | '.' [0-9]+ */
+  < DECIMAL : ( <Z_9r> "." <Z_9o> ) | ( "." <Z_9r> ) >
+  |
+  /* [79]    DOUBLE    ::=    [0-9]+ '.' [0-9]* EXPONENT | '.' ([0-9])+ EXPONENT | ([0-9])+ EXPONENT */
+  < DOUBLE : ( <Z_9r> "." <Z_9o>  <EXPONENT> ) | ( "." <Z_9r> <EXPONENT> ) | ( <Z_9r> <EXPONENT> ) >
+  |
+  /* [80]    INTEGER_POSITIVE    ::=    '+' INTEGER */
+  < INTEGER_POSITIVE : "+" <INTEGER> >
+  |
+  /* [81]    DECIMAL_POSITIVE    ::=    '+' DECIMAL */
+  < DECIMAL_POSITIVE : "+" <DECIMAL> >
+  |
+  /* [82]    DOUBLE_POSITIVE    ::=    '+' DOUBLE */
+  < DOUBLE_POSITIVE : "+" <DOUBLE> >
+  |
+  /* [83]    INTEGER_NEGATIVE    ::=    '-' INTEGER */
+  < INTEGER_NEGATIVE : "-" <INTEGER> >
+  |
+  /* [84]    DECIMAL_NEGATIVE    ::=    '-' DECIMAL */
+  < DECIMAL_NEGATIVE : "-" <DECIMAL> >
+  |
+  /* [85]    DOUBLE_NEGATIVE    ::=    '-' DOUBLE */
+  < DOUBLE_NEGATIVE : "-" <DOUBLE> >
+  |
+  /* [86]    EXPONENT    ::=    [eE] [+-]? [0-9]+ */
+  < #EXPONENT : ["e","E"] (["+","-"])? <Z_9r> >
+}
+
+TOKEN : {
+  /* [87]    STRING_LITERAL1    ::=    "'" ( ([^#x27#x5C#xA#xD]) | ECHAR )* "'" */
+  < STRING_LITERAL1 : "'" ( ~["'", "\\", "\r", "\n"] | <ECHAR> )* "'" >
+  |
+  /* [88]    STRING_LITERAL2    ::=    '"' ( ([^#x22#x5C#xA#xD]) | ECHAR )* '"' */
+  < STRING_LITERAL2 : "\"" ( ~["\"", "\\", "\r", "\n"] | <ECHAR> )* "\"" >
+  |
+  /* [89]    STRING_LITERAL_LONG1    ::=    "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR ) )* "'''" */
+  < STRING_LITERAL_LONG1 : "'''" ( ( "'" | "''" )? ( ~["'","\\"] | <ECHAR> ) )* "'''" >
+  |
+  /* [90]    STRING_LITERAL_LONG2    ::=    '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR ) )* '"""' */
+  < STRING_LITERAL_LONG2 : "\"\"\"" ( ( "\"" | "\"\"" )? ( ~["\"","\\"] | <ECHAR> ) )* "\"\"\"" >
+  |
+  /* [91]    #ECHAR    ::=    '\' [tbnrf\"'] */
+  < #ECHAR : "\\" ["t","b","n","r","f","\\","\"","'"] >
+}
+
+TOKEN : {
+  /* [92]    NIL    ::=    '(' WS* ')' */
+  < NIL : "(" (<WS>)* ")" >
+  |
+  /* [93]    WS    ::=    #x20 | #x9 | #xD | #xA */
+  < #WS : " " | "\t" | "\n" | "\r" >
+  |
+  /* [94]   ANON    ::=    '[' WS* ']' */
+  < ANON : "[" (<WS>)* "]" >
+}
+
+TOKEN : {
+  /* [95]   #PN_CHARS_BASE ::=  [A-Z] | [a-z] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x02FF] | [#x0370-#x037D] | [#x037F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] */
+  < #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"-"\uFDCF", "\uFDF0"-"\uFFFD"] >
+  |
+  /* [96]   #PN_CHARS_U    ::=  PN_CHARS_BASE | '_' */
+  < #PN_CHARS_U : <PN_CHARS_BASE> | "_" >
+  |
+  /* [97]   #VARNAME  ::=   ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )* */
+  < #VARNAME : (<PN_CHARS_U> | <Z_9>) ( <PN_CHARS_U> | <Z_9> | "\u00b7" | ["\u0300"-"\u036f"] | ["\u203f"-"\u2040"] )* >
+  |
+  /* [98]   #PN_CHARS  ::=  PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] */
+  < #PN_CHARS : <PN_CHARS_U> | "-" | <Z_9> | "\u00b7" | ["\u0300"-"\u036f"] | ["\u203f"-"\u2040"] >
+  |
+  /* [99]   PN_PREFIX  ::=  PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)? */
+  < PN_PREFIX : <PN_CHARS_BASE> (( <PN_CHARS> | "." )* <PN_CHARS>)? >
+  |
+  /* [100]  PN_LOCAL  ::=   ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)?  */
+  /* Note that SPARQL local names allow leading digits while XML local names do not. */
+  < PN_LOCAL : ( <PN_CHARS_U> | <Z_9> ) (( <PN_CHARS> | "." )* <PN_CHARS>)? >
+}

Added: trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParserConstants.java
===================================================================
--- trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParserConstants.java	                        (rev 0)
+++ trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParserConstants.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,181 @@
+/* Generated By:JavaCC: Do not edit this line. SparqlParserConstants.java */
+package org.mulgara.sparql.parser;
+
+public interface SparqlParserConstants {
+
+  int EOF = 0;
+  int COMMENT = 7;
+  int SELECT = 8;
+  int BASE = 9;
+  int ORDER = 10;
+  int BY = 11;
+  int FROM = 12;
+  int GRAPH = 13;
+  int STR = 14;
+  int IS_URI = 15;
+  int PREFIX = 16;
+  int CONSTRUCT = 17;
+  int LIMIT = 18;
+  int NAMED = 19;
+  int OPTIONAL = 20;
+  int LANG = 21;
+  int IS_IRI = 22;
+  int DESCRIBE = 23;
+  int OFFSET = 24;
+  int WHERE = 25;
+  int UNION = 26;
+  int LANGMATCHES = 27;
+  int IS_BLANK = 28;
+  int IS_LITERAL = 29;
+  int ASK = 30;
+  int DISTINCT = 31;
+  int FILTER = 32;
+  int DATATYPE = 33;
+  int REGEX = 34;
+  int REDUCED = 35;
+  int BOUND = 36;
+  int TRUE = 37;
+  int SAME_TERM = 38;
+  int FALSE = 39;
+  int IRI_REF = 66;
+  int PNAME_NS = 67;
+  int PNAME_LN = 68;
+  int BLANK_NODE_LABEL = 69;
+  int VAR1 = 70;
+  int VAR2 = 71;
+  int LANGTAG = 72;
+  int Z_9 = 73;
+  int Z_9r = 74;
+  int Z_9o = 75;
+  int INTEGER = 76;
+  int DECIMAL = 77;
+  int DOUBLE = 78;
+  int INTEGER_POSITIVE = 79;
+  int DECIMAL_POSITIVE = 80;
+  int DOUBLE_POSITIVE = 81;
+  int INTEGER_NEGATIVE = 82;
+  int DECIMAL_NEGATIVE = 83;
+  int DOUBLE_NEGATIVE = 84;
+  int EXPONENT = 85;
+  int STRING_LITERAL1 = 86;
+  int STRING_LITERAL2 = 87;
+  int STRING_LITERAL_LONG1 = 88;
+  int STRING_LITERAL_LONG2 = 89;
+  int ECHAR = 90;
+  int NIL = 91;
+  int WS = 92;
+  int ANON = 93;
+  int PN_CHARS_BASE = 94;
+  int PN_CHARS_U = 95;
+  int VARNAME = 96;
+  int PN_CHARS = 97;
+  int PN_PREFIX = 98;
+  int PN_LOCAL = 99;
+
+  int DEFAULT = 0;
+  int IN_COMMENT = 1;
+
+  String[] tokenImage = {
+    "<EOF>",
+    "\"\\t\"",
+    "\"\\n\"",
+    "\"\\r\"",
+    "\"\\f\"",
+    "\" \"",
+    "\"#\"",
+    "<COMMENT>",
+    "\"SELECT\"",
+    "\"BASE\"",
+    "\"ORDER\"",
+    "\"BY\"",
+    "\"FROM\"",
+    "\"GRAPH\"",
+    "\"STR\"",
+    "\"isURI\"",
+    "\"PREFIX\"",
+    "\"construct\"",
+    "\"limit\"",
+    "\"named\"",
+    "\"optional\"",
+    "\"lang\"",
+    "\"isIRI\"",
+    "\"describe\"",
+    "\"offset\"",
+    "\"where\"",
+    "\"union\"",
+    "\"LANGMATCHES\"",
+    "\"isBLANK\"",
+    "\"isLITERAL\"",
+    "\"ask\"",
+    "\"distinct\"",
+    "\"filter\"",
+    "\"datatype\"",
+    "\"regex\"",
+    "\"reduced\"",
+    "\"bound\"",
+    "\"true\"",
+    "\"sameTERM\"",
+    "\"false\"",
+    "\"*\"",
+    "\"ASC\"",
+    "\"DESC\"",
+    "\"{\"",
+    "\".\"",
+    "\"}\"",
+    "\"(\"",
+    "\",\"",
+    "\")\"",
+    "\";\"",
+    "\"a\"",
+    "\"[\"",
+    "\"]\"",
+    "\"||\"",
+    "\"&&\"",
+    "\"=\"",
+    "\"!=\"",
+    "\"<\"",
+    "\">\"",
+    "\"<=\"",
+    "\">=\"",
+    "\"+\"",
+    "\"-\"",
+    "\"/\"",
+    "\"!\"",
+    "\"^^\"",
+    "<IRI_REF>",
+    "<PNAME_NS>",
+    "<PNAME_LN>",
+    "<BLANK_NODE_LABEL>",
+    "<VAR1>",
+    "<VAR2>",
+    "<LANGTAG>",
+    "<Z_9>",
+    "<Z_9r>",
+    "<Z_9o>",
+    "<INTEGER>",
+    "<DECIMAL>",
+    "<DOUBLE>",
+    "<INTEGER_POSITIVE>",
+    "<DECIMAL_POSITIVE>",
+    "<DOUBLE_POSITIVE>",
+    "<INTEGER_NEGATIVE>",
+    "<DECIMAL_NEGATIVE>",
+    "<DOUBLE_NEGATIVE>",
+    "<EXPONENT>",
+    "<STRING_LITERAL1>",
+    "<STRING_LITERAL2>",
+    "<STRING_LITERAL_LONG1>",
+    "<STRING_LITERAL_LONG2>",
+    "<ECHAR>",
+    "<NIL>",
+    "<WS>",
+    "<ANON>",
+    "<PN_CHARS_BASE>",
+    "<PN_CHARS_U>",
+    "<VARNAME>",
+    "<PN_CHARS>",
+    "<PN_PREFIX>",
+    "<PN_LOCAL>",
+  };
+
+}

Added: trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParserTokenManager.java
===================================================================
--- trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParserTokenManager.java	                        (rev 0)
+++ trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParserTokenManager.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,2513 @@
+/* Generated By:JavaCC: Do not edit this line. SparqlParserTokenManager.java */
+package org.mulgara.sparql.parser;
+import java.io.StringReader;
+import static org.mulgara.sparql.parser.QueryType.*;
+import org.mulgara.sparql.parser.cst.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.LinkedList;
+import static org.mulgara.sparql.parser.cst.Nil.NIL_NODE;
+
+public class SparqlParserTokenManager implements SparqlParserConstants
+{
+  public  java.io.PrintStream debugStream = System.out;
+  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
+private final int jjStopAtPos(int pos, int kind)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   return pos + 1;
+}
+private final int jjMoveStringLiteralDfa0_0()
+{
+   switch(curChar)
+   {
+      case 9:
+         jjmatchedKind = 1;
+         return jjMoveNfa_0(0, 0);
+      case 10:
+         jjmatchedKind = 2;
+         return jjMoveNfa_0(0, 0);
+      case 12:
+         jjmatchedKind = 4;
+         return jjMoveNfa_0(0, 0);
+      case 13:
+         jjmatchedKind = 3;
+         return jjMoveNfa_0(0, 0);
+      case 32:
+         jjmatchedKind = 5;
+         return jjMoveNfa_0(0, 0);
+      case 33:
+         jjmatchedKind = 64;
+         return jjMoveStringLiteralDfa1_0(0x100000000000000L, 0x0L);
+      case 35:
+         jjmatchedKind = 6;
+         return jjMoveNfa_0(0, 0);
+      case 38:
+         return jjMoveStringLiteralDfa1_0(0x40000000000000L, 0x0L);
+      case 40:
+         jjmatchedKind = 46;
+         return jjMoveNfa_0(0, 0);
+      case 41:
+         jjmatchedKind = 48;
+         return jjMoveNfa_0(0, 0);
+      case 42:
+         jjmatchedKind = 40;
+         return jjMoveNfa_0(0, 0);
+      case 43:
+         jjmatchedKind = 61;
+         return jjMoveNfa_0(0, 0);
+      case 44:
+         jjmatchedKind = 47;
+         return jjMoveNfa_0(0, 0);
+      case 45:
+         jjmatchedKind = 62;
+         return jjMoveNfa_0(0, 0);
+      case 46:
+         jjmatchedKind = 44;
+         return jjMoveNfa_0(0, 0);
+      case 47:
+         jjmatchedKind = 63;
+         return jjMoveNfa_0(0, 0);
+      case 59:
+         jjmatchedKind = 49;
+         return jjMoveNfa_0(0, 0);
+      case 60:
+         jjmatchedKind = 57;
+         return jjMoveStringLiteralDfa1_0(0x800000000000000L, 0x0L);
+      case 61:
+         jjmatchedKind = 55;
+         return jjMoveNfa_0(0, 0);
+      case 62:
+         jjmatchedKind = 58;
+         return jjMoveStringLiteralDfa1_0(0x1000000000000000L, 0x0L);
+      case 65:
+         return jjMoveStringLiteralDfa1_0(0x20040000000L, 0x0L);
+      case 66:
+         return jjMoveStringLiteralDfa1_0(0x1000000a00L, 0x0L);
+      case 67:
+         return jjMoveStringLiteralDfa1_0(0x20000L, 0x0L);
+      case 68:
+         return jjMoveStringLiteralDfa1_0(0x40280800000L, 0x0L);
+      case 70:
+         return jjMoveStringLiteralDfa1_0(0x8100001000L, 0x0L);
+      case 71:
+         return jjMoveStringLiteralDfa1_0(0x2000L, 0x0L);
+      case 73:
+         return jjMoveStringLiteralDfa1_0(0x30408000L, 0x0L);
+      case 76:
+         return jjMoveStringLiteralDfa1_0(0x8240000L, 0x0L);
+      case 78:
+         return jjMoveStringLiteralDfa1_0(0x80000L, 0x0L);
+      case 79:
+         return jjMoveStringLiteralDfa1_0(0x1100400L, 0x0L);
+      case 80:
+         return jjMoveStringLiteralDfa1_0(0x10000L, 0x0L);
+      case 82:
+         return jjMoveStringLiteralDfa1_0(0xc00000000L, 0x0L);
+      case 83:
+         return jjMoveStringLiteralDfa1_0(0x4000004100L, 0x0L);
+      case 84:
+         return jjMoveStringLiteralDfa1_0(0x2000000000L, 0x0L);
+      case 85:
+         return jjMoveStringLiteralDfa1_0(0x4000000L, 0x0L);
+      case 87:
+         return jjMoveStringLiteralDfa1_0(0x2000000L, 0x0L);
+      case 91:
+         jjmatchedKind = 51;
+         return jjMoveNfa_0(0, 0);
+      case 93:
+         jjmatchedKind = 52;
+         return jjMoveNfa_0(0, 0);
+      case 94:
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x2L);
+      case 97:
+         jjmatchedKind = 50;
+         return jjMoveStringLiteralDfa1_0(0x40000000L, 0x0L);
+      case 98:
+         return jjMoveStringLiteralDfa1_0(0x1000000a00L, 0x0L);
+      case 99:
+         return jjMoveStringLiteralDfa1_0(0x20000L, 0x0L);
+      case 100:
+         return jjMoveStringLiteralDfa1_0(0x280800000L, 0x0L);
+      case 102:
+         return jjMoveStringLiteralDfa1_0(0x8100001000L, 0x0L);
+      case 103:
+         return jjMoveStringLiteralDfa1_0(0x2000L, 0x0L);
+      case 105:
+         return jjMoveStringLiteralDfa1_0(0x30408000L, 0x0L);
+      case 108:
+         return jjMoveStringLiteralDfa1_0(0x8240000L, 0x0L);
+      case 110:
+         return jjMoveStringLiteralDfa1_0(0x80000L, 0x0L);
+      case 111:
+         return jjMoveStringLiteralDfa1_0(0x1100400L, 0x0L);
+      case 112:
+         return jjMoveStringLiteralDfa1_0(0x10000L, 0x0L);
+      case 114:
+         return jjMoveStringLiteralDfa1_0(0xc00000000L, 0x0L);
+      case 115:
+         return jjMoveStringLiteralDfa1_0(0x4000004100L, 0x0L);
+      case 116:
+         return jjMoveStringLiteralDfa1_0(0x2000000000L, 0x0L);
+      case 117:
+         return jjMoveStringLiteralDfa1_0(0x4000000L, 0x0L);
+      case 119:
+         return jjMoveStringLiteralDfa1_0(0x2000000L, 0x0L);
+      case 123:
+         jjmatchedKind = 43;
+         return jjMoveNfa_0(0, 0);
+      case 124:
+         return jjMoveStringLiteralDfa1_0(0x20000000000000L, 0x0L);
+      case 125:
+         jjmatchedKind = 45;
+         return jjMoveNfa_0(0, 0);
+      default :
+         return jjMoveNfa_0(0, 0);
+   }
+}
+private final int jjMoveStringLiteralDfa1_0(long active0, long active1)
+{
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+   return jjMoveNfa_0(0, 0);
+   }
+   switch(curChar)
+   {
+      case 38:
+         if ((active0 & 0x40000000000000L) != 0L)
+         {
+            jjmatchedKind = 54;
+            jjmatchedPos = 1;
+         }
+         break;
+      case 61:
+         if ((active0 & 0x100000000000000L) != 0L)
+         {
+            jjmatchedKind = 56;
+            jjmatchedPos = 1;
+         }
+         else if ((active0 & 0x800000000000000L) != 0L)
+         {
+            jjmatchedKind = 59;
+            jjmatchedPos = 1;
+         }
+         else if ((active0 & 0x1000000000000000L) != 0L)
+         {
+            jjmatchedKind = 60;
+            jjmatchedPos = 1;
+         }
+         break;
+      case 65:
+         return jjMoveStringLiteralDfa2_0(active0, 0xc208280200L, active1, 0L);
+      case 69:
+         return jjMoveStringLiteralDfa2_0(active0, 0x40c00800100L, active1, 0L);
+      case 70:
+         return jjMoveStringLiteralDfa2_0(active0, 0x1000000L, active1, 0L);
+      case 72:
+         return jjMoveStringLiteralDfa2_0(active0, 0x2000000L, active1, 0L);
+      case 73:
+         return jjMoveStringLiteralDfa2_0(active0, 0x180040000L, active1, 0L);
+      case 78:
+         return jjMoveStringLiteralDfa2_0(active0, 0x4000000L, active1, 0L);
+      case 79:
+         return jjMoveStringLiteralDfa2_0(active0, 0x1000020000L, active1, 0L);
+      case 80:
+         return jjMoveStringLiteralDfa2_0(active0, 0x100000L, active1, 0L);
+      case 82:
+         return jjMoveStringLiteralDfa2_0(active0, 0x2000013400L, active1, 0L);
+      case 83:
+         return jjMoveStringLiteralDfa2_0(active0, 0x20070408000L, active1, 0L);
+      case 84:
+         return jjMoveStringLiteralDfa2_0(active0, 0x4000L, active1, 0L);
+      case 89:
+         if ((active0 & 0x800L) != 0L)
+         {
+            jjmatchedKind = 11;
+            jjmatchedPos = 1;
+         }
+         break;
+      case 94:
+         if ((active1 & 0x2L) != 0L)
+         {
+            jjmatchedKind = 65;
+            jjmatchedPos = 1;
+         }
+         break;
+      case 97:
+         return jjMoveStringLiteralDfa2_0(active0, 0xc208280200L, active1, 0L);
+      case 101:
+         return jjMoveStringLiteralDfa2_0(active0, 0xc00800100L, active1, 0L);
+      case 102:
+         return jjMoveStringLiteralDfa2_0(active0, 0x1000000L, active1, 0L);
+      case 104:
+         return jjMoveStringLiteralDfa2_0(active0, 0x2000000L, active1, 0L);
+      case 105:
+         return jjMoveStringLiteralDfa2_0(active0, 0x180040000L, active1, 0L);
+      case 110:
+         return jjMoveStringLiteralDfa2_0(active0, 0x4000000L, active1, 0L);
+      case 111:
+         return jjMoveStringLiteralDfa2_0(active0, 0x1000020000L, active1, 0L);
+      case 112:
+         return jjMoveStringLiteralDfa2_0(active0, 0x100000L, active1, 0L);
+      case 114:
+         return jjMoveStringLiteralDfa2_0(active0, 0x2000013400L, active1, 0L);
+      case 115:
+         return jjMoveStringLiteralDfa2_0(active0, 0x70408000L, active1, 0L);
+      case 116:
+         return jjMoveStringLiteralDfa2_0(active0, 0x4000L, active1, 0L);
+      case 121:
+         if ((active0 & 0x800L) != 0L)
+         {
+            jjmatchedKind = 11;
+            jjmatchedPos = 1;
+         }
+         break;
+      case 124:
+         if ((active0 & 0x20000000000000L) != 0L)
+         {
+            jjmatchedKind = 53;
+            jjmatchedPos = 1;
+         }
+         break;
+      default :
+         break;
+   }
+   return jjMoveNfa_0(0, 1);
+}
+private final int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1)
+{
+   if (((active0 &= old0) | (active1 &= old1)) == 0L)
+      return jjMoveNfa_0(0, 1);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+   return jjMoveNfa_0(0, 1);
+   }
+   switch(curChar)
+   {
+      case 65:
+         return jjMoveStringLiteralDfa3_0(active0, 0x2000L);
+      case 66:
+         return jjMoveStringLiteralDfa3_0(active0, 0x10000000L);
+      case 67:
+         if ((active0 & 0x20000000000L) != 0L)
+         {
+            jjmatchedKind = 41;
+            jjmatchedPos = 2;
+         }
+         break;
+      case 68:
+         return jjMoveStringLiteralDfa3_0(active0, 0x800000400L);
+      case 69:
+         return jjMoveStringLiteralDfa3_0(active0, 0x2010000L);
+      case 70:
+         return jjMoveStringLiteralDfa3_0(active0, 0x1000000L);
+      case 71:
+         return jjMoveStringLiteralDfa3_0(active0, 0x400000000L);
+      case 73:
+         return jjMoveStringLiteralDfa3_0(active0, 0x4400000L);
+      case 75:
+         if ((active0 & 0x40000000L) != 0L)
+         {
+            jjmatchedKind = 30;
+            jjmatchedPos = 2;
+         }
+         break;
+      case 76:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8120000100L);
+      case 77:
+         return jjMoveStringLiteralDfa3_0(active0, 0x40000c0000L);
+      case 78:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8220000L);
+      case 79:
+         return jjMoveStringLiteralDfa3_0(active0, 0x1000L);
+      case 82:
+         if ((active0 & 0x4000L) != 0L)
+         {
+            jjmatchedKind = 14;
+            jjmatchedPos = 2;
+         }
+         break;
+      case 83:
+         return jjMoveStringLiteralDfa3_0(active0, 0x40080800200L);
+      case 84:
+         return jjMoveStringLiteralDfa3_0(active0, 0x200100000L);
+      case 85:
+         return jjMoveStringLiteralDfa3_0(active0, 0x3000008000L);
+      case 97:
+         return jjMoveStringLiteralDfa3_0(active0, 0x2000L);
+      case 98:
+         return jjMoveStringLiteralDfa3_0(active0, 0x10000000L);
+      case 100:
+         return jjMoveStringLiteralDfa3_0(active0, 0x800000400L);
+      case 101:
+         return jjMoveStringLiteralDfa3_0(active0, 0x2010000L);
+      case 102:
+         return jjMoveStringLiteralDfa3_0(active0, 0x1000000L);
+      case 103:
+         return jjMoveStringLiteralDfa3_0(active0, 0x400000000L);
+      case 105:
+         return jjMoveStringLiteralDfa3_0(active0, 0x4400000L);
+      case 107:
+         if ((active0 & 0x40000000L) != 0L)
+         {
+            jjmatchedKind = 30;
+            jjmatchedPos = 2;
+         }
+         break;
+      case 108:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8120000100L);
+      case 109:
+         return jjMoveStringLiteralDfa3_0(active0, 0x40000c0000L);
+      case 110:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8220000L);
+      case 111:
+         return jjMoveStringLiteralDfa3_0(active0, 0x1000L);
+      case 114:
+         if ((active0 & 0x4000L) != 0L)
+         {
+            jjmatchedKind = 14;
+            jjmatchedPos = 2;
+         }
+         break;
+      case 115:
+         return jjMoveStringLiteralDfa3_0(active0, 0x80800200L);
+      case 116:
+         return jjMoveStringLiteralDfa3_0(active0, 0x200100000L);
+      case 117:
+         return jjMoveStringLiteralDfa3_0(active0, 0x3000008000L);
+      default :
+         break;
+   }
+   return jjMoveNfa_0(0, 2);
+}
+private final int jjMoveStringLiteralDfa3_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjMoveNfa_0(0, 2);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+   return jjMoveNfa_0(0, 2);
+   }
+   switch(curChar)
+   {
+      case 65:
+         return jjMoveStringLiteralDfa4_0(active0, 0x200000000L);
+      case 67:
+         if ((active0 & 0x40000000000L) != 0L)
+         {
+            jjmatchedKind = 42;
+            jjmatchedPos = 3;
+         }
+         return jjMoveStringLiteralDfa4_0(active0, 0x800000L);
+      case 69:
+         if ((active0 & 0x200L) != 0L)
+         {
+            jjmatchedKind = 9;
+            jjmatchedPos = 3;
+         }
+         else if ((active0 & 0x2000000000L) != 0L)
+         {
+            jjmatchedKind = 37;
+            jjmatchedPos = 3;
+         }
+         return jjMoveStringLiteralDfa4_0(active0, 0x4400080500L);
+      case 70:
+         return jjMoveStringLiteralDfa4_0(active0, 0x10000L);
+      case 71:
+         if ((active0 & 0x200000L) != 0L)
+         {
+            jjmatchedKind = 21;
+            jjmatchedPos = 3;
+         }
+         return jjMoveStringLiteralDfa4_0(active0, 0x8000000L);
+      case 73:
+         return jjMoveStringLiteralDfa4_0(active0, 0x20140000L);
+      case 76:
+         return jjMoveStringLiteralDfa4_0(active0, 0x10000000L);
+      case 77:
+         if ((active0 & 0x1000L) != 0L)
+         {
+            jjmatchedKind = 12;
+            jjmatchedPos = 3;
+         }
+         break;
+      case 78:
+         return jjMoveStringLiteralDfa4_0(active0, 0x1000000000L);
+      case 79:
+         return jjMoveStringLiteralDfa4_0(active0, 0x4000000L);
+      case 80:
+         return jjMoveStringLiteralDfa4_0(active0, 0x2000L);
+      case 82:
+         return jjMoveStringLiteralDfa4_0(active0, 0x2408000L);
+      case 83:
+         return jjMoveStringLiteralDfa4_0(active0, 0x8001020000L);
+      case 84:
+         return jjMoveStringLiteralDfa4_0(active0, 0x180000000L);
+      case 85:
+         return jjMoveStringLiteralDfa4_0(active0, 0x800000000L);
+      case 97:
+         return jjMoveStringLiteralDfa4_0(active0, 0x200000000L);
+      case 99:
+         return jjMoveStringLiteralDfa4_0(active0, 0x800000L);
+      case 101:
+         if ((active0 & 0x200L) != 0L)
+         {
+            jjmatchedKind = 9;
+            jjmatchedPos = 3;
+         }
+         else if ((active0 & 0x2000000000L) != 0L)
+         {
+            jjmatchedKind = 37;
+            jjmatchedPos = 3;
+         }
+         return jjMoveStringLiteralDfa4_0(active0, 0x4400080500L);
+      case 102:
+         return jjMoveStringLiteralDfa4_0(active0, 0x10000L);
+      case 103:
+         if ((active0 & 0x200000L) != 0L)
+         {
+            jjmatchedKind = 21;
+            jjmatchedPos = 3;
+         }
+         return jjMoveStringLiteralDfa4_0(active0, 0x8000000L);
+      case 105:
+         return jjMoveStringLiteralDfa4_0(active0, 0x20140000L);
+      case 108:
+         return jjMoveStringLiteralDfa4_0(active0, 0x10000000L);
+      case 109:
+         if ((active0 & 0x1000L) != 0L)
+         {
+            jjmatchedKind = 12;
+            jjmatchedPos = 3;
+         }
+         break;
+      case 110:
+         return jjMoveStringLiteralDfa4_0(active0, 0x1000000000L);
+      case 111:
+         return jjMoveStringLiteralDfa4_0(active0, 0x4000000L);
+      case 112:
+         return jjMoveStringLiteralDfa4_0(active0, 0x2000L);
+      case 114:
+         return jjMoveStringLiteralDfa4_0(active0, 0x2408000L);
+      case 115:
+         return jjMoveStringLiteralDfa4_0(active0, 0x8001020000L);
+      case 116:
+         return jjMoveStringLiteralDfa4_0(active0, 0x180000000L);
+      case 117:
+         return jjMoveStringLiteralDfa4_0(active0, 0x800000000L);
+      default :
+         break;
+   }
+   return jjMoveNfa_0(0, 3);
+}
+private final int jjMoveStringLiteralDfa4_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjMoveNfa_0(0, 3);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+   return jjMoveNfa_0(0, 3);
+   }
+   switch(curChar)
+   {
+      case 65:
+         return jjMoveStringLiteralDfa5_0(active0, 0x10000000L);
+      case 67:
+         return jjMoveStringLiteralDfa5_0(active0, 0x800000100L);
+      case 68:
+         if ((active0 & 0x80000L) != 0L)
+         {
+            jjmatchedKind = 19;
+            jjmatchedPos = 4;
+         }
+         else if ((active0 & 0x1000000000L) != 0L)
+         {
+            jjmatchedKind = 36;
+            jjmatchedPos = 4;
+         }
+         break;
+      case 69:
+         if ((active0 & 0x2000000L) != 0L)
+         {
+            jjmatchedKind = 25;
+            jjmatchedPos = 4;
+         }
+         else if ((active0 & 0x8000000000L) != 0L)
+         {
+            jjmatchedKind = 39;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x101000000L);
+      case 72:
+         if ((active0 & 0x2000L) != 0L)
+         {
+            jjmatchedKind = 13;
+            jjmatchedPos = 4;
+         }
+         break;
+      case 73:
+         if ((active0 & 0x8000L) != 0L)
+         {
+            jjmatchedKind = 15;
+            jjmatchedPos = 4;
+         }
+         else if ((active0 & 0x400000L) != 0L)
+         {
+            jjmatchedKind = 22;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x80010000L);
+      case 77:
+         return jjMoveStringLiteralDfa5_0(active0, 0x8000000L);
+      case 78:
+         if ((active0 & 0x4000000L) != 0L)
+         {
+            jjmatchedKind = 26;
+            jjmatchedPos = 4;
+         }
+         break;
+      case 79:
+         return jjMoveStringLiteralDfa5_0(active0, 0x100000L);
+      case 82:
+         if ((active0 & 0x400L) != 0L)
+         {
+            jjmatchedKind = 10;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x800000L);
+      case 84:
+         if ((active0 & 0x40000L) != 0L)
+         {
+            jjmatchedKind = 18;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x4220020000L);
+      case 88:
+         if ((active0 & 0x400000000L) != 0L)
+         {
+            jjmatchedKind = 34;
+            jjmatchedPos = 4;
+         }
+         break;
+      case 97:
+         return jjMoveStringLiteralDfa5_0(active0, 0x10000000L);
+      case 99:
+         return jjMoveStringLiteralDfa5_0(active0, 0x800000100L);
+      case 100:
+         if ((active0 & 0x80000L) != 0L)
+         {
+            jjmatchedKind = 19;
+            jjmatchedPos = 4;
+         }
+         else if ((active0 & 0x1000000000L) != 0L)
+         {
+            jjmatchedKind = 36;
+            jjmatchedPos = 4;
+         }
+         break;
+      case 101:
+         if ((active0 & 0x2000000L) != 0L)
+         {
+            jjmatchedKind = 25;
+            jjmatchedPos = 4;
+         }
+         else if ((active0 & 0x8000000000L) != 0L)
+         {
+            jjmatchedKind = 39;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x101000000L);
+      case 104:
+         if ((active0 & 0x2000L) != 0L)
+         {
+            jjmatchedKind = 13;
+            jjmatchedPos = 4;
+         }
+         break;
+      case 105:
+         if ((active0 & 0x8000L) != 0L)
+         {
+            jjmatchedKind = 15;
+            jjmatchedPos = 4;
+         }
+         else if ((active0 & 0x400000L) != 0L)
+         {
+            jjmatchedKind = 22;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x80010000L);
+      case 109:
+         return jjMoveStringLiteralDfa5_0(active0, 0x8000000L);
+      case 110:
+         if ((active0 & 0x4000000L) != 0L)
+         {
+            jjmatchedKind = 26;
+            jjmatchedPos = 4;
+         }
+         break;
+      case 111:
+         return jjMoveStringLiteralDfa5_0(active0, 0x100000L);
+      case 114:
+         if ((active0 & 0x400L) != 0L)
+         {
+            jjmatchedKind = 10;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x800000L);
+      case 116:
+         if ((active0 & 0x40000L) != 0L)
+         {
+            jjmatchedKind = 18;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x4220020000L);
+      case 120:
+         if ((active0 & 0x400000000L) != 0L)
+         {
+            jjmatchedKind = 34;
+            jjmatchedPos = 4;
+         }
+         break;
+      default :
+         break;
+   }
+   return jjMoveNfa_0(0, 4);
+}
+private final int jjMoveStringLiteralDfa5_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjMoveNfa_0(0, 4);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+   return jjMoveNfa_0(0, 4);
+   }
+   switch(curChar)
+   {
+      case 65:
+         return jjMoveStringLiteralDfa6_0(active0, 0x8000000L);
+      case 69:
+         return jjMoveStringLiteralDfa6_0(active0, 0x4820000000L);
+      case 73:
+         return jjMoveStringLiteralDfa6_0(active0, 0x800000L);
+      case 78:
+         return jjMoveStringLiteralDfa6_0(active0, 0x90100000L);
+      case 82:
+         if ((active0 & 0x100000000L) != 0L)
+         {
+            jjmatchedKind = 32;
+            jjmatchedPos = 5;
+         }
+         return jjMoveStringLiteralDfa6_0(active0, 0x20000L);
+      case 84:
+         if ((active0 & 0x100L) != 0L)
+         {
+            jjmatchedKind = 8;
+            jjmatchedPos = 5;
+         }
+         else if ((active0 & 0x1000000L) != 0L)
+         {
+            jjmatchedKind = 24;
+            jjmatchedPos = 5;
+         }
+         break;
+      case 88:
+         if ((active0 & 0x10000L) != 0L)
+         {
+            jjmatchedKind = 16;
+            jjmatchedPos = 5;
+         }
+         break;
+      case 89:
+         return jjMoveStringLiteralDfa6_0(active0, 0x200000000L);
+      case 97:
+         return jjMoveStringLiteralDfa6_0(active0, 0x8000000L);
+      case 101:
+         return jjMoveStringLiteralDfa6_0(active0, 0x4820000000L);
+      case 105:
+         return jjMoveStringLiteralDfa6_0(active0, 0x800000L);
+      case 110:
+         return jjMoveStringLiteralDfa6_0(active0, 0x90100000L);
+      case 114:
+         if ((active0 & 0x100000000L) != 0L)
+         {
+            jjmatchedKind = 32;
+            jjmatchedPos = 5;
+         }
+         return jjMoveStringLiteralDfa6_0(active0, 0x20000L);
+      case 116:
+         if ((active0 & 0x100L) != 0L)
+         {
+            jjmatchedKind = 8;
+            jjmatchedPos = 5;
+         }
+         else if ((active0 & 0x1000000L) != 0L)
+         {
+            jjmatchedKind = 24;
+            jjmatchedPos = 5;
+         }
+         break;
+      case 120:
+         if ((active0 & 0x10000L) != 0L)
+         {
+            jjmatchedKind = 16;
+            jjmatchedPos = 5;
+         }
+         break;
+      case 121:
+         return jjMoveStringLiteralDfa6_0(active0, 0x200000000L);
+      default :
+         break;
+   }
+   return jjMoveNfa_0(0, 5);
+}
+private final int jjMoveStringLiteralDfa6_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjMoveNfa_0(0, 5);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+   return jjMoveNfa_0(0, 5);
+   }
+   switch(curChar)
+   {
+      case 65:
+         return jjMoveStringLiteralDfa7_0(active0, 0x100000L);
+      case 66:
+         return jjMoveStringLiteralDfa7_0(active0, 0x800000L);
+      case 67:
+         return jjMoveStringLiteralDfa7_0(active0, 0x80000000L);
+      case 68:
+         if ((active0 & 0x800000000L) != 0L)
+         {
+            jjmatchedKind = 35;
+            jjmatchedPos = 6;
+         }
+         break;
+      case 75:
+         if ((active0 & 0x10000000L) != 0L)
+         {
+            jjmatchedKind = 28;
+            jjmatchedPos = 6;
+         }
+         break;
+      case 80:
+         return jjMoveStringLiteralDfa7_0(active0, 0x200000000L);
+      case 82:
+         return jjMoveStringLiteralDfa7_0(active0, 0x4020000000L);
+      case 84:
+         return jjMoveStringLiteralDfa7_0(active0, 0x8000000L);
+      case 85:
+         return jjMoveStringLiteralDfa7_0(active0, 0x20000L);
+      case 97:
+         return jjMoveStringLiteralDfa7_0(active0, 0x100000L);
+      case 98:
+         return jjMoveStringLiteralDfa7_0(active0, 0x800000L);
+      case 99:
+         return jjMoveStringLiteralDfa7_0(active0, 0x80000000L);
+      case 100:
+         if ((active0 & 0x800000000L) != 0L)
+         {
+            jjmatchedKind = 35;
+            jjmatchedPos = 6;
+         }
+         break;
+      case 107:
+         if ((active0 & 0x10000000L) != 0L)
+         {
+            jjmatchedKind = 28;
+            jjmatchedPos = 6;
+         }
+         break;
+      case 112:
+         return jjMoveStringLiteralDfa7_0(active0, 0x200000000L);
+      case 114:
+         return jjMoveStringLiteralDfa7_0(active0, 0x4020000000L);
+      case 116:
+         return jjMoveStringLiteralDfa7_0(active0, 0x8000000L);
+      case 117:
+         return jjMoveStringLiteralDfa7_0(active0, 0x20000L);
+      default :
+         break;
+   }
+   return jjMoveNfa_0(0, 6);
+}
+private final int jjMoveStringLiteralDfa7_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjMoveNfa_0(0, 6);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+   return jjMoveNfa_0(0, 6);
+   }
+   switch(curChar)
+   {
+      case 65:
+         return jjMoveStringLiteralDfa8_0(active0, 0x20000000L);
+      case 67:
+         return jjMoveStringLiteralDfa8_0(active0, 0x8020000L);
+      case 69:
+         if ((active0 & 0x800000L) != 0L)
+         {
+            jjmatchedKind = 23;
+            jjmatchedPos = 7;
+         }
+         else if ((active0 & 0x200000000L) != 0L)
+         {
+            jjmatchedKind = 33;
+            jjmatchedPos = 7;
+         }
+         break;
+      case 76:
+         if ((active0 & 0x100000L) != 0L)
+         {
+            jjmatchedKind = 20;
+            jjmatchedPos = 7;
+         }
+         break;
+      case 77:
+         if ((active0 & 0x4000000000L) != 0L)
+         {
+            jjmatchedKind = 38;
+            jjmatchedPos = 7;
+         }
+         break;
+      case 84:
+         if ((active0 & 0x80000000L) != 0L)
+         {
+            jjmatchedKind = 31;
+            jjmatchedPos = 7;
+         }
+         break;
+      case 97:
+         return jjMoveStringLiteralDfa8_0(active0, 0x20000000L);
+      case 99:
+         return jjMoveStringLiteralDfa8_0(active0, 0x8020000L);
+      case 101:
+         if ((active0 & 0x800000L) != 0L)
+         {
+            jjmatchedKind = 23;
+            jjmatchedPos = 7;
+         }
+         else if ((active0 & 0x200000000L) != 0L)
+         {
+            jjmatchedKind = 33;
+            jjmatchedPos = 7;
+         }
+         break;
+      case 108:
+         if ((active0 & 0x100000L) != 0L)
+         {
+            jjmatchedKind = 20;
+            jjmatchedPos = 7;
+         }
+         break;
+      case 109:
+         if ((active0 & 0x4000000000L) != 0L)
+         {
+            jjmatchedKind = 38;
+            jjmatchedPos = 7;
+         }
+         break;
+      case 116:
+         if ((active0 & 0x80000000L) != 0L)
+         {
+            jjmatchedKind = 31;
+            jjmatchedPos = 7;
+         }
+         break;
+      default :
+         break;
+   }
+   return jjMoveNfa_0(0, 7);
+}
+private final int jjMoveStringLiteralDfa8_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjMoveNfa_0(0, 7);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+   return jjMoveNfa_0(0, 7);
+   }
+   switch(curChar)
+   {
+      case 72:
+         return jjMoveStringLiteralDfa9_0(active0, 0x8000000L);
+      case 76:
+         if ((active0 & 0x20000000L) != 0L)
+         {
+            jjmatchedKind = 29;
+            jjmatchedPos = 8;
+         }
+         break;
+      case 84:
+         if ((active0 & 0x20000L) != 0L)
+         {
+            jjmatchedKind = 17;
+            jjmatchedPos = 8;
+         }
+         break;
+      case 104:
+         return jjMoveStringLiteralDfa9_0(active0, 0x8000000L);
+      case 108:
+         if ((active0 & 0x20000000L) != 0L)
+         {
+            jjmatchedKind = 29;
+            jjmatchedPos = 8;
+         }
+         break;
+      case 116:
+         if ((active0 & 0x20000L) != 0L)
+         {
+            jjmatchedKind = 17;
+            jjmatchedPos = 8;
+         }
+         break;
+      default :
+         break;
+   }
+   return jjMoveNfa_0(0, 8);
+}
+private final int jjMoveStringLiteralDfa9_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjMoveNfa_0(0, 8);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+   return jjMoveNfa_0(0, 8);
+   }
+   switch(curChar)
+   {
+      case 69:
+         return jjMoveStringLiteralDfa10_0(active0, 0x8000000L);
+      case 101:
+         return jjMoveStringLiteralDfa10_0(active0, 0x8000000L);
+      default :
+         break;
+   }
+   return jjMoveNfa_0(0, 9);
+}
+private final int jjMoveStringLiteralDfa10_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjMoveNfa_0(0, 9);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+   return jjMoveNfa_0(0, 9);
+   }
+   switch(curChar)
+   {
+      case 83:
+         if ((active0 & 0x8000000L) != 0L)
+         {
+            jjmatchedKind = 27;
+            jjmatchedPos = 10;
+         }
+         break;
+      case 115:
+         if ((active0 & 0x8000000L) != 0L)
+         {
+            jjmatchedKind = 27;
+            jjmatchedPos = 10;
+         }
+         break;
+      default :
+         break;
+   }
+   return jjMoveNfa_0(0, 10);
+}
+private final void jjCheckNAdd(int state)
+{
+   if (jjrounds[state] != jjround)
+   {
+      jjstateSet[jjnewStateCnt++] = state;
+      jjrounds[state] = jjround;
+   }
+}
+private final void jjAddStates(int start, int end)
+{
+   do {
+      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+   } while (start++ != end);
+}
+private final void jjCheckNAddTwoStates(int state1, int state2)
+{
+   jjCheckNAdd(state1);
+   jjCheckNAdd(state2);
+}
+private final void jjCheckNAddStates(int start, int end)
+{
+   do {
+      jjCheckNAdd(jjnextStates[start]);
+   } while (start++ != end);
+}
+private final void jjCheckNAddStates(int start)
+{
+   jjCheckNAdd(jjnextStates[start]);
+   jjCheckNAdd(jjnextStates[start + 1]);
+}
+static final long[] jjbitVec0 = {
+   0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec2 = {
+   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec3 = {
+   0xfffe7000fffffff6L, 0xffffffffffffffffL, 0xffffffffffffffffL, 0x5e00000000ffffffL
+};
+static final long[] jjbitVec4 = {
+   0x0L, 0x0L, 0x0L, 0xff7fffffff7fffffL
+};
+static final long[] jjbitVec5 = {
+   0x0L, 0xbfff000000000000L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec6 = {
+   0x3000L, 0xffff000000000000L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec7 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffL, 0x0L
+};
+static final long[] jjbitVec8 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffL
+};
+static final long[] jjbitVec9 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffff00000000ffffL
+};
+static final long[] jjbitVec10 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0x3fffffffffffffffL
+};
+static final long[] jjbitVec11 = {
+   0x0L, 0x0L, 0x80000000000000L, 0xff7fffffff7fffffL
+};
+static final long[] jjbitVec12 = {
+   0xffffffffffffffffL, 0xbfffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec13 = {
+   0x8000000000003000L, 0xffff000000000001L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+private final int jjMoveNfa_0(int startState, int curPos)
+{
+   int strKind = jjmatchedKind;
+   int strPos = jjmatchedPos;
+   int seenUpto;
+   input_stream.backup(seenUpto = curPos + 1);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) { throw new Error("Internal Error"); }
+   curPos = 0;
+   int[] nextStates;
+   int startsAt = 0;
+   jjnewStateCnt = 139;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int j, kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0x3ff000000000000L & l) != 0L)
+                  {
+                     if (kind > 76)
+                        kind = 76;
+                     jjCheckNAddStates(0, 6);
+                  }
+                  else if (curChar == 45)
+                     jjCheckNAddStates(7, 11);
+                  else if (curChar == 43)
+                     jjCheckNAddStates(12, 16);
+                  else if (curChar == 46)
+                     jjCheckNAddTwoStates(88, 89);
+                  else if (curChar == 58)
+                  {
+                     if (kind > 67)
+                        kind = 67;
+                     jjCheckNAdd(66);
+                  }
+                  else if (curChar == 40)
+                     jjCheckNAddTwoStates(51, 52);
+                  else if (curChar == 34)
+                     jjstateSet[jjnewStateCnt++] = 48;
+                  else if (curChar == 39)
+                     jjstateSet[jjnewStateCnt++] = 37;
+                  else if (curChar == 36)
+                     jjstateSet[jjnewStateCnt++] = 12;
+                  else if (curChar == 60)
+                     jjCheckNAddTwoStates(1, 2);
+                  else if (curChar == 63)
+                     jjstateSet[jjnewStateCnt++] = 9;
+                  if ((0x3ff000000000000L & l) != 0L)
+                  {
+                     if (kind > 99)
+                        kind = 99;
+                     jjCheckNAddTwoStates(57, 58);
+                  }
+                  else if (curChar == 34)
+                     jjCheckNAddStates(17, 19);
+                  else if (curChar == 39)
+                     jjCheckNAddStates(20, 22);
+                  break;
+               case 1:
+                  if ((0xaffffffa00000000L & l) != 0L)
+                     jjCheckNAddTwoStates(1, 2);
+                  break;
+               case 2:
+                  if (curChar == 62 && kind > 66)
+                     kind = 66;
+                  break;
+               case 3:
+                  if (curChar == 58)
+                     jjstateSet[jjnewStateCnt++] = 4;
+                  break;
+               case 4:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 69)
+                     kind = 69;
+                  jjCheckNAddTwoStates(5, 6);
+                  break;
+               case 5:
+                  if ((0x3ff600000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(5, 6);
+                  break;
+               case 6:
+                  if ((0x3ff200000000000L & l) != 0L && kind > 69)
+                     kind = 69;
+                  break;
+               case 8:
+                  if (curChar == 63)
+                     jjstateSet[jjnewStateCnt++] = 9;
+                  break;
+               case 9:
+               case 10:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 70)
+                     kind = 70;
+                  jjCheckNAdd(10);
+                  break;
+               case 11:
+                  if (curChar == 36)
+                     jjstateSet[jjnewStateCnt++] = 12;
+                  break;
+               case 12:
+               case 13:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAdd(13);
+                  break;
+               case 16:
+                  if (curChar == 45)
+                     jjCheckNAdd(17);
+                  break;
+               case 17:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 72)
+                     kind = 72;
+                  jjCheckNAddTwoStates(16, 17);
+                  break;
+               case 18:
+                  if (curChar == 39)
+                     jjCheckNAddStates(20, 22);
+                  break;
+               case 19:
+                  if ((0xffffff7fffffdbffL & l) != 0L)
+                     jjCheckNAddStates(20, 22);
+                  break;
+               case 21:
+                  if ((0x8400000000L & l) != 0L)
+                     jjCheckNAddStates(20, 22);
+                  break;
+               case 22:
+                  if (curChar == 39 && kind > 86)
+                     kind = 86;
+                  break;
+               case 23:
+                  if (curChar == 34)
+                     jjCheckNAddStates(17, 19);
+                  break;
+               case 24:
+                  if ((0xfffffffbffffdbffL & l) != 0L)
+                     jjCheckNAddStates(17, 19);
+                  break;
+               case 26:
+                  if ((0x8400000000L & l) != 0L)
+                     jjCheckNAddStates(17, 19);
+                  break;
+               case 27:
+                  if (curChar == 34 && kind > 87)
+                     kind = 87;
+                  break;
+               case 28:
+                  if (curChar == 39)
+                     jjCheckNAddStates(23, 26);
+                  break;
+               case 29:
+               case 34:
+                  if (curChar == 39)
+                     jjCheckNAddTwoStates(30, 31);
+                  break;
+               case 30:
+                  if ((0xffffff7fffffffffL & l) != 0L)
+                     jjCheckNAddStates(23, 26);
+                  break;
+               case 32:
+                  if ((0x8400000000L & l) != 0L)
+                     jjCheckNAddStates(23, 26);
+                  break;
+               case 33:
+                  if (curChar == 39)
+                     jjAddStates(27, 28);
+                  break;
+               case 35:
+                  if (curChar == 39 && kind > 88)
+                     kind = 88;
+                  break;
+               case 36:
+                  if (curChar == 39)
+                     jjstateSet[jjnewStateCnt++] = 35;
+                  break;
+               case 37:
+                  if (curChar == 39)
+                     jjstateSet[jjnewStateCnt++] = 28;
+                  break;
+               case 38:
+                  if (curChar == 39)
+                     jjstateSet[jjnewStateCnt++] = 37;
+                  break;
+               case 39:
+                  if (curChar == 34)
+                     jjCheckNAddStates(29, 32);
+                  break;
+               case 40:
+               case 45:
+                  if (curChar == 34)
+                     jjCheckNAddTwoStates(41, 42);
+                  break;
+               case 41:
+                  if ((0xfffffffbffffffffL & l) != 0L)
+                     jjCheckNAddStates(29, 32);
+                  break;
+               case 43:
+                  if ((0x8400000000L & l) != 0L)
+                     jjCheckNAddStates(29, 32);
+                  break;
+               case 44:
+                  if (curChar == 34)
+                     jjAddStates(33, 34);
+                  break;
+               case 46:
+                  if (curChar == 34 && kind > 89)
+                     kind = 89;
+                  break;
+               case 47:
+                  if (curChar == 34)
+                     jjstateSet[jjnewStateCnt++] = 46;
+                  break;
+               case 48:
+                  if (curChar == 34)
+                     jjstateSet[jjnewStateCnt++] = 39;
+                  break;
+               case 49:
+                  if (curChar == 34)
+                     jjstateSet[jjnewStateCnt++] = 48;
+                  break;
+               case 50:
+                  if (curChar == 40)
+                     jjCheckNAddTwoStates(51, 52);
+                  break;
+               case 51:
+                  if ((0x100002600L & l) != 0L)
+                     jjCheckNAddTwoStates(51, 52);
+                  break;
+               case 52:
+                  if (curChar == 41 && kind > 91)
+                     kind = 91;
+                  break;
+               case 54:
+                  if ((0x100002600L & l) != 0L)
+                     jjAddStates(35, 36);
+                  break;
+               case 56:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 99)
+                     kind = 99;
+                  jjCheckNAddTwoStates(57, 58);
+                  break;
+               case 57:
+                  if ((0x3ff600000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(57, 58);
+                  break;
+               case 58:
+                  if ((0x3ff200000000000L & l) != 0L && kind > 99)
+                     kind = 99;
+                  break;
+               case 60:
+                  if ((0x3ff600000000000L & l) != 0L)
+                     jjAddStates(37, 38);
+                  break;
+               case 61:
+                  if ((0x3ff200000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 62;
+                  break;
+               case 62:
+                  if (curChar == 58 && kind > 67)
+                     kind = 67;
+                  break;
+               case 63:
+                  if ((0x3ff600000000000L & l) != 0L)
+                     jjAddStates(39, 40);
+                  break;
+               case 64:
+                  if ((0x3ff200000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 65;
+                  break;
+               case 65:
+                  if (curChar == 58)
+                     jjCheckNAdd(66);
+                  break;
+               case 66:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 68)
+                     kind = 68;
+                  jjCheckNAddTwoStates(67, 68);
+                  break;
+               case 67:
+                  if ((0x3ff600000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(67, 68);
+                  break;
+               case 68:
+                  if ((0x3ff200000000000L & l) != 0L && kind > 68)
+                     kind = 68;
+                  break;
+               case 69:
+                  if ((0x3ff600000000000L & l) != 0L)
+                     jjAddStates(41, 42);
+                  break;
+               case 70:
+                  if ((0x3ff200000000000L & l) != 0L && kind > 98)
+                     kind = 98;
+                  break;
+               case 71:
+                  if (curChar != 58)
+                     break;
+                  if (kind > 67)
+                     kind = 67;
+                  jjCheckNAdd(66);
+                  break;
+               case 72:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 76)
+                     kind = 76;
+                  jjCheckNAddStates(0, 6);
+                  break;
+               case 73:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 76)
+                     kind = 76;
+                  jjCheckNAdd(73);
+                  break;
+               case 74:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(74, 75);
+                  break;
+               case 75:
+                  if (curChar != 46)
+                     break;
+                  if (kind > 77)
+                     kind = 77;
+                  jjCheckNAdd(76);
+                  break;
+               case 76:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 77)
+                     kind = 77;
+                  jjCheckNAdd(76);
+                  break;
+               case 77:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(77, 78);
+                  break;
+               case 78:
+                  if (curChar == 46)
+                     jjCheckNAddTwoStates(79, 80);
+                  break;
+               case 79:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(79, 80);
+                  break;
+               case 81:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(82);
+                  break;
+               case 82:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 78)
+                     kind = 78;
+                  jjCheckNAdd(82);
+                  break;
+               case 83:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(83, 84);
+                  break;
+               case 85:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(86);
+                  break;
+               case 86:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 78)
+                     kind = 78;
+                  jjCheckNAdd(86);
+                  break;
+               case 87:
+                  if (curChar == 46)
+                     jjCheckNAddTwoStates(88, 89);
+                  break;
+               case 88:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 77)
+                     kind = 77;
+                  jjCheckNAdd(88);
+                  break;
+               case 89:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(89, 90);
+                  break;
+               case 91:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(92);
+                  break;
+               case 92:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 78)
+                     kind = 78;
+                  jjCheckNAdd(92);
+                  break;
+               case 93:
+                  if (curChar == 43)
+                     jjCheckNAddStates(12, 16);
+                  break;
+               case 94:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 79)
+                     kind = 79;
+                  jjCheckNAdd(94);
+                  break;
+               case 95:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(95, 96);
+                  break;
+               case 96:
+                  if (curChar != 46)
+                     break;
+                  if (kind > 80)
+                     kind = 80;
+                  jjCheckNAdd(97);
+                  break;
+               case 97:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 80)
+                     kind = 80;
+                  jjCheckNAdd(97);
+                  break;
+               case 98:
+                  if (curChar == 46)
+                     jjCheckNAdd(99);
+                  break;
+               case 99:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 80)
+                     kind = 80;
+                  jjCheckNAdd(99);
+                  break;
+               case 100:
+                  if (curChar == 46)
+                     jjCheckNAdd(101);
+                  break;
+               case 101:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(101, 102);
+                  break;
+               case 103:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(104);
+                  break;
+               case 104:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 81)
+                     kind = 81;
+                  jjCheckNAdd(104);
+                  break;
+               case 105:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(43, 46);
+                  break;
+               case 106:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(106, 107);
+                  break;
+               case 107:
+                  if (curChar == 46)
+                     jjCheckNAddTwoStates(108, 109);
+                  break;
+               case 108:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(108, 109);
+                  break;
+               case 110:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(111);
+                  break;
+               case 111:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 81)
+                     kind = 81;
+                  jjCheckNAdd(111);
+                  break;
+               case 112:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(112, 113);
+                  break;
+               case 114:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(115);
+                  break;
+               case 115:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 81)
+                     kind = 81;
+                  jjCheckNAdd(115);
+                  break;
+               case 116:
+                  if (curChar == 45)
+                     jjCheckNAddStates(7, 11);
+                  break;
+               case 117:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 82)
+                     kind = 82;
+                  jjCheckNAdd(117);
+                  break;
+               case 118:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(118, 119);
+                  break;
+               case 119:
+                  if (curChar != 46)
+                     break;
+                  if (kind > 83)
+                     kind = 83;
+                  jjCheckNAdd(120);
+                  break;
+               case 120:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 83)
+                     kind = 83;
+                  jjCheckNAdd(120);
+                  break;
+               case 121:
+                  if (curChar == 46)
+                     jjCheckNAdd(122);
+                  break;
+               case 122:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 83)
+                     kind = 83;
+                  jjCheckNAdd(122);
+                  break;
+               case 123:
+                  if (curChar == 46)
+                     jjCheckNAdd(124);
+                  break;
+               case 124:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(124, 125);
+                  break;
+               case 126:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(127);
+                  break;
+               case 127:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 84)
+                     kind = 84;
+                  jjCheckNAdd(127);
+                  break;
+               case 128:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(47, 50);
+                  break;
+               case 129:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(129, 130);
+                  break;
+               case 130:
+                  if (curChar == 46)
+                     jjCheckNAddTwoStates(131, 132);
+                  break;
+               case 131:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(131, 132);
+                  break;
+               case 133:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(134);
+                  break;
+               case 134:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 84)
+                     kind = 84;
+                  jjCheckNAdd(134);
+                  break;
+               case 135:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(135, 136);
+                  break;
+               case 137:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(138);
+                  break;
+               case 138:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 84)
+                     kind = 84;
+                  jjCheckNAdd(138);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                  {
+                     if (kind > 99)
+                        kind = 99;
+                     jjCheckNAddTwoStates(57, 58);
+                  }
+                  else if (curChar == 91)
+                     jjAddStates(35, 36);
+                  else if (curChar == 64)
+                     jjCheckNAdd(15);
+                  if ((0x7fffffe07fffffeL & l) != 0L)
+                  {
+                     if (kind > 98)
+                        kind = 98;
+                     jjCheckNAddStates(51, 58);
+                  }
+                  else if (curChar == 95)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  break;
+               case 1:
+                  if ((0xc7fffffeafffffffL & l) != 0L)
+                     jjAddStates(59, 60);
+                  break;
+               case 4:
+                  if ((0x7fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 69)
+                     kind = 69;
+                  jjCheckNAddTwoStates(5, 6);
+                  break;
+               case 5:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                     jjCheckNAddTwoStates(5, 6);
+                  break;
+               case 6:
+                  if ((0x7fffffe87fffffeL & l) != 0L && kind > 69)
+                     kind = 69;
+                  break;
+               case 7:
+                  if (curChar == 95)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  break;
+               case 9:
+               case 10:
+                  if ((0x7fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 70)
+                     kind = 70;
+                  jjCheckNAdd(10);
+                  break;
+               case 12:
+               case 13:
+                  if ((0x7fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAdd(13);
+                  break;
+               case 14:
+                  if (curChar == 64)
+                     jjCheckNAdd(15);
+                  break;
+               case 15:
+                  if ((0x7fffffe07fffffeL & l) == 0L)
+                     break;
+                  if (kind > 72)
+                     kind = 72;
+                  jjCheckNAddTwoStates(15, 16);
+                  break;
+               case 17:
+                  if ((0x7fffffe07fffffeL & l) == 0L)
+                     break;
+                  if (kind > 72)
+                     kind = 72;
+                  jjCheckNAddTwoStates(16, 17);
+                  break;
+               case 19:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     jjCheckNAddStates(20, 22);
+                  break;
+               case 20:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 21;
+                  break;
+               case 21:
+                  if ((0x14404410000000L & l) != 0L)
+                     jjCheckNAddStates(20, 22);
+                  break;
+               case 24:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     jjCheckNAddStates(17, 19);
+                  break;
+               case 25:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 26;
+                  break;
+               case 26:
+                  if ((0x14404410000000L & l) != 0L)
+                     jjCheckNAddStates(17, 19);
+                  break;
+               case 30:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     jjCheckNAddStates(23, 26);
+                  break;
+               case 31:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 32;
+                  break;
+               case 32:
+                  if ((0x14404410000000L & l) != 0L)
+                     jjCheckNAddStates(23, 26);
+                  break;
+               case 41:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     jjCheckNAddStates(29, 32);
+                  break;
+               case 42:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 43;
+                  break;
+               case 43:
+                  if ((0x14404410000000L & l) != 0L)
+                     jjCheckNAddStates(29, 32);
+                  break;
+               case 53:
+                  if (curChar == 91)
+                     jjAddStates(35, 36);
+                  break;
+               case 55:
+                  if (curChar == 93 && kind > 93)
+                     kind = 93;
+                  break;
+               case 56:
+                  if ((0x7fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 99)
+                     kind = 99;
+                  jjCheckNAddTwoStates(57, 58);
+                  break;
+               case 57:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                     jjCheckNAddTwoStates(57, 58);
+                  break;
+               case 58:
+                  if ((0x7fffffe87fffffeL & l) != 0L && kind > 99)
+                     kind = 99;
+                  break;
+               case 59:
+                  if ((0x7fffffe07fffffeL & l) == 0L)
+                     break;
+                  if (kind > 98)
+                     kind = 98;
+                  jjCheckNAddStates(51, 58);
+                  break;
+               case 60:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                     jjCheckNAddTwoStates(60, 61);
+                  break;
+               case 61:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                     jjCheckNAdd(62);
+                  break;
+               case 63:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                     jjCheckNAddTwoStates(63, 64);
+                  break;
+               case 64:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                     jjCheckNAdd(65);
+                  break;
+               case 66:
+                  if ((0x7fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 68)
+                     kind = 68;
+                  jjCheckNAddTwoStates(67, 68);
+                  break;
+               case 67:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                     jjCheckNAddTwoStates(67, 68);
+                  break;
+               case 68:
+                  if ((0x7fffffe87fffffeL & l) != 0L && kind > 68)
+                     kind = 68;
+                  break;
+               case 69:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                     jjCheckNAddTwoStates(69, 70);
+                  break;
+               case 70:
+                  if ((0x7fffffe87fffffeL & l) != 0L && kind > 98)
+                     kind = 98;
+                  break;
+               case 80:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(61, 62);
+                  break;
+               case 84:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(63, 64);
+                  break;
+               case 90:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(65, 66);
+                  break;
+               case 102:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(67, 68);
+                  break;
+               case 109:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(69, 70);
+                  break;
+               case 113:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(71, 72);
+                  break;
+               case 125:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(73, 74);
+                  break;
+               case 132:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(75, 76);
+                  break;
+               case 136:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(77, 78);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if (jjCanMove_1(hiByte, i1, i2, l1, l2))
+                  {
+                     if (kind > 99)
+                        kind = 99;
+                     jjCheckNAddTwoStates(57, 58);
+                  }
+                  if (jjCanMove_1(hiByte, i1, i2, l1, l2))
+                  {
+                     if (kind > 98)
+                        kind = 98;
+                     jjCheckNAddStates(51, 58);
+                  }
+                  break;
+               case 1:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(59, 60);
+                  break;
+               case 4:
+                  if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 69)
+                     kind = 69;
+                  jjCheckNAddTwoStates(5, 6);
+                  break;
+               case 5:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     jjCheckNAddTwoStates(5, 6);
+                  break;
+               case 6:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2) && kind > 69)
+                     kind = 69;
+                  break;
+               case 9:
+                  if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 70)
+                     kind = 70;
+                  jjCheckNAdd(10);
+                  break;
+               case 10:
+                  if (!jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 70)
+                     kind = 70;
+                  jjCheckNAdd(10);
+                  break;
+               case 12:
+                  if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAdd(13);
+                  break;
+               case 13:
+                  if (!jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAdd(13);
+                  break;
+               case 19:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(20, 22);
+                  break;
+               case 24:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(17, 19);
+                  break;
+               case 30:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(23, 26);
+                  break;
+               case 41:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(29, 32);
+                  break;
+               case 56:
+                  if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 99)
+                     kind = 99;
+                  jjCheckNAddTwoStates(57, 58);
+                  break;
+               case 57:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     jjCheckNAddTwoStates(57, 58);
+                  break;
+               case 58:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2) && kind > 99)
+                     kind = 99;
+                  break;
+               case 59:
+                  if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 98)
+                     kind = 98;
+                  jjCheckNAddStates(51, 58);
+                  break;
+               case 60:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     jjCheckNAddTwoStates(60, 61);
+                  break;
+               case 61:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     jjCheckNAdd(62);
+                  break;
+               case 63:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     jjCheckNAddTwoStates(63, 64);
+                  break;
+               case 64:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     jjCheckNAdd(65);
+                  break;
+               case 66:
+                  if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 68)
+                     kind = 68;
+                  jjCheckNAddTwoStates(67, 68);
+                  break;
+               case 67:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     jjCheckNAddTwoStates(67, 68);
+                  break;
+               case 68:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2) && kind > 68)
+                     kind = 68;
+                  break;
+               case 69:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     jjCheckNAddTwoStates(69, 70);
+                  break;
+               case 70:
+                  if (jjCanMove_2(hiByte, i1, i2, l1, l2) && kind > 98)
+                     kind = 98;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 139 - (jjnewStateCnt = startsAt)))
+         break;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { break; }
+   }
+   if (jjmatchedPos > strPos)
+      return curPos;
+
+   int toRet = Math.max(curPos, seenUpto);
+
+   if (curPos < toRet)
+      for (i = toRet - Math.min(curPos, seenUpto); i-- > 0; )
+         try { curChar = input_stream.readChar(); }
+         catch(java.io.IOException e) { throw new Error("Internal Error : Please send a bug report."); }
+
+   if (jjmatchedPos < strPos)
+   {
+      jjmatchedKind = strKind;
+      jjmatchedPos = strPos;
+   }
+   else if (jjmatchedPos == strPos && jjmatchedKind > strKind)
+      jjmatchedKind = strKind;
+
+   return toRet;
+}
+private final int jjMoveStringLiteralDfa0_1()
+{
+   return jjMoveNfa_1(0, 0);
+}
+private final int jjMoveNfa_1(int startState, int curPos)
+{
+   int[] nextStates;
+   int startsAt = 0;
+   jjnewStateCnt = 1;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int j, kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0xffffffffffffdbffL & l) == 0L)
+                     break;
+                  kind = 7;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  kind = 7;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 7)
+                     kind = 7;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 1 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+static final int[] jjnextStates = {
+   73, 74, 75, 77, 78, 83, 84, 117, 118, 121, 123, 128, 94, 95, 98, 100, 
+   105, 24, 25, 27, 19, 20, 22, 29, 30, 31, 33, 34, 36, 40, 41, 42, 
+   44, 45, 47, 54, 55, 60, 61, 63, 64, 69, 70, 106, 107, 112, 113, 129, 
+   130, 135, 136, 60, 61, 62, 63, 64, 65, 69, 70, 1, 2, 81, 82, 85, 
+   86, 91, 92, 103, 104, 110, 111, 114, 115, 126, 127, 133, 134, 137, 138, 
+};
+private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec2[i2] & l2) != 0L);
+      default : 
+         if ((jjbitVec0[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+private static final boolean jjCanMove_1(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec4[i2] & l2) != 0L);
+      case 3:
+         return ((jjbitVec5[i2] & l2) != 0L);
+      case 32:
+         return ((jjbitVec6[i2] & l2) != 0L);
+      case 33:
+         return ((jjbitVec7[i2] & l2) != 0L);
+      case 47:
+         return ((jjbitVec8[i2] & l2) != 0L);
+      case 48:
+         return ((jjbitVec0[i2] & l2) != 0L);
+      case 253:
+         return ((jjbitVec9[i2] & l2) != 0L);
+      case 255:
+         return ((jjbitVec10[i2] & l2) != 0L);
+      default : 
+         if ((jjbitVec3[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+private static final boolean jjCanMove_2(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec11[i2] & l2) != 0L);
+      case 3:
+         return ((jjbitVec12[i2] & l2) != 0L);
+      case 32:
+         return ((jjbitVec13[i2] & l2) != 0L);
+      case 33:
+         return ((jjbitVec7[i2] & l2) != 0L);
+      case 47:
+         return ((jjbitVec8[i2] & l2) != 0L);
+      case 48:
+         return ((jjbitVec0[i2] & l2) != 0L);
+      case 253:
+         return ((jjbitVec9[i2] & l2) != 0L);
+      case 255:
+         return ((jjbitVec10[i2] & l2) != 0L);
+      default : 
+         if ((jjbitVec3[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+public static final String[] jjstrLiteralImages = {
+"", null, null, null, null, null, null, null, null, null, null, null, null, 
+null, null, null, null, null, null, null, null, null, null, null, null, null, null, 
+null, null, null, null, null, null, null, null, null, null, null, null, null, "\52", 
+"\101\123\103", "\104\105\123\103", "\173", "\56", "\175", "\50", "\54", "\51", "\73", "\141", 
+"\133", "\135", "\174\174", "\46\46", "\75", "\41\75", "\74", "\76", "\74\75", 
+"\76\75", "\53", "\55", "\57", "\41", "\136\136", null, null, null, null, null, null, 
+null, null, null, null, null, null, null, null, null, null, null, null, null, null, 
+null, null, null, null, null, null, null, null, null, null, null, null, null, null, };
+public static final String[] lexStateNames = {
+   "DEFAULT", 
+   "IN_COMMENT", 
+};
+public static final int[] jjnewLexState = {
+   -1, -1, -1, -1, -1, -1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+};
+static final long[] jjtoToken = {
+   0xffffffffffffff01L, 0xc2bdff1ffL, 
+};
+static final long[] jjtoSkip = {
+   0xbeL, 0x0L, 
+};
+static final long[] jjtoSpecial = {
+   0x80L, 0x0L, 
+};
+static final long[] jjtoMore = {
+   0x40L, 0x0L, 
+};
+protected SimpleCharStream input_stream;
+private final int[] jjrounds = new int[139];
+private final int[] jjstateSet = new int[278];
+StringBuffer image;
+int jjimageLen;
+int lengthOfMatch;
+protected char curChar;
+public SparqlParserTokenManager(SimpleCharStream stream){
+   if (SimpleCharStream.staticFlag)
+      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+   input_stream = stream;
+}
+public SparqlParserTokenManager(SimpleCharStream stream, int lexState){
+   this(stream);
+   SwitchTo(lexState);
+}
+public void ReInit(SimpleCharStream stream)
+{
+   jjmatchedPos = jjnewStateCnt = 0;
+   curLexState = defaultLexState;
+   input_stream = stream;
+   ReInitRounds();
+}
+private final void ReInitRounds()
+{
+   int i;
+   jjround = 0x80000001;
+   for (i = 139; i-- > 0;)
+      jjrounds[i] = 0x80000000;
+}
+public void ReInit(SimpleCharStream stream, int lexState)
+{
+   ReInit(stream);
+   SwitchTo(lexState);
+}
+public void SwitchTo(int lexState)
+{
+   if (lexState >= 2 || lexState < 0)
+      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+   else
+      curLexState = lexState;
+}
+
+protected Token jjFillToken()
+{
+   Token t = Token.newToken(jjmatchedKind);
+   t.kind = jjmatchedKind;
+   if (jjmatchedPos < 0)
+   {
+      if (image == null)
+         t.image = "";
+      else
+         t.image = image.toString();
+      t.beginLine = t.endLine = input_stream.getBeginLine();
+      t.beginColumn = t.endColumn = input_stream.getBeginColumn();
+   }
+   else
+   {
+      String im = jjstrLiteralImages[jjmatchedKind];
+      t.image = (im == null) ? input_stream.GetImage() : im;
+      t.beginLine = input_stream.getBeginLine();
+      t.beginColumn = input_stream.getBeginColumn();
+      t.endLine = input_stream.getEndLine();
+      t.endColumn = input_stream.getEndColumn();
+   }
+   return t;
+}
+
+int curLexState = 0;
+int defaultLexState = 0;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
+
+public Token getNextToken() 
+{
+  int kind;
+  Token specialToken = null;
+  Token matchedToken;
+  int curPos = 0;
+
+  EOFLoop :
+  for (;;)
+  {   
+   try   
+   {     
+      curChar = input_stream.BeginToken();
+   }     
+   catch(java.io.IOException e)
+   {        
+      jjmatchedKind = 0;
+      matchedToken = jjFillToken();
+      matchedToken.specialToken = specialToken;
+      return matchedToken;
+   }
+   image = null;
+   jjimageLen = 0;
+
+   for (;;)
+   {
+     switch(curLexState)
+     {
+       case 0:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_0();
+         break;
+       case 1:
+         jjmatchedKind = 7;
+         jjmatchedPos = -1;
+         curPos = 0;
+         curPos = jjMoveStringLiteralDfa0_1();
+         break;
+     }
+     if (jjmatchedKind != 0x7fffffff)
+     {
+        if (jjmatchedPos + 1 < curPos)
+           input_stream.backup(curPos - jjmatchedPos - 1);
+        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+           matchedToken = jjFillToken();
+           matchedToken.specialToken = specialToken;
+       if (jjnewLexState[jjmatchedKind] != -1)
+         curLexState = jjnewLexState[jjmatchedKind];
+           return matchedToken;
+        }
+        else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+           if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+           {
+              matchedToken = jjFillToken();
+              if (specialToken == null)
+                 specialToken = matchedToken;
+              else
+              {
+                 matchedToken.specialToken = specialToken;
+                 specialToken = (specialToken.next = matchedToken);
+              }
+              SkipLexicalActions(matchedToken);
+           }
+           else 
+              SkipLexicalActions(null);
+         if (jjnewLexState[jjmatchedKind] != -1)
+           curLexState = jjnewLexState[jjmatchedKind];
+           continue EOFLoop;
+        }
+        jjimageLen += jjmatchedPos + 1;
+      if (jjnewLexState[jjmatchedKind] != -1)
+        curLexState = jjnewLexState[jjmatchedKind];
+        curPos = 0;
+        jjmatchedKind = 0x7fffffff;
+        try {
+           curChar = input_stream.readChar();
+           continue;
+        }
+        catch (java.io.IOException e1) { }
+     }
+     int error_line = input_stream.getEndLine();
+     int error_column = input_stream.getEndColumn();
+     String error_after = null;
+     boolean EOFSeen = false;
+     try { input_stream.readChar(); input_stream.backup(1); }
+     catch (java.io.IOException e1) {
+        EOFSeen = true;
+        error_after = curPos <= 1 ? "" : input_stream.GetImage();
+        if (curChar == '\n' || curChar == '\r') {
+           error_line++;
+           error_column = 0;
+        }
+        else
+           error_column++;
+     }
+     if (!EOFSeen) {
+        input_stream.backup(1);
+        error_after = curPos <= 1 ? "" : input_stream.GetImage();
+     }
+     throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
+   }
+  }
+}
+
+void SkipLexicalActions(Token matchedToken)
+{
+   switch(jjmatchedKind)
+   {
+      default :
+         break;
+   }
+}
+}

Added: trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/Token.java
===================================================================
--- trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/Token.java	                        (rev 0)
+++ trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/Token.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,81 @@
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */
+package org.mulgara.sparql.parser;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token {
+
+  /**
+   * An integer that describes the kind of this token.  This numbering
+   * system is determined by JavaCCParser, and a table of these numbers is
+   * stored in the file ...Constants.java.
+   */
+  public int kind;
+
+  /**
+   * beginLine and beginColumn describe the position of the first character
+   * of this token; endLine and endColumn describe the position of the
+   * last character of this token.
+   */
+  public int beginLine, beginColumn, endLine, endColumn;
+
+  /**
+   * The string image of the token.
+   */
+  public String image;
+
+  /**
+   * A reference to the next regular (non-special) token from the input
+   * stream.  If this is the last token from the input stream, or if the
+   * token manager has not read tokens beyond this one, this field is
+   * set to null.  This is true only if this token is also a regular
+   * token.  Otherwise, see below for a description of the contents of
+   * this field.
+   */
+  public Token next;
+
+  /**
+   * This field is used to access special tokens that occur prior to this
+   * token, but after the immediately preceding regular (non-special) token.
+   * If there are no such special tokens, this field is set to null.
+   * When there are more than one such special token, this field refers
+   * to the last of these special tokens, which in turn refers to the next
+   * previous special token through its specialToken field, and so on
+   * until the first special token (whose specialToken field is null).
+   * The next fields of special tokens refer to other special tokens that
+   * immediately follow it (without an intervening regular token).  If there
+   * is no such token, this field is null.
+   */
+  public Token specialToken;
+
+  /**
+   * Returns the image.
+   */
+  public String toString()
+  {
+     return image;
+  }
+
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simlpy add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken();
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use it in your lexical actions.
+   */
+  public static final Token newToken(int ofKind)
+  {
+     switch(ofKind)
+     {
+       default : return new Token();
+     }
+  }
+
+}

Added: trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/TokenMgrError.java
===================================================================
--- trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/TokenMgrError.java	                        (rev 0)
+++ trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/TokenMgrError.java	2008-09-01 04:54:04 UTC (rev 1219)
@@ -0,0 +1,133 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */
+package org.mulgara.sparql.parser;
+
+public class TokenMgrError extends Error
+{
+   /*
+    * Ordinals for various reasons why an Error of this type can be thrown.
+    */
+
+   /**
+    * Lexical error occurred.
+    */
+   static final int LEXICAL_ERROR = 0;
+
+   /**
+    * An attempt was made to create a second instance of a static token manager.
+    */
+   static final int STATIC_LEXER_ERROR = 1;
+
+   /**
+    * Tried to change to an invalid lexical state.
+    */
+   static final int INVALID_LEXICAL_STATE = 2;
+
+   /**
+    * Detected (and bailed out of) an infinite loop in the token manager.
+    */
+   static final int LOOP_DETECTED = 3;
+
+   /**
+    * Indicates the reason why the exception is thrown. It will have
+    * one of the above 4 values.
+    */
+   int errorCode;
+
+   /**
+    * Replaces unprintable characters by their escaped (or unicode escaped)
+    * equivalents in the given string
+    */
+   protected static final String addEscapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case 0 :
+              continue;
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+   /**
+    * Returns a detailed message for the Error when it is thrown by the
+    * token manager to indicate a lexical error.
+    * Parameters : 
+    *    EOFSeen     : indicates if EOF caused the lexical error
+    *    curLexState : lexical state in which this error occurred
+    *    errorLine   : line number when the error occurred
+    *    errorColumn : column number when the error occurred
+    *    errorAfter  : prefix that was seen before this error occurred
+    *    curchar     : the offending character
+    * Note: You can customize the lexical error message by modifying this method.
+    */
+   protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+      return("Lexical error at line " +
+           errorLine + ", column " +
+           errorColumn + ".  Encountered: " +
+           (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+           "after : \"" + addEscapes(errorAfter) + "\"");
+   }
+
+   /**
+    * You can also modify the body of this method to customize your error messages.
+    * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+    * of end-users concern, so you can return something like : 
+    *
+    *     "Internal Error : Please file a bug report .... "
+    *
+    * from this method for such cases in the release version of your parser.
+    */
+   public String getMessage() {
+      return super.getMessage();
+   }
+
+   /*
+    * Constructors of various flavors follow.
+    */
+
+   public TokenMgrError() {
+   }
+
+   public TokenMgrError(String message, int reason) {
+      super(message);
+      errorCode = reason;
+   }
+
+   public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+      this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+   }
+}




More information about the Mulgara-svn mailing list