Map parsing
This commit is contained in:
parent
3f1c9bd626
commit
56e63051bc
@ -100,9 +100,26 @@ parse_expression2(Type, Tk, String, {integer, S, Row, Start, End}) ->
|
|||||||
end;
|
end;
|
||||||
parse_expression2(Type, Tk, String, {character, "[", Row, Start, _}) ->
|
parse_expression2(Type, Tk, String, {character, "[", Row, Start, _}) ->
|
||||||
parse_list(Type, Tk, String, Row, Start);
|
parse_list(Type, Tk, String, Row, Start);
|
||||||
|
parse_expression2(Type, Tk, String, {character, "{", Row, Start, _}) ->
|
||||||
|
parse_record_or_map(Type, Tk, String, Row, Start);
|
||||||
parse_expression2(_, _, _, {_, S, Row, Start, End}) ->
|
parse_expression2(_, _, _, {_, S, Row, Start, End}) ->
|
||||||
{error, {unexpected_token, S, Row, Start, End}}.
|
{error, {unexpected_token, S, Row, Start, End}}.
|
||||||
|
|
||||||
|
unknown_type() ->
|
||||||
|
{unknown_type, already_normalized, unknown_type}.
|
||||||
|
|
||||||
|
expect_tokens([], Tk, String) ->
|
||||||
|
{ok, {Tk, String}};
|
||||||
|
expect_tokens([Str | Rest], Tk, String) ->
|
||||||
|
case next_token(Tk, String) of
|
||||||
|
{ok, {{_, Str, _, _, _}, NewTk, NewString}} ->
|
||||||
|
expect_tokens(Rest, NewTk, NewString);
|
||||||
|
{ok, {{_, Actual, Row, Start, End}}} ->
|
||||||
|
{error, {unexpected_token, Actual, Row, Start, End}}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%% List Parsing
|
||||||
|
|
||||||
parse_list({_, _, {list, [Inner]}}, Tk, String, Row, Start) ->
|
parse_list({_, _, {list, [Inner]}}, Tk, String, Row, Start) ->
|
||||||
parse_list_loop(Inner, Tk, String, Row, Start, []);
|
parse_list_loop(Inner, Tk, String, Row, Start, []);
|
||||||
parse_list({_, _, unknown_type}, Tk, String, Row, Start) ->
|
parse_list({_, _, unknown_type}, Tk, String, Row, Start) ->
|
||||||
@ -137,8 +154,75 @@ parse_list_loop3(Inner, Tk, String, Row, Start, Acc) ->
|
|||||||
{error, Reason}
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
unknown_type() ->
|
%%% Record parsing
|
||||||
{unknown_type, already_normalized, unknown_type}.
|
|
||||||
|
parse_record_or_map({_, _, {map, [KeyType, ValueType]}}, Tk, String, _, _) ->
|
||||||
|
parse_map(KeyType, ValueType, Tk, String, #{});
|
||||||
|
parse_record_or_map({_, _, {record, Fields}}, Tk, String, _, _) ->
|
||||||
|
parse_record(Fields, Tk, String);
|
||||||
|
parse_record_or_map({_, _, unknown_type}, Tk, String, _, _) ->
|
||||||
|
case next_token(Tk, String) of
|
||||||
|
{ok, {{character, "}", _, _, _}, NewTk, NewString}} ->
|
||||||
|
{ok, {#{}, NewTk, NewString}};
|
||||||
|
{ok, {{character, "[", _, _, _}, NewTk, NewString}} ->
|
||||||
|
parse_map2(unknown_type(), unknown_type(), NewTk, NewString, #{});
|
||||||
|
{ok, {{alphanum, _, Row, Start, End}, _, _}} ->
|
||||||
|
{error, {unresolved_record, Row, Start, End}};
|
||||||
|
{ok, {{_, S, Row, Start, End}, _, _}} ->
|
||||||
|
{error, {unexpected_token, S, Row, Start, End}}
|
||||||
|
end;
|
||||||
|
parse_record_or_map({O, N, _}, _, _, Row, Start) ->
|
||||||
|
{error, {wrong_type, O, N, map, Row, Start, Start}}.
|
||||||
|
|
||||||
|
parse_record(Fields, Tk, String) ->
|
||||||
|
{error, not_yet_implemented}.
|
||||||
|
|
||||||
|
%%% Map Parsing
|
||||||
|
|
||||||
|
parse_map(KeyType, ValueType, Tk, String, Acc) ->
|
||||||
|
case next_token(Tk, String) of
|
||||||
|
{ok, {{character, "[", _, _, _}, NewTk, NewString}} ->
|
||||||
|
parse_map2(KeyType, ValueType, NewTk, NewString, Acc);
|
||||||
|
{ok, {{character, "}", _, _, _}, NewTk, NewString}} ->
|
||||||
|
{ok, {Acc, NewTk, NewString}};
|
||||||
|
{ok, {{_, S, Row, Start, End}}} ->
|
||||||
|
{error, {unexpected_token, S, Row, Start, End}}
|
||||||
|
end.
|
||||||
|
|
||||||
|
parse_map2(KeyType, ValueType, Tk, String, Acc) ->
|
||||||
|
case parse_expression(KeyType, Tk, String) of
|
||||||
|
{ok, {Result, NewTk, NewString}} ->
|
||||||
|
parse_map3(KeyType, ValueType, NewTk, NewString, Acc, Result);
|
||||||
|
{error, Reason} ->
|
||||||
|
wrap_error(Reason, {map_key, maps:size(Acc)})
|
||||||
|
end.
|
||||||
|
|
||||||
|
parse_map3(KeyType, ValueType, Tk, String, Acc, Key) ->
|
||||||
|
case expect_tokens(["]", "="], Tk, String) of
|
||||||
|
{ok, {NewTk, NewString}} ->
|
||||||
|
parse_map4(KeyType, ValueType, NewTk, NewString, Acc, Key);
|
||||||
|
{error, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
|
end.
|
||||||
|
|
||||||
|
parse_map4(KeyType, ValueType, Tk, String, Acc, Key) ->
|
||||||
|
case parse_expression(ValueType, Tk, String) of
|
||||||
|
{ok, {Result, NewTk, NewString}} ->
|
||||||
|
NewAcc = maps:put(Key, Result, Acc),
|
||||||
|
parse_map5(KeyType, ValueType, NewTk, NewString, NewAcc);
|
||||||
|
{error, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
|
end.
|
||||||
|
|
||||||
|
parse_map5(KeyType, ValueType, Tk, String, Acc) ->
|
||||||
|
case next_token(Tk, String) of
|
||||||
|
{ok, {{character, ",", _, _, _}, NewTk, NewString}} ->
|
||||||
|
parse_map(KeyType, ValueType, NewTk, NewString, Acc);
|
||||||
|
{ok, {{character, "}", _, _, _}, NewTk, NewString}} ->
|
||||||
|
{ok, {Acc, NewTk, NewString}};
|
||||||
|
{ok, {{_, S, Row, Start, End}}} ->
|
||||||
|
{error, {unexpected_token, S, Row, Start, End}}
|
||||||
|
end.
|
||||||
|
|
||||||
% TODO
|
% TODO
|
||||||
wrap_error(Reason, _) -> Reason.
|
wrap_error(Reason, _) -> Reason.
|
||||||
@ -175,3 +259,9 @@ int_test() ->
|
|||||||
list_test() ->
|
list_test() ->
|
||||||
check_parser("[1, 2, 3]", [1, 2, 3]).
|
check_parser("[1, 2, 3]", [1, 2, 3]).
|
||||||
|
|
||||||
|
list_of_lists_test() ->
|
||||||
|
check_parser("[[], [1], [2, 3]]", [[], [1], [2, 3]]).
|
||||||
|
|
||||||
|
maps_test() ->
|
||||||
|
check_parser("{[1] = 2, [3] = 4}", #{1 => 2, 3 => 4}).
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user