fix rule parser

This commit is contained in:
anlicheng 2023-02-28 00:56:40 +08:00
parent f97cf4a663
commit dd234af4d0

View File

@ -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.