diff --git a/lib/elixir/src/elixir_parser.yrl b/lib/elixir/src/elixir_parser.yrl index ee782bd882..7bda10d62b 100644 --- a/lib/elixir/src/elixir_parser.yrl +++ b/lib/elixir/src/elixir_parser.yrl @@ -3,12 +3,12 @@ Nonterminals grammar expr_list - expr block_expr fn_expr bracket_expr call_expr bracket_at_expr max_expr + expr paren_expr block_expr fn_expr bracket_expr call_expr bracket_at_expr max_expr base_expr matched_expr matched_op_expr unmatched_expr op_expr add_op mult_op unary_op two_op pipeline_op bin_concat_op match_op send_op default_op when_op pipe_op in_op inc_op stab_op range_op andand_op oror_op and_op or_op comp_expr_op colon_colon_op three_op at_op - open_paren close_paren + open_paren close_paren empty_paren open_bracket close_bracket open_curly close_curly open_bit close_bit @@ -80,9 +80,12 @@ grammar -> '$empty' : [nil]. % Note expressions are on reverse order expr_list -> expr : ['$1']. -expr_list -> open_paren ')' : [nil]. +expr_list -> empty_paren : [nil]. expr_list -> expr_list eol expr : ['$3'|'$1']. +paren_expr -> empty_paren : nil. +paren_expr -> expr : '$1'. + expr -> matched_expr : '$1'. expr -> unmatched_expr : '$1'. @@ -229,6 +232,8 @@ open_paren -> '(' eol : '$1'. close_paren -> ')' : '$1'. close_paren -> eol ')' : '$2'. +empty_paren -> open_paren ')' : nil. + open_bracket -> '[' : '$1'. open_bracket -> '[' eol : '$1'. close_bracket -> ']' : '$1'. @@ -388,17 +393,17 @@ call_args_parens_not_one -> open_paren ')' : []. call_args_parens_not_one -> open_paren matched_kw_base close_paren : ['$2']. call_args_parens_not_one -> open_paren matched_expr ',' call_args_no_parens close_paren : ['$2'|'$4']. -base_comma_expr -> expr ',' : ['$1']. -base_comma_expr -> base_comma_expr expr ',' : ['$2'|'$1']. +base_comma_expr -> paren_expr ',' : ['$1']. +base_comma_expr -> base_comma_expr paren_expr ',' : ['$2'|'$1']. -comma_expr -> expr : ['$1']. +comma_expr -> paren_expr : ['$1']. comma_expr -> kw_base : ['$1']. comma_expr -> base_comma_expr : '$1'. -comma_expr -> base_comma_expr expr : ['$2'|'$1']. +comma_expr -> base_comma_expr paren_expr : ['$2'|'$1']. comma_expr -> base_comma_expr kw_base : ['$2'|'$1']. -optional_comma_expr -> expr : '$1'. -optional_comma_expr -> expr ',' : '$1'. +optional_comma_expr -> paren_expr : '$1'. +optional_comma_expr -> paren_expr ',' : '$1'. call_args -> comma_expr : lists:reverse('$1'). @@ -409,7 +414,7 @@ call_args_parens -> open_paren call_args close_paren : '$2'. kw_eol -> kw_identifier : '$1'. kw_eol -> kw_identifier eol : '$1'. -kw_expr -> kw_eol expr : { ?exprs('$1'),'$2' }. +kw_expr -> kw_eol paren_expr : { ?exprs('$1'),'$2' }. kw_comma -> kw_expr ',' : ['$1']. kw_comma -> kw_comma kw_expr ',' : ['$2'|'$1']. @@ -419,6 +424,7 @@ kw_base -> kw_comma : lists:reverse('$1'). kw_base -> kw_comma kw_expr : lists:reverse(['$2'|'$1']). matched_kw_expr -> kw_eol matched_expr : {?exprs('$1'),'$2'}. +matched_kw_expr -> kw_eol empty_paren : {?exprs('$1'),nil}. matched_kw_comma -> matched_kw_expr : ['$1']. matched_kw_comma -> matched_kw_expr ',' matched_kw_comma : ['$1'|'$3']. matched_kw_base -> matched_kw_comma : '$1'. @@ -432,13 +438,13 @@ bracket_access -> open_bracket kw_base close_bracket : { '$2', ?line('$1') }. list -> open_bracket ']' : []. list -> open_bracket kw_base close_bracket : '$2'. list -> open_bracket optional_comma_expr close_bracket : ['$2']. -list -> open_bracket expr ',' call_args close_bracket : ['$2'|'$4']. +list -> open_bracket paren_expr ',' call_args close_bracket : ['$2'|'$4']. % Tuple tuple -> open_curly '}' : build_tuple('$1', []). tuple -> open_curly optional_comma_expr close_curly : build_tuple('$1', ['$2']). -tuple -> open_curly expr ',' call_args close_curly : build_tuple('$1', ['$2'|'$4']). +tuple -> open_curly paren_expr ',' call_args close_curly : build_tuple('$1', ['$2'|'$4']). % Bitstrings diff --git a/lib/elixir/test/elixir/kernel_test.exs b/lib/elixir/test/elixir/kernel_test.exs index 610c6d2eb0..6a44dc6e0a 100644 --- a/lib/elixir/test/elixir/kernel_test.exs +++ b/lib/elixir/test/elixir/kernel_test.exs @@ -20,6 +20,13 @@ defmodule KernelTest do refute x([]) end + test :paren do + assert nil?(()) + assert [ 1, (), 3 ] == [1, nil, 3 ] + assert [do: ()] == [do: nil] + assert { 1, (), 3 } == { 1, nil, 3 } + end + test :__info__ do assert { :in, 2 } inlist Kernel.__info__(:macros) end