解决parser的问题
This commit is contained in:
parent
6b678e454f
commit
84413ca1bc
@ -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};
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user