diff --git a/app/modules/filter/RuleParser.py b/app/modules/filter/RuleParser.py new file mode 100644 index 00000000..5e90d1b0 --- /dev/null +++ b/app/modules/filter/RuleParser.py @@ -0,0 +1,52 @@ +from pyparsing import Forward, Literal, Word, alphas, infixNotation, opAssoc, alphanums, Combine, nums, ParseResults + + +class RuleParser: + + def __init__(self): + """ + 定义语法规则 + """ + # 表达式 + expr: Forward = Forward() + # 原子 + atom: Combine = Combine(Word(alphas, alphanums) | Word(nums) + Word(alphas, alphanums)) + # 逻辑非操作符 + operator_not: Literal = Literal('!').setParseAction(lambda: 'not') + # 逻辑或操作符 + operator_or: Literal = Literal('|').setParseAction(lambda: 'or') + # 逻辑与操作符 + operator_and: Literal = Literal('&').setParseAction(lambda: 'and') + # 定义表达式的语法规则 + expr <<= operator_not + expr | operator_or | operator_and | atom | ('(' + expr + ')') + + # 运算符优先级 + self.expr = infixNotation(expr, + [(operator_not, 1, opAssoc.RIGHT), + (operator_and, 2, opAssoc.LEFT), + (operator_or, 2, opAssoc.LEFT)]) + + def parse(self, expression: str) -> ParseResults: + """ + 解析给定的表达式。 + + 参数: + expression -- 要解析的表达式 + + 返回: + 解析结果 + """ + return self.expr.parseString(expression) + + +if __name__ == '__main__': + # 测试代码 + expression1 = "!BLU & (1080P | CN)" + expression2 = "!(A | B) & C" + expression3 = "A & B | C" + parsed_expr1 = RuleParser().parse(expression1) + parsed_expr2 = RuleParser().parse(expression2) + parsed_expr3 = RuleParser().parse(expression3) + print(f"Parsed Expression 1: {parsed_expr1}") + print(f"Parsed Expression 2: {parsed_expr2}") + print(f"Parsed Expression 3: {parsed_expr3}") diff --git a/requirements.txt b/requirements.txt index 5082e468..79bcca7f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,4 +29,5 @@ qbittorrent-api==2023.5.48 plexapi~=4.14.0 transmission-rpc~=4.3.0 feapder~=1.8.5 -Jinja2~=3.1.2 \ No newline at end of file +Jinja2~=3.1.2 +pyparsing~=3.0.9 \ No newline at end of file