fix rule parser
This commit is contained in:
parent
f97cf4a663
commit
dd234af4d0
@ -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.
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user