X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fz3950%2Fzing%2Fcql%2FCQLParser.java;h=8a0fc172592a572a6cf25e9802009a59414d5905;hb=738438f3da478a1d0121cbbdab620c47f222c73e;hp=a4f2fc8ed287094c19e572c84d10ab122a42d22a;hpb=59200080b45184be8779f545d21ce87c4020ccf4;p=cql-java-moved-to-github.git diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index a4f2fc8..8a0fc17 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -1,14 +1,12 @@ package org.z3950.zing.cql; + import java.io.BufferedReader; import java.io.IOException; import java.util.Properties; import java.io.InputStream; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -221,7 +219,8 @@ public class CQLParser { throws CQLParseException, IOException { debug("in parseTerm()"); - String word; + String first; + StringBuilder all; while (true) { if (lexer.what() == '(') { debug("parenthesised term"); @@ -234,16 +233,23 @@ public class CQLParser { } debug("non-parenthesised term"); - word = matchSymbol("index or term"); - while (lexer.what() == CQLTokenizer.TT_WORD && !isRelation()) { - word = word + " " + lexer.value(); - match(CQLTokenizer.TT_WORD); + first = matchSymbol("index or term"); + all = new StringBuilder(first); + //match relation only on second postion + while (isWordOrString() && (all.length() > first.length() || !isRelation())) { + all.append(" ").append(lexer.value()); + match(lexer.what()); } if (!isRelation()) - break; - - index = word; + break; //we're done if no relation + + //we have relation, but it only makes sense if preceded by a single term + if (all.length() > first.length()) { + throw new CQLParseException("unexpected relation '"+lexer.value()+"'" + , lexer.pos()); + } + index = first; String relstr = (lexer.what() == CQLTokenizer.TT_WORD ? lexer.value() : lexer.render(lexer.what(), false)); relation = new CQLRelation(relstr); @@ -253,8 +259,7 @@ public class CQLParser { debug("index='" + index + ", " + "relation='" + relation.toCQL() + "'"); } - - CQLTermNode node = new CQLTermNode(index, relation, word); + CQLTermNode node = new CQLTermNode(index, relation, all.toString()); debug("made term node " + node.toCQL()); return node; } @@ -278,6 +283,11 @@ public class CQLParser { return new CQLPrefixNode(name, identifier, node); } + + private boolean isWordOrString() { + return CQLTokenizer.TT_WORD == lexer.what() + || CQLTokenizer.TT_STRING == lexer.what(); + } private boolean isRelation() { debug("isRelation: checking what()=" + lexer.what() + @@ -326,12 +336,10 @@ public class CQLParser { debug("in matchSymbol()"); if (lexer.what() == CQLTokenizer.TT_WORD || - lexer.what() == '"' || + lexer.what() == CQLTokenizer.TT_STRING || // The following is a complete list of keywords. Because // they're listed here, they can be used unquoted as // indexes, terms, prefix names and prefix identifiers. - // ### Instead, we should ask the lexer whether what we - // have is a keyword, and let the knowledge reside there. (allowKeywordTerms && lexer.what() == CQLTokenizer.TT_AND || lexer.what() == CQLTokenizer.TT_OR || @@ -470,6 +478,11 @@ public class CQLParser { root = parser.parse(cql); } catch (CQLParseException ex) { System.err.println("Syntax error: " + ex.getMessage()); + StringBuilder space = new StringBuilder(cql.length()); + System.out.println(cql); + for (int i=0; i