diff --git a/apps/iot/src/iot_rule_parser.erl b/apps/iot/src/iot_rule_parser.erl index 6946d54..ee94354 100644 --- a/apps/iot/src/iot_rule_parser.erl +++ b/apps/iot/src/iot_rule_parser.erl @@ -15,61 +15,64 @@ test() -> %Rule = <<"SELECT * FROM service.data WHERE id > 0 AND (name = 'anlicheng' OR name = 'test')">>, %parse(Rule), - Tokens = parse_condition(<<"id > 0 OR id < 3 AND (name = 'anlicheng' OR (name = 'test' AND (y = 1 OR x = 1))) AND (age > 1)">>), + %Tokens = parse_condition(<<"id > 0 OR id < 3 AND (name = 'anlicheng' OR (name = 'test' AND (y = 1 OR x = 1))) AND (age > 1)">>), + Tokens = parse_condition(<<"id < 3 OR (name = 'anlicheng' OR (name = 'test' AND (y = 1 OR x = 1))) AND (age > 1 OR y = 1)">>), % generate(Tokens, #{<<"name">> => <<"anlicheng">>, <<"id">> => 1234}), ok. scan(Tokens) -> ExprList = scan_or(Tokens), - lists:map(fun(Expr) -> scan_and(Expr) end, ExprList). + lists:map(fun({_, Expr}) -> + scan_and(Expr) + end, ExprList). + +scan_each([]) -> + []; +scan_each([H|Tail]) when length(H) > 1 -> + [scan(H)|scan_each(Tail)]. scan_or(Tokens) -> - scan_or(Tokens, [], [], 0). + lager:debug("tokens: ~p", [Tokens]), + scan_or(Tokens, [], [], 0, 0). %% 扫描完成并且最后一个表达式为空 -scan_or([], [], Acc, 0) -> +scan_or([], [], Acc, _, _) -> lists:reverse(Acc); %% 扫描完成并且最后一个表达式不为空 -scan_or([], Expr, Acc, 0) -> - lists:reverse([lists:reverse(Expr)|Acc]); +scan_or([], Expr, Acc, _, Deep) -> + lists:reverse([{get_tag(Deep), lists:reverse(Expr)}|Acc]); %% 遇到OR关键词, 并且此时的层级为0 -scan_or([32, $O, $R, 32|Tokens], Expr, Acc, 0) -> - scan_or(Tokens, [], [lists:reverse(Expr)|Acc], 0); +scan_or([32, $O, $R, 32|Tokens], Expr, Acc, 0, Deep) -> + scan_or(Tokens, [], [{get_tag(Deep), lists:reverse(Expr)}|Acc], 0, 0); %% 扫描到左括号 && Level > 0; 此时的Expr需要更多的字符 -scan_or([Token|Tokens], Expr, Acc, Level) when Token == $( -> - scan_or(Tokens, [Token|Expr], Acc, Level + 1); -%% 扫描到右括号 && Level == 1; 此时的Expr表达式的内部嵌套的子串扫描完成 -scan_or([Token|Tokens], Expr, Acc, 1) when Token == $) -> - scan_or(Tokens, [Token|Expr], Acc, 0); +scan_or([Token|Tokens], Expr, Acc, Level, Deep) when Token == $( -> + scan_or(Tokens, [Token|Expr], Acc, Level + 1, Deep + 1); %% 扫描到右括号 && Level > 1; 此时的Expr表达式的内部嵌套的子串扫描完成,Level的值减1 -scan_or([Token|Tokens], Expr, Acc, Level) when Token == $) -> - scan_or(Tokens, [Token|Expr], Acc, Level - 1); +scan_or([Token|Tokens], Expr, Acc, Level, Deep) when Token == $) -> + scan_or(Tokens, [Token|Expr], Acc, Level - 1, Deep); %% 普通字符 -scan_or([Token|Tokens], Expr, Acc, Level) -> - scan_or(Tokens, [Token|Expr], Acc, Level). +scan_or([Token|Tokens], Expr, Acc, Level, Deep) -> + scan_or(Tokens, [Token|Expr], Acc, Level, Deep). scan_and(Tokens) -> - scan_and(Tokens, [], [], 0). + scan_and(Tokens, [], [], 0, 0). %% 扫描完成并且最后一个表达式为空 -scan_and([], [], Acc, 0) -> +scan_and([], [], Acc, _, _) -> lists:reverse(Acc); %% 扫描完成并且最后一个表达式不为空 -scan_and([], Expr, Acc, 0) -> - lists:reverse([{simple, lists:reverse(Expr)}|Acc]); +scan_and([], Expr, Acc, _, Deep) -> + lists:reverse([{get_tag(Deep), lists:reverse(Expr)}|Acc]); %% 遇到OR关键词, 并且此时的层级为0 -scan_and([32, $A, $N, $D, 32|Tokens], Expr, Acc, 0) -> - scan_and(Tokens, [], [{simple, lists:reverse(Expr)}|Acc], 0); +scan_and([32, $A, $N, $D, 32|Tokens], Expr, Acc, 0, Deep) -> + scan_and(Tokens, [], [{get_tag(Deep), lists:reverse(Expr)}|Acc], 0, 0); %% 扫描到左括号 && Level > 0; 此时的Expr需要更多的字符 -scan_and([Token|Tokens], Expr, Acc, Level) when Token == $( -> - scan_and(Tokens, [Token|Expr], Acc, Level + 1); -%% 扫描到右括号 && Level == 1; 此时的Expr表达式的内部嵌套的子串扫描完成 -scan_and([Token|Tokens], Expr, Acc, 1) when Token == $) -> - scan_and(Tokens, [Token|Expr], Acc, 0); +scan_and([Token|Tokens], Expr, Acc, Level, Deep) when Token == $( -> + scan_and(Tokens, [Token|Expr], Acc, Level + 1, Deep + 1); %% 扫描到右括号 && Level > 1; 此时的Expr表达式的内部嵌套的子串扫描完成,Level的值减1 -scan_and([Token|Tokens], Expr, Acc, Level) when Token == $) -> - scan_and(Tokens, [Token|Expr], Acc, Level - 1); +scan_and([Token|Tokens], Expr, Acc, Level, Deep) when Token == $) -> + scan_and(Tokens, [Token|Expr], Acc, Level - 1, Deep); %% 普通字符 -scan_and([Token|Tokens], Expr, Acc, Level) -> - scan_and(Tokens, [Token|Expr], Acc, Level). +scan_and([Token|Tokens], Expr, Acc, Level, Deep) -> + scan_and(Tokens, [Token|Expr], Acc, Level, Deep). parse(Rule) -> {ok, MP} = re:compile("SELECT (.*) FROM (.*) WHERE (.*)"), @@ -124,3 +127,9 @@ generate([{simple, Expr}|ExprList], Data) -> +get_tag(0) -> + simple; +get_tag(_) -> + complex. + +