from collections import defaultdict import importlib from log import log from rule import Rule from symbols import Symbol, Symbols class Rules(list): def __init__(self, *args, files=[]): super().__init__() self.rule_set = set() self.by_phrase = defaultdict(list) for name in files: module = importlib.import_module('rules.' + name) self.extend(module.rules) for rule_or_rules in args: if isinstance(rule_or_rules, str): if '\n' in rule_or_rules: # víc pravidel jako řetězec, prozatím každé na svém řádku for line in (line.strip() for line in rule_or_rules.split( '\n')): if line and not line.startswith('#'): self.append(line) else: self.append(rule_or_rules) else: self.extend(rule_or_rules) def __add__(self, other): rules = Rules(self) rules.extend(other) return rules def __repr__(self): return 'Rules(' + super().__repr__() + ')' def append(self, rule): if isinstance(rule, str): rule = Rule(rule) if rule in self.rule_set: log.warning('duplicate rule %s', rule) else: super().append(rule) self.rule_set.add(rule) self.by_phrase[rule.left.phrase].append(rule) self.extend(rule.epsilon_rules) # je to iterátor, takže jen jednou def extend(self, rules): for rule in rules: self.append(rule) def insert_into_all(self, inserted_symbols, before=False, inside=False, after=False, position=None, repeat_self=False, update_left=None): if isinstance(inserted_symbols, str): inserted_symbols = Symbols(inserted_symbols) if isinstance(update_left, str): update_left = Symbol(update_left) return ( Rules(self if repeat_self else []) + Rules(rule.insert_symbols( inserted_symbols, before, inside, after, position, update_left) for rule in self)) def remove_attributes(self, removed_attributes, except_position=None, repeat_self=False): if isinstance(removed_attributes, str): removed_attributes = Symbol(removed_attributes) return ( Rules(self if repeat_self else []) + Rules(rule.remove_attributes( removed_attributes, except_position) for rule in self)) def print(self): for rule in self: log.debug('rule %s', rule) log.info('\n')