from statement import Rule, GrouperRule, AllenRule, Field, Arg from ftreader import FtReader import os def flatten(l): if isinstance(l,list): return sum(map(flatten,l)) else: return l def if_exists_delete(path): if os.path.exists(path): if path[path.find('h5'):] == 'h5': os.remove(path) def iterate_subrules(rule): for arg in rule.args: if type(arg) in [Rule, GrouperRule, AllenRule]: for r in iterate_subrules(arg): yield r yield arg def iterate_args(rule): for arg in rule.args: yield arg def iterate_rules(filter): for rule_list in filter.rules: for rule in rule_list: if type(rule) not in [Rule, GrouperRule, AllenRule]: continue yield rule for r in iterate_subrules(rule): yield r # returns the operation implementation from operators.py # module, based on the operation contained in rule.op attribute def find_op(rule, module='operators'): imp = __import__(module) op_name = rule.op # print getattr(imp, op_name) try: return getattr(imp, op_name) except AttributeError: try: external_imp = getattr(imp, 'external_import') return getattr(external_imp, op_name) except AttributeError: raise SyntaxError('Uknown operator %s at line %s.'%(op_name, rule.line)) def get_input_reader(parser): # TODO: create reader somewhere else """Returns a reader for the parser's input""" if not getattr(parser, "reader", None): parser.reader = FtReader(parser.input.name) return parser.reader def check_rule_fields(rule, reader): for arg in rule.args: if type(arg) is Field: if reader.supports_attr(arg.name): continue else: if arg.name == "rec_id": continue msg = 'There is no such field %s, '%arg.name msg += 'referenced at line %s'%rule.line raise SyntaxError(msg) def replace_bound_rules(filter): ''' Iterate over the rules replacing evaluatable rules with their values until there's nothing left to replace i.e. all remaining rules have field references. ''' def evaluate_rule(rule): ''' Evaluates rule if possible i.e. rule contains no record field references. If evaluation is not possible returns the original rule. ''' arg_types = [type(x) for x in rule.args] if Rule in arg_types or Field in arg_types: return rule else: # no references to record fields evaluate now replace_bound_rules.count += 1 op = find_op(rule) # hasattr() takes care of already replaced values args = [a.value if hasattr(a, 'value') else a for a in rule.args] result = op(*args) if not rule.NOT else not op(*args) return result replace_bound_rules.count = 0 for rule in iterate_rules(filter): newargs = [evaluate_rule(arg) if type(arg) is Rule else arg for arg in rule.args] rule.args = newargs # we have to break because nasty stuff happens # because the iterable is being changed if replace_bound_rules.count !=0: break if replace_bound_rules.count != 0: replace_bound_rules.count = 0 replace_bound_rules(filter) def replace_with_vals(filter): for rule in iterate_rules(filter): for i, arg in enumerate(rule.args): if type(arg) is Arg: rule.args[i] = arg.value