fix parser

This commit is contained in:
anlicheng 2025-06-10 22:35:12 +08:00
parent c965fcd17b
commit b3536f31b7
2 changed files with 19 additions and 11 deletions

View File

@ -30,16 +30,17 @@ parse_file(Filename) ->
lexer(Input) ->
lexer(Input, 1, [], []).
lexer(<<>>, _Line, _Current, Acc) -> lists:reverse(Acc);
lexer(<<>>, _Line, _Current, Acc) ->
lists:reverse(Acc);
lexer(<<$\s, Rest/binary>>, Line, Current, Acc) ->
lexer(Rest, Line, Current, Acc);
lexer(Rest, Line, [" "|Current], Acc);
lexer(<<$\n, Rest/binary>>, Line, Current, Acc) ->
lexer(Rest, Line+1, Current, Acc);
lexer(Rest, Line + 1, Current, Acc);
lexer(<<$\t, Rest/binary>>, Line, Current, Acc) ->
lexer(Rest, Line, Current, Acc);
lexer(<<$#, Rest/binary>>, Line, _Current, Acc) ->
{Comment, NewRest} = read_until(Rest, <<$\n>>),
lexer(NewRest, Line+1, [], [{comment, Line, Comment}|Acc]);
lexer(NewRest, Line + 1, [], [{comment, Line, Comment}|Acc]);
lexer(<<${, Rest/binary>>, Line, [], Acc) ->
lexer(Rest, Line, [], [{'{', Line}|Acc]);
lexer(<<$}, Rest/binary>>, Line, [], Acc) ->
@ -50,18 +51,21 @@ lexer(<<Char/utf8, Rest/binary>>, Line, Current, Acc) ->
case is_special(Char) of
true ->
NewAcc = case Current of
[] -> Acc;
_ -> [{ident, Line, list_to_binary(lists:reverse(Current))}|Acc]
[] ->
Acc;
_ ->
Ident = list_to_binary(string:trim(lists:reverse(Current))),
[{ident, Line, Ident}|Acc]
end,
lexer(Rest, Line, [], [{special, Line, Char}|NewAcc]);
false ->
lexer(Rest, Line, [Char|Current], Acc)
end.
read_until(Bin, Delim) ->
case binary:match(Bin, <<Delim>>) of
read_until(Bin, Delim) when is_binary(Bin), is_binary(Delim) ->
case binary:match(Bin, Delim) of
{Pos, _} ->
{binary:part(Bin, 0, Pos), binary:part(Bin, Pos+1, byte_size(Bin)-Pos-1)};
{binary:part(Bin, 0, Pos), binary:part(Bin, Pos + 1, byte_size(Bin) - Pos - 1)};
nomatch ->
{Bin, <<>>}
end.
@ -74,9 +78,12 @@ is_special(_) -> false.
%% AST
parser(Tokens) ->
lists:foreach(fun(T) ->
lager:debug("token is: ~p", [T])
end, Tokens),
parser(Tokens, []).
parser([], [Result]) -> {ok, Result};
parser([], Result) -> {ok, Result};
parser([{'{', _}|Tokens], Stack) ->
parser(Tokens, [open_block|Stack]);
parser([{'}', _}|Tokens], [open_block, {block, Type, Props}|Stack]) ->
@ -86,7 +93,7 @@ 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, Line, Name}, {special, _, $=}|Tokens], [{block, _, Props}|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) ->

View File

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