6 def __init__(self, col_types, col_names, query):
17 self.
valid_operators[
'!']={
'type':
'comparison',
'precedence':4,
'extension':
'!='}
18 self.
valid_operators[
'!=']={
'type':
'comparison',
'precedence':4,
'extension':
None}
19 self.
valid_operators[
'=']={
'type':
'comparison',
'precedence':4,
'extension':
'=='}
20 self.
valid_operators[
'==']={
'type':
'comparison',
'precedence':4,
'extension':
None}
21 self.
valid_operators[
'<=']={
'type':
'comparison',
'precedence':3,
'extension':
None}
22 self.
valid_operators[
'>=']={
'type':
'comparison',
'precedence':3,
'extension':
None}
23 self.
valid_operators[
'>']={
'type':
'comparison',
'precedence':3,
'extension':
'>='}
24 self.
valid_operators[
'<']={
'type':
'comparison',
'precedence':3,
'extension':
'<='}
31 self.
valid_operators[
'(']={
'type':
'left_bracket',
'precedence':float(
'NaN')}
32 self.
valid_operators[
'[']={
'type':
'left_bracket',
'precedence':float(
'NaN')}
33 self.
valid_operators[
'{']={
'type':
'left_bracket',
'precedence':float(
'NaN')}
34 self.
valid_operators[
')']={
'type':
'right_bracket',
'precedence':float(
'NaN')}
35 self.
valid_operators[
']']={
'type':
'right_bracket',
'precedence':float(
'NaN')}
36 self.
valid_operators[
'}']={
'type':
'right_bracket',
'precedence':float(
'NaN')}
48 self.tab_indices.append(self.
_GetIndex(exp))
49 self.exp_indices.append(i)
62 def _GetIndex(self, col):
64 raise ValueError(
'Table Selector has no column named "%s"' % col)
65 return self.col_names.index(col)
67 def _EvaluateAnd(self, lhs, rhs):
68 return lhs==
True and rhs==
True
70 def _EvaluateOr(self, lhs, rhs):
71 return lhs==
True or rhs==
True
73 def _EvaluateEqual(self, lhs, rhs):
76 def _EvaluateNonEqual(self, lhs, rhs):
79 def _EvaluateLower(self, lhs, rhs):
80 if lhs==
None or rhs==
None:
84 def _EvaluateGreater(self, lhs, rhs):
85 if lhs==
None or rhs==
None:
89 def _EvaluateLowerEqual(self, lhs, rhs):
90 if lhs==
None or rhs==
None:
94 def _EvaluateGreaterEqual(self, lhs, rhs):
95 if lhs==
None or rhs==
None:
99 def _EvaluateAdd(self, lhs, rhs):
100 if lhs==
None or rhs==
None:
104 def _EvaluateSubtract(self, lhs, rhs):
105 if lhs==
None or rhs==
None:
109 def _EvaluateMultiply(self, lhs, rhs):
110 if lhs==
None or rhs==
None:
114 def _EvaluateDivide(self, lhs, rhs):
115 if lhs==
None or rhs==
None:
120 def _EvaluateOperator(self, op, lhs, rhs):
136 elif op==
'=' or op==
'==':
138 elif op==
'!=' or op==
'!':
150 raise ValueError(
'Unknown operator: '+op)
152 def _EvaluateRPN(self, RPNExp):
161 raise ValueError(
'Cannot evaluate operator on less than two operands!')
171 raise ValueError(
'Too many operands for given operators!')
174 def _ShuntingYard(self, split_expression):
181 operator_stack=list()
184 if len(split_expression)==0:
186 if len(operator_stack)==0:
188 if self.
valid_operators[operator_stack[-1]][
'type']
in [
'left_bracket',
'right_bracket']:
189 raise ValueError(
'Parenthesis mismatch!')
190 output_stack.append(operator_stack.pop())
193 exp=split_expression.pop(0)
197 operator_stack.append(exp)
203 if len(operator_stack)==0:
204 raise ValueError(
'Parenthesis mismatch!')
208 output_stack.append(operator_stack.pop())
213 while len(operator_stack)>0:
217 output_stack.append(operator_stack.pop())
220 operator_stack.append(exp)
222 output_stack.append(exp)
226 def _ParseSubExpression(self, subexpression):
228 valid_types={
'float':
'numeric',
'int':
'numeric',
'string':
'string',
'bool':
'bool'}
233 final_expression=list()
236 for item
in subexpression:
238 column_names.append(item)
241 unique_type=list(set(column_types))
242 if len(unique_type)>1:
243 raise ValueError(
'Try to compare columns '+
','.join(column_names)+
' which have inconsistent types!')
244 if len(unique_type)==0:
245 raise ValueError(
'Try to evaluate subexpression '+
' '.join(subexpression)+
' that contains no valid column name of current table!')
247 for item
in subexpression:
249 final_expression.append(item)
251 if item
in column_names:
252 final_expression.append(item)
254 if unique_type[0]==
'numeric':
255 if item
in [
'NaN',
'nan',
'None',
'none']:
256 final_expression.append(
None)
260 final_expression.append(float(item))
263 raise RuntimeError(
'Tried to cast '+item+
' into numeric type to compare with column(s) '+
','.join(column_names)+
', but failed!')
264 elif unique_type[0]==
'bool':
265 if item
in [
'None',
'none']:
266 final_expression.append(
None)
268 if item
in [
'true',
'True']:
269 final_expression.append(
True)
271 if item
in [
'false',
'False']:
272 final_expression.append(
False)
274 raise RuntimeError(
'Tried to cast '+item+
' into boolean type to compare with column(s) '+
','.join(column_names)+
', but failed!')
275 elif unique_type[0]==
'string':
276 final_expression.append(item)
278 return final_expression
281 def _ParseExpression(self, split_expression):
284 for i
in range(len(split_expression)-3):
287 raise ValueError(
'Cannot Evaluate '+
' '.join(split_expression[i:i+3])+
' since both operators have same precedence!')
292 temp_split_expression=list()
295 for i
in range(len(split_expression)):
299 if ',' in split_expression[i]:
301 if split_expression[max(0,i-1)] !=
'=' and split_expression[min(i+1,len(split_expression)-1)] !=
'=':
302 raise ValueError(
'Can evaluate \',\' operator only in combination with \"=\" in subexpression ',
' '.join(split_expression[max(0,i-1):min(i+1,len(split_expression))]))
304 single_operands=split_expression[i].split(
',')
306 if split_expression[max(0,i-1)]==
'=':
308 raise ValueError(
'Cannot evaluate subexpression '+
' '.join(split_expression[max(0,i-1):min(i+1,len(split_expression))])+
' starting with an \'=\'')
309 main_operand=split_expression[i-2]
310 temp_split_expression.pop()
311 temp_split_expression.pop()
315 if i+2>len(split_expression)-1:
316 raise ValueError(
'Cannot evaluate subexpression '+
' '.join(split_expression[max(0,i-1):min(i+1,len(split_expression))])+
' ending with an \'=\'')
317 main_operand=split_expression[i+2]
320 temp_expression=list([
'('])
321 temp_expression+=
' or '.join([
'%s = %s'% (a,b)
for (a,b)
in zip(len(single_operands)*[main_operand],single_operands)]).split()
322 temp_expression.append(
')')
323 temp_split_expression+=temp_expression
326 temp_split_expression.append(split_expression[i])
328 split_expression=temp_split_expression
333 temp_split_expression=list()
336 for i
in range(len(split_expression)):
340 if ':' in split_expression[i]:
341 if split_expression[max(0,i-1)] !=
'=' and split_expression[min(i+1,len(split_expression)-1)] !=
'=':
342 raise ValueError(
'Can evaluate subexpression '+
' '.join(split_expression[max(0,i-1):min(i+1,len(split_expression))])+
' \':\' sign is only allowed in combination with \'=\'')
343 if len(split_expression[i].split(
':')) != 2:
344 raise ValueError(
'Can operate \':\' operator only on 2 operands in subexpression '+
' '.join(split_expression[max(0,i-1):min(i+1,len(split_expression))]))
346 lhs=split_expression[i].split(
':')[0]
347 rhs=split_expression[i].split(
':')[1]
349 template_expression=[
'(',
'',
'<=',
'',
'and',
'',
'<=',
'',
')']
351 if split_expression[max(0,i-1)] ==
'=':
353 raise ValueError(
'Cannot evaluate subexpression '+
' '.join(split_expression[max(0,i-1):min(i+1,len(split_expression))])+
' starting with an \'=\'')
354 temp_split_expression.pop()
355 temp_split_expression.pop()
356 template_expression[3]=split_expression[i-2]
357 template_expression[5]=split_expression[i-2]
361 if i+2>len(split_expression)-1:
362 raise ValueError(
'Cannot evaluate subexpression '+
' '.join(split_expression[max(0,i-1):min(i+1,len(split_expression))])+
' ending with an \'=\'')
363 template_expression[3]=split_expression[i+2]
364 template_expression[5]=split_expression[i+2]
367 template_expression[1]=lhs
368 template_expression[7]=rhs
369 temp_split_expression+=template_expression
372 temp_split_expression.append(split_expression[i])
374 split_expression=temp_split_expression
379 final_expression=list()
382 for item
in split_expression:
384 if self.
valid_operators[item][
'type']
in [
'boolean',
'left_bracket',
'right_bracket']:
385 if len(subexpression)>0:
389 final_expression.append(item)
391 subexpression.append(item)
393 if len(subexpression)>0:
396 return final_expression
399 def _ExpressionLexer(self, expression):
404 split_expression=list()
411 if actual_position>=len(expression):
412 if len(eaten_stuff)>0:
413 split_expression.append(eaten_stuff)
414 return split_expression
416 token=expression[actual_position]
419 if len(eaten_stuff)>0:
420 split_expression.append(eaten_stuff)
429 if len(eaten_stuff)>0:
430 split_expression.append(eaten_stuff)
432 split_expression.append(token)
437 if len(eaten_stuff)>0:
438 split_expression.append(eaten_stuff)
440 split_expression.append(token)
445 if len(eaten_stuff)>0:
446 split_expression.append(eaten_stuff)
449 if actual_position+len(self.
valid_operators[token][
'extension'])<len(expression):
454 split_expression.append(token)