2 * Copyright (c) 1995-2014, Index Datassss
4 * See the file LICENSE for details.
6 package org.z3950.zing.cql;
9 * Implementation of the CQL lexical syntax analyzer
12 public class CQLLexer implements CQLTokenizer {
16 private int what = TT_NOTHING;
19 private StringBuilder buf = new StringBuilder();
21 public CQLLexer(String cql, boolean debug) {
29 while (qi < ql && strchr(" \t\r\n\0", qs.charAt(qi)))
37 char c = qs.charAt(qi);
39 if (strchr("()/", c)) {
43 } else if (strchr("<>=", c)) {
48 char d = qs.charAt(qi);
49 String comp = String.valueOf((char) c) + String.valueOf((char) d);
50 if (comp.equals("==")) {
54 else if (comp.equals("<=")) {
58 else if (comp.equals(">=")) {
62 else if (comp.equals("<>")) {
68 } else if (strchr("\"", c)) { //no single-quotes
73 boolean escaped = false;
74 buf.setLength(0); //reset buffer
76 if (!escaped && qs.charAt(qi) == mark) //terminator
78 if (escaped && strchr("*?^\\", qs.charAt(qi))) //no escaping for d-quote
80 if (!escaped && qs.charAt(qi) == '\\') { //escape-char
85 escaped = false; //reset escape
86 buf.append(qs.charAt(qi));
90 lval = val.toLowerCase();
94 what = TT_EOF; //notify error
98 buf.setLength(0); //reset buffer
100 && !strchr("()/<>= \t\r\n", qs.charAt(qi))) {
101 if (qs.charAt(qi) != '\0')
102 buf.append(qs.charAt(qi));
105 val = buf.toString();
106 lval = val.toLowerCase();
107 if (lval.equals("or")) what = TT_OR;
108 else if (lval.equals("and")) what = TT_AND;
109 else if (lval.equals("not")) what = TT_NOT;
110 else if (lval.equals("prox")) what = TT_PROX;
111 else if (lval.equals("sortby")) what = TT_SORTBY;
115 private boolean strchr(String s, char ch) {
116 return s.indexOf(ch) >= 0;
120 public String value() {
130 public String render() {
131 return render(what, true);
135 public String render(int token, boolean quoteChars) {
140 return "word: '" + val + "'";
142 return "string: \"" + val + "\"";
162 //a single character, such as '(' or '/' or relation
163 String res = String.valueOf((char) token);
165 res = "'" + res + "'";
175 public static void main(String[] args) throws Exception {
176 if (args.length > 1) {
177 System.err.println("Usage: CQLLexer [<CQL-query>]");
178 System.err.println("If unspecified, query is read from stdin");
183 if (args.length == 1) {
186 byte[] bytes = new byte[10000];
188 // Read in the whole of standard input in one go
189 int nbytes = System.in.read(bytes);
190 } catch (java.io.IOException ex) {
191 System.err.println("Can't read query: " + ex.getMessage());
194 cql = new String(bytes);
197 CQLTokenizer lexer = new CQLLexer(cql, true);
198 while ((lexer.what()) != TT_EOF) {
200 System.out.println(lexer.render());