Skip to content

Commit c2d1699

Browse files
author
José Valim
committed
Improve error messages on else do grammar mistakes, closes #888
1 parent e412ce6 commit c2d1699

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

lib/elixir/src/elixir_tokenizer.erl

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -394,13 +394,15 @@ tokenize([H|_] = String, Line, Scope, Tokens) when ?is_upcase(H) ->
394394
tokenize([H|_] = String, Line, Scope, Tokens) when ?is_downcase(H); H == $_ ->
395395
{ Rest, { Kind, _, Identifier } } = tokenize_any_identifier(String, Line, [], Scope),
396396
case handle_keyword(Line, Kind, Identifier, Tokens) of
397-
false ->
397+
nomatch ->
398398
tokenize(Rest, Line, Scope, [{ Kind, Line, Identifier }|Tokens]);
399-
[Check|T] ->
399+
{ ok, [Check|T] } ->
400400
case handle_terminator(Check, Scope) of
401401
{ error, _ } = Error -> Error;
402402
New -> tokenize(Rest, Line, New, [Check|T])
403-
end
403+
end;
404+
{ error, Token } ->
405+
{ error, { Line, "syntax error before: ", Token } }
404406
end;
405407

406408
% Ambiguous unary/binary operators tokens
@@ -807,29 +809,40 @@ terminator('<<') -> '>>'.
807809

808810
% Keywords check
809811
handle_keyword(Line, Identifier, Atom, [{ '.', _ }|_] = Tokens) ->
810-
[{ Identifier, Line, Atom }|Tokens];
812+
{ ok, [{ Identifier, Line, Atom }|Tokens] };
811813

812814
handle_keyword(Line, Identifier, Atom, Tokens) when
813815
Identifier == identifier; Identifier == do_identifier;
814816
Identifier == bracket_identifier; Identifier == paren_identifier ->
815817
case keyword(Atom) of
816-
true -> [{ Atom, Line }|Tokens];
817-
op -> add_token_with_nl({ Atom, Line }, Tokens);
818-
block -> [{ block_identifier, Line, Atom }|Tokens];
819-
false -> false
818+
true -> { ok, [{ Atom, Line }|Tokens] };
819+
op -> { ok, add_token_with_nl({ Atom, Line }, Tokens) };
820+
block -> { ok, [{ block_identifier, Line, Atom }|Tokens] };
821+
do ->
822+
case do_keyword_valid(Tokens) of
823+
true -> { ok, [{ Atom, Line }|Tokens] };
824+
false -> { error, "do" }
825+
end;
826+
false -> nomatch
820827
end;
821828

822-
handle_keyword(_, _, _, _) -> false.
829+
handle_keyword(_, _, _, _) -> nomatch.
830+
831+
do_keyword_valid([{ Atom, _ }|_]) ->
832+
is_boolean(keyword(Atom));
833+
do_keyword_valid(_) -> true.
823834

824835
% Keywords
825836
keyword('fn') -> true;
826-
keyword('do') -> true;
827837
keyword('end') -> true;
828838
keyword('true') -> true;
829839
keyword('false') -> true;
830840
keyword('nil') -> true;
831841
keyword('not') -> true;
832842

843+
% Special handling for do
844+
keyword('do') -> do;
845+
833846
% Bin operator keywords
834847
keyword('and') -> op;
835848
keyword('or') -> op;

0 commit comments

Comments
 (0)