1 package util
.queryparser
;
3 import java
.io
.UnsupportedEncodingException
;
4 import java
.net
.URLDecoder
;
6 import org
.codehaus
.jparsec
.OperatorTable
;
7 import org
.codehaus
.jparsec
.Parser
;
8 import org
.codehaus
.jparsec
.Parsers
;
9 import org
.codehaus
.jparsec
.Scanners
;
10 import org
.codehaus
.jparsec
.Terminals
;
11 import org
.codehaus
.jparsec
.functors
.Binary
;
12 import org
.codehaus
.jparsec
.functors
.Map
;
13 import org
.codehaus
.jparsec
.pattern
.Patterns
;
15 public class QueryParser
{
17 private enum BinaryOperator
implements Binary
<Filter
> {
19 public Filter
map(Filter a
, Filter b
) {
24 public Filter
map(Filter a
, Filter b
) {
30 public static final Parser
<String
> SINGLE_QUOTE_STRING
=
31 Scanners
.pattern(Patterns
.regex("((\\\\.)|[^\'\\\\])*") ,"quoted string").between(
32 Scanners
.isChar('\''),
35 public static final Map
<String
, String
> SINGLE_QUOTE_STRING_MAP
= new Map
<String
, String
>() {
36 public String
map(String text
) {
37 return text
.substring(1, text
.length()-1).replace("\\'", "'");
39 @Override public String
toString() {
40 return "SINGLE_QUOTE_STRING";
44 private static final Parser
<Filter
> TOKEN
= Terminals
.StringLiteral
.PARSER
.map(new org
.codehaus
.jparsec
.functors
.Map
<String
, Filter
>() {
45 public Token
map(String s
) {
50 private static final Terminals OPERATORS
= Terminals
.operators("+", ",", "(", ")");
52 private static final Parser
<Object
> TOKENIZER
=
53 Parsers
.or(SINGLE_QUOTE_STRING
.map(SINGLE_QUOTE_STRING_MAP
), OPERATORS
.tokenizer());
55 private static Parser
<?
> term(String
... names
) {
56 return OPERATORS
.token(names
);
59 private static <T
> Parser
<T
> op(String name
, T value
) {
60 return term(name
).retn(value
);
63 private static Parser
<Filter
> query(Parser
<Filter
> atom
) {
64 Parser
.Reference
<Filter
> ref
= Parser
.newReference();
65 Parser
<Filter
> unit
= ref
.lazy().between(term("("), term(")")).or(atom
);
66 Parser
<Filter
> parser
= new OperatorTable
<Filter
>()
67 .infixl(op(",", BinaryOperator
.OR
), 10)
68 .infixl(op("+", BinaryOperator
.AND
), 20)
74 private static Parser
<Void
> nodelim
= Parsers
.always();
76 private static final Parser
<Filter
> parser
= query(TOKEN
).from(TOKENIZER
, nodelim
);
78 public static Filter
parse(String source
) {
79 /*String decoded = "";
80 char[] chars = source.toCharArray();
81 for (int i = 0; i < chars.length; i++) {
82 if (chars[i] == '%') {
85 if (a >= 'A') a = a-'A';
87 if (b >= 'A') b = b-'A';
89 decoded += (char)(16*a+b);
93 source
= source
.replace("+", "%2B");
95 source
= URLDecoder
.decode(source
, "UTF-8");
96 } catch (UnsupportedEncodingException e
) {
99 System
.out
.println(source
);
100 return parser
.parse(source
);
103 public static void main(String args
[]) {
104 //System.out.println(SINGLE_QUOTE_STRING.parse("'foo'"));
105 System
.out
.println(QueryParser
.parse("'hi: bye'+'ho!:bo+ o\\\'n'"));