All pastes #499105 Raw Edit

Cody Brocious

public python v1 · immutable
·published 2007-05-20 21:39 UTC
rendered paste body
import copyclass Matcher(object):    matchers = []    def __init__(self, cls, name, children=(), toplevel=False):        self.cls = cls        self.name = name        self.children = children        self.toplevel = toplevel        self.setName = None        def __call__(self, *children):        self = copy.deepcopy(self)        if self.toplevel:            self.matchers.append(self)        self.children = list(self.children)                for child in children:            for i in range(len(self.matchers)):                if self.matchers[i] == child:                    del self.matchers[i]                    break                        matcher = Matcher(child.cls, child.name, tuple(child.children), toplevel=False)            matcher.set(child.setName)            self.children.append(matcher)                self.children = tuple(self.children)                return self    def match(self, pattern, tree):        if not isinstance(tree, self.cls):            return None        if self.setName != None:            value = pattern.setValue(self.setName)            value.append(tree)        if len(self.children) == 0:            return tree        else:            ret = []                        for branch in tree:                for child in self.children:                    match = child.match(pattern, branch)                                        if match != None:                        ret.append(match)                                    return ret    def set(self, name=None):        self.setName = name        return self    def __getattr__(self, name):        return Matcher(getattr(self.cls, name), self.name + '.' + name)        def __repr__(self):        return self.name + `self.children`class Pattern(object):    def __init__(self, namespace=None):        self.namespace = namespace    def __call__(self, func):        names = func.func_code.co_names        for name in names:            try:                cls = getattr(self.namespace, name)                func.func_globals[name] = Matcher(cls, name, toplevel=True)            except:                pass        if func.func_code.co_argcount == 1:            func(self)        else:            func()        return Matcher.matchers[-1]    def match(self, tree):        return self.__pattern__.match(self, tree)        def __getattr__(self, name):        try:            value = object.__getattr__(self, name)            return value        except:            pass        return name    def setValue(self, name):        try:            return object.__getattribute__(self, name)        except:            pass        value = []        setattr(self, name, value)        return value