From 4886cce6a79fa4e1d3365319e2b24a642b179f59 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 19 Mar 2014 15:28:03 +0100 Subject: [PATCH] Disallow multi-token index names That, in turn, binds non-symbolic relations to the second position and allows more free-form parsing. --- src/main/java/org/z3950/zing/cql/CQLParser.java | 29 ++++++++------ .../java/org/z3950/zing/cql/CQLParserTest.java | 2 +- src/test/resources/regression/09/01.xcql | 42 ++++++++++++++------ 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index b435aa3..4d4f025 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 (isWordOrString() && !isRelation()) { - word = word + " " + lexer.value(); + 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; } diff --git a/src/test/java/org/z3950/zing/cql/CQLParserTest.java b/src/test/java/org/z3950/zing/cql/CQLParserTest.java index 2566e13..34d5999 100644 --- a/src/test/java/org/z3950/zing/cql/CQLParserTest.java +++ b/src/test/java/org/z3950/zing/cql/CQLParserTest.java @@ -133,7 +133,7 @@ public class CQLParserTest { params.load(is); is.close(); CQLGenerator generator = new CQLGenerator(params); - for (int i=0; i<100; i++) { + for (int i=0; i<1000; i++) { CQLNode random = generator.generate(); String expected = random.toCQL(); out.println("Generated query: "+expected); diff --git a/src/test/resources/regression/09/01.xcql b/src/test/resources/regression/09/01.xcql index f721ed0..aefe23d 100644 --- a/src/test/resources/regression/09/01.xcql +++ b/src/test/resources/regression/09/01.xcql @@ -1,20 +1,36 @@ - and + prox - or + and - - cql.serverChoice - - = - - any - + + + or + + + + cql.serverChoice + + = + + any + + + + + cql.serverChoice + + = + + all:stem + + + @@ -22,18 +38,18 @@ = - all:stem + all contains any - all contains + cql.serverChoice - any + = - prox proxfuzzy + proxfuzzy -- 1.7.10.4