You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.8 KiB
Python

from statement import Rule, GrouperRule, AllenRule, Field, Arg
10 years ago
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):
10 years ago
# TODO: create reader somewhere else
"""Returns a reader for the parser's input"""
10 years ago
if not getattr(parser, "reader", None):
parser.reader = FtReader(parser.input.name)
return parser.reader
10 years ago
def check_rule_fields(rule, reader):
for arg in rule.args:
if type(arg) is Field:
10 years ago
if reader.supports_attr(arg.name):
continue
else:
10 years ago
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