解决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(NewRest, Line + 1, [], [{comment, Line, Comment}|Acc]);
|
||||||
%% 处理特殊字符开头的行, ‘$=’ 不会是一行的开头
|
%% 处理特殊字符开头的行, ‘$=’ 不会是一行的开头
|
||||||
lexer(<<${, Rest/binary>>, 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/binary>>, Line, [], Acc) ->
|
||||||
lexer(Rest, Line, [], [{'}', Line}|Acc]);
|
lexer(Rest, Line, [], [{special, Line, $}}|Acc]);
|
||||||
lexer(<<$;, Rest/binary>>, 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) ->
|
lexer(<<Char/utf8, Rest/binary>>, Line, Current, Acc) ->
|
||||||
case is_special(Char) of
|
case is_special(Char) of
|
||||||
true ->
|
true ->
|
||||||
case Current of
|
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))),
|
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;
|
end;
|
||||||
false ->
|
false ->
|
||||||
lexer(Rest, Line, [Char|Current], Acc)
|
lexer(Rest, Line, [Char|Current], Acc)
|
||||||
@ -79,32 +79,61 @@ is_special(_) -> false.
|
|||||||
|
|
||||||
%% 语法分析:将标记序列转换为AST
|
%% 语法分析:将标记序列转换为AST
|
||||||
parser(Tokens) ->
|
parser(Tokens) ->
|
||||||
lists:foreach(fun(T) ->
|
%display_tokens(Tokens),
|
||||||
lager:debug("token is: ~p", [T])
|
parser(Tokens, 0, []).
|
||||||
end, Tokens),
|
|
||||||
parser(Tokens, []).
|
|
||||||
|
|
||||||
parser([], Result) -> {ok, Result};
|
display_tokens(Tokens) ->
|
||||||
parser([{'{', _}|Tokens], Stack) ->
|
lists:foreach(fun(T) -> lager:debug("token is: ~p", [T]) end, Tokens).
|
||||||
parser(Tokens, [open_block|Stack]);
|
|
||||||
parser([{'}', _}|Tokens], [open_block, {block, Type, Props}|Stack]) ->
|
%% 将tokens解析成block
|
||||||
Block = #{type => Type, properties => lists:reverse(Props)},
|
|
||||||
parser(Tokens, [Block|Stack]);
|
parser([], 0, Blocks0) ->
|
||||||
parser([{ident, _, <<"modbus">>}|Tokens], Stack) ->
|
Blocks = lists:reverse(Blocks0),
|
||||||
parser(Tokens, [{block, modbus, []}|Stack]);
|
lager:debug("parse result: ~p", [Blocks]),
|
||||||
parser([{ident, _, <<"device">>}, {ident, _, Name}|Tokens], Stack) ->
|
{ok, Blocks};
|
||||||
parser(Tokens, [{block, {device, Name}, []}|Stack]);
|
|
||||||
parser([{ident, _, <<"processor">>}, {ident, _, Name}|Tokens], Stack) ->
|
%% 这里很重要,要到Block的关闭字符
|
||||||
parser(Tokens, [{block, {processor, Name}, []}|Stack]);
|
parser([{special, _, $}}|Tokens], 1, Stack) ->
|
||||||
parser([{ident, _, <<"alarm">>}, {ident, _, Name}|Tokens], Stack) ->
|
parser(Tokens, 0, Stack);
|
||||||
parser(Tokens, [{block, {alarm, Name}, []}|Stack]);
|
parser([{special, _, $}}|Tokens], Level, Stack) ->
|
||||||
parser([{ident, _Line, Name}, {special, _, $=}|Tokens], [{block, _, Props}|Stack]) ->
|
parser(Tokens, Level - 1, Stack);
|
||||||
{Value, Rest} = parse_value(Tokens, []),
|
|
||||||
parser(Rest, [{block, Props#{binary_to_atom(Name, utf8) => Value}}|Stack]);
|
parser([{special, _, $;}|Tokens], Level, Stack) ->
|
||||||
parser([{';', _}|Tokens], Stack) ->
|
parser(Tokens, Level, Stack);
|
||||||
parser(Tokens, Stack);
|
%% 处理空的定义
|
||||||
parser([{comment, _, _}|Tokens], Stack) ->
|
parser([{ident, _, <<>>}|Tokens], Level, Stack) ->
|
||||||
parser(Tokens, 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([{ident, _, Value}|Tokens], _) -> {binary_to_atom(Value, utf8), Tokens};
|
||||||
parse_value([{integer, _, Value}|Tokens], _) -> {Value, Tokens};
|
parse_value([{integer, _, Value}|Tokens], _) -> {Value, Tokens};
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
test() ->
|
test() ->
|
||||||
{ok, Config} = file:read_file("/usr/local/code/cloudkit/modbus/modbus.conf"),
|
{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),
|
{ok, AST} = modbus_parser:parse(Config),
|
||||||
|
|
||||||
modbus_parser:validate(AST),
|
modbus_parser:validate(AST),
|
||||||
|
|||||||
@ -107,10 +107,10 @@ processor temperature_processor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 输出目标
|
# 输出目标
|
||||||
output {
|
#output {
|
||||||
mqtt "sensors/boiler/temp";
|
# mqtt "sensors/boiler/temp";
|
||||||
influxdb "plant_metrics" measurement="temperature";
|
# influxdb "plant_metrics" measurement="temperature";
|
||||||
}
|
#}
|
||||||
}
|
}
|
||||||
|
|
||||||
alarm high_temperature {
|
alarm high_temperature {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user