@@ -87,6 +87,28 @@ expr -> matched_expr : '$1'.
8787expr -> no_parens_expr : '$1' .
8888expr -> unmatched_expr : '$1' .
8989
90+ % % In Elixir we have three main call syntaxes: with parentheses,
91+ % % without parentheses and with do blocks. They are represented
92+ % % in the AST as matched, no_parens and unmatched.
93+ % %
94+ % % The distinction is required because we can't, for example, have
95+ % % a function call with a do block as argument inside another do
96+ % % block call, unless there are parentheses:
97+ % %
98+ % % if if true do true else false end do #=> invalid
99+ % % if(if true do true else false end) do #=> valid
100+ % %
101+ % % Similarly, it is not possible to nest calls without parentheses
102+ % % if their arity is more than 1:
103+ % %
104+ % % foo a, bar b, c #=> invalid
105+ % % foo(a, bar b, c) #=> invalid
106+ % % foo a, bar b #=> valid
107+ % % foo a, bar(b, c) #=> valid
108+ % %
109+ % % So the different grammar rules need to take into account
110+ % % if calls without parentheses are do blocks in particular
111+ % % segments and act accordingly.
90112matched_expr -> matched_expr matched_op_expr : build_op (element (1 , '$2' ), '$1' , element (2 , '$2' )).
91113matched_expr -> matched_expr no_parens_op_expr : build_op (element (1 , '$2' ), '$1' , element (2 , '$2' )).
92114matched_expr -> unary_op_eol matched_expr : build_unary_op ('$1' , '$2' ).
@@ -140,13 +162,16 @@ no_parens_op_expr -> tail_op_eol no_parens_expr : { '$1', '$2' }.
140162no_parens_op_expr -> than_op_eol no_parens_expr : { '$1' , '$2' }.
141163no_parens_op_expr -> in_op_eol no_parens_expr : { '$1' , '$2' }.
142164no_parens_op_expr -> inc_op_eol no_parens_expr : { '$1' , '$2' }.
143- no_parens_op_expr -> when_op_eol no_parens_expr : { '$1' , '$2' }.
144165no_parens_op_expr -> range_op_eol no_parens_expr : { '$1' , '$2' }.
145166no_parens_op_expr -> default_op_eol no_parens_expr : { '$1' , '$2' }.
146167no_parens_op_expr -> type_op_eol no_parens_expr : { '$1' , '$2' }.
147168no_parens_op_expr -> comp_op_eol no_parens_expr : { '$1' , '$2' }.
148169no_parens_op_expr -> arrow_op_eol no_parens_expr : { '$1' , '$2' }.
149170
171+ % % Allow when (and only when) with keywords
172+ no_parens_op_expr -> when_op_eol no_parens_expr : { '$1' , '$2' }.
173+ no_parens_op_expr -> when_op_eol call_args_no_parens_kw : { '$1' , '$2' }.
174+
150175matched_op_expr -> match_op_eol matched_expr : { '$1' , '$2' }.
151176matched_op_expr -> add_op_eol matched_expr : { '$1' , '$2' }.
152177matched_op_expr -> mult_op_eol matched_expr : { '$1' , '$2' }.
0 commit comments