From: mike Date: Tue, 3 Jul 2007 13:34:30 +0000 (+0000) Subject: New method parseTopLevelPrefixes() handles both initial prefixes and a X-Git-Tag: v1.5~57 X-Git-Url: http://sru.miketaylor.org.uk/cgi-bin?a=commitdiff_plain;h=4eb901c2c0122b303564fd6c14f6294be1a00251;p=cql-java-moved-to-github.git New method parseTopLevelPrefixes() handles both initial prefixes and a sortby clause if any. parseQuery() breaks on SORTBY as well as ")" and EOF. parsePrefix() now takes an additional boolean argument topLevel: if true, then recursion is to parseTopLevelPrefixes() rather than parseQuery(). --- diff --git a/src/org/z3950/zing/cql/CQLParser.java b/src/org/z3950/zing/cql/CQLParser.java index b23506c..f622bbb 100644 --- a/src/org/z3950/zing/cql/CQLParser.java +++ b/src/org/z3950/zing/cql/CQLParser.java @@ -1,4 +1,4 @@ -// $Id: CQLParser.java,v 1.36 2007-06-29 15:39:09 mike Exp $ +// $Id: CQLParser.java,v 1.37 2007-07-03 13:34:30 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.36 2007-06-29 15:39:09 mike Exp $ + * @version $Id: CQLParser.java,v 1.37 2007-07-03 13:34:30 mike Exp $ * @see http://zing.z3950.org/cql/index.html */ @@ -77,20 +77,48 @@ public class CQLParser { lexer.nextToken(); debug("about to parseQuery()"); - CQLNode root = parseQuery("cql.serverChoice", - new CQLRelation(compat == V1POINT2 ? "=" : "scr")); + CQLNode root = parseTopLevelPrefixes("cql.serverChoice", + new CQLRelation(compat == V1POINT2 ? "=" : "scr")); if (lexer.ttype != lexer.TT_EOF) throw new CQLParseException("junk after end: " + lexer.render()); return root; } + private CQLNode parseTopLevelPrefixes(String index, CQLRelation relation) + throws CQLParseException, IOException { + debug("top-level prefix mapping"); + + if (lexer.ttype == '>') { + return parsePrefix(index, relation, true); + } + + CQLNode node = parseQuery(index, relation); + if ((compat == V1POINT2 || compat == V1POINT1SORT) && + lexer.ttype == lexer.TT_SORTBY) { + match(lexer.ttype); + debug("sortspec"); + + CQLSortNode sortnode = new CQLSortNode(node); + while (lexer.ttype != lexer.TT_EOF) { + String sortindex = matchSymbol("sort index"); + ModifierSet ms = gatherModifiers(sortindex); + sortnode.addSortIndex(ms); + } + node = sortnode; + } + + return node; + } + private CQLNode parseQuery(String index, CQLRelation relation) throws CQLParseException, IOException { debug("in parseQuery()"); CQLNode term = parseTerm(index, relation); - while (lexer.ttype != lexer.TT_EOF && lexer.ttype != ')') { + while (lexer.ttype != lexer.TT_EOF && + lexer.ttype != ')' && + lexer.ttype != lexer.TT_SORTBY) { if (lexer.ttype == lexer.TT_AND || lexer.ttype == lexer.TT_OR || lexer.ttype == lexer.TT_NOT || @@ -154,8 +182,7 @@ public class CQLParser { match(')'); return expr; } else if (lexer.ttype == '>') { - match('>'); - return parsePrefix(index, relation); + return parsePrefix(index, relation, false); } debug("non-parenthesised term"); @@ -179,10 +206,12 @@ public class CQLParser { return node; } - private CQLNode parsePrefix(String index, CQLRelation relation) + private CQLNode parsePrefix(String index, CQLRelation relation, + boolean topLevel) throws CQLParseException, IOException { debug("prefix mapping"); + match('>'); String name = null; String identifier = matchSymbol("prefix-name"); if (lexer.ttype == '=') { @@ -190,8 +219,11 @@ public class CQLParser { name = identifier; identifier = matchSymbol("prefix-identifer"); } - CQLNode term = parseQuery(index, relation); - return new CQLPrefixNode(name, identifier, term); + CQLNode node = topLevel ? + parseTopLevelPrefixes(index, relation) : + parseQuery(index, relation); + + return new CQLPrefixNode(name, identifier, node); } // Checks for a relation @@ -235,7 +267,8 @@ public class CQLParser { lexer.ttype == lexer.TT_AND || lexer.ttype == lexer.TT_OR || lexer.ttype == lexer.TT_NOT || - lexer.ttype == lexer.TT_PROX) { + lexer.ttype == lexer.TT_PROX || + lexer.ttype == lexer.TT_SORTBY) { String symbol = (lexer.ttype == lexer.TT_NUMBER) ? lexer.render() : lexer.sval; match(lexer.ttype);