From b4c5b8c050cdbb295bf437edc77e7e1cf1200aee Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Wed, 11 Jun 2025 16:16:13 +0800 Subject: [PATCH] fix parser --- apps/modbus/src/modbus_parser.erl | 104 +++++++++++++++++------------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/apps/modbus/src/modbus_parser.erl b/apps/modbus/src/modbus_parser.erl index 3a8642a..0403453 100644 --- a/apps/modbus/src/modbus_parser.erl +++ b/apps/modbus/src/modbus_parser.erl @@ -14,11 +14,14 @@ %% 主解析函数 parse(Input) when is_binary(Input) -> Tokens = lexer(Input), - {ok, AST} = parser(Tokens), - case validate(AST) of - ok -> {ok, AST}; - {error, Reason} -> {error, Reason} - end. + R = parser(Tokens), + lager:debug("parse result is: ~p", [R]). + + %{ok, AST} = parser(Tokens), + %case validate(AST) of + % ok -> {ok, AST}; + % {error, Reason} -> {error, Reason} + %end. parse_file(Filename) -> case file:read_file(Filename) of @@ -80,60 +83,71 @@ is_special(_) -> false. %% 语法分析:将标记序列转换为AST parser(Tokens) -> %display_tokens(Tokens), - parser(Tokens, 0, []). + {_, B} = parser_block0(Tokens), + {ok, B}. display_tokens(Tokens) -> lists:foreach(fun(T) -> lager:debug("token is: ~p", [T]) end, Tokens). -%% 将tokens解析成block +%% 将tokens解析成block, 返回值格式为:{ResetToken, Block} -parser([], 0, Blocks0) -> - Blocks = lists:reverse(Blocks0), - lager:debug("parse result: ~p", [Blocks]), - {ok, Blocks}; +%% 忽略掉注释信息 +parser_block0([{comment, _, _}|Tokens]) -> + parser_block0(Tokens); +parser_block0([{ident, _, Ident}, {special, _, ${}|Tokens]) -> + parser_block1(Tokens, {block, Ident, []}). %% 这里很重要,要到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_block1([{special, _, $}}|Tokens], B) -> + {Tokens, B}; +parser_block1([{special, _, $;}|Tokens], B) -> + parser_block1(Tokens, B); %% 处理空的定义 -parser([{ident, _, <<>>}|Tokens], Level, Stack) -> - parser(Tokens, Level, Stack); +parser_block1([{ident, _, <<>>}|Tokens], B) -> + parser_block1(Tokens, B); +%% 其他定义,是基于: port /dev/ttyUSB0; 这样的格式的 +parser_block1([{ident, _Line, Prop}, {special, _, $;}|Tokens], {block, Block, Props}) -> + parser_block1(Tokens, {block, Block, [Prop|Props]}); +%% 忽略掉注释信息 +parser_block1([{comment, _, _}|Tokens], B) -> + parser_block1(Tokens, B). -%% 预定义支持的标签, 顶层定义, 遇到是,目前的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]); +%% 解析属性, 返回值: {ResetTokens, Props} +%% 这里很重要,要到Block的关闭字符 +parser_props([{special, _, $}}|Tokens], 0, Props) -> + {Tokens, lists:reverse(Props)}; +parser_props([{special, _, $}}|Tokens], Level, Props) -> + lager:debug("call level: ~p, me here: ~p", [Level, Props]), + parser_props(Tokens, Level - 1, Props); -%% 运行被嵌套的定义 -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_props([{special, _, $;}|Tokens], Level, Props) -> + parser_props(Tokens, Level, Props); +%% 处理空的定义 +parser_props([{ident, _, <<>>}|Tokens], Level, Props) -> + parser_props(Tokens, Level, Props); + +%% 允许被嵌套的定义 +parser_props([{ident, _, <<"transport", Proto/binary>>}, {special, _, ${} | Tokens], Level, Props) -> + {RestTokens, ChildProps} = parser_props(Tokens, 1, []), + + display_tokens(Tokens), + + parser_props(RestTokens, Level - 1, [{block, {transport, Proto}, ChildProps}|Props]); +parser_props([{ident, _, <<"variables">>}, {special, _, ${}|Tokens], Level, Props) -> + {RestTokens, ChildProps} = parser_props(Tokens, 1, []), + parser_props(RestTokens, Level + 1, [{block, variables, ChildProps}|Props]); %% 非标准定义 -parser([{ident, _, BlockName}, {special, _, ${}|Tokens], Level, Stack) -> - parser(Tokens, Level + 1, [{block, BlockName, []}|Stack]); +parser_props([{ident, _, BlockName}, {special, _, ${}|Tokens], Level, Props) -> + {RestTokens, ChildProps} = parser_props(Tokens, 1, []), + parser_props(RestTokens, Level + 1, [{block, BlockName, ChildProps}|Props]); %% 其他定义,是基于: port /dev/ttyUSB0; 这样的格式的 -parser([{ident, _Line, Prop}, {special, _, $;}|Tokens], Level, [{block, Block, Props}|Stack]) -> - parser(Tokens, Level, [{block, Block, [Prop|Props]}|Stack]); +parser_props([{ident, _Line, Prop}, {special, _, $;}|Tokens], Level, Props) -> + parser_props(Tokens, Level, [Prop|Props]); -%% 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). +%% 忽略掉注释信息 +parser_props([{comment, _, _}|Tokens], Level, Props) -> + parser_props(Tokens, Level, Props). parse_value([{ident, _, Value}|Tokens], _) -> {binary_to_atom(Value, utf8), Tokens}; parse_value([{integer, _, Value}|Tokens], _) -> {Value, Tokens};