@@ -20,7 +20,7 @@ Nonterminals
20
20
call_args_no_parens_comma_expr call_args_no_parens_all call_args_no_parens_many
21
21
call_args_no_parens_many_strict
22
22
stab stab_eoe stab_expr stab_op_eol_and_expr stab_parens_many
23
- kw_eol kw_base kw call_args_no_parens_kw_expr call_args_no_parens_kw
23
+ kw_eol kw_base kw_data kw_call call_args_no_parens_kw_expr call_args_no_parens_kw
24
24
dot_op dot_alias dot_bracket_identifier dot_call_identifier
25
25
dot_identifier dot_op_identifier dot_do_identifier dot_paren_identifier
26
26
do_block fn_eoe do_eoe end_eoe block_eoe block_item block_list
@@ -285,7 +285,7 @@ number -> char : handle_number(?exprs('$1'), '$1', number_value('$1')).
285
285
parens_call -> dot_call_identifier call_args_parens : build_parens ('$1' , '$2' , {[], []}).
286
286
parens_call -> dot_call_identifier call_args_parens call_args_parens : build_nested_parens ('$1' , '$2' , '$3' , {[], []}).
287
287
288
- bracket_arg -> open_bracket kw close_bracket : build_access_arg ('$1' , '$2' , '$3' ).
288
+ bracket_arg -> open_bracket kw_data close_bracket : build_access_arg ('$1' , '$2' , '$3' ).
289
289
bracket_arg -> open_bracket container_expr close_bracket : build_access_arg ('$1' , '$2' , '$3' ).
290
290
bracket_arg -> open_bracket container_expr ',' close_bracket : build_access_arg ('$1' , '$2' , '$4' ).
291
291
@@ -513,7 +513,7 @@ container_args_base -> container_args_base ',' container_expr : ['$3' | '$1'].
513
513
514
514
container_args -> container_args_base : reverse ('$1' ).
515
515
container_args -> container_args_base ',' : reverse ('$1' ).
516
- container_args -> container_args_base ',' kw : reverse (['$3' | '$1' ]).
516
+ container_args -> container_args_base ',' kw_call : reverse (['$3' | '$1' ]).
517
517
518
518
% Function calls with parentheses
519
519
@@ -528,16 +528,16 @@ call_args_parens -> open_paren ')' :
528
528
{newlines_pair ('$1' , '$2' ), []}.
529
529
call_args_parens -> open_paren no_parens_expr close_paren :
530
530
{newlines_pair ('$1' , '$3' ), ['$2' ]}.
531
- call_args_parens -> open_paren kw_base close_paren :
532
- {newlines_pair ('$1' , '$3' ), [reverse ( '$2' ) ]}.
533
- call_args_parens -> open_paren kw_base ',' close_paren :
534
- warn_trailing_comma ('$3' ), {newlines_pair ('$1' , '$4' ), [reverse ( '$2' ) ]}.
531
+ call_args_parens -> open_paren kw_call close_paren :
532
+ {newlines_pair ('$1' , '$3' ), ['$2' ]}.
533
+ call_args_parens -> open_paren kw_call ',' close_paren :
534
+ warn_trailing_comma ('$3' ), {newlines_pair ('$1' , '$4' ), ['$2' ]}.
535
535
call_args_parens -> open_paren call_args_parens_base close_paren :
536
536
{newlines_pair ('$1' , '$3' ), reverse ('$2' )}.
537
- call_args_parens -> open_paren call_args_parens_base ',' kw_base close_paren :
538
- {newlines_pair ('$1' , '$5' ), reverse ([reverse ( '$4' ) | '$2' ])}.
539
- call_args_parens -> open_paren call_args_parens_base ',' kw_base ',' close_paren :
540
- warn_trailing_comma ('$5' ), {newlines_pair ('$1' , '$6' ), reverse ([reverse ( '$4' ) | '$2' ])}.
537
+ call_args_parens -> open_paren call_args_parens_base ',' kw_call close_paren :
538
+ {newlines_pair ('$1' , '$5' ), reverse (['$4' | '$2' ])}.
539
+ call_args_parens -> open_paren call_args_parens_base ',' kw_call ',' close_paren :
540
+ warn_trailing_comma ('$5' ), {newlines_pair ('$1' , '$6' ), reverse (['$4' | '$2' ])}.
541
541
542
542
% KV
543
543
@@ -551,21 +551,27 @@ kw_eol -> kw_identifier_unsafe eol : build_quoted_atom('$1', false, [{format, ke
551
551
kw_base -> kw_eol container_expr : [{'$1' , '$2' }].
552
552
kw_base -> kw_base ',' kw_eol container_expr : [{'$3' , '$4' } | '$1' ].
553
553
554
- kw -> kw_base : reverse ('$1' ).
555
- kw -> kw_base ',' : reverse ('$1' ).
554
+ kw_call -> kw_base : reverse ('$1' ).
555
+ kw_call -> kw_base ',' : reverse ('$1' ).
556
+ kw_call -> kw_base ',' matched_expr : error_bad_keyword_call_follow_up ('$2' ).
557
+
558
+ kw_data -> kw_base : reverse ('$1' ).
559
+ kw_data -> kw_base ',' : reverse ('$1' ).
560
+ kw_data -> kw_base ',' matched_expr : error_bad_keyword_data_follow_up ('$2' ).
556
561
557
562
call_args_no_parens_kw_expr -> kw_eol matched_expr : {'$1' , '$2' }.
558
563
call_args_no_parens_kw_expr -> kw_eol no_parens_expr : {'$1' , '$2' }.
559
564
560
565
call_args_no_parens_kw -> call_args_no_parens_kw_expr : ['$1' ].
561
566
call_args_no_parens_kw -> call_args_no_parens_kw_expr ',' call_args_no_parens_kw : ['$1' | '$3' ].
567
+ call_args_no_parens_kw -> call_args_no_parens_kw_expr ',' matched_expr : error_bad_keyword_call_follow_up ('$2' ).
562
568
563
569
% Lists
564
570
565
- list_args -> kw : '$1' .
571
+ list_args -> kw_data : '$1' .
566
572
list_args -> container_args_base : reverse ('$1' ).
567
573
list_args -> container_args_base ',' : reverse ('$1' ).
568
- list_args -> container_args_base ',' kw : reverse ('$1' , '$3' ).
574
+ list_args -> container_args_base ',' kw_data : reverse ('$1' , '$3' ).
569
575
570
576
list -> open_bracket ']' : build_list ('$1' , [], '$2' ).
571
577
list -> open_bracket list_args close_bracket : build_list ('$1' , '$2' , '$3' ).
@@ -595,8 +601,8 @@ assoc_expr -> parens_call : '$1'.
595
601
assoc_update -> matched_expr pipe_op_eol assoc_expr : {'$2' , '$1' , ['$3' ]}.
596
602
assoc_update -> unmatched_expr pipe_op_eol assoc_expr : {'$2' , '$1' , ['$3' ]}.
597
603
598
- assoc_update_kw -> matched_expr pipe_op_eol kw : {'$2' , '$1' , '$3' }.
599
- assoc_update_kw -> unmatched_expr pipe_op_eol kw : {'$2' , '$1' , '$3' }.
604
+ assoc_update_kw -> matched_expr pipe_op_eol kw_data : {'$2' , '$1' , '$3' }.
605
+ assoc_update_kw -> unmatched_expr pipe_op_eol kw_data : {'$2' , '$1' , '$3' }.
600
606
601
607
assoc_base -> assoc_expr : ['$1' ].
602
608
assoc_base -> assoc_base ',' assoc_expr : ['$3' | '$1' ].
@@ -607,9 +613,9 @@ assoc -> assoc_base ',' : reverse('$1').
607
613
map_op -> '%{}' : '$1' .
608
614
map_op -> '%{}' eol : '$1' .
609
615
610
- map_close -> kw close_curly : {'$1' , '$2' }.
616
+ map_close -> kw_data close_curly : {'$1' , '$2' }.
611
617
map_close -> assoc close_curly : {'$1' , '$2' }.
612
- map_close -> assoc_base ',' kw close_curly : {reverse ('$1' , '$3' ), '$4' }.
618
+ map_close -> assoc_base ',' kw_data close_curly : {reverse ('$1' , '$3' ), '$4' }.
613
619
614
620
map_args -> open_curly '}' : build_map ('$1' , [], '$2' ).
615
621
map_args -> open_curly map_close : build_map ('$1' , element (1 , '$2' ), element (2 , '$2' )).
@@ -1053,6 +1059,24 @@ error_bad_atom(Token) ->
1053
1059
" If the '.' was meant to be part of the atom's name, "
1054
1060
" the atom name must be quoted. Syntax error before: " , " '.'" ).
1055
1061
1062
+ error_bad_keyword_call_follow_up (Token ) ->
1063
+ return_error (meta_from_token (Token ),
1064
+ " unexpected expression after keyword list. Keyword lists must always come as the last argument. Therefore, this is not allowed:\n\n "
1065
+ " function_call(1, some: :option, 2)\n\n "
1066
+ " Instead, wrap the keyword in brackets:\n\n "
1067
+ " function_call(1, [some: :option], 2)\n\n "
1068
+ " Syntax error after: " , " ','" ).
1069
+
1070
+ error_bad_keyword_data_follow_up (Token ) ->
1071
+ return_error (meta_from_token (Token ),
1072
+ " unexpected expression after keyword list. Keyword lists must always come last in lists and maps. Therefore, this is not allowed:\n\n "
1073
+ " [some: :value, :another]\n "
1074
+ " %{some: :value, another => value}\n\n "
1075
+ " Instead, reorder it to be the last entry:\n\n "
1076
+ " [:another, some: :value]\n "
1077
+ " %{another => value, some: :value}\n\n "
1078
+ " Syntax error after: " , " ','" ).
1079
+
1056
1080
error_no_parens_strict (Token ) ->
1057
1081
return_error (meta_from_token (Token ), " unexpected parentheses. If you are making a "
1058
1082
" function call, do not insert spaces between the function name and the "
0 commit comments