Remove CVS expansions
[cql-java-moved-to-github.git] / src / main / java / org / z3950 / zing / cql / CQLParser.java
index 9970aa7..2509563 100644 (file)
@@ -1,4 +1,3 @@
-// $Id: CQLParser.java,v 1.39 2007-08-06 15:54:48 mike Exp $
 
 package org.z3950.zing.cql;
 import java.io.IOException;
@@ -15,12 +14,12 @@ import java.util.List;
 /**
  * Compiles CQL strings into parse trees of CQLNode subtypes.
  *
- * @version    $Id: CQLParser.java,v 1.39 2007-08-06 15:54:48 mike Exp $
  * @see                <A href="http://zing.z3950.org/cql/index.html"
  *                     >http://zing.z3950.org/cql/index.html</A>
  */
 public class CQLParser {
     private CQLLexer lexer;
+    private PositionAwareReader par; //active reader with position
     private int compat;        // When false, implement CQL 1.2
     public static final int V1POINT1 = 12368;
     public static final int V1POINT2 = 12369;
@@ -96,14 +95,16 @@ public class CQLParser {
      * tree representing the query.  */
     public CQLNode parse(Reader cql)
        throws CQLParseException, IOException {
-       lexer = new CQLLexer(cql, LEXDEBUG);
+        par = new PositionAwareReader(cql);
+       lexer = new CQLLexer(par, LEXDEBUG);
 
        lexer.nextToken();
        debug("about to parseQuery()");
        CQLNode root = parseTopLevelPrefixes("cql.serverChoice",
                new CQLRelation(compat == V1POINT2 ? "=" : "scr"));
        if (lexer.ttype != CQLLexer.TT_EOF)
-           throw new CQLParseException("junk after end: " + lexer.render());
+           throw new CQLParseException("junk after end: " + lexer.render(), 
+              par.getPosition());
 
        return root;
     }
@@ -130,7 +131,7 @@ public class CQLParser {
            }
 
            if (sortnode.keys.size() == 0) {
-               throw new CQLParseException("no sort keys");
+               throw new CQLParseException("no sort keys", par.getPosition());
            }
 
            node = sortnode;
@@ -162,7 +163,7 @@ public class CQLParser {
                                                 new CQLProxNode(term, term2, ms));
            } else {
                throw new CQLParseException("expected boolean, got " +
-                                           lexer.render());
+                                           lexer.render(), par.getPosition());
            }
        }
 
@@ -179,7 +180,8 @@ public class CQLParser {
            match('/');
            if (lexer.ttype != CQLLexer.TT_WORD)
                throw new CQLParseException("expected modifier, "
-                                           + "got " + lexer.render());
+                                           + "got " + lexer.render(), 
+                  par.getPosition());
            String type = lexer.sval.toLowerCase();
            match(lexer.ttype);
            if (!isSymbolicRelation()) {
@@ -268,7 +270,7 @@ public class CQLParser {
              lexer.sval.equals("all") ||
              lexer.sval.equals("within") ||
              lexer.sval.equals("encloses") ||
-             lexer.sval.equals("exact") ||
+             (lexer.sval.equals("exact") && compat != V1POINT2) ||
              (lexer.sval.equals("scr") && compat != V1POINT2) ||
              (lexer.sval.equals("adj") && compat == V1POINT2)))
           return true;
@@ -294,7 +296,8 @@ public class CQLParser {
        if (lexer.ttype != token)
            throw new CQLParseException("expected " +
                                        lexer.render(token, true) +
-                                       ", " + "got " + lexer.render());
+                                       ", " + "got " + lexer.render(), 
+              par.getPosition());
        int tmp = lexer.nextToken();
        debug("match() got token=" + lexer.ttype + ", " +
              "nval=" + lexer.nval + ", sval='" + lexer.sval + "'" +
@@ -325,7 +328,7 @@ public class CQLParser {
        }
 
        throw new CQLParseException("expected " + expected + ", " +
-                                   "got " + lexer.render());
+                                   "got " + lexer.render(), par.getPosition());
     }