基于lark-parser的简易规则系统。
$ pip install lark-parser
run demo:
$ python3 demo.py
根据规则需求自定义grammar,语法格式可参考lark文档。
示例:
grammar = """ ?start: "if" logit "then" value "else" value -> assign ?value: "true" -> true | "false" -> false | string ?logit: and | variable -> variable_self | "!"variable -> not_variable_self | variable ">" NUMBER -> bigger ... ?and: atom | logit "and" logit -> and_op | logit "or" logit -> or_op ?atom: "(" logit ")" string : ESCAPED_STRING -> string variable: "@"NAME | "@"string -> variable %import common.CNAME -> NAME %import common.ESCAPED_STRING %import common.NUMBER %import common.WS %ignore WS """
根据所定义的grammar,编写符合语法格式的规则,例如:
from rule.rule import init_grammar_parser # 定义规则:买5个包子回来,如果看到西瓜并且西瓜重量大于或等于10,买1个 rule = """ if ("西瓜" in @"物品列表" and @"西瓜重量" >= 10) then "买1个包子" else "买5个包子" """ # 构建grammar parser parser = init_grammar_parser() # 将规则解析为语法树 tree = parser.parse(rule) print(tree.pretty())
解析得到的tree如下所示:
assign
and_op
exist_in
string "西瓜"
variable
string "物品列表"
bigger_equal
variable
string "西瓜重量"
10
string "买1个包子"
string "买5个包子"
以上述grammar和规则为例,前缀为@的符号表示变量,可以从程序中实时传入,例如有如下variable:
from rule.rule import EvalTree variable_dict = { "西瓜重量": 10, "物品列表": {"包子", "西瓜", "香蕉"}, } tree_evaluator = EvalTree() rule_result = tree_evaluator.transform_tree(tree, variable_dict) print(rule_result) # 买1个包子
- lark-parser官方文档:https://lark-parser.readthedocs.io/en/latest/