diff --git a/lib/elixir/src/elixir_parser.yrl b/lib/elixir/src/elixir_parser.yrl index 46119edbcb..e125000506 100644 --- a/lib/elixir/src/elixir_parser.yrl +++ b/lib/elixir/src/elixir_parser.yrl @@ -1,7 +1,6 @@ Nonterminals grammar expr_list - expr container_expr block_expr access_expr - no_parens_expr no_parens_one_expr no_parens_one_ambig_expr + expr container_expr block_expr no_parens_expr no_parens_one_expr access_expr bracket_expr bracket_at_expr bracket_arg matched_expr unmatched_expr max_expr op_expr matched_op_expr no_parens_op_expr comp_op_eol at_op_eol unary_op_eol and_op_eol or_op_eol capture_op_eol @@ -16,9 +15,8 @@ Nonterminals assoc_op_eol assoc_expr assoc_base assoc_update assoc_update_kw assoc container_args_base container_args call_args_parens_expr call_args_parens_base call_args_parens parens_call - call_args_no_parens_one call_args_no_parens_one_ambig call_args_no_parens_expr - call_args_no_parens_comma_expr call_args_no_parens_all call_args_no_parens_many - call_args_no_parens_many_strict + call_args_no_parens_one call_args_no_parens_expr call_args_no_parens_comma_expr + call_args_no_parens_all call_args_no_parens_many call_args_no_parens_many_strict stab stab_eoe stab_expr stab_maybe_expr stab_parens_many kw_eol kw_base kw call_args_no_parens_kw_expr call_args_no_parens_kw dot_op dot_alias dot_identifier dot_op_identifier dot_do_identifier @@ -88,29 +86,11 @@ expr_list -> expr_list eoe expr : ['$3'|'$1']. expr -> matched_expr : '$1'. expr -> no_parens_expr : '$1'. -expr -> no_parens_one_ambig_expr : '$1'. expr -> unmatched_expr : '$1'. %% In Elixir we have three main call syntaxes: with parentheses, %% without parentheses and with do blocks. They are represented %% in the AST as matched, no_parens and unmatched. -%% -%% Calls without parentheses are further divided according to how -%% problematic they are: -%% -%% (a) no_parens: a call with several arguments (e.g. `f a, b`) -%% -%% (b) no_parens_one: a call with one unproblematic argument -%% (e.g. `f a` or `f g a` and similar) -%% -%% (c) no_parens_one_ambig: a call with one argument which is -%% itself a no_parens or no_parens_one_ambig (e.g. `f g a, b` -%% or `f g h a, b` and similar) -%% -%% Note, in particular, that no_parens_one_ambig expressions are -%% ambiguous and are interpreted such that the outer function has -%% arity 1 (e.g. `f g a, b` is interpreted as `f(g(a, b))` rather -%% than `f(g(a), b)`). Hence the name, no_parens_one_ambig. %% %% The distinction is required because we can't, for example, have %% a function call with a do block as argument inside another do @@ -212,9 +192,6 @@ no_parens_one_expr -> dot_identifier call_args_no_parens_one : build_identifier( no_parens_one_expr -> dot_do_identifier : build_identifier('$1', nil). no_parens_one_expr -> dot_identifier : build_identifier('$1', nil). -no_parens_one_ambig_expr -> dot_op_identifier call_args_no_parens_one_ambig : build_identifier('$1', '$2'). -no_parens_one_ambig_expr -> dot_identifier call_args_no_parens_one_ambig : build_identifier('$1', '$2'). - %% From this point on, we just have constructs that can be %% used with the access syntax. Notice that (dot_)identifier %% is not included in this list simply because the tokenizer @@ -430,22 +407,17 @@ parens_call -> matched_expr dot_call_op : {'.', meta('$2'), ['$1']}. % Fun/local % Function calls with no parentheses call_args_no_parens_expr -> matched_expr : '$1'. -call_args_no_parens_expr -> no_parens_one_ambig_expr : '$1'. call_args_no_parens_expr -> no_parens_expr : throw_no_parens_many_strict('$1'). call_args_no_parens_comma_expr -> matched_expr ',' call_args_no_parens_expr : ['$3', '$1']. -call_args_no_parens_comma_expr -> no_parens_one_ambig_expr ',' call_args_no_parens_expr : ['$3', '$1']. call_args_no_parens_comma_expr -> call_args_no_parens_comma_expr ',' call_args_no_parens_expr : ['$3'|'$1']. call_args_no_parens_all -> call_args_no_parens_one : '$1'. -call_args_no_parens_all -> call_args_no_parens_one_ambig : '$1'. call_args_no_parens_all -> call_args_no_parens_many : '$1'. call_args_no_parens_one -> call_args_no_parens_kw : ['$1']. call_args_no_parens_one -> matched_expr : ['$1']. - -call_args_no_parens_one_ambig -> no_parens_expr : ['$1']. -call_args_no_parens_one_ambig -> no_parens_one_ambig_expr : ['$1']. +call_args_no_parens_one -> no_parens_expr : ['$1']. call_args_no_parens_many -> matched_expr ',' call_args_no_parens_kw : ['$1', '$3']. call_args_no_parens_many -> call_args_no_parens_comma_expr : reverse('$1'). @@ -462,7 +434,6 @@ stab_parens_many -> open_paren call_args_no_parens_many close_paren : '$2'. container_expr -> matched_expr : '$1'. container_expr -> unmatched_expr : '$1'. -container_expr -> no_parens_one_ambig_expr : throw_no_parens_many_strict('$1'). container_expr -> no_parens_expr : throw_no_parens_many_strict('$1'). container_args_base -> container_expr : ['$1']. diff --git a/lib/elixir/test/elixir/kernel/errors_test.exs b/lib/elixir/test/elixir/kernel/errors_test.exs index efce105b60..758e8af5d5 100644 --- a/lib/elixir/test/elixir/kernel/errors_test.exs +++ b/lib/elixir/test/elixir/kernel/errors_test.exs @@ -129,18 +129,15 @@ defmodule Kernel.ErrorsTest do "nested calls. Syntax error before: ','" assert_compile_fail SyntaxError, msg, '[foo 1, 2]' - assert_compile_fail SyntaxError, msg, '[foo bar 1, 2]' assert_compile_fail SyntaxError, msg, '[do: foo 1, 2]' assert_compile_fail SyntaxError, msg, 'foo(do: bar 1, 2)' assert_compile_fail SyntaxError, msg, '{foo 1, 2}' - assert_compile_fail SyntaxError, msg, '{foo bar 1, 2}' assert_compile_fail SyntaxError, msg, 'foo 1, foo 2, 3' assert_compile_fail SyntaxError, msg, 'foo(1, foo 2, 3)' assert is_list List.flatten [1] assert is_list Enum.reverse [3, 2, 1], [4, 5, 6] assert is_list(Enum.reverse [3, 2, 1], [4, 5, 6]) - assert [List.flatten List.flatten [1]] == [[1]] end test :syntax_error_on_atom_dot_alias do