|
|
@@ -149,12 +149,12 @@ class _QueryParser(object): |
|
|
|
## TODO: balance tree |
|
|
|
## -------------------------------------------------------------------- |
|
|
|
|
|
|
|
def SCAN_FOR_MARKER(string, markers): |
|
|
|
def SCAN_FOR_MARKERS(string, markers): |
|
|
|
best_marker, best_index = None, maxsize |
|
|
|
for marker in markers: |
|
|
|
index = string.find(marker) |
|
|
|
if index > 0 and string[index - 1] == "\\" and (index == 1 or string[index - 2] != "\\"): |
|
|
|
_, new_index = SCAN_FOR_MARKER(string[index + 1:], marker) |
|
|
|
_, new_index = SCAN_FOR_MARKERS(string[index + 1:], marker) |
|
|
|
index += new_index + 1 |
|
|
|
if index >= 0 and index < best_index: |
|
|
|
best_marker, best_index = marker, index |
|
|
@@ -164,35 +164,43 @@ class _QueryParser(object): |
|
|
|
string = string.lstrip() |
|
|
|
if not string: |
|
|
|
return [] |
|
|
|
marker, index = SCAN_FOR_MARKER(string, " \"'()") |
|
|
|
marker, index = SCAN_FOR_MARKERS(string, " \"'()") |
|
|
|
|
|
|
|
if not marker: |
|
|
|
return [string] |
|
|
|
|
|
|
|
before = [string[:index]] if index > 0 else [] |
|
|
|
nest = [string[:index]] if index > 0 else [] |
|
|
|
after = string[index + 1:] |
|
|
|
|
|
|
|
if marker == " ": |
|
|
|
return before + SPLIT_QUERY_STRING(after, parens) |
|
|
|
nest += SPLIT_QUERY_STRING(after, parens) |
|
|
|
|
|
|
|
elif marker in ('"', "'"): |
|
|
|
close_marker, close_index = SCAN_FOR_MARKER(after, marker) |
|
|
|
if not close_marker: |
|
|
|
return before + [after] |
|
|
|
quoted, after = after[:close_index], after[close_index + 1:] |
|
|
|
return before + [quoted] + SPLIT_QUERY_STRING(after, parens) |
|
|
|
close_marker, close_index = SCAN_FOR_MARKERS(after, marker) |
|
|
|
if close_marker: |
|
|
|
if close_index > 0: |
|
|
|
nest.append(after[:close_index]) |
|
|
|
after = after[close_index + 1:] |
|
|
|
nest += SPLIT_QUERY_STRING(after, parens) |
|
|
|
elif after: |
|
|
|
nest.append(after) |
|
|
|
|
|
|
|
elif marker == "(": |
|
|
|
inner = SPLIT_QUERY_STRING(after, True) |
|
|
|
inner, after = SPLIT_QUERY_STRING(after, True), [] |
|
|
|
if inner and isinstance(inner[-1], tuple): |
|
|
|
after, inner = inner.pop()[0], [inner] if inner else [] |
|
|
|
return before + inner + SPLIT_QUERY_STRING(after, parens) |
|
|
|
return before + [inner] |
|
|
|
after = SPLIT_QUERY_STRING(inner.pop()[0], parens) |
|
|
|
if inner: |
|
|
|
nest.append(inner) |
|
|
|
if after: |
|
|
|
nest += after |
|
|
|
|
|
|
|
elif marker == ")": |
|
|
|
if parens: |
|
|
|
return before + [(after,)] |
|
|
|
return before + SPLIT_QUERY_STRING(after) |
|
|
|
nest.append((after,)) |
|
|
|
else: |
|
|
|
nest += SPLIT_QUERY_STRING(after) |
|
|
|
|
|
|
|
return nest |
|
|
|
|
|
|
|
nest = SPLIT_QUERY_STRING(query.rstrip()) |
|
|
|
if not nest: |
|
|
|