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;
|
||||
parse_expression2(Type, Tk, String, {character, "[", 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}) ->
|
||||
{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_loop(Inner, 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}
|
||||
end.
|
||||
|
||||
unknown_type() ->
|
||||
{unknown_type, already_normalized, unknown_type}.
|
||||
%%% Record parsing
|
||||
|
||||
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
|
||||
wrap_error(Reason, _) -> Reason.
|
||||
@ -175,3 +259,9 @@ int_test() ->
|
||||
list_test() ->
|
||||
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