解决parser的问题

This commit is contained in:
anlicheng 2025-06-11 00:23:20 +08:00
parent 6b678e454f
commit 84413ca1bc
3 changed files with 64 additions and 35 deletions

View File

@ -43,21 +43,21 @@ lexer(<<$#, Rest/binary>>, Line, _Current, Acc) ->
lexer(NewRest, Line + 1, [], [{comment, Line, Comment}|Acc]);
%% , $=
lexer(<<${, Rest/binary>>, Line, [], Acc) ->
lexer(Rest, Line, [], [{'{', Line}|Acc]);
lexer(Rest, Line, [], [{special, Line, ${}|Acc]);
lexer(<<$}, Rest/binary>>, Line, [], Acc) ->
lexer(Rest, Line, [], [{'}', Line}|Acc]);
lexer(Rest, Line, [], [{special, Line, $}}|Acc]);
lexer(<<$;, Rest/binary>>, Line, [], Acc) ->
lexer(Rest, Line, [], [{';', Line}|Acc]);
lexer(Rest, Line, [], [{special, Line, $;}|Acc]);
%%
lexer(<<Char/utf8, Rest/binary>>, Line, Current, Acc) ->
case is_special(Char) of
true ->
case Current of
[] ->
lexer(Rest, Line, [], [{special, Line, list_to_binary([Char])}|Acc]);
lexer(Rest, Line, [], [{special, Line, Char}|Acc]);
_ ->
Ident = list_to_binary(string:trim(lists:reverse(Current))),
lexer(Rest, Line, [], [{special, Line, list_to_binary([Char])}, {ident, Line, Ident}|Acc])
lexer(Rest, Line, [], [{special, Line, Char}, {ident, Line, Ident}|Acc])
end;
false ->
lexer(Rest, Line, [Char|Current], Acc)
@ -79,32 +79,61 @@ is_special(_) -> false.
%% AST
parser(Tokens) ->
lists:foreach(fun(T) ->
lager:debug("token is: ~p", [T])
end, Tokens),
parser(Tokens, []).
%display_tokens(Tokens),
parser(Tokens, 0, []).
parser([], Result) -> {ok, Result};
parser([{'{', _}|Tokens], Stack) ->
parser(Tokens, [open_block|Stack]);
parser([{'}', _}|Tokens], [open_block, {block, Type, Props}|Stack]) ->
Block = #{type => Type, properties => lists:reverse(Props)},
parser(Tokens, [Block|Stack]);
parser([{ident, _, <<"modbus">>}|Tokens], Stack) ->
parser(Tokens, [{block, modbus, []}|Stack]);
parser([{ident, _, <<"device">>}, {ident, _, Name}|Tokens], Stack) ->
parser(Tokens, [{block, {device, Name}, []}|Stack]);
parser([{ident, _, <<"processor">>}, {ident, _, Name}|Tokens], Stack) ->
parser(Tokens, [{block, {processor, Name}, []}|Stack]);
parser([{ident, _, <<"alarm">>}, {ident, _, Name}|Tokens], Stack) ->
parser(Tokens, [{block, {alarm, Name}, []}|Stack]);
parser([{ident, _Line, Name}, {special, _, $=}|Tokens], [{block, _, Props}|Stack]) ->
{Value, Rest} = parse_value(Tokens, []),
parser(Rest, [{block, Props#{binary_to_atom(Name, utf8) => Value}}|Stack]);
parser([{';', _}|Tokens], Stack) ->
parser(Tokens, Stack);
parser([{comment, _, _}|Tokens], Stack) ->
parser(Tokens, Stack).
display_tokens(Tokens) ->
lists:foreach(fun(T) -> lager:debug("token is: ~p", [T]) end, Tokens).
%% tokens解析成block
parser([], 0, Blocks0) ->
Blocks = lists:reverse(Blocks0),
lager:debug("parse result: ~p", [Blocks]),
{ok, Blocks};
%% Block的关闭字符
parser([{special, _, $}}|Tokens], 1, Stack) ->
parser(Tokens, 0, Stack);
parser([{special, _, $}}|Tokens], Level, Stack) ->
parser(Tokens, Level - 1, Stack);
parser([{special, _, $;}|Tokens], Level, Stack) ->
parser(Tokens, Level, Stack);
%%
parser([{ident, _, <<>>}|Tokens], Level, Stack) ->
parser(Tokens, Level, Stack);
%% , , level值必须等于0
parser([{ident, _, <<"modbus">>}, {special, _, ${} |Tokens], 0, Stack) ->
parser(Tokens, 1, [{block, modbus, []}|Stack]);
parser([{ident, _, <<"device", Name/binary>>}, {special, _, ${}|Tokens], 0, Stack) ->
parser(Tokens, 1, [{block, {device, string:trim(Name)}, []}|Stack]);
parser([{ident, _, <<"processor", Name/binary>>}, {special, _, ${}|Tokens], 0, Stack) ->
parser(Tokens, 1, [{block, {processor, string:trim(Name)}, []}|Stack]);
parser([{ident, _, <<"alarm", Name/binary>>}, {special, _, ${}|Tokens], 0, Stack) ->
parser(Tokens, 1, [{block, {alarm, string:trim(Name)}, []}|Stack]);
%%
parser([{ident, _, <<"transport", Proto/binary>>}, {special, _, ${} | Tokens], Level, Stack) ->
parser(Tokens, Level + 1, [{block, {transport, string:trim(Proto)}, []}|Stack]);
parser([{ident, _, <<"variables">>}, {special, _, ${}|Tokens], Level, Stack) ->
parser(Tokens, Level + 1, [{block, variables, []}|Stack]);
%%
parser([{ident, _, BlockName}, {special, _, ${}|Tokens], Level, Stack) ->
parser(Tokens, Level + 1, [{block, BlockName, []}|Stack]);
%% : port /dev/ttyUSB0;
parser([{ident, _Line, Prop}, {special, _, $;}|Tokens], Level, [{block, Block, Props}|Stack]) ->
parser(Tokens, Level, [{block, Block, [Prop|Props]}|Stack]);
%% todo
%parser([{ident, _Line, Name}, {special, _, $=}|Tokens], [{block, _, Props}|Stack]) ->
% {Value, Rest} = parse_value(Tokens, []),
% parser(Rest, [{block, Props#{binary_to_atom(Name, utf8) => Value}}|Stack]);
parser([{comment, _, _}|Tokens], Level, Stack) ->
parser(Tokens, Level, Stack).
parse_value([{ident, _, Value}|Tokens], _) -> {binary_to_atom(Value, utf8), Tokens};
parse_value([{integer, _, Value}|Tokens], _) -> {Value, Tokens};

View File

@ -14,7 +14,7 @@
test() ->
{ok, Config} = file:read_file("/usr/local/code/cloudkit/modbus/modbus.conf"),
lager:debug("config is: ~ts", [Config]),
%lager:debug("config is: ~ts", [Config]),
{ok, AST} = modbus_parser:parse(Config),
modbus_parser:validate(AST),

View File

@ -107,10 +107,10 @@ processor temperature_processor {
}
# 输出目标
output {
mqtt "sensors/boiler/temp";
influxdb "plant_metrics" measurement="temperature";
}
#output {
# mqtt "sensors/boiler/temp";
# influxdb "plant_metrics" measurement="temperature";
#}
}
alarm high_temperature {