2 * Copyright (c) 1995-2014, Index Datassss
4 * See the file LICENSE for details.
6 package org.z3950.zing.cql;
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", 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 buf.append(qs.charAt(qi));
104 val = buf.toString();
105 lval = val.toLowerCase();
106 if (lval.equals("or")) what = TT_OR;
107 else if (lval.equals("and")) what = TT_AND;
108 else if (lval.equals("not")) what = TT_NOT;
109 else if (lval.equals("prox")) what = TT_PROX;
110 else if (lval.equals("sortby")) what = TT_SORTBY;
114 private boolean strchr(String s, char ch) {
115 return s.indexOf(ch) >= 0;
119 public String value() {
129 public String render() {
130 return render(what, true);
134 public String render(int token, boolean quoteChars) {
139 return "word: '" + val + "'";
141 return "string: \"" + val + "\"";
161 //a single character, such as '(' or '/' or relation
162 String res = String.valueOf((char) token);
164 res = "'" + res + "'";
174 public static void main(String[] args) throws Exception {
175 if (args.length > 1) {
176 System.err.println("Usage: CQLLexer [<CQL-query>]");
177 System.err.println("If unspecified, query is read from stdin");
182 if (args.length == 1) {
185 byte[] bytes = new byte[10000];
187 // Read in the whole of standard input in one go
188 int nbytes = System.in.read(bytes);
189 } catch (java.io.IOException ex) {
190 System.err.println("Can't read query: " + ex.getMessage());
193 cql = new String(bytes);
196 CQLTokenizer lexer = new CQLLexer(cql, true);
197 while ((lexer.what()) != TT_EOF) {
199 System.out.println(lexer.render());