@@ -0,0 +1,3290 @@
+import re%0A%0Afn_map = %7B%0A    '&': lambda x, y:  x and y,%0A    '%7C': lambda x, y: x or y,%0A    '!': lambda x: not x%0A%7D%0A%0A%0Aclass Token:%0A    LEFT_BRACKETS = 1%0A    RIGHT_BRACKETS = 2%0A    SYMBOL = 3%0A    EXPRESSION = 4%0A%0A    SYMBOLS = '&%7C!'%0A%0A    def __init__(self, value, type):%0A        self.value = value%0A        self.type = type%0A%0A%0Aclass ASTree:%0A    def __init__(self, value):%0A        self.root = value%0A        self.left = None%0A        self.right = None%0A%0A%0Aclass Matcher:%0A    def __init__(self, origin):%0A        self.origin = origin%0A        self.ast = Matcher.make_ast(self.tokenize())%0A%0A    def tokenize(self):%0A        tokens = %5B%5D%0A        is_expr = False%0A        expr = %5B%5D%0A        for c in self.origin:%0A            if c == '#':%0A                if not is_expr:%0A                    is_expr = True%0A                else:%0A                    is_expr = False%0A                    tokens.append(Token(''.join(expr), Token.EXPRESSION))%0A                    expr = %5B%5D%0A            elif is_expr:%0A                expr.append(c)%0A            elif c in Token.SYMBOLS:%0A                tokens.append(Token(c, Token.SYMBOL))%0A            elif c == '(':%0A                tokens.append(Token(c, Token.LEFT_BRACKETS))%0A            elif c == ')':%0A                tokens.append(Token(c, Token.RIGHT_BRACKETS))%0A        return tokens%0A%0A    @staticmethod%0A    def make_sub_tree(stack, t):%0A        current = t%0A        while stack and stack%5B-1%5D.root.type != Token.LEFT_BRACKETS:%0A            node = stack.pop()%0A            if node.root.type != Token.SYMBOL:%0A                raise Exception(%22parse error%22)%0A            node.right = current%0A            if node.root.value == '&' or node.root.value == '%7C':%0A                left = stack.pop()%0A                if left.root.type != Token.SYMBOL and left.root.type != Token.EXPRESSION:%0A                    raise Exception(%22parse error%22)%0A                node.left = left%0A            current = node%0A        stack.append(current)%0A%0A    @staticmethod%0A    def make_ast(tokens):%0A        stack = %5B%5D%0A        for token in tokens:%0A            t = ASTree(token)%0A            if t.root.type == Token.SYMBOL or t.root.type == Token.LEFT_BRACKETS:%0A                stack.append(t)%0A            elif t.root.type == Token.EXPRESSION:%0A                Matcher.make_sub_tree(stack, t)%0A            else:%0A                t = stack.pop()%0A                tmp = stack.pop()%0A                if tmp.root.type != Token.LEFT_BRACKETS:%0A                    raise Exception(%22parse error%22)%0A                Matcher.make_sub_tree(stack, t)%0A        return stack.pop()%0A%0A    @staticmethod%0A    def eval(ast, line):%0A%0A        if ast.root.type == Token.EXPRESSION:%0A            return re.match(ast.root.value, line) is not None%0A        if ast.root.value == '!':%0A            if ast.right is None:%0A                raise Exception('syntax error')%0A            return fn_map%5B'!'%5D(Matcher.eval(ast.right, line))%0A        if ast.left is None:%0A            raise Exception('syntax error')%0A        if ast.right is None:%0A            raise Exception('syntax error')%0A        return fn_map%5Bast.root.value%5D(Matcher.eval(ast.left, line), Matcher.eval(ast.right, line))%0A%0A    def match(self, line):%0A        return Matcher.eval(self.ast, line)%0A%0A%0Aif __name__ == '__main__':%0A    m = Matcher('#test# & #abc# %7C (!#sdf# & #123#)')%0A    print(m.match(%22test acd dds 234%22))%0A

add match