easy_rec/python/utils/expr_util.py (104 lines of code) (raw):

from collections import deque def _process_multi_expr(expr): expr = expr.strip() size = len(expr) idx = 0 two_expr = ['>=', '<=', '=='] expr_list = [] while (idx < size): if idx + 2 <= size and expr[idx:idx + 2] in two_expr: expr_list.append(expr[idx:idx + 2]) idx += 2 else: expr_list.append(expr[idx]) idx += 1 return expr_list def _process_enum(enum, input_names, prefix=''): enum = enum.strip() if enum in input_names: enum = "parsed_dict['%s']" % (prefix + enum) return enum def _get_expression_list(expression, input_names, prefix=''): ops = [ '+', '-', '*', '/', '(', ')', '>', '>=', '<', '<=', '==', '=', '&', '|' ] expression_list = [] eunm = '' pre_expr = '' for i in expression: if i in ops: if eunm: expression_list.append(_process_enum(eunm, input_names, prefix=prefix)) eunm = '' pre_expr += i else: eunm += i if pre_expr: expression_list.extend(_process_multi_expr(pre_expr)) pre_expr = '' if eunm: expression_list.append(_process_enum(eunm, input_names, prefix=prefix)) if pre_expr: expression_list.extend(_process_multi_expr(pre_expr)) final_expression_list = [''] ops = ['(', ')', '>=', '<=', '==', '>', '<', '&', '|'] for expr in expression_list: if expr in ops: final_expression_list.append(expr) elif final_expression_list[-1] not in ops: final_expression_list[-1] += expr else: final_expression_list.append(expr) final_expression_list = [expr for expr in final_expression_list if expr] return final_expression_list def _solve(enum, sign, stack): if len(stack) == 0 or enum == '' or sign == '': return enum op1 = stack.pop() op2 = enum if sign == '>': result = 'tf.greater(%s, %s)' % (op1, op2) elif sign == '>=': result = 'tf.greater_equal(%s, %s)' % (op1, op2) elif sign == '<': result = 'tf.less(%s, %s)' % (op1, op2) elif sign == '<=': result = 'tf.less_equal(%s, %s)' % (op1, op2) elif sign == '==': result = 'tf.equal(%s, %s)' % (op1, op2) elif sign == '&': result = '%s & %s' % (op1, op2) elif sign == '|': result = '%s | %s' % (op1, op2) else: assert False return result def _expression_eval(expr_list): ops = ['>', '>=', '<', '<=', '==', '&', '|', '(', ')'] stack = deque() sign = '' operand = '' for c in expr_list: if c == ' ': continue elif c not in ops: operand = c elif c == '(': stack.append(sign) sign = '' else: result = _solve(operand, sign, stack) operand = '' if c == ')': sign = stack.pop() operand = _solve(result, sign, stack) sign = '' else: sign = c stack.append(result) expr_str = _solve(operand, sign, stack) return expr_str def get_expression(expression, input_names, prefix=''): expression_list = _get_expression_list(expression, input_names, prefix=prefix) expression = _expression_eval(expression_list) return expression