1
2 package org.apache.lucene.queryParser;
3
4 import java.io.IOException;
5 import java.io.StringReader;
6 import java.text.DateFormat;
7 import java.text.Collator;
8 import java.util.ArrayList;
9 import java.util.Calendar;
10 import java.util.Date;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Locale;
14 import java.util.Map;
15 import java.util.Vector;
16
17 import org.apache.lucene.analysis.Analyzer;
18 import org.apache.lucene.analysis.TokenStream;
19 import org.apache.lucene.document.DateField;
20 import org.apache.lucene.document.DateTools;
21 import org.apache.lucene.index.Term;
22 import org.apache.lucene.search.BooleanClause;
23 import org.apache.lucene.search.BooleanQuery;
24 import org.apache.lucene.search.ConstantScoreRangeQuery;
25 import org.apache.lucene.search.FuzzyQuery;
26 import org.apache.lucene.search.MatchAllDocsQuery;
27 import org.apache.lucene.search.MultiPhraseQuery;
28 import org.apache.lucene.search.PhraseQuery;
29 import org.apache.lucene.search.PrefixQuery;
30 import org.apache.lucene.search.Query;
31 import org.apache.lucene.search.RangeQuery;
32 import org.apache.lucene.search.TermQuery;
33 import org.apache.lucene.search.WildcardQuery;
34 import org.apache.lucene.util.Parameter;
35
36
99 public class QueryParser implements QueryParserConstants {
100
101 private static final int CONJ_NONE = 0;
102 private static final int CONJ_AND = 1;
103 private static final int CONJ_OR = 2;
104
105 private static final int MOD_NONE = 0;
106 private static final int MOD_NOT = 10;
107 private static final int MOD_REQ = 11;
108
109
112 public static final Operator AND_OPERATOR = Operator.AND;
113
114 public static final Operator OR_OPERATOR = Operator.OR;
115
116
117 private Operator operator = OR_OPERATOR;
118
119 boolean lowercaseExpandedTerms = true;
120 boolean useOldRangeQuery= false;
121 boolean allowLeadingWildcard = false;
122 boolean enablePositionIncrements = false;
123
124 Analyzer analyzer;
125 String field;
126 int phraseSlop = 0;
127 float fuzzyMinSim = FuzzyQuery.defaultMinSimilarity;
128 int fuzzyPrefixLength = FuzzyQuery.defaultPrefixLength;
129 Locale locale = Locale.getDefault();
130
131 DateTools.Resolution dateResolution = null;
133 Map fieldToDateResolution = null;
135
136 Collator rangeCollator = null;
139
140
143 static public final class Operator extends Parameter {
144 private Operator(String name) {
145 super(name);
146 }
147 static public final Operator OR = new Operator("OR");
148 static public final Operator AND = new Operator("AND");
149 }
150
151
152
156 public QueryParser(String f, Analyzer a) {
157 this(new FastCharStream(new StringReader("")));
158 analyzer = a;
159 field = f;
160 }
161
162
166 public Query parse(String query) throws ParseException {
167 ReInit(new FastCharStream(new StringReader(query)));
168 try {
169 Query res = TopLevelQuery(field);
171 return res!=null ? res : newBooleanQuery(false);
172 }
173 catch (ParseException tme) {
174 throw new ParseException("Cannot parse '" +query+ "': " + tme.getMessage());
176 }
177 catch (TokenMgrError tme) {
178 throw new ParseException("Cannot parse '" +query+ "': " + tme.getMessage());
179 }
180 catch (BooleanQuery.TooManyClauses tmc) {
181 throw new ParseException("Cannot parse '" +query+ "': too many boolean clauses");
182 }
183 }
184
185
188 public Analyzer getAnalyzer() {
189 return analyzer;
190 }
191
192
195 public String getField() {
196 return field;
197 }
198
199
202 public float getFuzzyMinSim() {
203 return fuzzyMinSim;
204 }
205
206
210 public void setFuzzyMinSim(float fuzzyMinSim) {
211 this.fuzzyMinSim = fuzzyMinSim;
212 }
213
214
218 public int getFuzzyPrefixLength() {
219 return fuzzyPrefixLength;
220 }
221
222
226 public void setFuzzyPrefixLength(int fuzzyPrefixLength) {
227 this.fuzzyPrefixLength = fuzzyPrefixLength;
228 }
229
230
234 public void setPhraseSlop(int phraseSlop) {
235 this.phraseSlop = phraseSlop;
236 }
237
238
241 public int getPhraseSlop() {
242 return phraseSlop;
243 }
244
245
246
256 public void setAllowLeadingWildcard(boolean allowLeadingWildcard) {
257 this.allowLeadingWildcard = allowLeadingWildcard;
258 }
259
260
263 public boolean getAllowLeadingWildcard() {
264 return allowLeadingWildcard;
265 }
266
267
277 public void setEnablePositionIncrements(boolean enable) {
278 this.enablePositionIncrements = enable;
279 }
280
281
284 public boolean getEnablePositionIncrements() {
285 return enablePositionIncrements;
286 }
287
288
296 public void setDefaultOperator(Operator op) {
297 this.operator = op;
298 }
299
300
301
305 public Operator getDefaultOperator() {
306 return operator;
307 }
308
309
310
314 public void setLowercaseExpandedTerms(boolean lowercaseExpandedTerms) {
315 this.lowercaseExpandedTerms = lowercaseExpandedTerms;
316 }
317
318
319
322 public boolean getLowercaseExpandedTerms() {
323 return lowercaseExpandedTerms;
324 }
325
326
335 public void setUseOldRangeQuery(boolean useOldRangeQuery) {
336 this.useOldRangeQuery = useOldRangeQuery;
337 }
338
339
340
343 public boolean getUseOldRangeQuery() {
344 return useOldRangeQuery;
345 }
346
347
350 public void setLocale(Locale locale) {
351 this.locale = locale;
352 }
353
354
357 public Locale getLocale() {
358 return locale;
359 }
360
361
368 public void setDateResolution(DateTools.Resolution dateResolution) {
369 this.dateResolution = dateResolution;
370 }
371
372
378 public void setDateResolution(String fieldName, DateTools.Resolution dateResolution) {
379 if (fieldName == null) {
380 throw new IllegalArgumentException("Field cannot be null.");
381 }
382
383 if (fieldToDateResolution == null) {
384 fieldToDateResolution = new HashMap();
386 }
387
388 fieldToDateResolution.put(fieldName, dateResolution);
389 }
390
391
397 public DateTools.Resolution getDateResolution(String fieldName) {
398 if (fieldName == null) {
399 throw new IllegalArgumentException("Field cannot be null.");
400 }
401
402 if (fieldToDateResolution == null) {
403 return this.dateResolution;
405 }
406
407 DateTools.Resolution resolution = (DateTools.Resolution) fieldToDateResolution.get(fieldName);
408 if (resolution == null) {
409 resolution = this.dateResolution;
411 }
412
413 return resolution;
414 }
415
416
431 public void setRangeCollator(Collator rc) {
432 rangeCollator = rc;
433 }
434
435
441 public Collator getRangeCollator() {
442 return rangeCollator;
443 }
444
445
448 protected void addClause(Vector clauses, int conj, int mods, Query q) {
449 addClause((List) clauses, conj, mods, q);
450 }
451
452 protected void addClause(List clauses, int conj, int mods, Query q) {
453 boolean required, prohibited;
454
455 if (clauses.size() > 0 && conj == CONJ_AND) {
458 BooleanClause c = (BooleanClause) clauses.get(clauses.size()-1);
459 if (!c.isProhibited())
460 c.setOccur(BooleanClause.Occur.MUST);
461 }
462
463 if (clauses.size() > 0 && operator == AND_OPERATOR && conj == CONJ_OR) {
464 BooleanClause c = (BooleanClause) clauses.get(clauses.size()-1);
469 if (!c.isProhibited())
470 c.setOccur(BooleanClause.Occur.SHOULD);
471 }
472
473 if (q == null)
476 return;
477
478 if (operator == OR_OPERATOR) {
479 prohibited = (mods == MOD_NOT);
482 required = (mods == MOD_REQ);
483 if (conj == CONJ_AND && !prohibited) {
484 required = true;
485 }
486 } else {
487 prohibited = (mods == MOD_NOT);
490 required = (!prohibited && conj != CONJ_OR);
491 }
492 if (required && !prohibited)
493 clauses.add(newBooleanClause(q, BooleanClause.Occur.MUST));
494 else if (!required && !prohibited)
495 clauses.add(newBooleanClause(q, BooleanClause.Occur.SHOULD));
496 else if (!required && prohibited)
497 clauses.add(newBooleanClause(q, BooleanClause.Occur.MUST_NOT));
498 else
499 throw new RuntimeException("Clause cannot be both required and prohibited");
500 }
501
502
503
506 protected Query getFieldQuery(String field, String queryText) throws ParseException {
507
510 TokenStream source = analyzer.tokenStream(field, new StringReader(queryText));
511 List list = new ArrayList();
512 final org.apache.lucene.analysis.Token reusableToken = new org.apache.lucene.analysis.Token();
513 org.apache.lucene.analysis.Token nextToken;
514 int positionCount = 0;
515 boolean severalTokensAtSamePosition = false;
516
517 while (true) {
518 try {
519 nextToken = source.next(reusableToken);
520 }
521 catch (IOException e) {
522 nextToken = null;
523 }
524 if (nextToken == null)
525 break;
526 list.add(nextToken.clone());
527 if (nextToken.getPositionIncrement() != 0)
528 positionCount += nextToken.getPositionIncrement();
529 else
530 severalTokensAtSamePosition = true;
531 }
532 try {
533 source.close();
534 }
535 catch (IOException e) {
536 }
538
539 if (list.size() == 0)
540 return null;
541 else if (list.size() == 1) {
542 nextToken = (org.apache.lucene.analysis.Token) list.get(0);
543 return newTermQuery(new Term(field, nextToken.term()));
544 } else {
545 if (severalTokensAtSamePosition) {
546 if (positionCount == 1) {
547 BooleanQuery q = newBooleanQuery(true);
549 for (int i = 0; i < list.size(); i++) {
550 nextToken = (org.apache.lucene.analysis.Token) list.get(i);
551 Query currentQuery = newTermQuery(
552 new Term(field, nextToken.term()));
553 q.add(currentQuery, BooleanClause.Occur.SHOULD);
554 }
555 return q;
556 }
557 else {
558 MultiPhraseQuery mpq = newMultiPhraseQuery();
560 mpq.setSlop(phraseSlop);
561 List multiTerms = new ArrayList();
562 int position = -1;
563 for (int i = 0; i < list.size(); i++) {
564 nextToken = (org.apache.lucene.analysis.Token) list.get(i);
565 if (nextToken.getPositionIncrement() > 0 && multiTerms.size() > 0) {
566 if (enablePositionIncrements) {
567 mpq.add((Term[])multiTerms.toArray(new Term[0]),position);
568 } else {
569 mpq.add((Term[])multiTerms.toArray(new Term[0]));
570 }
571 multiTerms.clear();
572 }
573 position += nextToken.getPositionIncrement();
574 multiTerms.add(new Term(field, nextToken.term()));
575 }
576 if (enablePositionIncrements) {
577 mpq.add((Term[])multiTerms.toArray(new Term[0]),position);
578 } else {
579 mpq.add((Term[])multiTerms.toArray(new Term[0]));
580 }
581 return mpq;
582 }
583 }
584 else {
585 PhraseQuery pq = newPhraseQuery();
586 pq.setSlop(phraseSlop);
587 int position = -1;
588 for (int i = 0; i < list.size(); i++) {
589 nextToken = (org.apache.lucene.analysis.Token) list.get(i);
590 if (enablePositionIncrements) {
591 position += nextToken.getPositionIncrement();
592 pq.add(new Term(field, nextToken.term()),position);
593 } else {
594 pq.add(new Term(field, nextToken.term()));
595 }
596 }
597 return pq;
598 }
599 }
600 }
601
602
603
610 protected Query getFieldQuery(String field, String queryText, int slop)
611 throws ParseException {
612 Query query = getFieldQuery(field, queryText);
613
614 if (query instanceof PhraseQuery) {
615 ((PhraseQuery) query).setSlop(slop);
616 }
617 if (query instanceof MultiPhraseQuery) {
618 ((MultiPhraseQuery) query).setSlop(slop);
619 }
620
621 return query;
622 }
623
624
625
628 protected Query getRangeQuery(String field,
629 String part1,
630 String part2,
631 boolean inclusive) throws ParseException
632 {
633 if (lowercaseExpandedTerms) {
634 part1 = part1.toLowerCase();
635 part2 = part2.toLowerCase();
636 }
637 try {
638 DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
639 df.setLenient(true);
640 Date d1 = df.parse(part1);
641 Date d2 = df.parse(part2);
642 if (inclusive) {
643 Calendar cal = Calendar.getInstance(locale);
647 cal.setTime(d2);
648 cal.set(Calendar.HOUR_OF_DAY, 23);
649 cal.set(Calendar.MINUTE, 59);
650 cal.set(Calendar.SECOND, 59);
651 cal.set(Calendar.MILLISECOND, 999);
652 d2 = cal.getTime();
653 }
654 DateTools.Resolution resolution = getDateResolution(field);
655 if (resolution == null) {
656 part1 = DateField.dateToString(d1);
660 part2 = DateField.dateToString(d2);
661 } else {
662 part1 = DateTools.dateToString(d1, resolution);
663 part2 = DateTools.dateToString(d2, resolution);
664 }
665 }
666 catch (Exception e) { }
667
668 return newRangeQuery(field, part1, part2, inclusive);
669 }
670
671
676 protected BooleanQuery newBooleanQuery(boolean disableCoord) {
677 return new BooleanQuery(disableCoord);
678 }
679
680
686 protected BooleanClause newBooleanClause(Query q, BooleanClause.Occur occur) {
687 return new BooleanClause(q, occur);
688 }
689
690
695 protected Query newTermQuery(Term term){
696 return new TermQuery(term);
697 }
698
699
703 protected PhraseQuery newPhraseQuery(){
704 return new PhraseQuery();
705 }
706
707
711 protected MultiPhraseQuery newMultiPhraseQuery(){
712 return new MultiPhraseQuery();
713 }
714
715
720 protected Query newPrefixQuery(Term prefix){
721 return new PrefixQuery(prefix);
722 }
723
724
731 protected Query newFuzzyQuery(Term term, float minimumSimilarity, int prefixLength) {
732 return new FuzzyQuery(term,minimumSimilarity,prefixLength);
733 }
734
735
743 protected Query newRangeQuery(String field, String part1, String part2, boolean inclusive) {
744 if(useOldRangeQuery)
745 {
746 return new RangeQuery(new Term(field, part1),
747 new Term(field, part2),
748 inclusive, rangeCollator);
749 }
750 else
751 {
752 return new ConstantScoreRangeQuery
753 (field, part1, part2, inclusive, inclusive, rangeCollator);
754 }
755 }
756
757
761 protected Query newMatchAllDocsQuery() {
762 return new MatchAllDocsQuery();
763 }
764
765
770 protected Query newWildcardQuery(Term t) {
771 return new WildcardQuery(t);
772 }
773
774
788 protected Query getBooleanQuery(Vector clauses) throws ParseException {
789 return getBooleanQuery((List) clauses, false);
790 }
791
792
805 protected Query getBooleanQuery(List clauses) throws ParseException {
806 return getBooleanQuery(clauses, false);
807 }
808
809
824 protected Query getBooleanQuery(Vector clauses, boolean disableCoord)
825 throws ParseException
826 {
827 return getBooleanQuery((List) clauses, disableCoord);
828 }
829
830
844 protected Query getBooleanQuery(List clauses, boolean disableCoord)
845 throws ParseException
846 {
847 if (clauses.size()==0) {
848 return null; }
850 BooleanQuery query = newBooleanQuery(disableCoord);
851 for (int i = 0; i < clauses.size(); i++) {
852 query.add((BooleanClause)clauses.get(i));
853 }
854 return query;
855 }
856
857
878 protected Query getWildcardQuery(String field, String termStr) throws ParseException
879 {
880 if ("*".equals(field)) {
881 if ("*".equals(termStr)) return newMatchAllDocsQuery();
882 }
883 if (!allowLeadingWildcard && (termStr.startsWith("*") || termStr.startsWith("?")))
884 throw new ParseException("'*' or '?' not allowed as first character in WildcardQuery");
885 if (lowercaseExpandedTerms) {
886 termStr = termStr.toLowerCase();
887 }
888 Term t = new Term(field, termStr);
889 return newWildcardQuery(t);
890 }
891
892
915 protected Query getPrefixQuery(String field, String termStr) throws ParseException
916 {
917 if (!allowLeadingWildcard && termStr.startsWith("*"))
918 throw new ParseException("'*' not allowed as first character in PrefixQuery");
919 if (lowercaseExpandedTerms) {
920 termStr = termStr.toLowerCase();
921 }
922 Term t = new Term(field, termStr);
923 return newPrefixQuery(t);
924 }
925
926
937 protected Query getFuzzyQuery(String field, String termStr, float minSimilarity) throws ParseException
938 {
939 if (lowercaseExpandedTerms) {
940 termStr = termStr.toLowerCase();
941 }
942 Term t = new Term(field, termStr);
943 return newFuzzyQuery(t, minSimilarity, fuzzyPrefixLength);
944 }
945
946
954 private String discardEscapeChar(String input) throws ParseException {
955 char[] output = new char[input.length()];
957
958 int length = 0;
962
963 boolean lastCharWasEscapeChar = false;
966
967 int codePointMultiplier = 0;
970
971 int codePoint = 0;
973
974 for (int i = 0; i < input.length(); i++) {
975 char curChar = input.charAt(i);
976 if (codePointMultiplier > 0) {
977 codePoint += hexToInt(curChar) * codePointMultiplier;
978 codePointMultiplier >>>= 4;
979 if (codePointMultiplier == 0) {
980 output[length++] = (char)codePoint;
981 codePoint = 0;
982 }
983 } else if (lastCharWasEscapeChar) {
984 if (curChar == 'u') {
985 codePointMultiplier = 16 * 16 * 16;
987 } else {
988 output[length] = curChar;
990 length++;
991 }
992 lastCharWasEscapeChar = false;
993 } else {
994 if (curChar == '\\') {
995 lastCharWasEscapeChar = true;
996 } else {
997 output[length] = curChar;
998 length++;
999 }
1000 }
1001 }
1002
1003 if (codePointMultiplier > 0) {
1004 throw new ParseException("Truncated unicode escape sequence.");
1005 }
1006
1007 if (lastCharWasEscapeChar) {
1008 throw new ParseException("Term can not end with escape character.");
1009 }
1010
1011 return new String(output, 0, length);
1012 }
1013
1014
1015 private static final int hexToInt(char c) throws ParseException {
1016 if ('0' <= c && c <= '9') {
1017 return c - '0';
1018 } else if ('a' <= c && c <= 'f'){
1019 return c - 'a' + 10;
1020 } else if ('A' <= c && c <= 'F') {
1021 return c - 'A' + 10;
1022 } else {
1023 throw new ParseException("None-hex character in unicode escape sequence: " + c);
1024 }
1025 }
1026
1027
1031 public static String escape(String s) {
1032 StringBuffer sb = new StringBuffer();
1033 for (int i = 0; i < s.length(); i++) {
1034 char c = s.charAt(i);
1035 if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':'
1037 || c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~'
1038 || c == '*' || c == '?' || c == '|' || c == '&') {
1039 sb.append('\\');
1040 }
1041 sb.append(c);
1042 }
1043 return sb.toString();
1044 }
1045
1046
1051 public static void main(String[] args) throws Exception {
1052 if (args.length == 0) {
1053 System.out.println("Usage: java org.apache.lucene.queryParser.QueryParser <input>");
1054 System.exit(0);
1055 }
1056 QueryParser qp = new QueryParser("field",
1057 new org.apache.lucene.analysis.SimpleAnalyzer());
1058 Query q = qp.parse(args[0]);
1059 System.out.println(q.toString("field"));
1060 }
1061
1062 final public int Conjunction() throws ParseException {
1065 int ret = CONJ_NONE;
1066 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1067 case AND:
1068 case OR:
1069 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1070 case AND:
1071 jj_consume_token(AND);
1072 ret = CONJ_AND;
1073 break;
1074 case OR:
1075 jj_consume_token(OR);
1076 ret = CONJ_OR;
1077 break;
1078 default:
1079 jj_la1[0] = jj_gen;
1080 jj_consume_token(-1);
1081 throw new ParseException();
1082 }
1083 break;
1084 default:
1085 jj_la1[1] = jj_gen;
1086 ;
1087 }
1088 {if (true) return ret;}
1089 throw new Error("Missing return statement in function");
1090 }
1091
1092 final public int Modifiers() throws ParseException {
1093 int ret = MOD_NONE;
1094 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1095 case NOT:
1096 case PLUS:
1097 case MINUS:
1098 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1099 case PLUS:
1100 jj_consume_token(PLUS);
1101 ret = MOD_REQ;
1102 break;
1103 case MINUS:
1104 jj_consume_token(MINUS);
1105 ret = MOD_NOT;
1106 break;
1107 case NOT:
1108 jj_consume_token(NOT);
1109 ret = MOD_NOT;
1110 break;
1111 default:
1112 jj_la1[2] = jj_gen;
1113 jj_consume_token(-1);
1114 throw new ParseException();
1115 }
1116 break;
1117 default:
1118 jj_la1[3] = jj_gen;
1119 ;
1120 }
1121 {if (true) return ret;}
1122 throw new Error("Missing return statement in function");
1123 }
1124
1125 final public Query TopLevelQuery(String field) throws ParseException {
1127 Query q;
1128 q = Query(field);
1129 jj_consume_token(0);
1130 {if (true) return q;}
1131 throw new Error("Missing return statement in function");
1132 }
1133
1134 final public Query Query(String field) throws ParseException {
1135 List clauses = new ArrayList();
1136 Query q, firstQuery=null;
1137 int conj, mods;
1138 mods = Modifiers();
1139 q = Clause(field);
1140 addClause(clauses, CONJ_NONE, mods, q);
1141 if (mods == MOD_NONE)
1142 firstQuery=q;
1143 label_1:
1144 while (true) {
1145 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1146 case AND:
1147 case OR:
1148 case NOT:
1149 case PLUS:
1150 case MINUS:
1151 case LPAREN:
1152 case STAR:
1153 case QUOTED:
1154 case TERM:
1155 case PREFIXTERM:
1156 case WILDTERM:
1157 case RANGEIN_START:
1158 case RANGEEX_START:
1159 case NUMBER:
1160 ;
1161 break;
1162 default:
1163 jj_la1[4] = jj_gen;
1164 break label_1;
1165 }
1166 conj = Conjunction();
1167 mods = Modifiers();
1168 q = Clause(field);
1169 addClause(clauses, conj, mods, q);
1170 }
1171 if (clauses.size() == 1 && firstQuery != null)
1172 {if (true) return firstQuery;}
1173 else {
1174 {if (true) return getBooleanQuery(clauses);}
1175 }
1176 throw new Error("Missing return statement in function");
1177 }
1178
1179 final public Query Clause(String field) throws ParseException {
1180 Query q;
1181 Token fieldToken=null, boost=null;
1182 if (jj_2_1(2)) {
1183 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1184 case TERM:
1185 fieldToken = jj_consume_token(TERM);
1186 jj_consume_token(COLON);
1187 field=discardEscapeChar(fieldToken.image);
1188 break;
1189 case STAR:
1190 jj_consume_token(STAR);
1191 jj_consume_token(COLON);
1192 field="*";
1193 break;
1194 default:
1195 jj_la1[5] = jj_gen;
1196 jj_consume_token(-1);
1197 throw new ParseException();
1198 }
1199 } else {
1200 ;
1201 }
1202 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1203 case STAR:
1204 case QUOTED:
1205 case TERM:
1206 case PREFIXTERM:
1207 case WILDTERM:
1208 case RANGEIN_START:
1209 case RANGEEX_START:
1210 case NUMBER:
1211 q = Term(field);
1212 break;
1213 case LPAREN:
1214 jj_consume_token(LPAREN);
1215 q = Query(field);
1216 jj_consume_token(RPAREN);
1217 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1218 case CARAT:
1219 jj_consume_token(CARAT);
1220 boost = jj_consume_token(NUMBER);
1221 break;
1222 default:
1223 jj_la1[6] = jj_gen;
1224 ;
1225 }
1226 break;
1227 default:
1228 jj_la1[7] = jj_gen;
1229 jj_consume_token(-1);
1230 throw new ParseException();
1231 }
1232 if (boost != null) {
1233 float f = (float)1.0;
1234 try {
1235 f = Float.valueOf(boost.image).floatValue();
1236 q.setBoost(f);
1237 } catch (Exception ignored) { }
1238 }
1239 {if (true) return q;}
1240 throw new Error("Missing return statement in function");
1241 }
1242
1243 final public Query Term(String field) throws ParseException {
1244 Token term, boost=null, fuzzySlop=null, goop1, goop2;
1245 boolean prefix = false;
1246 boolean wildcard = false;
1247 boolean fuzzy = false;
1248 boolean rangein = false;
1249 Query q;
1250 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1251 case STAR:
1252 case TERM:
1253 case PREFIXTERM:
1254 case WILDTERM:
1255 case NUMBER:
1256 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1257 case TERM:
1258 term = jj_consume_token(TERM);
1259 break;
1260 case STAR:
1261 term = jj_consume_token(STAR);
1262 wildcard=true;
1263 break;
1264 case PREFIXTERM:
1265 term = jj_consume_token(PREFIXTERM);
1266 prefix=true;
1267 break;
1268 case WILDTERM:
1269 term = jj_consume_token(WILDTERM);
1270 wildcard=true;
1271 break;
1272 case NUMBER:
1273 term = jj_consume_token(NUMBER);
1274 break;
1275 default:
1276 jj_la1[8] = jj_gen;
1277 jj_consume_token(-1);
1278 throw new ParseException();
1279 }
1280 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1281 case FUZZY_SLOP:
1282 fuzzySlop = jj_consume_token(FUZZY_SLOP);
1283 fuzzy=true;
1284 break;
1285 default:
1286 jj_la1[9] = jj_gen;
1287 ;
1288 }
1289 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1290 case CARAT:
1291 jj_consume_token(CARAT);
1292 boost = jj_consume_token(NUMBER);
1293 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1294 case FUZZY_SLOP:
1295 fuzzySlop = jj_consume_token(FUZZY_SLOP);
1296 fuzzy=true;
1297 break;
1298 default:
1299 jj_la1[10] = jj_gen;
1300 ;
1301 }
1302 break;
1303 default:
1304 jj_la1[11] = jj_gen;
1305 ;
1306 }
1307 String termImage=discardEscapeChar(term.image);
1308 if (wildcard) {
1309 q = getWildcardQuery(field, termImage);
1310 } else if (prefix) {
1311 q = getPrefixQuery(field,
1312 discardEscapeChar(term.image.substring
1313 (0, term.image.length()-1)));
1314 } else if (fuzzy) {
1315 float fms = fuzzyMinSim;
1316 try {
1317 fms = Float.valueOf(fuzzySlop.image.substring(1)).floatValue();
1318 } catch (Exception ignored) { }
1319 if(fms < 0.0f || fms > 1.0f){
1320 {if (true) throw new ParseException("Minimum similarity for a FuzzyQuery has to be between 0.0f and 1.0f !");}
1321 }
1322 q = getFuzzyQuery(field, termImage,fms);
1323 } else {
1324 q = getFieldQuery(field, termImage);
1325 }
1326 break;
1327 case RANGEIN_START:
1328 jj_consume_token(RANGEIN_START);
1329 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1330 case RANGEIN_GOOP:
1331 goop1 = jj_consume_token(RANGEIN_GOOP);
1332 break;
1333 case RANGEIN_QUOTED:
1334 goop1 = jj_consume_token(RANGEIN_QUOTED);
1335 break;
1336 default:
1337 jj_la1[12] = jj_gen;
1338 jj_consume_token(-1);
1339 throw new ParseException();
1340 }
1341 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1342 case RANGEIN_TO:
1343 jj_consume_token(RANGEIN_TO);
1344 break;
1345 default:
1346 jj_la1[13] = jj_gen;
1347 ;
1348 }
1349 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1350 case RANGEIN_GOOP:
1351 goop2 = jj_consume_token(RANGEIN_GOOP);
1352 break;
1353 case RANGEIN_QUOTED:
1354 goop2 = jj_consume_token(RANGEIN_QUOTED);
1355 break;
1356 default:
1357 jj_la1[14] = jj_gen;
1358 jj_consume_token(-1);
1359 throw new ParseException();
1360 }
1361 jj_consume_token(RANGEIN_END);
1362 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1363 case CARAT:
1364 jj_consume_token(CARAT);
1365 boost = jj_consume_token(NUMBER);
1366 break;
1367 default:
1368 jj_la1[15] = jj_gen;
1369 ;
1370 }
1371 if (goop1.kind == RANGEIN_QUOTED) {
1372 goop1.image = goop1.image.substring(1, goop1.image.length()-1);
1373 }
1374 if (goop2.kind == RANGEIN_QUOTED) {
1375 goop2.image = goop2.image.substring(1, goop2.image.length()-1);
1376 }
1377 q = getRangeQuery(field, discardEscapeChar(goop1.image), discardEscapeChar(goop2.image), true);
1378 break;
1379 case RANGEEX_START:
1380 jj_consume_token(RANGEEX_START);
1381 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1382 case RANGEEX_GOOP:
1383 goop1 = jj_consume_token(RANGEEX_GOOP);
1384 break;
1385 case RANGEEX_QUOTED:
1386 goop1 = jj_consume_token(RANGEEX_QUOTED);
1387 break;
1388 default:
1389 jj_la1[16] = jj_gen;
1390 jj_consume_token(-1);
1391 throw new ParseException();
1392 }
1393 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1394 case RANGEEX_TO:
1395 jj_consume_token(RANGEEX_TO);
1396 break;
1397 default:
1398 jj_la1[17] = jj_gen;
1399 ;
1400 }
1401 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1402 case RANGEEX_GOOP:
1403 goop2 = jj_consume_token(RANGEEX_GOOP);
1404 break;
1405 case RANGEEX_QUOTED:
1406 goop2 = jj_consume_token(RANGEEX_QUOTED);
1407 break;
1408 default:
1409 jj_la1[18] = jj_gen;
1410 jj_consume_token(-1);
1411 throw new ParseException();
1412 }
1413 jj_consume_token(RANGEEX_END);
1414 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1415 case CARAT:
1416 jj_consume_token(CARAT);
1417 boost = jj_consume_token(NUMBER);
1418 break;
1419 default:
1420 jj_la1[19] = jj_gen;
1421 ;
1422 }
1423 if (goop1.kind == RANGEEX_QUOTED) {
1424 goop1.image = goop1.image.substring(1, goop1.image.length()-1);
1425 }
1426 if (goop2.kind == RANGEEX_QUOTED) {
1427 goop2.image = goop2.image.substring(1, goop2.image.length()-1);
1428 }
1429
1430 q = getRangeQuery(field, discardEscapeChar(goop1.image), discardEscapeChar(goop2.image), false);
1431 break;
1432 case QUOTED:
1433 term = jj_consume_token(QUOTED);
1434 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1435 case FUZZY_SLOP:
1436 fuzzySlop = jj_consume_token(FUZZY_SLOP);
1437 break;
1438 default:
1439 jj_la1[20] = jj_gen;
1440 ;
1441 }
1442 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1443 case CARAT:
1444 jj_consume_token(CARAT);
1445 boost = jj_consume_token(NUMBER);
1446 break;
1447 default:
1448 jj_la1[21] = jj_gen;
1449 ;
1450 }
1451 int s = phraseSlop;
1452
1453 if (fuzzySlop != null) {
1454 try {
1455 s = Float.valueOf(fuzzySlop.image.substring(1)).intValue();
1456 }
1457 catch (Exception ignored) { }
1458 }
1459 q = getFieldQuery(field, discardEscapeChar(term.image.substring(1, term.image.length()-1)), s);
1460 break;
1461 default:
1462 jj_la1[22] = jj_gen;
1463 jj_consume_token(-1);
1464 throw new ParseException();
1465 }
1466 if (boost != null) {
1467 float f = (float) 1.0;
1468 try {
1469 f = Float.valueOf(boost.image).floatValue();
1470 }
1471 catch (Exception ignored) {
1472
1475 }
1476
1477 if (q != null) {
1479 q.setBoost(f);
1480 }
1481 }
1482 {if (true) return q;}
1483 throw new Error("Missing return statement in function");
1484 }
1485
1486 private boolean jj_2_1(int xla) {
1487 jj_la = xla; jj_lastpos = jj_scanpos = token;
1488 try { return !jj_3_1(); }
1489 catch(LookaheadSuccess ls) { return true; }
1490 finally { jj_save(0, xla); }
1491 }
1492
1493 private boolean jj_3R_3() {
1494 if (jj_scan_token(STAR)) return true;
1495 if (jj_scan_token(COLON)) return true;
1496 return false;
1497 }
1498
1499 private boolean jj_3R_2() {
1500 if (jj_scan_token(TERM)) return true;
1501 if (jj_scan_token(COLON)) return true;
1502 return false;
1503 }
1504
1505 private boolean jj_3_1() {
1506 Token xsp;
1507 xsp = jj_scanpos;
1508 if (jj_3R_2()) {
1509 jj_scanpos = xsp;
1510 if (jj_3R_3()) return true;
1511 }
1512 return false;
1513 }
1514
1515
1516 public QueryParserTokenManager token_source;
1517
1518 public Token token;
1519
1520 public Token jj_nt;
1521 private int jj_ntk;
1522 private Token jj_scanpos, jj_lastpos;
1523 private int jj_la;
1524 private int jj_gen;
1525 final private int[] jj_la1 = new int[23];
1526 static private int[] jj_la1_0;
1527 static private int[] jj_la1_1;
1528 static {
1529 jj_la1_init_0();
1530 jj_la1_init_1();
1531 }
1532 private static void jj_la1_init_0() {
1533 jj_la1_0 = new int[] {0x300,0x300,0x1c00,0x1c00,0x3ed3f00,0x90000,0x20000,0x3ed2000,0x2690000,0x100000,0x100000,0x20000,0x30000000,0x4000000,0x30000000,0x20000,0x0,0x40000000,0x0,0x20000,0x100000,0x20000,0x3ed0000,};
1534 }
1535 private static void jj_la1_init_1() {
1536 jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x3,0x0,0x0,0x0,0x0,};
1537 }
1538 final private JJCalls[] jj_2_rtns = new JJCalls[1];
1539 private boolean jj_rescan = false;
1540 private int jj_gc = 0;
1541
1542
1543 public QueryParser(CharStream stream) {
1544 token_source = new QueryParserTokenManager(stream);
1545 token = new Token();
1546 jj_ntk = -1;
1547 jj_gen = 0;
1548 for (int i = 0; i < 23; i++) jj_la1[i] = -1;
1549 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1550 }
1551
1552
1553 public void ReInit(CharStream stream) {
1554 token_source.ReInit(stream);
1555 token = new Token();
1556 jj_ntk = -1;
1557 jj_gen = 0;
1558 for (int i = 0; i < 23; i++) jj_la1[i] = -1;
1559 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1560 }
1561
1562
1563 public QueryParser(QueryParserTokenManager tm) {
1564 token_source = tm;
1565 token = new Token();
1566 jj_ntk = -1;
1567 jj_gen = 0;
1568 for (int i = 0; i < 23; i++) jj_la1[i] = -1;
1569 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1570 }
1571
1572
1573 public void ReInit(QueryParserTokenManager tm) {
1574 token_source = tm;
1575 token = new Token();
1576 jj_ntk = -1;
1577 jj_gen = 0;
1578 for (int i = 0; i < 23; i++) jj_la1[i] = -1;
1579 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1580 }
1581
1582 private Token jj_consume_token(int kind) throws ParseException {
1583 Token oldToken;
1584 if ((oldToken = token).next != null) token = token.next;
1585 else token = token.next = token_source.getNextToken();
1586 jj_ntk = -1;
1587 if (token.kind == kind) {
1588 jj_gen++;
1589 if (++jj_gc > 100) {
1590 jj_gc = 0;
1591 for (int i = 0; i < jj_2_rtns.length; i++) {
1592 JJCalls c = jj_2_rtns[i];
1593 while (c != null) {
1594 if (c.gen < jj_gen) c.first = null;
1595 c = c.next;
1596 }
1597 }
1598 }
1599 return token;
1600 }
1601 token = oldToken;
1602 jj_kind = kind;
1603 throw generateParseException();
1604 }
1605
1606 static private final class LookaheadSuccess extends java.lang.Error { }
1607 final private LookaheadSuccess jj_ls = new LookaheadSuccess();
1608 private boolean jj_scan_token(int kind) {
1609 if (jj_scanpos == jj_lastpos) {
1610 jj_la--;
1611 if (jj_scanpos.next == null) {
1612 jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
1613 } else {
1614 jj_lastpos = jj_scanpos = jj_scanpos.next;
1615 }
1616 } else {
1617 jj_scanpos = jj_scanpos.next;
1618 }
1619 if (jj_rescan) {
1620 int i = 0; Token tok = token;
1621 while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
1622 if (tok != null) jj_add_error_token(kind, i);
1623 }
1624 if (jj_scanpos.kind != kind) return true;
1625 if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
1626 return false;
1627 }
1628
1629
1630
1631 final public Token getNextToken() {
1632 if (token.next != null) token = token.next;
1633 else token = token.next = token_source.getNextToken();
1634 jj_ntk = -1;
1635 jj_gen++;
1636 return token;
1637 }
1638
1639
1640 final public Token getToken(int index) {
1641 Token t = token;
1642 for (int i = 0; i < index; i++) {
1643 if (t.next != null) t = t.next;
1644 else t = t.next = token_source.getNextToken();
1645 }
1646 return t;
1647 }
1648
1649 private int jj_ntk() {
1650 if ((jj_nt=token.next) == null)
1651 return (jj_ntk = (token.next=token_source.getNextToken()).kind);
1652 else
1653 return (jj_ntk = jj_nt.kind);
1654 }
1655
1656 private java.util.List jj_expentries = new java.util.ArrayList();
1657 private int[] jj_expentry;
1658 private int jj_kind = -1;
1659 private int[] jj_lasttokens = new int[100];
1660 private int jj_endpos;
1661
1662 private void jj_add_error_token(int kind, int pos) {
1663 if (pos >= 100) return;
1664 if (pos == jj_endpos + 1) {
1665 jj_lasttokens[jj_endpos++] = kind;
1666 } else if (jj_endpos != 0) {
1667 jj_expentry = new int[jj_endpos];
1668 for (int i = 0; i < jj_endpos; i++) {
1669 jj_expentry[i] = jj_lasttokens[i];
1670 }
1671 jj_entries_loop: for (java.util.Iterator it = jj_expentries.iterator(); it.hasNext();) {
1672 int[] oldentry = (int[])(it.next());
1673 if (oldentry.length == jj_expentry.length) {
1674 for (int i = 0; i < jj_expentry.length; i++) {
1675 if (oldentry[i] != jj_expentry[i]) {
1676 continue jj_entries_loop;
1677 }
1678 }
1679 jj_expentries.add(jj_expentry);
1680 break jj_entries_loop;
1681 }
1682 }
1683 if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
1684 }
1685 }
1686
1687
1688 public ParseException generateParseException() {
1689 jj_expentries.clear();
1690 boolean[] la1tokens = new boolean[34];
1691 if (jj_kind >= 0) {
1692 la1tokens[jj_kind] = true;
1693 jj_kind = -1;
1694 }
1695 for (int i = 0; i < 23; i++) {
1696 if (jj_la1[i] == jj_gen) {
1697 for (int j = 0; j < 32; j++) {
1698 if ((jj_la1_0[i] & (1<<j)) != 0) {
1699 la1tokens[j] = true;
1700 }
1701 if ((jj_la1_1[i] & (1<<j)) != 0) {
1702 la1tokens[32+j] = true;
1703 }
1704 }
1705 }
1706 }
1707 for (int i = 0; i < 34; i++) {
1708 if (la1tokens[i]) {
1709 jj_expentry = new int[1];
1710 jj_expentry[0] = i;
1711 jj_expentries.add(jj_expentry);
1712 }
1713 }
1714 jj_endpos = 0;
1715 jj_rescan_token();
1716 jj_add_error_token(0, 0);
1717 int[][] exptokseq = new int[jj_expentries.size()][];
1718 for (int i = 0; i < jj_expentries.size(); i++) {
1719 exptokseq[i] = (int[])jj_expentries.get(i);
1720 }
1721 return new ParseException(token, exptokseq, tokenImage);
1722 }
1723
1724
1725 final public void enable_tracing() {
1726 }
1727
1728
1729 final public void disable_tracing() {
1730 }
1731
1732 private void jj_rescan_token() {
1733 jj_rescan = true;
1734 for (int i = 0; i < 1; i++) {
1735 try {
1736 JJCalls p = jj_2_rtns[i];
1737 do {
1738 if (p.gen > jj_gen) {
1739 jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
1740 switch (i) {
1741 case 0: jj_3_1(); break;
1742 }
1743 }
1744 p = p.next;
1745 } while (p != null);
1746 } catch(LookaheadSuccess ls) { }
1747 }
1748 jj_rescan = false;
1749 }
1750
1751 private void jj_save(int index, int xla) {
1752 JJCalls p = jj_2_rtns[index];
1753 while (p.gen > jj_gen) {
1754 if (p.next == null) { p = p.next = new JJCalls(); break; }
1755 p = p.next;
1756 }
1757 p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
1758 }
1759
1760 static final class JJCalls {
1761 int gen;
1762 Token first;
1763 int arg;
1764 JJCalls next;
1765 }
1766
1767}
1768