Handle token/parse errors more carefully
This commit is contained in:
parent
bb4bcbb7de
commit
d014ae0982
@ -24,8 +24,8 @@ parse_literal2(Result, Pos, String) ->
|
|||||||
case next_token(Pos, String) of
|
case next_token(Pos, String) of
|
||||||
{ok, {{eof, _, _, _, _}, _, _}} ->
|
{ok, {{eof, _, _, _, _}, _, _}} ->
|
||||||
{ok, Result};
|
{ok, Result};
|
||||||
{ok, {{_, S, _, Row, Start, End}, _, _}} ->
|
{ok, {Token, _, _}} ->
|
||||||
{error, {unexpected_token, S, Row, Start, End}};
|
unexpected_token(Token);
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
{error, Reason}
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
@ -235,8 +235,10 @@ parse_expression2(Type, Pos, String, {character, "{", _, Row, Start, _}) ->
|
|||||||
parse_record_or_map(Type, Pos, String, Row, Start);
|
parse_record_or_map(Type, Pos, String, Row, Start);
|
||||||
parse_expression2(Type, Pos, String, {alphanum, S, _, Row, Start, End}) ->
|
parse_expression2(Type, Pos, String, {alphanum, S, _, Row, Start, End}) ->
|
||||||
parse_alphanum(Type, Pos, String, S, Row, Start, End);
|
parse_alphanum(Type, Pos, String, S, Row, Start, End);
|
||||||
parse_expression2(_, _, _, {_, S, _, Row, Start, End}) ->
|
parse_expression2(_, _, _, {eof, _, _, _, _, _}) ->
|
||||||
{error, {unexpected_token, S, Row, Start, End}}.
|
{error, unexpected_end_of_file};
|
||||||
|
parse_expression2(_, _, _, Token) ->
|
||||||
|
unexpected_token(Token).
|
||||||
|
|
||||||
unknown_type() ->
|
unknown_type() ->
|
||||||
{unknown_type, already_normalized, unknown_type}.
|
{unknown_type, already_normalized, unknown_type}.
|
||||||
@ -247,10 +249,24 @@ expect_tokens([Str | Rest], Pos, String) ->
|
|||||||
case next_token(Pos, String) of
|
case next_token(Pos, String) of
|
||||||
{ok, {{_, Str, _, _, _, _}, NewPos, NewString}} ->
|
{ok, {{_, Str, _, _, _, _}, NewPos, NewString}} ->
|
||||||
expect_tokens(Rest, NewPos, NewString);
|
expect_tokens(Rest, NewPos, NewString);
|
||||||
{ok, {{_, Actual, _, Row, Start, End}, _, _}} ->
|
{ok, {Token, _, _}} ->
|
||||||
{error, {unexpected_token, Actual, Row, Start, End}}
|
unexpected_token(Token, Str);
|
||||||
|
{error, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
unexpected_token(Token, _Expected) ->
|
||||||
|
% I don't know if this is a good idea, but sometimes there are only one or
|
||||||
|
% two tokens that could have worked, which might make for simple
|
||||||
|
% non-technical error messages. I don't know how to format that yet,
|
||||||
|
% though.
|
||||||
|
unexpected_token(Token).
|
||||||
|
|
||||||
|
unexpected_token({eof, _, _, _, _, _}) ->
|
||||||
|
{error, expression_incomplete};
|
||||||
|
unexpected_token({_, S, _, Row, Start, End}) ->
|
||||||
|
{error, {unexpected_token, S, Row, Start, End}}.
|
||||||
|
|
||||||
%%% Ambiguous Chain Object vs Identifier Parsing
|
%%% Ambiguous Chain Object vs Identifier Parsing
|
||||||
|
|
||||||
parse_alphanum(Type, Pos, String, [C | _] = S, Row, Start, End) when ?IS_LATIN_UPPER(C) ->
|
parse_alphanum(Type, Pos, String, [C | _] = S, Row, Start, End) when ?IS_LATIN_UPPER(C) ->
|
||||||
@ -328,7 +344,9 @@ parse_list_loop(Inner, Pos, String, CloseChar, Row, Start, Acc) ->
|
|||||||
{ok, {{character, CloseChar, _, _, _, _}, NewPos, NewString}} ->
|
{ok, {{character, CloseChar, _, _, _, _}, NewPos, NewString}} ->
|
||||||
{ok, {lists:reverse(Acc), NewPos, NewString}};
|
{ok, {lists:reverse(Acc), NewPos, NewString}};
|
||||||
{ok, {Token, NewPos, NewString}} ->
|
{ok, {Token, NewPos, NewString}} ->
|
||||||
parse_list_loop2(Inner, NewPos, NewString, CloseChar, Row, Start, Acc, Token)
|
parse_list_loop2(Inner, NewPos, NewString, CloseChar, Row, Start, Acc, Token);
|
||||||
|
{error, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
parse_list_loop2(Inner, Pos, String, CloseChar, Row, Start, Acc, Token) ->
|
parse_list_loop2(Inner, Pos, String, CloseChar, Row, Start, Acc, Token) ->
|
||||||
@ -348,6 +366,8 @@ parse_list_loop3(Inner, Pos, String, CloseChar, Row, Start, Acc) ->
|
|||||||
{ok, {lists:reverse(Acc), NewPos, NewString}};
|
{ok, {lists:reverse(Acc), NewPos, NewString}};
|
||||||
{ok, {{character, ",", _, _, _, _}, NewPos, NewString}} ->
|
{ok, {{character, ",", _, _, _, _}, NewPos, NewString}} ->
|
||||||
parse_list_loop(Inner, NewPos, NewString, CloseChar, Row, Start, Acc);
|
parse_list_loop(Inner, NewPos, NewString, CloseChar, Row, Start, Acc);
|
||||||
|
{ok, {Token, _, _}} ->
|
||||||
|
unexpected_token(Token, CloseChar);
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
{error, Reason}
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
@ -472,9 +492,9 @@ parse_tuple_tails(O, N, ExcessCount, HeadTerm, Tails, Pos, String) ->
|
|||||||
{ok, {{character, ",", _, _, _, _}, NewPos, NewString}} ->
|
{ok, {{character, ",", _, _, _, _}, NewPos, NewString}} ->
|
||||||
% It is a real tuple! Try the normal logic, then.
|
% It is a real tuple! Try the normal logic, then.
|
||||||
parse_tuple_tails2(O, N, ExcessCount, HeadTerm, Tails, NewPos, NewString);
|
parse_tuple_tails2(O, N, ExcessCount, HeadTerm, Tails, NewPos, NewString);
|
||||||
{ok, {{_, Actual, _, Row, Start, End}, _, _}} ->
|
{ok, {Token, _, _}} ->
|
||||||
% Anything else is just a boring parse error we can complain about.
|
% Anything else is just a boring parse error we can complain about.
|
||||||
{error, {unexpected_token, Actual, Row, Start, End}};
|
unexpected_token(Token, ")");
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
{error, Reason}
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
@ -509,7 +529,9 @@ parse_multivalue(ElemTypes, Pos, String, Row, Start, Acc) ->
|
|||||||
{ok, {{character, ")", _, Row2, Start2, _}, NewPos, NewString}} ->
|
{ok, {{character, ")", _, Row2, Start2, _}, NewPos, NewString}} ->
|
||||||
check_multivalue_long_enough(ElemTypes, NewPos, NewString, Row2, Start2, Acc);
|
check_multivalue_long_enough(ElemTypes, NewPos, NewString, Row2, Start2, Acc);
|
||||||
{ok, {Token, NewPos, NewString}} ->
|
{ok, {Token, NewPos, NewString}} ->
|
||||||
parse_multivalue2(ElemTypes, NewPos, NewString, Row, Start, Acc, Token)
|
parse_multivalue2(ElemTypes, NewPos, NewString, Row, Start, Acc, Token);
|
||||||
|
{error, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
parse_multivalue2([Next | Rest], Pos, String, Row, Start, Acc, Token) ->
|
parse_multivalue2([Next | Rest], Pos, String, Row, Start, Acc, Token) ->
|
||||||
@ -524,8 +546,8 @@ parse_multivalue2([Next | Rest], Pos, String, Row, Start, Acc, Token) ->
|
|||||||
end;
|
end;
|
||||||
parse_multivalue2([], Pos, String, _, _, Acc, {character, ")", _, _, _, _}) ->
|
parse_multivalue2([], Pos, String, _, _, Acc, {character, ")", _, _, _, _}) ->
|
||||||
{ok, {lists:reverse(Acc), Pos, String}};
|
{ok, {lists:reverse(Acc), Pos, String}};
|
||||||
parse_multivalue2([], _, _, _, _, _, {_, S, _, Row, Start, End}) ->
|
parse_multivalue2([], _, _, _, _, _, Token) ->
|
||||||
{error, {unexpected_token, S, Row, Start, End}}.
|
unexpected_token(Token, ")").
|
||||||
|
|
||||||
parse_multivalue3(ElemTypes, Pos, String, Row, Start, Acc) ->
|
parse_multivalue3(ElemTypes, Pos, String, Row, Start, Acc) ->
|
||||||
case next_token(Pos, String) of
|
case next_token(Pos, String) of
|
||||||
@ -533,8 +555,8 @@ parse_multivalue3(ElemTypes, Pos, String, Row, Start, Acc) ->
|
|||||||
check_multivalue_long_enough(ElemTypes, NewPos, NewString, Row2, Start2, Acc);
|
check_multivalue_long_enough(ElemTypes, NewPos, NewString, Row2, Start2, Acc);
|
||||||
{ok, {{character, ",", _, _, _, _}, NewPos, NewString}} ->
|
{ok, {{character, ",", _, _, _, _}, NewPos, NewString}} ->
|
||||||
parse_multivalue(ElemTypes, NewPos, NewString, Row, Start, Acc);
|
parse_multivalue(ElemTypes, NewPos, NewString, Row, Start, Acc);
|
||||||
{ok, {{_, Actual, _, Row, Start, End}, _, _}} ->
|
{ok, {Token, _, _}} ->
|
||||||
{error, {unexpected_token, Actual, Row, Start, End}};
|
unexpected_token(Token, ")");
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
{error, Reason}
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
@ -578,8 +600,10 @@ parse_variant3(Arities, Tag, ElemTypes, Pos, String) ->
|
|||||||
case next_token(Pos, String) of
|
case next_token(Pos, String) of
|
||||||
{ok, {{character, "(", _, Row, Start, _}, NewPos, NewString}} ->
|
{ok, {{character, "(", _, Row, Start, _}, NewPos, NewString}} ->
|
||||||
parse_variant4(Arities, Tag, ElemTypes, NewPos, NewString, Row, Start);
|
parse_variant4(Arities, Tag, ElemTypes, NewPos, NewString, Row, Start);
|
||||||
{ok, {{_, Actual, _, Row, Start, End}, _, _}} ->
|
{ok, {Token, _, _}} ->
|
||||||
{error, {unexpected_token, Actual, Row, Start, End}}
|
unexpected_token(Token, "(");
|
||||||
|
{error, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
parse_variant4(Arities, Tag, ElemTypes, Pos, String, Row, Start) ->
|
parse_variant4(Arities, Tag, ElemTypes, Pos, String, Row, Start) ->
|
||||||
@ -612,8 +636,10 @@ parse_record_or_map({_, _, unknown_type}, Pos, String, _, _) ->
|
|||||||
parse_map2(unknown_type(), unknown_type(), NewPos, NewString, #{});
|
parse_map2(unknown_type(), unknown_type(), NewPos, NewString, #{});
|
||||||
{ok, {{alphanum, _, _, Row, Start, End}, _, _}} ->
|
{ok, {{alphanum, _, _, Row, Start, End}, _, _}} ->
|
||||||
{error, {unresolved_record, Row, Start, End}};
|
{error, {unresolved_record, Row, Start, End}};
|
||||||
{ok, {{_, S, _, Row, Start, End}, _, _}} ->
|
{ok, {Token, _, _}} ->
|
||||||
{error, {unexpected_token, S, Row, Start, End}}
|
unexpected_token(Token, "}");
|
||||||
|
{error, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
end;
|
end;
|
||||||
parse_record_or_map({O, N, _}, _, _, Row, Start) ->
|
parse_record_or_map({O, N, _}, _, _, Row, Start) ->
|
||||||
{error, {wrong_type, O, N, map, Row, Start, Start}}.
|
{error, {wrong_type, O, N, map, Row, Start, Start}}.
|
||||||
@ -624,8 +650,8 @@ parse_record(Fields, Pos, String, Acc) ->
|
|||||||
parse_record2(Fields, NewPos, NewString, Acc, Ident, Row, Start, End);
|
parse_record2(Fields, NewPos, NewString, Acc, Ident, Row, Start, End);
|
||||||
{ok, {{character, "}", _, Row, Start, End}, NewPos, NewString}} ->
|
{ok, {{character, "}", _, Row, Start, End}, NewPos, NewString}} ->
|
||||||
parse_record_end(Fields, NewPos, NewString, Acc, Row, Start, End);
|
parse_record_end(Fields, NewPos, NewString, Acc, Row, Start, End);
|
||||||
{ok, {{_, S, _, Row, Start, End}, _, _}} ->
|
{ok, {Token, _, _}} ->
|
||||||
{error, {unexpected_token, S, Row, Start, End}};
|
unexpected_token(Token, "}");
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
{error, Reason}
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
@ -669,8 +695,8 @@ parse_record6(Fields, Pos, String, Acc) ->
|
|||||||
parse_record(Fields, NewPos, NewString, Acc);
|
parse_record(Fields, NewPos, NewString, Acc);
|
||||||
{ok, {{character, "}", _, Row, Start, End}, NewPos, NewString}} ->
|
{ok, {{character, "}", _, Row, Start, End}, NewPos, NewString}} ->
|
||||||
parse_record_end(Fields, NewPos, NewString, Acc, Row, Start, End);
|
parse_record_end(Fields, NewPos, NewString, Acc, Row, Start, End);
|
||||||
{ok, {{_, S, _, Row, Start, End}, _, _}} ->
|
{ok, {Token, _, _}} ->
|
||||||
{error, {unexpected_token, S, Row, Start, End}};
|
unexpected_token(Token, "}");
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
{error, Reason}
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
@ -708,8 +734,10 @@ parse_map(KeyType, ValueType, Pos, String, Acc) ->
|
|||||||
parse_map2(KeyType, ValueType, NewPos, NewString, Acc);
|
parse_map2(KeyType, ValueType, NewPos, NewString, Acc);
|
||||||
{ok, {{character, "}", _, _, _, _}, NewPos, NewString}} ->
|
{ok, {{character, "}", _, _, _, _}, NewPos, NewString}} ->
|
||||||
{ok, {Acc, NewPos, NewString}};
|
{ok, {Acc, NewPos, NewString}};
|
||||||
{ok, {{_, S, _, Row, Start, End}, _, _}} ->
|
{ok, {Token, _, _}} ->
|
||||||
{error, {unexpected_token, S, Row, Start, End}}
|
unexpected_token(Token, "}");
|
||||||
|
{error, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
parse_map2(KeyType, ValueType, Pos, String, Acc) ->
|
parse_map2(KeyType, ValueType, Pos, String, Acc) ->
|
||||||
@ -743,8 +771,10 @@ parse_map5(KeyType, ValueType, Pos, String, Acc) ->
|
|||||||
parse_map(KeyType, ValueType, NewPos, NewString, Acc);
|
parse_map(KeyType, ValueType, NewPos, NewString, Acc);
|
||||||
{ok, {{character, "}", _, _, _, _}, NewPos, NewString}} ->
|
{ok, {{character, "}", _, _, _, _}, NewPos, NewString}} ->
|
||||||
{ok, {Acc, NewPos, NewString}};
|
{ok, {Acc, NewPos, NewString}};
|
||||||
{ok, {{_, S, _, Row, Start, End}, _, _}} ->
|
{ok, {Token, _, _}} ->
|
||||||
{error, {unexpected_token, S, Row, Start, End}}
|
unexpected_token(Token, "}");
|
||||||
|
{error, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
% TODO
|
% TODO
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user