1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
import os
import sys
class QueryGenerator(list):
def __init__(self, grammar, maps={}):
self.grammar = grammar
self.ignores = maps.get('replace_map', {})
self.max_repeat_n_map = maps.get('max_repeat_n_map', {})
self.max_list_n_map = maps.get('max_list_n_map', {})
self.default_list_n = maps.get('default_list_n', 1)
self.regex_map = maps.get('regex_map', {})
def generate_queries(self, ename='START'):
try:
ele = getattr(self.grammar, ename)
except AttributeError:
print('{} element not found in tree'.format(ename))
else:
for q in self._addq([ele]):
yield ' '.join(map(str, q)).strip()
def _addq(self, q):
for i, e in enumerate(q):
if isinstance(e, str) or isinstance(e, int) or \
isinstance(e, float):
continue
ename = getattr(e, 'name', None)
iv = self.ignores.get(ename)
if iv is not None:
q[i] = iv
break
self.append(ename)
func = getattr(self, '_on_'+e.__class__.__name__, lambda q, i: [])
for q1 in func(q, i):
for q2 in self._addq(q1):
yield q2
self.pop()
q[i] = e
break
else:
yield q
def _on_Keyword(self, q, i):
q[i] = q[i]._keyword
yield q
def _on_Regex(self, q, i):
regex_ename = self[-1]
if regex_ename in self.regex_map:
re_map = self.regex_map[regex_ename]
for ename in self[::-1]:
val = re_map.get(ename)
if val is not None:
q[i] = val
yield q
break
# debug code
# else:
# print('no value found for:')
# print(ename)
# print(q[:i+1])
# print(i, len(self), self)
# print(self.regex_map)
# else:
# print('unknown regex element')
# print(ename)
def _on_Token(self, q, i):
q[i] = q[i]._token
yield q
def _on_Tokens(self, q, i):
for e1 in q[i]._tokens:
q[i] = e1
yield q
def _on_Sequence(self, q, i):
q = q[:i]+q[i]._elements+q[i+1:]
yield q
def _on_List(self, q, i):
if q[i]._min == 0:
q0 = q[:i]+q[i+1:]
yield q0
if q[i]._max == 1:
q0 = q[:i]+list(q[i]._elements)[:1]+q[i+1:]
yield q0
else:
name = getattr(q[i], 'name', getattr(q[i]._element, 'name', None))
n = self.max_list_n_map.get(name, self.default_list_n)
if q[i]._max:
n = min(n, q[i]._max)
eles = list(q[i]._elements)[:1] + \
[q[i]._delimiter, list(q[i]._elements)[0]]*(n-1)
q0 = q[:i]+eles+q[i+1:]
yield q0
def _on_Repeat(self, q, i):
if q[i]._min == 0:
q0 = q[:i]+q[i+1:]
yield q0
if q[i]._max == 1:
q0 = q[:i]+list(q[i]._elements)[:1]+q[i+1:]
yield q0
else:
n = self.max_repeat_n_map.get(getattr(q[i], 'name', None), 1)
eles = list(q[i]._elements)[:1]*n
q0 = q[:i]+eles+q[i+1:]
yield q0
def _on_Optional(self, q, i):
q[i] = list(q[i]._elements)[0]
yield q
q[i] = ''
yield q
def _on_Choice(self, q, i):
for e1 in q[i]._elements:
q[i] = e1
yield q
def _on_Rule(self, q, i):
for e1 in q[i]._element._elements:
if e1.__class__.__name__ == 'Sequence' and sum(
e2.__class__.__name__ == 'This' for e2 in e1._elements):
continue
q[i] = e1
yield q
|