addModifier() now uses broader ModifierSet API.
[cql-java-moved-to-github.git] / src / org / z3950 / zing / cql / CQLParser.java
index 85ee63b..84b0488 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: CQLParser.java,v 1.22 2002-11-20 01:15:15 mike Exp $
+// $Id: CQLParser.java,v 1.26 2007-06-27 22:16:23 mike Exp $
 
 package org.z3950.zing.cql;
 import java.io.IOException;
@@ -12,7 +12,7 @@ import java.io.FileNotFoundException;
 /**
  * Compiles CQL strings into parse trees of CQLNode subtypes.
  *
- * @version    $Id: CQLParser.java,v 1.22 2002-11-20 01:15:15 mike Exp $
+ * @version    $Id: CQLParser.java,v 1.26 2007-06-27 22:16:23 mike Exp $
  * @see                <A href="http://zing.z3950.org/cql/index.html"
  *                     >http://zing.z3950.org/cql/index.html</A>
  */
@@ -114,7 +114,9 @@ public class CQLParser {
                break;
 
            qualifier = word;
-           relation = new CQLRelation(lexer.render(lexer.ttype, false));
+           relation = new CQLRelation(lexer.ttype == lexer.TT_WORD ?
+                                      lexer.sval :
+                                      lexer.render(lexer.ttype, false));
            match(lexer.ttype);
 
            while (lexer.ttype == '/') {
@@ -122,9 +124,16 @@ public class CQLParser {
                if (lexer.ttype != lexer.TT_RELEVANT &&
                    lexer.ttype != lexer.TT_FUZZY &&
                    lexer.ttype != lexer.TT_STEM &&
-                   lexer.ttype != lexer.TT_PHONETIC)
+                   lexer.ttype != lexer.TT_PHONETIC &&
+                   lexer.ttype != lexer.TT_WORD)
                    throw new CQLParseException("expected relation modifier, "
                                                + "got " + lexer.render());
+               if (lexer.ttype == lexer.TT_WORD &&
+                   lexer.sval.indexOf('.') == -1)
+                   throw new CQLParseException("unknown first-class " +
+                                               "relation modifier: " +
+                                               lexer.sval);
+
                relation.addModifier(lexer.sval.toLowerCase());
                match(lexer.ttype);
            }
@@ -179,7 +188,7 @@ public class CQLParser {
        if (!isProxRelation())
            throw new CQLParseException("expected proximity relation, got " +
                                        lexer.render());
-       node.addModifier("relation", lexer.render(lexer.ttype, false));
+       node.addModifier("relation", null, lexer.render(lexer.ttype, false));
        match(lexer.ttype);
        debug("gPR matched " + lexer.render(lexer.ttype, false));
     }
@@ -189,7 +198,7 @@ public class CQLParser {
        if (lexer.ttype != lexer.TT_NUMBER)
            throw new CQLParseException("expected proximity distance, got " +
                                        lexer.render());
-       node.addModifier("distance", lexer.render(lexer.ttype, false));
+       node.addModifier("distance", null, lexer.render(lexer.ttype, false));
        match(lexer.ttype);
        debug("gPD matched " + lexer.render(lexer.ttype, false));
     }
@@ -202,7 +211,7 @@ public class CQLParser {
            lexer.ttype != lexer.TT_ELEMENT)
            throw new CQLParseException("expected proximity unit, got " +
                                        lexer.render());
-       node.addModifier("unit", lexer.render());
+       node.addModifier("unit", null, lexer.render());
        match(lexer.ttype);
     }
 
@@ -212,18 +221,26 @@ public class CQLParser {
            lexer.ttype != lexer.TT_UNORDERED)
            throw new CQLParseException("expected proximity ordering, got " +
                                        lexer.render());
-       node.addModifier("ordering", lexer.render());
+       node.addModifier("ordering", null, lexer.render());
        match(lexer.ttype);
     }
 
-    private boolean isBaseRelation() {
+    private boolean isBaseRelation()
+       throws CQLParseException {
        debug("isBaseRelation: checking ttype=" + lexer.ttype +
              " (" + lexer.render() + ")");
+
+       if (lexer.ttype == lexer.TT_WORD &&
+           lexer.sval.indexOf('.') == -1)
+           throw new CQLParseException("unknown first-class relation: " +
+                                       lexer.sval);
+
        return (isProxRelation() ||
                lexer.ttype == lexer.TT_ANY ||
                lexer.ttype == lexer.TT_ALL ||
                lexer.ttype == lexer.TT_EXACT ||
-               lexer.ttype == lexer.TT_SCR);
+               lexer.ttype == lexer.TT_SCR ||
+               lexer.ttype == lexer.TT_WORD);
     }
 
     // Checks for a relation that may be used inside a prox operator
@@ -351,11 +368,16 @@ public class CQLParser {
        char mode = 'x';        // x=XCQL, c=CQL, p=PQF
        String pfile = null;
 
-       Vector argv = new Vector();
+       Vector<String> argv = new Vector<String>();
        for (int i = 0; i < args.length; i++) {
            argv.add(args[i]);
        }
 
+       if (argv.size() > 0 && argv.get(0).equals("-d")) {
+           DEBUG = true;
+           argv.remove(0);
+       }
+
        if (argv.size() > 0 && argv.get(0).equals("-c")) {
            mode = 'c';
            argv.remove(0);
@@ -367,8 +389,7 @@ public class CQLParser {
        }
 
        if (argv.size() > 1) {
-           System.err.println(
-               "Usage: CQLParser [-c] [-p <pqf-properties> [<CQL-query>]");
+           System.err.println("Usage: CQLParser [-d] [-c] [-p <pqf-properties> [<CQL-query>]");
            System.err.println("If unspecified, query is read from stdin");
            System.exit(1);
        }